Skip to content

Commit 8bb3bfe

Browse files
committed
Refine train braking algorithm
1 parent df4fde4 commit 8bb3bfe

File tree

1 file changed

+72
-129
lines changed

1 file changed

+72
-129
lines changed

Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs

Lines changed: 72 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ public float SetSpeedMpS
7777
public List<float> AccelerationTable = new List<float>();
7878
public enum SpeedRegulatorMode { Manual, Auto, Testing, AVV }
7979
public enum SpeedSelectorMode { Parking, Neutral, On, Start }
80-
protected float brakePercent = 0;
8180
public float DynamicBrakeIncreaseSpeed = 0;
8281
public float DynamicBrakeDecreaseSpeed = 0;
8382
public uint MinimumMetersToPass = 19;
@@ -415,6 +414,7 @@ public void Update(float elapsedClockSeconds)
415414
{
416415
WasForceReset = false;
417416
CCThrottleOrDynBrakePercent = 0;
417+
trainBrakePercent = 0;
418418
return;
419419
}
420420

@@ -437,14 +437,17 @@ public void Update(float elapsedClockSeconds)
437437
{
438438
WasBraking = true;
439439
CCThrottleOrDynBrakePercent = 0;
440+
trainBrakePercent = 0;
440441
}
441442
else if (SpeedRegMode == SpeedRegulatorMode.Manual || (SpeedRegMode == SpeedRegulatorMode.Auto && DynamicBrakePriority))
442443
{
443444
WasForceReset = false;
444445
CCThrottleOrDynBrakePercent = 0;
446+
trainBrakePercent = 0;
445447
}
446448
else if (SpeedRegMode == SpeedRegulatorMode.Auto)
447449
{
450+
float prevTrainBrakePercent = trainBrakePercent;
448451
CalculateRequiredForce(elapsedClockSeconds, Locomotive.AbsWheelSpeedMpS);
449452
CCThrottleOrDynBrakePercent = MathHelper.Clamp(CCThrottleOrDynBrakePercent, -100, 100);
450453
if (CCThrottleOrDynBrakePercent >= 0)
@@ -458,6 +461,10 @@ public void Update(float elapsedClockSeconds)
458461
Locomotive.ThrottlePercent = 0;
459462
Locomotive.DynamicBrakePercent = -CCThrottleOrDynBrakePercent;
460463
}
464+
if (prevTrainBrakePercent != trainBrakePercent && !TrainBrakePriority)
465+
{
466+
Locomotive.TrainBrakeController.SetPercent(trainBrakePercent); // TODO: do not move actual train brake lever
467+
}
461468
IsActive = true;
462469
}
463470
if (!IsActive && wasActive && SpeedRegMode == SpeedRegulatorMode.Auto)
@@ -1059,76 +1066,62 @@ public void CalculateRequiredForce(float elapsedClockSeconds, float AbsWheelSpee
10591066
TrainBrakePriority = false;
10601067
}
10611068

1062-
if (TrainBrakePriority)
1063-
{
1064-
WasForceReset = false;
1065-
WasBraking = true;
1066-
if (SpeedSelMode == SpeedSelectorMode.Parking)
1067-
if (AbsWheelSpeedMpS < (SpeedIsMph ? MpS.FromMpH(ParkingBrakeEngageSpeed) : MpS.FromKpH(ParkingBrakeEngageSpeed)))
1068-
Locomotive.SetEngineBrakePercent(ParkingBrakePercent);
1069-
CCThrottleOrDynBrakePercent = 0;
1070-
return;
1071-
}
1072-
1073-
bool canAddForce = false;
10741069
if ((SpeedSelMode == SpeedSelectorMode.On || SpeedSelMode == SpeedSelectorMode.Start) && !TrainBrakePriority)
10751070
{
1076-
canAddForce = true;
1071+
if (Locomotive.AbsSpeedMpS == 0)
1072+
{
1073+
timeFromEngineMoved = 0;
1074+
reducingForce = true;
1075+
}
1076+
else if (reducingForce)
1077+
{
1078+
1079+
timeFromEngineMoved += elapsedClockSeconds;
1080+
float timeToReduce = Locomotive.SelectedTrainType == MSTSLocomotive.TrainType.Pax ? PowerReductionDelayPaxTrain : PowerReductionDelayCargoTrain;
1081+
if (timeFromEngineMoved > timeToReduce)
1082+
reducingForce = false;
1083+
}
10771084
}
10781085
else
10791086
{
1080-
canAddForce = false;
10811087
timeFromEngineMoved = 0;
10821088
reducingForce = true;
10831089
}
10841090

