@@ -936,6 +936,11 @@ public float SlipSpeedPercent
936
936
}
937
937
}
938
938
939
+ /// <summary>
940
+ /// Percentage of wheelslip (different models use different observables to calculate it)
941
+ /// </summary>
942
+ public float SlipPercent ;
943
+
939
944
/// <summary>
940
945
/// Slip speed rate of change value, in metric (meters per second) per second
941
946
/// </summary>
@@ -1097,7 +1102,7 @@ public void Save(BinaryWriter outf)
1097
1102
{
1098
1103
double slipSpeedMpS = axleSpeedMpS - TrainSpeedMpS ;
1099
1104
// Compute force transmitted to rail according to adhesion curves
1100
- double axleOutForceN = 0 ;
1105
+ double axleOutForceN ;
1101
1106
if ( Axles . UsePolachAdhesion )
1102
1107
{
1103
1108
axleOutForceN = Math . Sign ( slipSpeedMpS ) * AxleWeightN * SlipCharacteristicsPolach ( slipSpeedMpS ) ;
@@ -1361,51 +1366,52 @@ public virtual void Update(float elapsedSeconds)
1361
1366
if ( advancedAdhesion )
1362
1367
{
1363
1368
Integrate ( elapsedSeconds ) ;
1364
- if ( SlipSpeedPercent > ( Car is MSTSLocomotive loco && loco . SlipControlSystem == MSTSLocomotive . SlipControlType . Full ? ( 200 - SlipWarningTresholdPercent ) : 100 ) )
1365
- {
1366
- // Wheel slip internally happens instantaneously, but may correct itself in a short period, so HuD indication has a small time delay to eliminate "false" indications
1367
- IsWheelSlip = IsWheelSlipWarning = true ;
1368
1369
1369
- // Wait some time before indicating the HuD wheelslip to avoid false triggers
1370
- // TODO: set an increased HUD wheelslip threshold if a slip control system is fitted, as it operates close to the wheelslip threshold
1371
- if ( WheelSlipTimeS > WheelSlipThresholdTimeS )
1372
- {
1373
- HuDIsWheelSlip = HuDIsWheelSlipWarning = true ;
1374
- }
1375
- WheelSlipTimeS += elapsedSeconds ;
1376
- }
1377
- else if ( Math . Abs ( SlipSpeedPercent ) > SlipWarningTresholdPercent )
1378
- {
1379
- // Wheel slip internally happens instantaneously, but may correct itself in a short period, so HuD indication has a small time delay to eliminate "false" indications
1380
- IsWheelSlipWarning = true ;
1381
- IsWheelSlip = false ;
1382
-
1383
- // Wait some time before indicating wheelslip to avoid false triggers
1384
- if ( WheelSlipWarningTimeS > WheelSlipWarningThresholdTimeS ) HuDIsWheelSlipWarning = true ;
1385
- HuDIsWheelSlip = false ;
1386
- WheelSlipWarningTimeS += elapsedSeconds ;
1387
- }
1388
- else
1370
+ SlipPercent = SlipSpeedPercent ;
1371
+
1372
+ if ( elapsedSeconds > 0.0f )
1389
1373
{
1390
- HuDIsWheelSlipWarning = false ;
1391
- HuDIsWheelSlip = false ;
1392
- IsWheelSlipWarning = false ;
1393
- IsWheelSlip = false ;
1394
- WheelSlipWarningTimeS = WheelSlipTimeS = 0 ;
1374
+ slipDerivationMpSS = ( SlipSpeedMpS - previousSlipSpeedMpS ) / elapsedSeconds ;
1375
+ previousSlipSpeedMpS = SlipSpeedMpS ;
1376
+
1377
+ slipDerivationPercentpS = ( SlipSpeedPercent - previousSlipPercent ) / elapsedSeconds ;
1378
+ previousSlipPercent = SlipSpeedPercent ;
1395
1379
}
1396
1380
}
1397
1381
else
1398
1382
{
1399
1383
UpdateSimpleAdhesion ( elapsedSeconds ) ;
1400
1384
}
1385
+ if ( SlipPercent > ( Car is MSTSLocomotive loco && loco . SlipControlSystem == MSTSLocomotive . SlipControlType . Full && Math . Abs ( DriveForceN ) > BrakeRetardForceN ? ( 200 - SlipWarningTresholdPercent ) : 100 ) )
1386
+ {
1387
+ // Wheel slip internally happens instantaneously, but may correct itself in a short period, so HuD indication has a small time delay to eliminate "false" indications
1388
+ IsWheelSlip = IsWheelSlipWarning = true ;
1401
1389
1402
- if ( elapsedSeconds > 0.0f )
1390
+ // Wait some time before indicating the HuD wheelslip to avoid false triggers
1391
+ if ( WheelSlipTimeS > WheelSlipThresholdTimeS )
1392
+ {
1393
+ HuDIsWheelSlip = HuDIsWheelSlipWarning = true ;
1394
+ }
1395
+ WheelSlipTimeS += elapsedSeconds ;
1396
+ }
1397
+ else if ( SlipPercent > SlipWarningTresholdPercent )
1403
1398
{
1404
- slipDerivationMpSS = ( SlipSpeedMpS - previousSlipSpeedMpS ) / elapsedSeconds ;
1405
- previousSlipSpeedMpS = SlipSpeedMpS ;
1399
+ // Wheel slip internally happens instantaneously, but may correct itself in a short period, so HuD indication has a small time delay to eliminate "false" indications
1400
+ IsWheelSlipWarning = true ;
1401
+ IsWheelSlip = false ;
1406
1402
1407
- slipDerivationPercentpS = ( SlipSpeedPercent - previousSlipPercent ) / elapsedSeconds ;
1408
- previousSlipPercent = SlipSpeedPercent ;
1403
+ // Wait some time before indicating wheelslip to avoid false triggers
1404
+ if ( WheelSlipWarningTimeS > WheelSlipWarningThresholdTimeS ) HuDIsWheelSlipWarning = true ;
1405
+ HuDIsWheelSlip = false ;
1406
+ WheelSlipWarningTimeS += elapsedSeconds ;
1407
+ }
1408
+ else
1409
+ {
1410
+ HuDIsWheelSlipWarning = false ;
1411
+ HuDIsWheelSlip = false ;
1412
+ IsWheelSlipWarning = false ;
1413
+ IsWheelSlip = false ;
1414
+ WheelSlipWarningTimeS = WheelSlipTimeS = 0 ;
1409
1415
}
1410
1416
}
1411
1417
@@ -1427,56 +1433,45 @@ public void UpdateSimpleAdhesion(float elapsedClockSeconds)
1427
1433
AxleFrictionForceN = frictionForceN ;
1428
1434
AxleSpeedMpS = TrainSpeedMpS ;
1429
1435
1430
- float maxAdhesionForceN = AxleWeightN * AdhesionLimit ;
1431
- if ( Math . Abs ( axleOutForceN ) > maxAdhesionForceN )
1436
+ float adhesionForceN = AxleWeightN * AdhesionLimit ;
1437
+ SlipPercent = Math . Abs ( axleOutForceN ) / adhesionForceN * 100 ;
1438
+ if ( SlipPercent > 100 )
1432
1439
{
1433
- axleOutForceN = MathHelper . Clamp ( axleOutForceN , - maxAdhesionForceN , maxAdhesionForceN ) ;
1434
- if ( ! Car . Simulator . UseAdvancedAdhesion || Car . Simulator . Settings . SimpleControlPhysics || ! Car . Train . IsPlayerDriven )
1440
+ axleOutForceN = MathHelper . Clamp ( axleOutForceN , - adhesionForceN , adhesionForceN ) ;
1441
+ // Simple adhesion, simple wheelslip conditions
1442
+ if ( Car is MSTSLocomotive locomotive && ! locomotive . AdvancedAdhesionModel )
1435
1443
{
1436
- if ( Car is MSTSLocomotive locomotive && ! locomotive . AntiSlip ) axleOutForceN *= locomotive . Adhesion1 ;
1444
+ if ( ! locomotive . AntiSlip ) axleOutForceN *= locomotive . Adhesion1 ;
1445
+ else SlipPercent = 100 ;
1437
1446
}
1447
+ else if ( ! Car . Simulator . UseAdvancedAdhesion || Car . Simulator . Settings . SimpleControlPhysics || ! Car . Train . IsPlayerDriven )
1448
+ {
1449
+ // No wagon skid in simple adhesion
1450
+ SlipPercent = 100 ;
1451
+ }
1452
+ // Semi-advanced adhesion. Used in non-driven axles when advanced adhesion is enabled, to avoid running the integrator
1438
1453
else
1439
1454
{
1440
- float adhesionForceN ;
1441
- if ( ( TrainSpeedMpS > 0 && axleOutForceN < 0 ) || ( TrainSpeedMpS < 0 && axleOutForceN > 0 ) )
1442
- {
1443
- // Compute adhesion as if wheel is fully locked
1444
- adhesionForceN = AxleWeightN * SlipCharacteristicsPacha ( - TrainSpeedMpS , TrainSpeedMpS , AdhesionK , AdhesionLimit ) ;
1445
- }
1446
- else
1447
- {
1448
- // Get asymptotic (dynamic) adhesion coefficient
1449
- adhesionForceN = AxleWeightN * SlipCharacteristicsPacha ( 1000.0f , Math . Abs ( TrainSpeedMpS ) , AdhesionK , AdhesionLimit ) ;
1450
- }
1455
+ // For non-driven axles, only brake skid is possible (no wheel slip). Consider wheels to be fully locked
1456
+ AxleSpeedMpS = 0 ;
1457
+ // Use the advanced adhesion coefficient
1458
+ adhesionForceN = AxleWeightN * SlipCharacteristicsPacha ( SlipSpeedMpS , TrainSpeedMpS , AdhesionK , AdhesionLimit ) ;
1451
1459
axleOutForceN = MathHelper . Clamp ( axleOutForceN , - adhesionForceN , adhesionForceN ) ;
1452
1460
}
1453
-
1454
- HuDIsWheelSlip = HuDIsWheelSlipWarning = IsWheelSlip = IsWheelSlipWarning = true ;
1455
-
1456
- if ( ( TrainSpeedMpS > 0 && axleOutForceN < 0 ) || ( TrainSpeedMpS < 0 && axleOutForceN > 0 ) )
1461
+ // In case of wheel skid, reduce indicated brake force
1462
+ if ( ( ( TrainSpeedMpS > 0 && axleOutForceN < 0 ) || ( TrainSpeedMpS < 0 && axleOutForceN > 0 ) ) && Math . Abs ( DriveForceN ) < BrakeRetardForceN && Math . Sign ( TrainSpeedMpS ) * ( - axleOutForceN + axleInForceN ) - frictionForceN > 0 )
1457
1463
{
1458
- if ( Math . Abs ( axleInForceN ) < BrakeRetardForceN && Math . Sign ( TrainSpeedMpS ) * ( - axleOutForceN + axleInForceN ) - frictionForceN > 0 )
1459
- {
1460
- AxleBrakeForceN = Math . Sign ( TrainSpeedMpS ) * ( - axleOutForceN + axleInForceN ) - frictionForceN ;
1461
- AxleSpeedMpS = 0 ;
1462
- }
1463
- else
1464
- {
1465
- AxleMotiveForceN = axleOutForceN + Math . Sign ( TrainSpeedMpS ) * totalFrictionForceN ;
1466
- }
1464
+ AxleBrakeForceN = Math . Sign ( TrainSpeedMpS ) * ( - axleOutForceN + axleInForceN ) - frictionForceN ;
1467
1465
}
1466
+ // Otherwise, indicate that slip is reducing motive force
1468
1467
else
1469
1468
{
1470
1469
AxleMotiveForceN = axleOutForceN + Math . Sign ( TrainSpeedMpS ) * totalFrictionForceN ;
1471
1470
}
1472
1471
}
1473
- else
1474
- {
1475
- HuDIsWheelSlip = HuDIsWheelSlipWarning = IsWheelSlip = IsWheelSlipWarning = false ;
1476
- }
1477
1472
AxlePositionRad += AxleSpeedMpS / WheelRadiusM * elapsedClockSeconds ;
1478
1473
1479
- if ( Math . Abs ( TrainSpeedMpS ) < 0.001f && Math . Abs ( axleInForceN ) < totalFrictionForceN )
1474
+ if ( Math . Abs ( TrainSpeedMpS ) < 0.001f && Math . Abs ( DriveForceN ) < totalFrictionForceN )
1480
1475
{
1481
1476
axleOutForceN = 0 ;
1482
1477
}
0 commit comments