Skip to content

Commit 84be72c

Browse files
authored
Merge pull request #1157 from cesarBLG/dynamic-brake-authorization
Dynamic brake authorization by TCS
2 parents 62070ad + 39cd994 commit 84be72c

File tree

6 files changed

+48
-12
lines changed

6 files changed

+48
-12
lines changed

Source/Documentation/Manual/physics.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5348,11 +5348,13 @@ the tables below.
53485348
.. index::
53495349
single: DoesBrakeCutPower
53505350
single: BrakeCutsPowerAtBrakeCylinderPressure
5351+
single: OrtsEmergencyBrakeCutsDynamicBrake
53515352

5352-
Two other parameters in the Engine section of the ENG file are used by the TCS:
5353+
Other parameters in the Engine section of the ENG file are used by the TCS:
53535354

53545355
- ``DoesBrakeCutPower( x )`` sets whether applying brake on the locomotive cuts the traction (1 for enabled, 0 for disabled)
53555356
- ``BrakeCutsPowerAtBrakeCylinderPressure( x )`` sets the minimum pressure in the brake cylinder that cuts the traction (by default 4 PSI)
5357+
- ``OrtsEmergencyBrakeCutsDynamicBrake`` sets whether an emergency braking disables dynamic brakes
53565358

53575359

53585360
Train Derailment