1085-
1086-
if (SpeedSelMode == SpeedSelectorMode.Start) WasForceReset = true;
1087-
if (SelectedMaxAccelerationPercent == 0 && SelectedMaxAccelerationStep == 0)
1091+
if (TrainBrakePriority)
1092+
{
1093+
WasForceReset = false;
1094+
WasBraking = true;
1095+
}
1096+
else if (SpeedSelMode == SpeedSelectorMode.Start) WasForceReset = true;
1097+
else if (SelectedMaxAccelerationPercent == 0 && SelectedMaxAccelerationStep == 0)
10881098
{
10891099
WasBraking = false;
10901100
WasForceReset = true;
10911101
}
1092-
1093-
if (ForceResetRequiredAfterBraking && (!WasForceReset || (WasBraking && (SelectedMaxAccelerationStep > 0 || SelectedMaxAccelerationPercent > 0))))
1102+
if (TrainBrakePriority || (ThrottleNeutralPosition && SelectedSpeedMpS == 0) || SelectedMaxAccelerationStep == 0 ||
1103+
(ForceResetRequiredAfterBraking &&
1104+
(!WasForceReset || (WasBraking && (SelectedMaxAccelerationStep > 0 || SelectedMaxAccelerationPercent > 0)))))
10941105
{
1095-
CCThrottleOrDynBrakePercent = 0;
10961106
if (SpeedSelMode == SpeedSelectorMode.Parking)
10971107
if (AbsWheelSpeedMpS < (SpeedIsMph ? MpS.FromMpH(ParkingBrakeEngageSpeed) : MpS.FromKpH(ParkingBrakeEngageSpeed)))
10981108
Locomotive.SetEngineBrakePercent(ParkingBrakePercent);
1099-
return;
1100-
}
1101-
1102-
if (ThrottleNeutralPosition && SelectedSpeedMpS == 0)
1103-
{
11041109
CCThrottleOrDynBrakePercent = 0;
1110+
trainBrakePercent = 0;
11051111
return;
11061112
}
1107-
1108-
if (canAddForce)
1113+
if (Locomotive.TrainBrakeController.MaxPressurePSI - Locomotive.BrakeSystem.BrakeLine1PressurePSI > 1)
11091114
{
1110-
if (Locomotive.AbsSpeedMpS == 0)
1115+
if (!UseTrainBrakeAndDynBrake || !CCIsUsingTrainBrake)
11111116
{
1112-
timeFromEngineMoved = 0;
11131117
reducingForce = true;
1118+
timeFromEngineMoved = 0;
1119+
if (CCThrottleOrDynBrakePercent > 0)
1120+
CCThrottleOrDynBrakePercent = 0;
1121+
return;
11141122
}
1115-
else if (reducingForce)
1116-
{
1117-
1118-
timeFromEngineMoved += elapsedClockSeconds;
1119-
float timeToReduce = Locomotive.SelectedTrainType == MSTSLocomotive.TrainType.Pax ? PowerReductionDelayPaxTrain : PowerReductionDelayCargoTrain;
1120-
if (timeFromEngineMoved > timeToReduce)
1121-
reducingForce = false;
1122-
}
1123-
}
1124-
if ((!UseTrainBrakeAndDynBrake || !CCIsUsingTrainBrake) && Locomotive.TrainBrakeController.MaxPressurePSI - Locomotive.BrakeSystem.BrakeLine1PressurePSI > 1)
1125-
{
1126-
reducingForce = true;
1127-
timeFromEngineMoved = 0;
1128-
if (CCThrottleOrDynBrakePercent > 0)
1129-
CCThrottleOrDynBrakePercent = 0;
1130-
return;
11311123
}
1124+
else if (trainBrakePercent == 0) CCIsUsingTrainBrake = false;
11321125

