Skip to content

Commit fc4146c

Browse files
committed
Add relay valve option for two stage brakes, add inshot, and fix an oversight in initialization
1 parent 3112a51 commit fc4146c

File tree

2 files changed

+47
-8
lines changed

2 files changed

+47
-8
lines changed

Source/Documentation/Manual/physics.rst

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3037,13 +3037,16 @@ MaxAuxilaryChargingRate and EmergencyResChargingRate.
30373037
single: ORTSEmergencyResQuickRelease
30383038
single: ORTSMainResPipeAuxResCharging
30393039
single: ORTSBrakeRelayValveRatio
3040+
single: ORTSBrakeRelayValveInshot
30403041
single: ORTSEngineBrakeRelayValveRatio
3042+
single: ORTSEngineBrakeRelayValveInshot
30413043
single: ORTSBrakeRelayValveApplicationRate
30423044
single: ORTSBrakeRelayValveReleaseRate
30433045
single: ORTSMaxTripleValveCylinderPressure
30443046
single: ORTSMaxServiceCylinderPressure
30453047
single: ORTSMaxServiceApplicationRate
30463048
single: ORTSTwoStageLowPressure
3049+
single: ORTSTwoStageRelayValveRatio
30473050
single: ORTSTwoStageIncreasingSpeed
30483051
single: ORTSTwoStageDecreasingSpeed
30493052
single: ORTSHighSpeedReducingPressure
@@ -3116,7 +3119,15 @@ MaxAuxilaryChargingRate and EmergencyResChargingRate.
31163119
This is achieved via a relay valve which sets BC pressure proportionally.
31173120
Relay valves may be installed to achieve higher brake cylinder pressures,
31183121
dynamic brake blending or variable load compensation.
3119-
- ``Wagon(ORTSBrakeRelayValveRatio`` -- Same as above, but for the engine brake
3122+
- ``Wagon(ORTSBrakeRelayValveInshot`` -- Sets the "in-shot" pressure for the relay
3123+
valve. Relay valves with a ratio less than 1 may not produce sufficient pressure
3124+
to extend the brake cylinders. In-shot solves this problem by applying additional
3125+
pressure at a 1:1 ratio, regardless of the actual relay valve ratio. The pressure
3126+
defined here is the maximum amount of additional pressure to apply.
3127+
- ``Wagon(ORTSEngineBrakeRelayValveRatio`` -- Same as ``ORTSBrakeRelayValveRatio``,
3128+
but for the engine brake.
3129+
- ``Wagon(ORTSEngineBrakeRelayValveInshot`` -- Same as ``ORTSBrakeRelayValveInshot``,
3130+
but for the engine brake.
31203131
- ``Wagon(ORTSBrakeRelayValveApplicationRate`` -- Brake cylinder pressure application
31213132
rate achieved by the relay valve, if fitted.
31223133
- ``Wagon(ORTSBrakeRelayValveReleaseRate`` -- Brake cylinder pressure release
@@ -3135,6 +3146,9 @@ MaxAuxilaryChargingRate and EmergencyResChargingRate.
31353146
is reduced at lower speeds and increased at higher speeds, sets the maximum cylinder
31363147
pressure demanded when at slower speeds (defaults to 0, disabling two stage braking).
31373148
For high speed, use ``ORTSMaxTripleValveCylinderPressure`` to set the pressure limit.
3149+
- ``Wagon(ORTSTwoStageRelayValveRatio`` -- Alternatey, sets a relay valve ratio to
3150+
be used by the two stage system at low speeds. At high speed, the relay valve
3151+
uses the ratio set by ``ORTSBrakeRelayValveRatio``.
31383152
- ``Wagon(ORTSTwoStageIncreasingSpeed`` -- The speed at which the two stage braking
31393153
system changes from low pressure to high pressure during acceleration.
31403154
- ``Wagon(ORTSTwoStageDecreasingSpeed`` -- The speed at which the two stage braking

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

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ public class AirSinglePipe : MSTSBrakeSystem
6868
protected float EmergAuxVolumeRatio = 1.4f;
6969
protected bool RelayValveFitted = false;
7070
public float RelayValveRatio { get; protected set; } = 1;
71+
protected float RelayValveInshot;
7172
protected float EngineRelayValveRatio = 0;
73+
protected float EngineRelayValveInshot;
7274
protected float RelayValveApplicationRatePSIpS = 50;
7375
protected float RelayValveReleaseRatePSIpS = 50;
7476
protected string DebugType = string.Empty;
@@ -95,6 +97,7 @@ public class AirSinglePipe : MSTSBrakeSystem
9597
protected float ServiceMaxCylPressurePSI;
9698
protected float ServiceApplicationRatePSIpS;
9799
protected float TwoStageLowPressurePSI;
100+
protected float TwoStageRelayValveRatio;
98101
protected float TwoStageSpeedUpMpS;
99102
protected float TwoStageSpeedDownMpS;
100103
protected bool TwoStageLowPressureActive;
@@ -180,7 +183,9 @@ public override void InitializeFromCopy(BrakeSystem copy)
180183
HoldingValve = thiscopy.HoldingValve;
181184
RelayValveFitted = thiscopy.RelayValveFitted;
182185
RelayValveRatio = thiscopy.RelayValveRatio;
186+
RelayValveInshot = thiscopy.RelayValveInshot;
183187
EngineRelayValveRatio = thiscopy.EngineRelayValveRatio;
188+
EngineRelayValveInshot = thiscopy.EngineRelayValveInshot;
184189
RelayValveApplicationRatePSIpS = thiscopy.RelayValveApplicationRatePSIpS;
185190
RelayValveReleaseRatePSIpS = thiscopy.RelayValveReleaseRatePSIpS;
186191
MaxTripleValveCylPressurePSI = thiscopy.MaxTripleValveCylPressurePSI;
@@ -200,6 +205,7 @@ public override void InitializeFromCopy(BrakeSystem copy)
200205
ServiceMaxCylPressurePSI = thiscopy.ServiceMaxCylPressurePSI;
201206
ServiceApplicationRatePSIpS = thiscopy.ServiceApplicationRatePSIpS;
202207
TwoStageLowPressurePSI = thiscopy.TwoStageLowPressurePSI;
208+
TwoStageRelayValveRatio = thiscopy.TwoStageRelayValveRatio;
203209
TwoStageSpeedUpMpS = thiscopy.TwoStageSpeedUpMpS;
204210
TwoStageSpeedDownMpS = thiscopy.TwoStageSpeedDownMpS;
205211
HighSpeedReducingPressurePSI = thiscopy.HighSpeedReducingPressurePSI;
@@ -334,7 +340,9 @@ public override void Parse(string lowercasetoken, STFReader stf)
334340
RelayValveFitted = false;
335341
}
336342
break;
343+
case "wagon(ortsbrakerelayvalveinshot": RelayValveInshot = stf.ReadFloatBlock(STFReader.UNITS.PressureDefaultPSI, null); break;
337344
case "wagon(ortsenginebrakerelayvalveratio": EngineRelayValveRatio = stf.ReadFloatBlock(STFReader.UNITS.None, null); break;
345+
case "wagon(ortsenginebrakerelayvalveinshot": EngineRelayValveInshot = stf.ReadFloatBlock(STFReader.UNITS.PressureDefaultPSI, null); break;
338346
case "wagon(ortsbrakerelayvalveapplicationrate": RelayValveApplicationRatePSIpS = stf.ReadFloatBlock(STFReader.UNITS.PressureRateDefaultPSIpS, null); break;
339347
case "wagon(ortsbrakerelayvalvereleaserate": RelayValveReleaseRatePSIpS = stf.ReadFloatBlock(STFReader.UNITS.PressureRateDefaultPSIpS, null); break;
340348
case "wagon(ortsmaxtriplevalvecylinderpressure": MaxTripleValveCylPressurePSI = stf.ReadFloatBlock(STFReader.UNITS.PressureDefaultPSI, null); break;
@@ -354,6 +362,7 @@ public override void Parse(string lowercasetoken, STFReader stf)
354362
case "wagon(ortsmaxservicecylinderpressure": ServiceMaxCylPressurePSI = stf.ReadFloatBlock(STFReader.UNITS.PressureDefaultPSI, null); break;
355363
case "wagon(ortsmaxserviceapplicationrate": ServiceApplicationRatePSIpS = stf.ReadFloatBlock(STFReader.UNITS.PressureRateDefaultPSIpS, null); break;
356364
case "wagon(ortstwostagelowpressure": TwoStageLowPressurePSI = stf.ReadFloatBlock(STFReader.UNITS.PressureDefaultPSI, null); break;
365+
case "wagon(ortstwostagerelayvalveratio": TwoStageRelayValveRatio = stf.ReadFloatBlock(STFReader.UNITS.None, null); break;
357366
case "wagon(ortstwostageincreasingspeed": TwoStageSpeedUpMpS = stf.ReadFloatBlock(STFReader.UNITS.Speed, null); break;
358367
case "wagon(ortstwostagedecreasingspeed": TwoStageSpeedDownMpS = stf.ReadFloatBlock(STFReader.UNITS.Speed, null); break;
359368
case "wagon(ortshighspeedreducingpressure": HighSpeedReducingPressurePSI = stf.ReadFloatBlock(STFReader.UNITS.PressureDefaultPSI, null); break;
@@ -479,8 +488,12 @@ public override void Initialize()
479488
if (Car.Simulator.Settings.SimpleControlPhysics && EmergResVolumeM3 > 2.0)
480489
EmergResVolumeM3 = 0.7f;
481490

482-
if (MaxTripleValveCylPressurePSI == 0) MaxTripleValveCylPressurePSI = MaxCylPressurePSI / RelayValveRatio;
483-
if (EngineRelayValveRatio == 0) EngineRelayValveRatio = RelayValveRatio;
491+
if (ServiceMaxCylPressurePSI == 0)
492+
ServiceMaxCylPressurePSI = MaxTripleValveCylPressurePSI;
493+
if (MaxTripleValveCylPressurePSI == 0)
494+
MaxTripleValveCylPressurePSI = MaxCylPressurePSI / RelayValveRatio;
495+
if (EngineRelayValveRatio == 0)
496+
EngineRelayValveRatio = RelayValveRatio;
484497

485498
if (ServiceApplicationRatePSIpS == 0)
486499
ServiceApplicationRatePSIpS = MaxApplicationRatePSIpS;
@@ -530,7 +543,8 @@ public override void Initialize()
530543
if (CylVolumeM3 == 0) CylVolumeM3 = EmergResVolumeM3 / EmergAuxVolumeRatio / AuxCylVolumeRatio;
531544

532545
RelayValveFitted |= (Car is MSTSLocomotive loco && (loco.DynamicBrakeAutoBailOff || loco.DynamicBrakePartialBailOff)) ||
533-
(Car as MSTSWagon).BrakeValve == MSTSWagon.BrakeValveType.DistributingValve || (Car as MSTSWagon).SupplyReservoirPresent;
546+
(Car as MSTSWagon).BrakeValve == MSTSWagon.BrakeValveType.DistributingValve || (Car as MSTSWagon).SupplyReservoirPresent ||
547+
TwoStageRelayValveRatio != 0;
534548

535549
// If user specified only one two stage speed, set the other to be equal
536550
if (TwoStageSpeedDownMpS == 0 && TwoStageSpeedUpMpS > 0)
@@ -542,6 +556,9 @@ public override void Initialize()
542556
(TwoStageSpeedUpMpS, TwoStageSpeedDownMpS) = (TwoStageSpeedDownMpS, TwoStageSpeedUpMpS);
543557
if (TwoStageLowPressurePSI == 0)
544558
TwoStageLowPressurePSI = MaxCylPressurePSI;
559+
// If relay valve ratio isn't used, assume it doesn't change
560+
if (TwoStageRelayValveRatio == 0)
561+
TwoStageRelayValveRatio = RelayValveRatio;
545562
}
546563

547564
/// <summary>
@@ -687,7 +704,7 @@ public void UpdateAngleCockState(bool AngleCockOpen, ref float AngleCockOpenAmou
687704
else if (currentTime - AngleCockOpenTime > AngleCockOpeningTime)
688705
{
689706
// Finish opening anglecock at a faster rate once time has elapsed
690-
AngleCockOpenAmount = (currentTime - ((float)AngleCockOpenTime + AngleCockOpeningTime)) / 5 + 0.3f;
707+
AngleCockOpenAmount = MathHelper.Lerp(0.3f, 1.0f, (currentTime - ((float)AngleCockOpenTime + AngleCockOpeningTime)) / 5);
691708

692709
if (AngleCockOpenAmount >= 1.0f)
693710
{
@@ -698,7 +715,7 @@ public void UpdateAngleCockState(bool AngleCockOpen, ref float AngleCockOpenAmou
698715
else
699716
{
700717
// Gradually open anglecock toward 30% over 30 seconds
701-
AngleCockOpenAmount = 0.3f * (currentTime - (float)AngleCockOpenTime) / AngleCockOpeningTime;
718+
AngleCockOpenAmount = MathHelper.Lerp(0.0f, 0.3f, (currentTime - (float)AngleCockOpenTime) / AngleCockOpeningTime);
702719
}
703720
}
704721
else if (!AngleCockOpen && AngleCockOpenAmount > 0.0f)
@@ -744,7 +761,7 @@ public override void Update(float elapsedClockSeconds)
744761
}
745762
if (TwoStageLowPressureActive && threshold > TwoStageLowPressurePSI)
746763
threshold = TwoStageLowPressurePSI;
747-
else if (ServiceMaxCylPressurePSI > 0 && threshold > ServiceMaxCylPressurePSI)
764+
else if (threshold > ServiceMaxCylPressurePSI)
748765
threshold = ServiceMaxCylPressurePSI;
749766
else if (threshold > MaxTripleValveCylPressurePSI)
750767
threshold = MaxTripleValveCylPressurePSI;
@@ -1233,7 +1250,15 @@ public override void Update(float elapsedClockSeconds)
12331250
}
12341251
if (RelayValveFitted)
12351252
{
1236-
demandedPressurePSI = Math.Max(RelayValveRatio * demandedPressurePSI, EngineRelayValveRatio * BrakeLine3PressurePSI);
1253+
float automaticDemandedPressurePSI;
1254+
float engineDemandedPressurePSI;
1255+
1256+
// Add in-shot pressure (if equipped) to pressure demanded from relay valve
1257+
// In-shot: A small amount of additional pressure at a 1:1 ratio is added to ensure positive brake application
1258+
automaticDemandedPressurePSI = Math.Min(demandedPressurePSI, RelayValveInshot) + demandedPressurePSI * (TwoStageLowPressureActive ? TwoStageRelayValveRatio : RelayValveRatio);
1259+
engineDemandedPressurePSI = Math.Min(BrakeLine3PressurePSI, EngineRelayValveInshot) + BrakeLine3PressurePSI * EngineRelayValveRatio;
1260+
1261+
demandedPressurePSI = Math.Max(automaticDemandedPressurePSI, engineDemandedPressurePSI);
12371262
if (demandedPressurePSI > CylPressurePSI)
12381263
{
12391264
float dp = elapsedClockSeconds * RelayValveApplicationRatePSIpS;

0 commit comments

Comments
 (0)