Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements for air brakes #3 - Emergency valves #829

Merged
merged 4 commits into from Jul 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions Source/Documentation/Manual/physics.rst
Expand Up @@ -2944,6 +2944,8 @@ MaxAuxilaryChargingRate and EmergencyResChargingRate.
.. index::
single: BrakePipeVolume
single: ORTSEmergencyValveActuationRate
single: ORTSEmergencyDumpValveRate
single: ORTSEmergencyDumpValveTimer
single: ORTSMainResPipeAuxResCharging
single: ORTSMainResChargingRate
single: ORTSEngineBrakeReleaseRate
Expand Down Expand Up @@ -2972,6 +2974,11 @@ MaxAuxilaryChargingRate and EmergencyResChargingRate.
brake actuation of the triple valve. If the pressure in the brake pipe
decreases at a higher rate than specified, the triple valve will switch to
emergency mode.
- ``Wagon(ORTSEmergencyDumpValveRate)``-- Rate at which BP is locally discharged
at every wagon during an emergency brake application.
- ``Wagon(ORTSEmergencyDumpValveTimer)``-- Timer for emergency dump valve to close
after it is activated. If set to 0, it will close as soon as BP is discharged.
Default value will prevent BP from being charged for 2 minutes.
- ``Wagon(ORTSMainResPipeAuxResCharging`` -- Boolean value that indicates,
for twin pipe systems, if the main reservoir pipe is used for charging the auxiliary
reservoirs. If set to false, the main reservoir pipe will not be used
Expand Down
3 changes: 3 additions & 0 deletions Source/Documentation/Manual/sound.rst
Expand Up @@ -403,6 +403,9 @@ Trigger Function
243 GenericItem2Off
========= =====================================

Trigger 252 is activated when the braking system detects an
emergency brake application and starts venting air from the Brake Pipe.

Variable Triggers
-----------------

Expand Down
2 changes: 2 additions & 0 deletions Source/Orts.Simulation/Common/Events.cs
Expand Up @@ -255,6 +255,7 @@ public enum Event

OverchargeBrakingOn,
OverchargeBrakingOff,
EmergencyVentValveOn,

// Cruise Control
LeverFromZero,
Expand Down Expand Up @@ -523,6 +524,7 @@ public static Event From(Source source, int eventID)

case 250: return Event.OverchargeBrakingOn;
case 251: return Event.OverchargeBrakingOff;
case 252: return Event.EmergencyVentValveOn;

// Cruise Control
case 298: return Event.LeverFromZero;
Expand Down
Expand Up @@ -51,6 +51,9 @@ public class AirSinglePipe : MSTSBrakeSystem
protected float MaxAuxilaryChargingRatePSIpS = 1.684f;
protected float BrakeInsensitivityPSIpS = 0.07f;
protected float EmergencyValveActuationRatePSIpS = 0;
protected float EmergencyDumpValveRatePSIpS = 0;
protected float EmergencyDumpValveTimerS = 120;
protected float? EmergencyDumpStartTime;
protected float EmergResChargingRatePSIpS = 1.684f;
protected float EmergAuxVolumeRatio = 1.4f;
protected string DebugType = string.Empty;
Expand Down Expand Up @@ -116,6 +119,8 @@ public override void InitializeFromCopy(BrakeSystem copy)
MaxAuxilaryChargingRatePSIpS = thiscopy.MaxAuxilaryChargingRatePSIpS;
BrakeInsensitivityPSIpS = thiscopy.BrakeInsensitivityPSIpS;
EmergencyValveActuationRatePSIpS = thiscopy.EmergencyValveActuationRatePSIpS;
EmergencyDumpValveRatePSIpS = thiscopy.EmergencyDumpValveRatePSIpS;
EmergencyDumpValveTimerS = thiscopy.EmergencyDumpValveTimerS;
EmergResChargingRatePSIpS = thiscopy.EmergResChargingRatePSIpS;
EmergAuxVolumeRatio = thiscopy.EmergAuxVolumeRatio;
TwoPipes = thiscopy.TwoPipes;
Expand Down Expand Up @@ -232,6 +237,8 @@ public override void Parse(string lowercasetoken, STFReader stf)
case "wagon(brakepipevolume": BrakePipeVolumeM3 = Me3.FromFt3(stf.ReadFloatBlock(STFReader.UNITS.VolumeDefaultFT3, null)); break;
case "wagon(ortsbrakeinsensitivity": BrakeInsensitivityPSIpS = stf.ReadFloatBlock(STFReader.UNITS.PressureRateDefaultPSIpS, 0.07f); break;
case "wagon(ortsemergencyvalveactuationrate": EmergencyValveActuationRatePSIpS = stf.ReadFloatBlock(STFReader.UNITS.PressureRateDefaultPSIpS, 15f); break;
case "wagon(ortsemergencydumpvalverate": EmergencyDumpValveRatePSIpS = stf.ReadFloatBlock(STFReader.UNITS.PressureRateDefaultPSIpS, 15f); break;
case "wagon(ortsemergencydumpvalvetimer": EmergencyDumpValveTimerS = stf.ReadFloatBlock(STFReader.UNITS.Time, 120.0f); break;
case "wagon(ortsmainrespipeauxrescharging": MRPAuxResCharging = this is AirTwinPipe && stf.ReadBoolBlock(true); break;
}
}
Expand Down Expand Up @@ -307,7 +314,10 @@ public override void Initialize(bool handbrakeOn, float maxPressurePSI, float fu
CylPressurePSI = AutoCylPressurePSI = immediateRelease ? 0 : Math.Min((maxPressurePSI - BrakeLine1PressurePSI) * AuxCylVolumeRatio, MaxCylPressurePSI);
AuxResPressurePSI = Math.Max(TwoPipes ? maxPressurePSI : maxPressurePSI - AutoCylPressurePSI / AuxCylVolumeRatio, BrakeLine1PressurePSI);
if ((Car as MSTSWagon).EmergencyReservoirPresent)
{
EmergResPressurePSI = Math.Max(AuxResPressurePSI, maxPressurePSI);
if (EmergencyValveActuationRatePSIpS == 0) EmergencyValveActuationRatePSIpS = 15;
}
TripleValveState = AutoCylPressurePSI < 1 ? ValveState.Release : ValveState.Lap;
HoldingValve = ValveState.Release;
HandbrakePercent = handbrakeOn & (Car as MSTSWagon).HandBrakePresent ? 100 : 0;
Expand Down Expand Up @@ -340,23 +350,25 @@ public override void InitializeMoving ()

public void UpdateTripleValveState(float elapsedClockSeconds)
{
var prevState = TripleValveState;
var valveType = (Car as MSTSWagon).BrakeValve;
bool disableGradient = !(Car.Train.LeadLocomotive is MSTSLocomotive) && Car.Train.TrainType != Orts.Simulation.Physics.Train.TRAINTYPE.STATIC;
if (valveType == MSTSWagon.BrakeValveType.Distributor)
{
float targetPressurePSI = (ControlResPressurePSI - BrakeLine1PressurePSI) * AuxCylVolumeRatio;
if (targetPressurePSI > AutoCylPressurePSI && EmergencyValveActuationRatePSIpS > 0 && (prevBrakePipePressurePSI - BrakeLine1PressurePSI) > Math.Max(elapsedClockSeconds, 0.0001f) * EmergencyValveActuationRatePSIpS)
if (!disableGradient && targetPressurePSI > AutoCylPressurePSI && EmergencyValveActuationRatePSIpS > 0 && (prevBrakePipePressurePSI - BrakeLine1PressurePSI) > Math.Max(elapsedClockSeconds, 0.0001f) * EmergencyValveActuationRatePSIpS)
TripleValveState = ValveState.Emergency;
else if (targetPressurePSI < AutoCylPressurePSI - (TripleValveState != ValveState.Release ? 2.2f : 0f)
|| targetPressurePSI < 2.2f) // The latter is a UIC regulation (0.15 bar)
TripleValveState = ValveState.Release;
else if (TripleValveState != ValveState.Emergency && targetPressurePSI > AutoCylPressurePSI + (TripleValveState != ValveState.Apply ? 2.2f : 0f))
TripleValveState = ValveState.Apply;
else
else if (TripleValveState != ValveState.Emergency)
TripleValveState = ValveState.Lap;
}
else if (valveType == MSTSWagon.BrakeValveType.TripleValve || valveType == MSTSWagon.BrakeValveType.DistributingValve)
{
if (BrakeLine1PressurePSI < AuxResPressurePSI - 1 && EmergencyValveActuationRatePSIpS > 0 && (prevBrakePipePressurePSI - BrakeLine1PressurePSI) > Math.Max(elapsedClockSeconds, 0.0001f) * EmergencyValveActuationRatePSIpS)
if (!disableGradient && BrakeLine1PressurePSI < AuxResPressurePSI - 1 && EmergencyValveActuationRatePSIpS > 0 && (prevBrakePipePressurePSI - BrakeLine1PressurePSI) > Math.Max(elapsedClockSeconds, 0.0001f) * EmergencyValveActuationRatePSIpS)
TripleValveState = ValveState.Emergency;
else if (BrakeLine1PressurePSI > AuxResPressurePSI + 1)
TripleValveState = ValveState.Release;
Expand All @@ -371,6 +383,15 @@ public void UpdateTripleValveState(float elapsedClockSeconds)
{
TripleValveState = ValveState.Release;
}
if (TripleValveState == ValveState.Emergency)
{
if (prevState != ValveState.Emergency)
{
EmergencyDumpStartTime = (float)Car.Simulator.GameTime;
Car.SignalEvent(Event.EmergencyVentValveOn);
}
}
else EmergencyDumpStartTime = null;
prevBrakePipePressurePSI = BrakeLine1PressurePSI;
}

Expand Down Expand Up @@ -440,6 +461,20 @@ public override void Update(float elapsedClockSeconds)
EmergResPressurePSI -= dp;
AuxResPressurePSI += dp * EmergAuxVolumeRatio;
}
if (EmergencyDumpValveTimerS == 0)
{
if (BrakeLine1PressurePSI < 1) EmergencyDumpStartTime = null;
}
else if (Car.Simulator.GameTime - EmergencyDumpStartTime > EmergencyDumpValveTimerS)
{
EmergencyDumpStartTime = null;
}
if (EmergencyDumpValveRatePSIpS > 0 && EmergencyDumpStartTime != null)
{
BrakeLine1PressurePSI -= elapsedClockSeconds * EmergencyDumpValveRatePSIpS;
if (BrakeLine1PressurePSI < 0)
BrakeLine1PressurePSI = 0;
}
}
}

Expand Down