Skip to content

Commit 10cd343

Browse files
committed
Support for emergency vent valves, and addition of accelerated emergency release
1 parent e8e9469 commit 10cd343

File tree

1 file changed

+71
-22
lines changed
  • Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS

1 file changed

+71
-22
lines changed

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

Lines changed: 71 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,20 @@ public class AirSinglePipe : MSTSBrakeSystem
6161
protected string RetainerDebugState = string.Empty;
6262
protected bool MRPAuxResCharging;
6363
protected float CylVolumeM3;
64-
protected bool EmergResQuickRelease = false;
64+
protected bool EmergResQuickRelease;
6565
protected float UniformChargingThresholdPSI = 3.0f;
66-
protected float UniformChargingRatio = 0;
67-
protected bool QuickServiceActive = false;
68-
protected float QuickServiceLimitPSI = 0;
69-
protected float QuickServiceApplicationRatePSIpS = 0;
70-
protected float QuickServiceVentRatePSIpS = 0;
71-
protected float AcceleratedApplicationRatio = 0;
66+
protected float UniformChargingRatio;
67+
protected bool UniformChargingActive;
68+
protected bool QuickServiceActive;
69+
protected float QuickServiceLimitPSI;
70+
protected float QuickServiceApplicationRatePSIpS;
71+
protected float QuickServiceVentRatePSIpS;
72+
protected float AcceleratedApplicationRatio;
7273
protected float AcceleratedApplicationLimitPSIpS = 10.0f;
7374
protected float InitialApplicationThresholdPSI = 1.0f;
74-
protected float BrakeCylinderSpringPressurePSI = 0;
75-
protected float ServiceMaxCylPressurePSI = 0;
75+
protected float BrakeCylinderSpringPressurePSI;
76+
protected float ServiceMaxCylPressurePSI;
77+
protected float AcceleratedEmergencyReleaseThresholdPSI = 20.0f;
7678

7779

7880
protected bool TrainBrakePressureChanging = false;
@@ -301,6 +303,7 @@ public override void Save(BinaryWriter outf)
301303
outf.Write(BleedOffValveOpen);
302304
outf.Write((int)HoldingValve);
303305
outf.Write(CylVolumeM3);
306+
outf.Write(UniformChargingActive);
304307
outf.Write(QuickServiceActive);
305308
}
306309

@@ -324,6 +327,7 @@ public override void Restore(BinaryReader inf)
324327
BleedOffValveOpen = inf.ReadBoolean();
325328
HoldingValve = (ValveState)inf.ReadInt32();
326329
CylVolumeM3 = inf.ReadSingle();
330+
UniformChargingActive = inf.ReadBoolean();
327331
QuickServiceActive = inf.ReadBoolean();
328332
}
329333

