Skip to content

Commit 128520d

Browse files
committed
Reimplement legacy slip control systems
1 parent f9691cf commit 128520d

File tree

1 file changed

+51
-10
lines changed

1 file changed

+51
-10
lines changed

Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -241,10 +241,14 @@ public float CurrentLocomotiveSteamHeatBoilerWaterCapacityL
241241
// Adhesion parameters
242242
public enum SlipControlType
243243
{
244+
Unknown,
244245
None,
246+
CutPower,
247+
ReduceForce,
245248
Full
246249
}
247250
public SlipControlType SlipControlSystem;
251+
public bool[] SlipControlActive;
248252
float BaseFrictionCoefficientFactor; // Factor used to adjust Curtius formula depending upon weather conditions
249253
float SlipFrictionCoefficientFactor;
250254
public float SteamStaticWheelForce;
@@ -929,10 +933,10 @@ public override void Parse(string lowercasetoken, STFReader stf)
929933
case "engine(ortsunloadingspeed": UnloadingSpeedMpS = stf.ReadFloatBlock(STFReader.UNITS.Speed, null); break;
930934
case "engine(ortsslipcontrolsystem":
931935
stf.MustMatch("(");
932-
string slipControlType = stf.ReadString().ToLowerInvariant();
936+
string slipControlType = stf.ReadString();
933937
try
934938
{
935-
SlipControlSystem = (SlipControlType)Enum.Parse(typeof(SlipControlType), slipControlType.First().ToString().ToUpper() + slipControlType.Substring(1));
939+
SlipControlSystem = (SlipControlType)Enum.Parse(typeof(SlipControlType), slipControlType, true);
936940
}
937941
catch
938942
{
@@ -1683,6 +1687,13 @@ public override void Initialize()
16831687
}
16841688
}
16851689
}
1690+
SlipControlActive = new bool[LocomotiveAxles.Count];
1691+
if (SlipControlSystem == SlipControlType.Unknown)
1692+
{
1693+
if (AntiSlip) SlipControlSystem = SlipControlType.ReduceForce;
1694+
else if (WheelslipCausesThrottleDown) SlipControlSystem = SlipControlType.CutPower;
1695+
else SlipControlSystem = SlipControlType.None;
1696+
}
16861697

16871698
// Calculate minimum speed to pickup water
16881699
const float Aconst = 2;
@@ -2719,8 +2730,9 @@ protected virtual void UpdateTractiveForce(float elapsedClockSeconds)
27192730
UpdateDynamicBrakeForce(elapsedClockSeconds);
27202731
TractiveForceN -= Math.Sign(WheelSpeedMpS) * DynamicBrakeForceN;
27212732

2722-
foreach (var axle in LocomotiveAxles)
2733+
for (int i=0; i<LocomotiveAxles.Count; i++)
27232734
{
2735+
var axle = LocomotiveAxles[i];
27242736
if (axle.DriveType == AxleDriveType.ForceDriven)
27252737
{
27262738
float prevForceN = axle.DriveForceN;
@@ -2736,17 +2748,46 @@ protected virtual void UpdateTractiveForce(float elapsedClockSeconds)
27362748
else adhesionLimit = axle.MaximumWheelAdhesion;
27372749
axle.DriveForceN = Math.Sign(axle.DriveForceN) * Math.Min(adhesionLimit * axle.AxleWeightN, Math.Abs(axle.DriveForceN));
27382750
}
2739-
else if (TractionForceN > 0) // only for traction (not for dynamic brake)
2751+
else if (SlipControlSystem == SlipControlType.CutPower)
2752+
{
2753+
if (TractionForceN > 0)
2754+
{
2755+
if (axle.HuDIsWheelSlip) SlipControlActive[i] = true;
2756+
}
2757+
else
2758+
{
2759+
// Only restore traction when throttle is set to 0
2760+
SlipControlActive[i] = false;
2761+
}
2762+
// Disable traction in the axle if slipping
2763+
if (SlipControlActive[i]) axle.DriveForceN = 0;
2764+
}
2765+
else if (SlipControlSystem == SlipControlType.ReduceForce)
27402766
{
2741-
if (WheelslipCausesThrottleDown && WheelSlip)
2767+
if (TractionForceN > 0 && axle.DriveForceN != 0 && AdvancedAdhesionModel)
27422768
{
2743-
// Disable traction in the axle if slipping
2744-
axle.DriveForceN = 0;
2769+
if (axle.SlipPercent > axle.SlipWarningTresholdPercent) SlipControlActive[i] = true;
27452770
}
2746-
else if (AntiSlip && AdvancedAdhesionModel && WheelSlipWarning)
2771+
else
27472772
{
2748-
// Reduce tractive force to 0 in 3 seconds until wheel slip warning ends
2749-
float newForceN = Math.Max(Math.Abs(prevForceN) - TractiveForceN * axle.TractiveForceFraction * elapsedClockSeconds / 3, 0);
2773+
SlipControlActive[i] = false;
2774+
}
2775+
if (SlipControlActive[i])
2776+
{
2777+
float absForceN = Math.Abs(axle.DriveForceN);
2778+
float newForceN;
2779+
if (axle.SlipPercent < axle.SlipWarningTresholdPercent * 0.9f)
2780+
{
2781+
// If well below slip threshold, restore full power in 10 seconds
2782+
newForceN = Math.Min(Math.Abs(prevForceN) + absForceN * elapsedClockSeconds / 10, absForceN);
2783+
2784+
// If full force is restored, disengage slip control
2785+
if (newForceN / absForceN > 0.95f) SlipControlActive[i] = false;
2786+
}
2787+
else
2788+
{
2789+
newForceN = Math.Max(Math.Abs(prevForceN) - absForceN * elapsedClockSeconds / 3, 0);
2790+
}
27502791
if (axle.DriveForceN > 0 && prevForceN >= 0) axle.DriveForceN = newForceN;
27512792
else if (axle.DriveForceN < 0 && prevForceN <= 0) axle.DriveForceN = -newForceN;
27522793
}

0 commit comments

Comments
 (0)