Source/Orts.Simulation/Common/Scripting/TrainControlSystem.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,10 @@ internal void AttachToHost(ScriptedTrainControlSystem host)
249249
/// </summary>
250250
public Func<bool> TractionAuthorization;
251251
/// <summary>
252+
/// True if dynamic braking is authorized.
253+
/// </summary>
254+
public Func<bool> DynamicBrakingAuthorization;
255+
/// <summary>
252256
/// Train brake pipe pressure. Returns float.MaxValue if no data is available.
253257
/// </summary>
254258
public Func<float> BrakePipePressureBar;
@@ -265,6 +269,10 @@ internal void AttachToHost(ScriptedTrainControlSystem host)
265269
/// </summary>
266270
public Func<float> BrakeCutsPowerAtBrakeCylinderPressureBar;
267271
/// <summary>
272+
/// True if dynamic brake must be cut if the emergency brake is applied.
273+
/// </summary>
274+
public bool EmergencyBrakeCutsDynamicBrake => Locomotive.EmergencyBrakeCutsDynamicBrake;
275+
/// <summary>
268276
/// State of the train brake controller.
269277
/// </summary>
270278
public Func<ControllerState> TrainBrakeControllerState;
@@ -387,6 +395,10 @@ internal void AttachToHost(ScriptedTrainControlSystem host)
387395
/// </summary>
388396
public Action<bool> SetTractionAuthorization;
389397
/// <summary>
398+
/// Set the dynamic braking authorization.
399+
/// </summary>
400+
public Action<bool> SetDynamicBrakingAuthorization;
401+
/// <summary>
390402
/// Set the maximum throttle percent
391403
/// Range: 0 to 100
392404
/// </summary>

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,7 @@ public float OdometerM
464464
public float BrakeCutsPowerAtBrakePipePressurePSI;
465465
public bool DoesVacuumBrakeCutPower { get; private set; }
466466
public bool DoesBrakeCutPower { get; private set; }
467+
public bool EmergencyBrakeCutsDynamicBrake { get; private set; }
467468
public float BrakeCutsPowerAtBrakeCylinderPressurePSI { get; private set; }
468469
public bool DoesHornTriggerBell { get; private set; }
469470
public bool DPSyncTrainApplication { get; private set; }
@@ -1118,6 +1119,7 @@ public override void Parse(string lowercasetoken, STFReader stf)
11181119
case "engine(brakecutspoweratbrakecylinderpressure": BrakeCutsPowerAtBrakeCylinderPressurePSI = stf.ReadFloatBlock(STFReader.UNITS.PressureDefaultPSI, null); break;
11191120
case "engine(ortsbrakecutspoweratbrakepipepressure": BrakeCutsPowerAtBrakePipePressurePSI = stf.ReadFloatBlock(STFReader.UNITS.PressureDefaultPSI, null); break;
11201121
case "engine(ortsbrakerestorespoweratbrakepipepressure": BrakeRestoresPowerAtBrakePipePressurePSI = stf.ReadFloatBlock(STFReader.UNITS.PressureDefaultPSI, null); break;
1122+
case "engine(ortsemergencybrakecutsdynamicbrake": EmergencyBrakeCutsDynamicBrake = stf.ReadBoolBlock(false); break;
11211123
case "engine(doeshorntriggerbell": DoesHornTriggerBell = stf.ReadBoolBlock(false); break;
11221124
case "engine(ortshornlightstimer": HornTimerS = stf.ReadFloatBlock(STFReader.UNITS.Time, null); break;
11231125
case "engine(ortsbelllightstimer": BellTimerS = stf.ReadFloatBlock(STFReader.UNITS.Time, null); break;
@@ -1337,6 +1339,7 @@ public override void Copy(MSTSWagon copy)
13371339
BrakeCutsPowerAtBrakeCylinderPressurePSI = locoCopy.BrakeCutsPowerAtBrakeCylinderPressurePSI;
13381340
BrakeCutsPowerAtBrakePipePressurePSI = locoCopy.BrakeCutsPowerAtBrakePipePressurePSI;
13391341
BrakeRestoresPowerAtBrakePipePressurePSI = locoCopy.BrakeRestoresPowerAtBrakePipePressurePSI;
1342+
EmergencyBrakeCutsDynamicBrake = locoCopy.EmergencyBrakeCutsDynamicBrake;
13401343
DynamicBrakeCommandStartTime = locoCopy.DynamicBrakeCommandStartTime;
13411344
DynamicBrakeBlendingOverride = locoCopy.DynamicBrakeBlendingOverride;
13421345
DynamicBrakeBlendingForceMatch = locoCopy.DynamicBrakeBlendingForceMatch;
@@ -2673,7 +2676,7 @@ protected virtual void UpdateDynamicBrakeForce(float elapsedClockSeconds)
26732676
DynamicBrake = false;
26742677
DynamicBrakeCommandStartTime = null;
26752678
}
2676-
float maxdynamic = DynamicBrake ? 1 : 0;
2679+
float maxdynamic = DynamicBrake ? MaxDynamicBrakePercent / 100 : 0;
26772680
float d = DynamicBrakePercent / 100;
26782681
bool dynamicLimited = d > maxdynamic;
26792682
if (dynamicLimited) d = maxdynamic;

Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/AirSinglePipe.cs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1768,9 +1768,8 @@ public override void Update(float elapsedClockSeconds)
17681768
}
17691769
}
17701770
}
1771-
if (loco.LocomotivePowerSupply.DynamicBrakeAvailable)
17721771
{
1773-
if (loco.DynamicBrakePercent > 0 && Car.FrictionBrakeBlendingMaxForceN > 0)
1772+
if (loco.LocomotivePowerSupply.DynamicBrakeAvailable && loco.MaxDynamicBrakePercent > 0 && loco.DynamicBrakePercent > 0 && Car.FrictionBrakeBlendingMaxForceN > 0)
17741773
{
17751774
if (loco.DynamicBrakePartialBailOff)
17761775
{
@@ -1808,14 +1807,14 @@ public override void Update(float elapsedClockSeconds)
18081807
}
18091808
}
18101809
}
1811-
if (loco.DynamicBrakeEngineBrakeReplacement && loco.RemoteControlGroup == 0 && loco.AbsTractionSpeedMpS < loco.DynamicBrakeEngineBrakeReplacementSpeed && loco.Train.LeadLocomotive is MSTSLocomotive lead && lead.TrainBrakeController.TrainDynamicBrakeIntervention > 0)
1812-
{
1813-
var requiredBrakeForceN = loco.MaxDynamicBrakeForceN * lead.TrainBrakeController.TrainDynamicBrakeIntervention;
1814-
var reverseBlendingPressurePSI = Math.Min(Math.Max((requiredBrakeForceN - loco.DynamicBrakeForceN) / Car.FrictionBrakeBlendingMaxForceN * ReferencePressurePSI
1815-
+ BrakeCylinderSpringPressurePSI, 0), MaxCylPressurePSI);
1816-
reverseBlendingPressurePSI /= RelayValveRatio;
1817-
if (demandedPressurePSI < reverseBlendingPressurePSI) demandedPressurePSI = reverseBlendingPressurePSI;
1818-
}
1810+
}
1811+
if (loco.DynamicBrakeEngineBrakeReplacement && loco.RemoteControlGroup == 0 && loco.AbsTractionSpeedMpS < loco.DynamicBrakeEngineBrakeReplacementSpeed && loco.Train.LeadLocomotive is MSTSLocomotive lead && lead.TrainBrakeController.TrainDynamicBrakeIntervention > 0)
1812+
{
1813+
var requiredBrakeForceN = loco.MaxDynamicBrakeForceN * lead.TrainBrakeController.TrainDynamicBrakeIntervention;
1814+
var reverseBlendingPressurePSI = Math.Min(Math.Max((requiredBrakeForceN - loco.DynamicBrakeForceN) / Car.FrictionBrakeBlendingMaxForceN * ReferencePressurePSI
1815+
+ BrakeCylinderSpringPressurePSI, 0), MaxCylPressurePSI);
1816+
reverseBlendingPressurePSI /= RelayValveRatio;
1817+
if (demandedPressurePSI < reverseBlendingPressurePSI) demandedPressurePSI = reverseBlendingPressurePSI;
18191818
}
18201819
}
18211820
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ protected set
150150
public bool CircuitBreakerClosingOrder { get; private set; }
151151
public bool CircuitBreakerOpeningOrder { get; private set; }
152152
public bool TractionAuthorization { get; private set; }
153+
public bool DynamicBrakingAuthorization { get; private set; }
153154
public float MaxThrottlePercent { get; private set; } = 100f;
154155
public bool FullDynamicBrakingOrder { get; private set; }
155156