@@ -399,20 +403,27 @@ public void UpdateTripleValveState(float elapsedClockSeconds)
399403
var prevState = TripleValveState;
400404
var valveType = (Car as MSTSWagon).BrakeValve;
401405
bool disableGradient = !(Car.Train.LeadLocomotive is MSTSLocomotive) && Car.Train.TrainType != Orts.Simulation.Physics.Train.TRAINTYPE.STATIC;
406+
402407
if (valveType == MSTSWagon.BrakeValveType.Distributor)
403408
{
404409
float targetPressurePSI = (ControlResPressurePSI - BrakeLine1PressurePSI) * AuxCylVolumeRatio;
405410
if (!disableGradient && EmergencyValveActuationRatePSIpS > 0 && (prevBrakePipePressurePSI - BrakeLine1PressurePSI) > Math.Max(elapsedClockSeconds, 0.0001f) * EmergencyValveActuationRatePSIpS)
406411
{
407-
if (TripleValveState == ValveState.Release) // If valve transitions from release to emergency, quick service activates
412+
if (prevState == ValveState.Release) // If valve transitions from release to emergency, quick service activates
413+
{
408414
QuickServiceActive = true;
415+
UniformChargingActive = false;
416+
}
409417
TripleValveState = ValveState.Emergency;
410418
}
411419
else if (TripleValveState != ValveState.Emergency &&
412420
targetPressurePSI > AutoCylPressurePSI + (TripleValveState == ValveState.Release ? AuxCylVolumeRatio * InitialApplicationThresholdPSI : (TripleValveState == ValveState.Apply ? 0.0f : 2.2f)))
413421
{
414-
if (TripleValveState == ValveState.Release) // If valve transitions from release to apply, quick service activates
422+
if (prevState == ValveState.Release) // If valve transitions from release to apply, quick service activates
423+
{
415424
QuickServiceActive = true;
425+
UniformChargingActive = false;
426+
}
416427
TripleValveState = ValveState.Apply;
417428
}
418429
else if (targetPressurePSI < AutoCylPressurePSI - (TripleValveState == ValveState.Release ? 0.0f : 2.2f) || targetPressurePSI < 2.2f)
@@ -428,15 +439,21 @@ public void UpdateTripleValveState(float elapsedClockSeconds)
428439
{
429440
if (!disableGradient && EmergencyValveActuationRatePSIpS > 0 && (prevBrakePipePressurePSI - BrakeLine1PressurePSI) > Math.Max(elapsedClockSeconds, 0.0001f) * EmergencyValveActuationRatePSIpS)
430441
{
431-
if (TripleValveState == ValveState.Release) // If valve transitions from release to emergency, quick service activates
442+
if (prevState == ValveState.Release) // If valve transitions from release to emergency, quick service activates
443+
{
432444
QuickServiceActive = true;
445+
UniformChargingActive = false;
446+
}
433447
TripleValveState = ValveState.Emergency;
434448
}
435449
else if (TripleValveState != ValveState.Emergency &&
436450
BrakeLine1PressurePSI < AuxResPressurePSI - (TripleValveState == ValveState.Release ? InitialApplicationThresholdPSI : (TripleValveState == ValveState.Apply ? 0.0f : 1.0f)))
437451
{
438-
if (TripleValveState == ValveState.Release) // If valve transitions from release to apply, quick service activates
452+
if (prevState == ValveState.Release) // If valve transitions from release to apply, quick service activates
453+
{
439454
QuickServiceActive = true;
455+
UniformChargingActive = false;
456+
}
440457
TripleValveState = ValveState.Apply;
441458
}
442459
else if (BrakeLine1PressurePSI > AuxResPressurePSI + (TripleValveState == ValveState.Release ? 0.0f : 2.0f))
@@ -515,18 +532,24 @@ public override void Update(float elapsedClockSeconds)
515532
{
516533
dpPipe = Math.Abs(elapsedClockSeconds * QuickServiceVentRatePSIpS);
517534
if (CylPressurePSI > QuickServiceLimitPSI * 0.75f) // Vent rate is reduced when quick service is nearly complete
535+
{
518536
dpPipe /= 3;
537+
}
519538
}
520539
dp = elapsedClockSeconds * Math.Max(QuickServiceApplicationRatePSIpS, MaxApplicationRatePSIpS);
521540
}
522541
else
523542
{
524543
if (TripleValveState == ValveState.Apply && AcceleratedApplicationRatio > 0) // Accelerated application: Air is vented from the brake pipe to speed up service applications
544+
{
525545
dpPipe = Math.Min(BrakePipeChange * AcceleratedApplicationRatio, elapsedClockSeconds * AcceleratedApplicationLimitPSIpS); // Amount of air vented is proportional to pressure reduction from external sources
546+
}
526547
dp = elapsedClockSeconds * MaxApplicationRatePSIpS;
527548
}
528549
if (BrakeLine1PressurePSI - dpPipe < 0)
550+
{
529551
dpPipe = BrakeLine1PressurePSI;
552+
}
530553

531554
if (TripleValveState != ValveState.Emergency && BrakeLine1PressurePSI < AuxResPressurePSI + 1)
532555
dp *= MathHelper.Clamp(AuxResPressurePSI - BrakeLine1PressurePSI, 0.1f, 1.0f); // Reduce application rate if nearing equalization to prevent rapid toggling between apply and lap
@@ -556,12 +579,33 @@ public override void Update(float elapsedClockSeconds)
556579
{
557580
if ((Car as MSTSWagon).EmergencyReservoirPresent)
558581
{
559-
dp = elapsedClockSeconds * MaxApplicationRatePSIpS;
560-
if (EmergResPressurePSI - dp < AuxResPressurePSI + dp * EmergAuxVolumeRatio)
561-
dp = (EmergResPressurePSI - AuxResPressurePSI) / (1 + EmergAuxVolumeRatio);
562-
EmergResPressurePSI -= dp;
563-
AuxResPressurePSI += dp * EmergAuxVolumeRatio;
582+
if (EmergencyDumpValveTimerS != 0 && EmergencyDumpStartTime == null && BrakeLine1PressurePSI > AcceleratedEmergencyReleaseThresholdPSI)
583+
{
584+
// Accelerated emergency release: Aux res and BP air are routed into the brake pipe once the emergency application is complete, speeds up emergency release
585+
// Triggers at 20 psi brake pipe pressure
586+
587+
dp = elapsedClockSeconds * MaxReleaseRatePSIpS;
588+
if (AutoCylPressurePSI - dp < AuxResPressurePSI + dp / AuxCylVolumeRatio)
589+
dp = Math.Max((AutoCylPressurePSI - AuxResPressurePSI) * (AuxCylVolumeRatio / (1 + AuxCylVolumeRatio)), 0);
590+
AutoCylPressurePSI -= dp;
591+
AuxResPressurePSI += dp / AuxCylVolumeRatio;
592+
593+
dp = elapsedClockSeconds * MaxAuxilaryChargingRatePSIpS;
594+
if (AuxResPressurePSI - dp < BrakeLine1PressurePSI + dp * AuxBrakeLineVolumeRatio)
595+
dp = Math.Max((AuxResPressurePSI - BrakeLine1PressurePSI) / (1 + AuxBrakeLineVolumeRatio), 0);
596+
AuxResPressurePSI -= dp;
597+
BrakeLine1PressurePSI += dp * AuxBrakeLineVolumeRatio;
598+
}
599+
else
600+
{
601+
dp = elapsedClockSeconds * MaxApplicationRatePSIpS;
602+
if (EmergResPressurePSI - dp < AuxResPressurePSI + dp * EmergAuxVolumeRatio)
603+
dp = (EmergResPressurePSI - AuxResPressurePSI) / (1 + EmergAuxVolumeRatio);
604+
EmergResPressurePSI -= dp;
605+
AuxResPressurePSI += dp * EmergAuxVolumeRatio;
606+
}
564607
}
608+
565609
if (EmergencyDumpValveTimerS == 0)
566610
{
567611
if (BrakeLine1PressurePSI < 1) EmergencyDumpStartTime = null;
@@ -636,7 +680,6 @@ public override void Update(float elapsedClockSeconds)
636680
}
637681
else // Quick recharge: Emergency res air used to recharge aux res on older control valves
638682
{
639-
640683
float dp = elapsedClockSeconds * MaxAuxilaryChargingRatePSIpS;
641684
if (AuxResPressurePSI + dp > EmergResPressurePSI - dp / EmergAuxVolumeRatio)
642685
dp = (EmergResPressurePSI - AuxResPressurePSI) * EmergAuxVolumeRatio / (1 + EmergAuxVolumeRatio);
@@ -674,8 +717,15 @@ public override void Update(float elapsedClockSeconds)
674717
{
675718
if (AuxResPressurePSI < BrakeLine1PressurePSI && (valveType == MSTSWagon.BrakeValveType.Distributor ? true : TripleValveState == ValveState.Release) && !BleedOffValveOpen)
676719
{
677-
if (UniformChargingRatio > 0 && AuxResPressurePSI < BrakeLine1PressurePSI - UniformChargingThresholdPSI)
678-
dpAux /= UniformChargingRatio; // Uniform charging: Aux res charging is slowed down when the brake pipe is substantially higher than the aux res
720+
if (UniformChargingRatio > 0) // Uniform charging: Aux res charging is slowed down when the brake pipe is substantially higher than the aux res
721+
{
722+
if (!UniformChargingActive && AuxResPressurePSI < BrakeLine1PressurePSI - UniformChargingThresholdPSI)
723+
UniformChargingActive = true;
724+
else if (UniformChargingActive && AuxResPressurePSI > BrakeLine1PressurePSI - UniformChargingThresholdPSI / 2)
725+
UniformChargingActive = false;
726+
if (UniformChargingActive)
727+
dpAux /= UniformChargingRatio;
728+
}
679729
if (AuxResPressurePSI + dpAux > BrakeLine1PressurePSI - dpAux * AuxBrakeLineVolumeRatio)
680730
dpAux = (BrakeLine1PressurePSI - AuxResPressurePSI) / (1 + AuxBrakeLineVolumeRatio);
681731
AuxResPressurePSI += dpAux;
@@ -949,7 +999,6 @@ public override void Update(float elapsedClockSeconds)
949999
lead.BrakeOverchargeSoundOn = false;
9501000
}
9511001
}
952-
9531002
}
9541003
prevBrakePipePressurePSI = BrakeLine1PressurePSI;
9551004
SoundTriggerCounter += elapsedClockSeconds;

0 commit comments

Comments
 (0)