Skip to content

Commit

Permalink
Add relay valve option for two stage brakes, add inshot, and fix an o…
Browse files Browse the repository at this point in the history
…versight in initialization
  • Loading branch information
SteelFill committed Feb 18, 2024
1 parent 3112a51 commit fc4146c
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 8 deletions.
16 changes: 15 additions & 1 deletion Source/Documentation/Manual/physics.rst
Expand Up @@ -3037,13 +3037,16 @@ MaxAuxilaryChargingRate and EmergencyResChargingRate.
single: ORTSEmergencyResQuickRelease
single: ORTSMainResPipeAuxResCharging
single: ORTSBrakeRelayValveRatio
single: ORTSBrakeRelayValveInshot
single: ORTSEngineBrakeRelayValveRatio
single: ORTSEngineBrakeRelayValveInshot
single: ORTSBrakeRelayValveApplicationRate
single: ORTSBrakeRelayValveReleaseRate
single: ORTSMaxTripleValveCylinderPressure
single: ORTSMaxServiceCylinderPressure
single: ORTSMaxServiceApplicationRate
single: ORTSTwoStageLowPressure
single: ORTSTwoStageRelayValveRatio
single: ORTSTwoStageIncreasingSpeed
single: ORTSTwoStageDecreasingSpeed
single: ORTSHighSpeedReducingPressure
Expand Down Expand Up @@ -3116,7 +3119,15 @@ MaxAuxilaryChargingRate and EmergencyResChargingRate.
This is achieved via a relay valve which sets BC pressure proportionally.
Relay valves may be installed to achieve higher brake cylinder pressures,
dynamic brake blending or variable load compensation.
- ``Wagon(ORTSBrakeRelayValveRatio`` -- Same as above, but for the engine brake
- ``Wagon(ORTSBrakeRelayValveInshot`` -- Sets the "in-shot" pressure for the relay
valve. Relay valves with a ratio less than 1 may not produce sufficient pressure
to extend the brake cylinders. In-shot solves this problem by applying additional
pressure at a 1:1 ratio, regardless of the actual relay valve ratio. The pressure
defined here is the maximum amount of additional pressure to apply.
- ``Wagon(ORTSEngineBrakeRelayValveRatio`` -- Same as ``ORTSBrakeRelayValveRatio``,
but for the engine brake.
- ``Wagon(ORTSEngineBrakeRelayValveInshot`` -- Same as ``ORTSBrakeRelayValveInshot``,
but for the engine brake.
- ``Wagon(ORTSBrakeRelayValveApplicationRate`` -- Brake cylinder pressure application
rate achieved by the relay valve, if fitted.
- ``Wagon(ORTSBrakeRelayValveReleaseRate`` -- Brake cylinder pressure release
Expand All @@ -3135,6 +3146,9 @@ MaxAuxilaryChargingRate and EmergencyResChargingRate.
is reduced at lower speeds and increased at higher speeds, sets the maximum cylinder
pressure demanded when at slower speeds (defaults to 0, disabling two stage braking).
For high speed, use ``ORTSMaxTripleValveCylinderPressure`` to set the pressure limit.
- ``Wagon(ORTSTwoStageRelayValveRatio`` -- Alternatey, sets a relay valve ratio to
be used by the two stage system at low speeds. At high speed, the relay valve
uses the ratio set by ``ORTSBrakeRelayValveRatio``.
- ``Wagon(ORTSTwoStageIncreasingSpeed`` -- The speed at which the two stage braking
system changes from low pressure to high pressure during acceleration.
- ``Wagon(ORTSTwoStageDecreasingSpeed`` -- The speed at which the two stage braking
Expand Down
Expand Up @@ -68,7 +68,9 @@ public class AirSinglePipe : MSTSBrakeSystem
protected float EmergAuxVolumeRatio = 1.4f;
protected bool RelayValveFitted = false;
public float RelayValveRatio { get; protected set; } = 1;
protected float RelayValveInshot;
protected float EngineRelayValveRatio = 0;
protected float EngineRelayValveInshot;
protected float RelayValveApplicationRatePSIpS = 50;
protected float RelayValveReleaseRatePSIpS = 50;
protected string DebugType = string.Empty;
Expand All @@ -95,6 +97,7 @@ public class AirSinglePipe : MSTSBrakeSystem
protected float ServiceMaxCylPressurePSI;
protected float ServiceApplicationRatePSIpS;
protected float TwoStageLowPressurePSI;
protected float TwoStageRelayValveRatio;
protected float TwoStageSpeedUpMpS;
protected float TwoStageSpeedDownMpS;
protected bool TwoStageLowPressureActive;
Expand Down Expand Up @@ -180,7 +183,9 @@ public override void InitializeFromCopy(BrakeSystem copy)
HoldingValve = thiscopy.HoldingValve;
RelayValveFitted = thiscopy.RelayValveFitted;
RelayValveRatio = thiscopy.RelayValveRatio;
RelayValveInshot = thiscopy.RelayValveInshot;
EngineRelayValveRatio = thiscopy.EngineRelayValveRatio;
EngineRelayValveInshot = thiscopy.EngineRelayValveInshot;
RelayValveApplicationRatePSIpS = thiscopy.RelayValveApplicationRatePSIpS;
RelayValveReleaseRatePSIpS = thiscopy.RelayValveReleaseRatePSIpS;
MaxTripleValveCylPressurePSI = thiscopy.MaxTripleValveCylPressurePSI;
Expand All @@ -200,6 +205,7 @@ public override void InitializeFromCopy(BrakeSystem copy)
ServiceMaxCylPressurePSI = thiscopy.ServiceMaxCylPressurePSI;
ServiceApplicationRatePSIpS = thiscopy.ServiceApplicationRatePSIpS;
TwoStageLowPressurePSI = thiscopy.TwoStageLowPressurePSI;
TwoStageRelayValveRatio = thiscopy.TwoStageRelayValveRatio;
TwoStageSpeedUpMpS = thiscopy.TwoStageSpeedUpMpS;
TwoStageSpeedDownMpS = thiscopy.TwoStageSpeedDownMpS;
HighSpeedReducingPressurePSI = thiscopy.HighSpeedReducingPressurePSI;
Expand Down Expand Up @@ -334,7 +340,9 @@ public override void Parse(string lowercasetoken, STFReader stf)
RelayValveFitted = false;
}
break;
case "wagon(ortsbrakerelayvalveinshot": RelayValveInshot = stf.ReadFloatBlock(STFReader.UNITS.PressureDefaultPSI, null); break;
case "wagon(ortsenginebrakerelayvalveratio": EngineRelayValveRatio = stf.ReadFloatBlock(STFReader.UNITS.None, null); break;
case "wagon(ortsenginebrakerelayvalveinshot": EngineRelayValveInshot = stf.ReadFloatBlock(STFReader.UNITS.PressureDefaultPSI, null); break;
case "wagon(ortsbrakerelayvalveapplicationrate": RelayValveApplicationRatePSIpS = stf.ReadFloatBlock(STFReader.UNITS.PressureRateDefaultPSIpS, null); break;
case "wagon(ortsbrakerelayvalvereleaserate": RelayValveReleaseRatePSIpS = stf.ReadFloatBlock(STFReader.UNITS.PressureRateDefaultPSIpS, null); break;
case "wagon(ortsmaxtriplevalvecylinderpressure": MaxTripleValveCylPressurePSI = stf.ReadFloatBlock(STFReader.UNITS.PressureDefaultPSI, null); break;
Expand All @@ -354,6 +362,7 @@ public override void Parse(string lowercasetoken, STFReader stf)
case "wagon(ortsmaxservicecylinderpressure": ServiceMaxCylPressurePSI = stf.ReadFloatBlock(STFReader.UNITS.PressureDefaultPSI, null); break;
case "wagon(ortsmaxserviceapplicationrate": ServiceApplicationRatePSIpS = stf.ReadFloatBlock(STFReader.UNITS.PressureRateDefaultPSIpS, null); break;
case "wagon(ortstwostagelowpressure": TwoStageLowPressurePSI = stf.ReadFloatBlock(STFReader.UNITS.PressureDefaultPSI, null); break;
case "wagon(ortstwostagerelayvalveratio": TwoStageRelayValveRatio = stf.ReadFloatBlock(STFReader.UNITS.None, null); break;
case "wagon(ortstwostageincreasingspeed": TwoStageSpeedUpMpS = stf.ReadFloatBlock(STFReader.UNITS.Speed, null); break;
case "wagon(ortstwostagedecreasingspeed": TwoStageSpeedDownMpS = stf.ReadFloatBlock(STFReader.UNITS.Speed, null); break;
case "wagon(ortshighspeedreducingpressure": HighSpeedReducingPressurePSI = stf.ReadFloatBlock(STFReader.UNITS.PressureDefaultPSI, null); break;
Expand Down Expand Up @@ -479,8 +488,12 @@ public override void Initialize()
if (Car.Simulator.Settings.SimpleControlPhysics && EmergResVolumeM3 > 2.0)
EmergResVolumeM3 = 0.7f;

if (MaxTripleValveCylPressurePSI == 0) MaxTripleValveCylPressurePSI = MaxCylPressurePSI / RelayValveRatio;
if (EngineRelayValveRatio == 0) EngineRelayValveRatio = RelayValveRatio;
if (ServiceMaxCylPressurePSI == 0)
ServiceMaxCylPressurePSI = MaxTripleValveCylPressurePSI;
if (MaxTripleValveCylPressurePSI == 0)
MaxTripleValveCylPressurePSI = MaxCylPressurePSI / RelayValveRatio;
if (EngineRelayValveRatio == 0)
EngineRelayValveRatio = RelayValveRatio;

if (ServiceApplicationRatePSIpS == 0)
ServiceApplicationRatePSIpS = MaxApplicationRatePSIpS;
Expand Down Expand Up @@ -530,7 +543,8 @@ public override void Initialize()
if (CylVolumeM3 == 0) CylVolumeM3 = EmergResVolumeM3 / EmergAuxVolumeRatio / AuxCylVolumeRatio;

RelayValveFitted |= (Car is MSTSLocomotive loco && (loco.DynamicBrakeAutoBailOff || loco.DynamicBrakePartialBailOff)) ||
(Car as MSTSWagon).BrakeValve == MSTSWagon.BrakeValveType.DistributingValve || (Car as MSTSWagon).SupplyReservoirPresent;
(Car as MSTSWagon).BrakeValve == MSTSWagon.BrakeValveType.DistributingValve || (Car as MSTSWagon).SupplyReservoirPresent ||
TwoStageRelayValveRatio != 0;

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

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

if (AngleCockOpenAmount >= 1.0f)
{
Expand All @@ -698,7 +715,7 @@ public void UpdateAngleCockState(bool AngleCockOpen, ref float AngleCockOpenAmou
else
{
// Gradually open anglecock toward 30% over 30 seconds
AngleCockOpenAmount = 0.3f * (currentTime - (float)AngleCockOpenTime) / AngleCockOpeningTime;
AngleCockOpenAmount = MathHelper.Lerp(0.0f, 0.3f, (currentTime - (float)AngleCockOpenTime) / AngleCockOpeningTime);
}
}
else if (!AngleCockOpen && AngleCockOpenAmount > 0.0f)
Expand Down Expand Up @@ -744,7 +761,7 @@ public override void Update(float elapsedClockSeconds)
}
if (TwoStageLowPressureActive && threshold > TwoStageLowPressurePSI)
threshold = TwoStageLowPressurePSI;
else if (ServiceMaxCylPressurePSI > 0 && threshold > ServiceMaxCylPressurePSI)
else if (threshold > ServiceMaxCylPressurePSI)
threshold = ServiceMaxCylPressurePSI;
else if (threshold > MaxTripleValveCylPressurePSI)
threshold = MaxTripleValveCylPressurePSI;
Expand Down Expand Up @@ -1233,7 +1250,15 @@ public override void Update(float elapsedClockSeconds)
}
if (RelayValveFitted)
{
demandedPressurePSI = Math.Max(RelayValveRatio * demandedPressurePSI, EngineRelayValveRatio * BrakeLine3PressurePSI);
float automaticDemandedPressurePSI;
float engineDemandedPressurePSI;

// Add in-shot pressure (if equipped) to pressure demanded from relay valve
// In-shot: A small amount of additional pressure at a 1:1 ratio is added to ensure positive brake application
automaticDemandedPressurePSI = Math.Min(demandedPressurePSI, RelayValveInshot) + demandedPressurePSI * (TwoStageLowPressureActive ? TwoStageRelayValveRatio : RelayValveRatio);
engineDemandedPressurePSI = Math.Min(BrakeLine3PressurePSI, EngineRelayValveInshot) + BrakeLine3PressurePSI * EngineRelayValveRatio;

demandedPressurePSI = Math.Max(automaticDemandedPressurePSI, engineDemandedPressurePSI);
if (demandedPressurePSI > CylPressurePSI)
{
float dp = elapsedClockSeconds * RelayValveApplicationRatePSIpS;
Expand Down

0 comments on commit fc4146c

Please sign in to comment.