@@ -187,6 +188,7 @@ public ScriptedTrainControlSystem(MSTSLocomotive locomotive)
187188
CircuitBreakerClosingOrder = false;
188189
CircuitBreakerOpeningOrder = false;
189190
TractionAuthorization = true;
191+
DynamicBrakingAuthorization = true;
190192
FullDynamicBrakingOrder = false;
191193
}
192194

@@ -363,6 +365,7 @@ public void Initialize()
363365
Script.MaxThrottlePercent = () => MaxThrottlePercent;
364366
Script.DynamicBrakePercent = () => Locomotive.DynamicBrakeController == null ? 0 : Locomotive.DynamicBrakeController.CurrentValue * 100;
365367
Script.TractionAuthorization = () => TractionAuthorization;
368+
Script.DynamicBrakingAuthorization = () => DynamicBrakingAuthorization;
366369
Script.BrakePipePressureBar = () => Locomotive.BrakeSystem != null ? Bar.FromPSI(Locomotive.BrakeSystem.BrakeLine1PressurePSI) : float.MaxValue;
367370
Script.LocomotiveBrakeCylinderPressureBar = () => Locomotive.BrakeSystem != null ? Bar.FromPSI(Locomotive.BrakeSystem.GetCylPressurePSI()) : float.MaxValue;
368371
Script.DoesBrakeCutPower = () => Locomotive.DoesBrakeCutPower;
@@ -457,6 +460,7 @@ public void Initialize()
457460
Script.SetCircuitBreakerClosingOrder = (value) => CircuitBreakerClosingOrder = value;
458461
Script.SetCircuitBreakerOpeningOrder = (value) => CircuitBreakerOpeningOrder = value;
459462
Script.SetTractionAuthorization = (value) => TractionAuthorization = value;
463+
Script.SetDynamicBrakingAuthorization = (value) => DynamicBrakingAuthorization = value;
460464
Script.SetMaxThrottlePercent = (value) =>
461465
{
462466
if (value >= 0 && value <= 100f)
@@ -1195,6 +1199,7 @@ public override void Update()
11951199
}
11961200

11971201
SetTractionAuthorization(!DoesBrakeCutPower() || LocomotiveBrakeCylinderPressureBar() < BrakeCutsPowerAtBrakeCylinderPressureBar());
1202+
SetDynamicBrakingAuthorization(!EmergencyBrakeCutsDynamicBrake || !IsBrakeEmergency());
11981203

11991204
SetEmergencyBrake(EmergencyBrake);
12001205
SetFullBrake(FullBrake);

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,21 @@ public int GearboxGearIndex
502502
}
503503

504504
public float LocalDynamicBrakePercent = -1;
505+
public float MaxDynamicBrakePercent
506+
{
507+
get
508+
{
509+
float percent = 100;
510+
if (RemoteControlGroup == 0 && Train != null && Train.LeadLocomotive is MSTSLocomotive locomotive)
511+
{
512+
if (!locomotive.TrainControlSystem.DynamicBrakingAuthorization)
513+
{
514+
percent = 0;
515+
}
516+
}
517+
return percent;
518+
}
519+
}
505520
public float DynamicBrakePercent
506521
{
507522
get

0 commit comments

Comments
 (0)