11331126
if (SpeedRegulatorOptions.Contains("engageforceonnonzerospeed") && SelectedSpeedMpS > 0)
11341127
{
@@ -1144,11 +1137,6 @@ public void CalculateRequiredForce(float elapsedClockSeconds, float AbsWheelSpee
11441137
firstIteration = false;
11451138
}
11461139

1147-
if (SelectedMaxAccelerationStep == 0) // no effort, no throttle (i.e. for reverser change, etc) and return
1148-
{
1149-
CCThrottleOrDynBrakePercent = 0;
1150-
return;
1151-
}
11521140
float deltaSpeedMpS = SetSpeedMpS - AbsWheelSpeedMpS;
11531141
if (SpeedSelMode == SpeedSelectorMode.Parking && !EngineBrakePriority)
11541142
{
@@ -1167,6 +1155,7 @@ public void CalculateRequiredForce(float elapsedClockSeconds, float AbsWheelSpee
11671155
// Progressively stop accelerating/braking: reach 0
11681156
if (CCThrottleOrDynBrakePercent < 0) IncreaseForce(ref CCThrottleOrDynBrakePercent, elapsedClockSeconds, 0);
11691157
else if (CCThrottleOrDynBrakePercent > 0) DecreaseForce(ref CCThrottleOrDynBrakePercent, elapsedClockSeconds, 0);
1158+
trainBrakePercent = 0;
11701159
}
11711160
else // start braking
11721161
{
@@ -1176,10 +1165,9 @@ public void CalculateRequiredForce(float elapsedClockSeconds, float AbsWheelSpee
11761165
}
11771166
else
11781167
{
1168+
deltaSpeedMpS = SetSpeedMpS + (trainElevation < -0.01 ? trainElevation * (SelectedNumberOfAxles / 12) : 0) - AbsWheelSpeedMpS;
11791169
if (Locomotive.DynamicBrakeAvailable)
11801170
{
1181-
deltaSpeedMpS = SetSpeedMpS + (trainElevation < -0.01 ? trainElevation * (SelectedNumberOfAxles / 12) : 0) - AbsWheelSpeedMpS;
1182-
11831171
AccelerationDemandMpSS = (float)-Math.Sqrt(-StartReducingSpeedDeltaDownwards * deltaSpeedMpS);
11841172

11851173
if (CCThrottleOrDynBrakePercent < -(AccelerationDemandMpSS * 100) && AccelerationDemandMpSS < -0.05f)
@@ -1192,44 +1180,8 @@ public void CalculateRequiredForce(float elapsedClockSeconds, float AbsWheelSpee
11921180
IncreaseForce(ref CCThrottleOrDynBrakePercent, elapsedClockSeconds, 0);
11931181
}
11941182
}
1195-
else // use TrainBrake
1196-
{
1197-
CCThrottleOrDynBrakePercent = 0;
1198-
if (deltaSpeedMpS > -1)
1199-
{
1200-
brakePercent = TrainBrakeMinPercentValue - 3.0f + (-deltaSpeedMpS * 10);
1201-
}
1202-
else
1203-
{
1204-
if (RelativeAccelerationMpSS > -MaxDecelerationMpSS + 0.01f)
1205-
brakePercent += 0.5f;
1206-
else if (RelativeAccelerationMpSS < -MaxDecelerationMpSS - 0.01f)
1207-
brakePercent -= 1;
1208-
brakePercent = MathHelper.Clamp(brakePercent, TrainBrakeMinPercentValue - 3.0f, TrainBrakeMaxPercentValue);
1209-
}
1210-
Locomotive.SetTrainBrakePercent(brakePercent);
1211-
}
1212-
if (UseTrainBrakeAndDynBrake)
1213-
{
1214-
if (-deltaSpeedMpS > SpeedDeltaToEnableTrainBrake)
1215-
{
1216-
CCIsUsingTrainBrake = true;
1217-
/* brakePercent = Math.Max(TrainBrakeMinPercentValue + 3.0f, -deltaSpeedMpS * 2);
1218-
if (brakePercent > TrainBrakeMaxPercentValue)
1219-
brakePercent = TrainBrakeMaxPercentValue;*/
1220-
brakePercent = (TrainBrakeMaxPercentValue - TrainBrakeMinPercentValue - 3.0f) * SelectedMaxAccelerationStep / SpeedRegulatorMaxForceSteps + TrainBrakeMinPercentValue + 3.0f;
1221-
if (-deltaSpeedMpS < SpeedDeltaToEnableFullTrainBrake)
1222-
brakePercent = Math.Min(brakePercent, TrainBrakeMinPercentValue + 13.0f);
1223-
Locomotive.SetTrainBrakePercent(brakePercent);
1224-
}
1225-
else if (-deltaSpeedMpS < SpeedDeltaToEnableTrainBrake)
1226-
{
1227-
brakePercent = 0;
1228-
Locomotive.SetTrainBrakePercent(brakePercent);
1229-
if (Bar.FromPSI(Locomotive.BrakeSystem.BrakeLine1PressurePSI) >= 4.98)
1230-
CCIsUsingTrainBrake = false;
1231-
}
1232-
}
1183+
if (UseTrainBrakeAndDynBrake || !Locomotive.DynamicBrakeAvailable) // use TrainBrake
1184+
SetTrainBrake(ref trainBrakePercent, elapsedClockSeconds, deltaSpeedMpS);
12331185
}
12341186
}
12351187
}
@@ -1240,10 +1192,11 @@ public void CalculateRequiredForce(float elapsedClockSeconds, float AbsWheelSpee
12401192
if (deltaSpeedMpS >= 0)
12411193
{
12421194
AccelerationDemandMpSS = (float)Math.Sqrt(StartReducingSpeedDelta * coeff * deltaSpeedMpS);
1243-
if ((SpeedSelMode == SpeedSelectorMode.On || SpeedSelMode == SpeedSelectorMode.Start) && CCThrottleOrDynBrakePercent <= 0)
1195+
if ((SpeedSelMode == SpeedSelectorMode.On || SpeedSelMode == SpeedSelectorMode.Start) && CCThrottleOrDynBrakePercent < 0)
12441196
{
12451197
IncreaseForce(ref CCThrottleOrDynBrakePercent, elapsedClockSeconds, 0);
12461198
}
1199+
trainBrakePercent = 0;
12471200
}
12481201
else // start braking
12491202
{
@@ -1267,43 +1220,8 @@ public void CalculateRequiredForce(float elapsedClockSeconds, float AbsWheelSpee
12671220
IncreaseForce(ref CCThrottleOrDynBrakePercent, elapsedClockSeconds, 0);
12681221
}
12691222
}
1270-
else // use TrainBrake
1271-
{
1272-
if (deltaSpeedMpS > -1)
1273-
{
1274-
brakePercent = TrainBrakeMinPercentValue - 3.0f + (-deltaSpeedMpS * 10);
1275-
}
1276-
else
1277-
{
1278-
if (RelativeAccelerationMpSS > -MaxDecelerationMpSS + 0.01f)
1279-
brakePercent += 0.5f;
1280-
else if (RelativeAccelerationMpSS < -MaxDecelerationMpSS - 0.01f)
1281-
brakePercent -= 1;
1282-
brakePercent = MathHelper.Clamp(brakePercent, TrainBrakeMinPercentValue - 3.0f, TrainBrakeMaxPercentValue);
1283-
}
1284-
Locomotive.SetTrainBrakePercent(brakePercent);
1285-
}
1286-
if (UseTrainBrakeAndDynBrake)
1287-
{
1288-
if (-deltaSpeedMpS > SpeedDeltaToEnableTrainBrake)
1289-
{
1290-
CCIsUsingTrainBrake = true;
1291-
/* brakePercent = Math.Max(TrainBrakeMinPercentValue + 3.0f, -deltaSpeedMpS * 2);
1292-
if (brakePercent > TrainBrakeMaxPercentValue)
1293-
brakePercent = TrainBrakeMaxPercentValue;*/
1294-
brakePercent = (TrainBrakeMaxPercentValue - TrainBrakeMinPercentValue - 3.0f) * SelectedMaxAccelerationStep / SpeedRegulatorMaxForceSteps + TrainBrakeMinPercentValue + 3.0f;
1295-
if (-deltaSpeedMpS < SpeedDeltaToEnableFullTrainBrake)
1296-
brakePercent = Math.Min(brakePercent, TrainBrakeMinPercentValue + 13.0f);
1297-
Locomotive.SetTrainBrakePercent(brakePercent);
1298-
}
1299-
else if (-deltaSpeedMpS < SpeedDeltaToEnableTrainBrake)
1300-
{
1301-
brakePercent = 0;
1302-
Locomotive.SetTrainBrakePercent(brakePercent);
1303-
if (Bar.FromPSI(Locomotive.BrakeSystem.BrakeLine1PressurePSI) >= 4.98)
1304-
CCIsUsingTrainBrake = false;
1305-
}
1306-
}
1223+
if (UseTrainBrakeAndDynBrake || !Locomotive.DynamicBrakeAvailable) // use TrainBrake
1224+
SetTrainBrake(ref trainBrakePercent, elapsedClockSeconds, deltaSpeedMpS);
13071225
}
13081226
}
13091227

