Skip to content

Commit e7bad63

Browse files
committed
Simple and semi-simple adhesion
1 parent 43a12f4 commit e7bad63

File tree

2 files changed

+68
-73
lines changed
  • Source/Orts.Simulation/Simulation/RollingStocks

2 files changed

+68
-73
lines changed

Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/PowerTransmissions/Axle.cs

Lines changed: 64 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,11 @@ public float SlipSpeedPercent
936936
}
937937
}
938938

939+
/// <summary>
940+
/// Percentage of wheelslip (different models use different observables to calculate it)
941+
/// </summary>
942+
public float SlipPercent;
943+
939944
/// <summary>
940945
/// Slip speed rate of change value, in metric (meters per second) per second
941946
/// </summary>
@@ -1097,7 +1102,7 @@ public void Save(BinaryWriter outf)
10971102
{
10981103
double slipSpeedMpS = axleSpeedMpS - TrainSpeedMpS;
10991104
// Compute force transmitted to rail according to adhesion curves
1100-
double axleOutForceN = 0;
1105+
double axleOutForceN;
11011106
if (Axles.UsePolachAdhesion)
11021107
{
11031108
axleOutForceN = Math.Sign(slipSpeedMpS) * AxleWeightN * SlipCharacteristicsPolach(slipSpeedMpS);
@@ -1361,51 +1366,52 @@ public virtual void Update(float elapsedSeconds)
13611366
if (advancedAdhesion)
13621367
{
13631368
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;
13681369

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)
13891373
{
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;
13951379
}
13961380
}
13971381
else
13981382
{
13991383
UpdateSimpleAdhesion(elapsedSeconds);
14001384
}
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;
14011389

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)
14031398
{
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;
14061402

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;
14091415
}
14101416
}
14111417

@@ -1427,56 +1433,45 @@ public void UpdateSimpleAdhesion(float elapsedClockSeconds)
14271433
AxleFrictionForceN = frictionForceN;
14281434
AxleSpeedMpS = TrainSpeedMpS;
14291435

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)
14321439
{
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)
14351443
{
1436-
if (Car is MSTSLocomotive locomotive && !locomotive.AntiSlip) axleOutForceN *= locomotive.Adhesion1;
1444+
if (!locomotive.AntiSlip) axleOutForceN *= locomotive.Adhesion1;
1445+
else SlipPercent = 100;
14371446
}
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
14381453
else
14391454
{
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);
14511459
axleOutForceN = MathHelper.Clamp(axleOutForceN, -adhesionForceN, adhesionForceN);
14521460
}
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)
14571463
{
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;
14671465
}
1466+
// Otherwise, indicate that slip is reducing motive force
14681467
else
14691468
{
14701469
AxleMotiveForceN = axleOutForceN + Math.Sign(TrainSpeedMpS) * totalFrictionForceN;
14711470
}
14721471
}
1473-
else
1474-
{
1475-
HuDIsWheelSlip = HuDIsWheelSlipWarning = IsWheelSlip = IsWheelSlipWarning = false;
1476-
}
14771472
AxlePositionRad += AxleSpeedMpS / WheelRadiusM * elapsedClockSeconds;
14781473

1479-
if (Math.Abs(TrainSpeedMpS) < 0.001f && Math.Abs(axleInForceN) < totalFrictionForceN)
1474+
if (Math.Abs(TrainSpeedMpS) < 0.001f && Math.Abs(DriveForceN) < totalFrictionForceN)
14801475
{
14811476
axleOutForceN = 0;
14821477
}

Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,7 +1106,7 @@ public void InitializeCarTemperatures()
11061106

11071107
public virtual void UpdateBrakeSlideCalculation()
11081108
{
1109-
if (this is MSTSLocomotive)
1109+
if (this is MSTSLocomotive locomotive)
11101110
{
11111111
// If advanced adhesion model indicates wheel slip warning, then check other conditions (throttle and brake force) to determine whether it is a wheel slip or brake skid
11121112
if (WheelSlipWarning && ThrottlePercent < 0.1f && BrakeRetardForceN > 25.0)
@@ -1190,7 +1190,7 @@ public virtual void UpdateBrakeSlideCalculation()
11901190
BrakeForceN = BrakeRetardForceN;
11911191
if (BrakeSkid) BrakeForceN = Math.Min(BrakeForceN, MassKG * GravitationalAccelerationMpS2 * SkidFriction);
11921192
}
1193-
else // set default values if simple adhesion model, or if diesel or electric locomotive is used, which doesn't check for brake skid.
1193+
else // set default values if simple adhesion model
11941194
{
11951195
BrakeSkid = false; // wagon wheel is not slipping
11961196
BrakeForceN = BrakeRetardForceN;
@@ -2141,8 +2141,8 @@ public virtual string GetDebugStatus()
21412141
ThrottlePercent,
21422142
String.Format("{0}", FormatStrings.FormatSpeedDisplay(SpeedMpS, IsMetric)),
21432143
// For Locomotive HUD display shows "forward" motive power (& force) as a positive value, braking power (& force) will be shown as negative values.
2144-
FormatStrings.FormatPower(loco.LocomotiveAxles.DrivePowerW, IsMetric, false, false),
2145-
String.Format("{0}{1}", FormatStrings.FormatForce(loco.LocomotiveAxles.DriveForceN, IsMetric), WheelSlip ? "!!!" : WheelSlipWarning ? "???" : ""),
2144+
FormatStrings.FormatPower((this as MSTSWagon).LocomotiveAxles.DrivePowerW, IsMetric, false, false),
2145+
String.Format("{0}{1}", FormatStrings.FormatForce((this as MSTSWagon).LocomotiveAxles.DriveForceN, IsMetric), WheelSlip ? "!!!" : WheelSlipWarning ? "???" : ""),
21462146
Simulator.Catalog.GetString(locomotivetypetext)
21472147
);
21482148
}

0 commit comments

Comments
 (0)