@@ -1425,6 +1343,31 @@ void DecreaseForce(ref float throttleOrDynPercent, float elapsedClockSeconds, fl
14251343
}
14261344
}
14271345

1346+
void SetTrainBrake(ref float brakePercent, float elapsedClockSeconds, float deltaSpeedMpS)
1347+
{
1348+
if (deltaSpeedMpS > -SpeedDeltaToEnableFullTrainBrake)
1349+
{
1350+
if (!Locomotive.DynamicBrakeAvailable || deltaSpeedMpS < -SpeedDeltaToEnableTrainBrake)
1351+
{
1352+
CCIsUsingTrainBrake = true;
1353+
brakePercent = TrainBrakeMinPercentValue - 3.0f + (-deltaSpeedMpS * 10)/SpeedDeltaToEnableTrainBrake;
1354+
}
1355+
else
1356+
{
1357+
brakePercent = 0;
1358+
}
1359+
}
1360+
else
1361+
{
1362+
CCIsUsingTrainBrake = true;
1363+
if (RelativeAccelerationMpSS > -MaxDecelerationMpSS + 0.01f)
1364+
brakePercent += 10*elapsedClockSeconds;
1365+
else if (RelativeAccelerationMpSS < -MaxDecelerationMpSS - 0.01f)
1366+
brakePercent -= 20*elapsedClockSeconds;
1367+
brakePercent = MathHelper.Clamp(brakePercent, TrainBrakeMinPercentValue - 3.0f, TrainBrakeMaxPercentValue);
1368+
}
1369+
}
1370+
14281371
private float previousSelectedSpeed = 0;
14291372
public float GetDataOf(CabViewControl cvc)
14301373
{

0 commit comments

Comments
 (0)