Skip to content

Commit

Permalink
Support for emergency vent valves, and addition of accelerated emerge…
Browse files Browse the repository at this point in the history
…ncy release
  • Loading branch information
SteelFill committed Jul 11, 2023
1 parent e8e9469 commit 10cd343
Showing 1 changed file with 71 additions and 22 deletions.
Expand Up @@ -61,18 +61,20 @@ public class AirSinglePipe : MSTSBrakeSystem
protected string RetainerDebugState = string.Empty;
protected bool MRPAuxResCharging;
protected float CylVolumeM3;
protected bool EmergResQuickRelease = false;
protected bool EmergResQuickRelease;
protected float UniformChargingThresholdPSI = 3.0f;
protected float UniformChargingRatio = 0;
protected bool QuickServiceActive = false;
protected float QuickServiceLimitPSI = 0;
protected float QuickServiceApplicationRatePSIpS = 0;
protected float QuickServiceVentRatePSIpS = 0;
protected float AcceleratedApplicationRatio = 0;
protected float UniformChargingRatio;
protected bool UniformChargingActive;
protected bool QuickServiceActive;
protected float QuickServiceLimitPSI;
protected float QuickServiceApplicationRatePSIpS;
protected float QuickServiceVentRatePSIpS;
protected float AcceleratedApplicationRatio;
protected float AcceleratedApplicationLimitPSIpS = 10.0f;
protected float InitialApplicationThresholdPSI = 1.0f;
protected float BrakeCylinderSpringPressurePSI = 0;
protected float ServiceMaxCylPressurePSI = 0;
protected float BrakeCylinderSpringPressurePSI;
protected float ServiceMaxCylPressurePSI;
protected float AcceleratedEmergencyReleaseThresholdPSI = 20.0f;


protected bool TrainBrakePressureChanging = false;
Expand Down Expand Up @@ -301,6 +303,7 @@ public override void Save(BinaryWriter outf)
outf.Write(BleedOffValveOpen);
outf.Write((int)HoldingValve);
outf.Write(CylVolumeM3);
outf.Write(UniformChargingActive);
outf.Write(QuickServiceActive);
}

Expand All @@ -324,6 +327,7 @@ public override void Restore(BinaryReader inf)
BleedOffValveOpen = inf.ReadBoolean();
HoldingValve = (ValveState)inf.ReadInt32();
CylVolumeM3 = inf.ReadSingle();
UniformChargingActive = inf.ReadBoolean();
QuickServiceActive = inf.ReadBoolean();
}

Expand Down Expand Up @@ -399,20 +403,27 @@ 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 (!disableGradient && EmergencyValveActuationRatePSIpS > 0 && (prevBrakePipePressurePSI - BrakeLine1PressurePSI) > Math.Max(elapsedClockSeconds, 0.0001f) * EmergencyValveActuationRatePSIpS)
{
if (TripleValveState == ValveState.Release) // If valve transitions from release to emergency, quick service activates
if (prevState == ValveState.Release) // If valve transitions from release to emergency, quick service activates
{
QuickServiceActive = true;
UniformChargingActive = false;
}
TripleValveState = ValveState.Emergency;
}
else if (TripleValveState != ValveState.Emergency &&
targetPressurePSI > AutoCylPressurePSI + (TripleValveState == ValveState.Release ? AuxCylVolumeRatio * InitialApplicationThresholdPSI : (TripleValveState == ValveState.Apply ? 0.0f : 2.2f)))
{
if (TripleValveState == ValveState.Release) // If valve transitions from release to apply, quick service activates
if (prevState == ValveState.Release) // If valve transitions from release to apply, quick service activates
{
QuickServiceActive = true;
UniformChargingActive = false;
}
TripleValveState = ValveState.Apply;
}
else if (targetPressurePSI < AutoCylPressurePSI - (TripleValveState == ValveState.Release ? 0.0f : 2.2f) || targetPressurePSI < 2.2f)
Expand All @@ -428,15 +439,21 @@ public void UpdateTripleValveState(float elapsedClockSeconds)
{
if (!disableGradient && EmergencyValveActuationRatePSIpS > 0 && (prevBrakePipePressurePSI - BrakeLine1PressurePSI) > Math.Max(elapsedClockSeconds, 0.0001f) * EmergencyValveActuationRatePSIpS)
{
if (TripleValveState == ValveState.Release) // If valve transitions from release to emergency, quick service activates
if (prevState == ValveState.Release) // If valve transitions from release to emergency, quick service activates
{
QuickServiceActive = true;
UniformChargingActive = false;
}
TripleValveState = ValveState.Emergency;
}
else if (TripleValveState != ValveState.Emergency &&
BrakeLine1PressurePSI < AuxResPressurePSI - (TripleValveState == ValveState.Release ? InitialApplicationThresholdPSI : (TripleValveState == ValveState.Apply ? 0.0f : 1.0f)))
{
if (TripleValveState == ValveState.Release) // If valve transitions from release to apply, quick service activates
if (prevState == ValveState.Release) // If valve transitions from release to apply, quick service activates
{
QuickServiceActive = true;
UniformChargingActive = false;
}
TripleValveState = ValveState.Apply;
}
else if (BrakeLine1PressurePSI > AuxResPressurePSI + (TripleValveState == ValveState.Release ? 0.0f : 2.0f))
Expand Down Expand Up @@ -515,18 +532,24 @@ public override void Update(float elapsedClockSeconds)
{
dpPipe = Math.Abs(elapsedClockSeconds * QuickServiceVentRatePSIpS);
if (CylPressurePSI > QuickServiceLimitPSI * 0.75f) // Vent rate is reduced when quick service is nearly complete
{
dpPipe /= 3;
}
}
dp = elapsedClockSeconds * Math.Max(QuickServiceApplicationRatePSIpS, MaxApplicationRatePSIpS);
}
else
{
if (TripleValveState == ValveState.Apply && AcceleratedApplicationRatio > 0) // Accelerated application: Air is vented from the brake pipe to speed up service applications
{
dpPipe = Math.Min(BrakePipeChange * AcceleratedApplicationRatio, elapsedClockSeconds * AcceleratedApplicationLimitPSIpS); // Amount of air vented is proportional to pressure reduction from external sources
}
dp = elapsedClockSeconds * MaxApplicationRatePSIpS;
}
if (BrakeLine1PressurePSI - dpPipe < 0)
{
dpPipe = BrakeLine1PressurePSI;
}

if (TripleValveState != ValveState.Emergency && BrakeLine1PressurePSI < AuxResPressurePSI + 1)
dp *= MathHelper.Clamp(AuxResPressurePSI - BrakeLine1PressurePSI, 0.1f, 1.0f); // Reduce application rate if nearing equalization to prevent rapid toggling between apply and lap
Expand Down Expand Up @@ -556,12 +579,33 @@ public override void Update(float elapsedClockSeconds)
{
if ((Car as MSTSWagon).EmergencyReservoirPresent)
{
dp = elapsedClockSeconds * MaxApplicationRatePSIpS;
if (EmergResPressurePSI - dp < AuxResPressurePSI + dp * EmergAuxVolumeRatio)
dp = (EmergResPressurePSI - AuxResPressurePSI) / (1 + EmergAuxVolumeRatio);
EmergResPressurePSI -= dp;
AuxResPressurePSI += dp * EmergAuxVolumeRatio;
if (EmergencyDumpValveTimerS != 0 && EmergencyDumpStartTime == null && BrakeLine1PressurePSI > AcceleratedEmergencyReleaseThresholdPSI)
{
// Accelerated emergency release: Aux res and BP air are routed into the brake pipe once the emergency application is complete, speeds up emergency release
// Triggers at 20 psi brake pipe pressure

dp = elapsedClockSeconds * MaxReleaseRatePSIpS;
if (AutoCylPressurePSI - dp < AuxResPressurePSI + dp / AuxCylVolumeRatio)
dp = Math.Max((AutoCylPressurePSI - AuxResPressurePSI) * (AuxCylVolumeRatio / (1 + AuxCylVolumeRatio)), 0);
AutoCylPressurePSI -= dp;
AuxResPressurePSI += dp / AuxCylVolumeRatio;

dp = elapsedClockSeconds * MaxAuxilaryChargingRatePSIpS;
if (AuxResPressurePSI - dp < BrakeLine1PressurePSI + dp * AuxBrakeLineVolumeRatio)
dp = Math.Max((AuxResPressurePSI - BrakeLine1PressurePSI) / (1 + AuxBrakeLineVolumeRatio), 0);
AuxResPressurePSI -= dp;
BrakeLine1PressurePSI += dp * AuxBrakeLineVolumeRatio;
}
else
{
dp = elapsedClockSeconds * MaxApplicationRatePSIpS;
if (EmergResPressurePSI - dp < AuxResPressurePSI + dp * EmergAuxVolumeRatio)
dp = (EmergResPressurePSI - AuxResPressurePSI) / (1 + EmergAuxVolumeRatio);
EmergResPressurePSI -= dp;
AuxResPressurePSI += dp * EmergAuxVolumeRatio;
}
}

if (EmergencyDumpValveTimerS == 0)
{
if (BrakeLine1PressurePSI < 1) EmergencyDumpStartTime = null;
Expand Down Expand Up @@ -636,7 +680,6 @@ public override void Update(float elapsedClockSeconds)
}
else // Quick recharge: Emergency res air used to recharge aux res on older control valves
{

float dp = elapsedClockSeconds * MaxAuxilaryChargingRatePSIpS;
if (AuxResPressurePSI + dp > EmergResPressurePSI - dp / EmergAuxVolumeRatio)
dp = (EmergResPressurePSI - AuxResPressurePSI) * EmergAuxVolumeRatio / (1 + EmergAuxVolumeRatio);
Expand Down Expand Up @@ -674,8 +717,15 @@ public override void Update(float elapsedClockSeconds)
{
if (AuxResPressurePSI < BrakeLine1PressurePSI && (valveType == MSTSWagon.BrakeValveType.Distributor ? true : TripleValveState == ValveState.Release) && !BleedOffValveOpen)
{
if (UniformChargingRatio > 0 && AuxResPressurePSI < BrakeLine1PressurePSI - UniformChargingThresholdPSI)
dpAux /= UniformChargingRatio; // Uniform charging: Aux res charging is slowed down when the brake pipe is substantially higher than the aux res
if (UniformChargingRatio > 0) // Uniform charging: Aux res charging is slowed down when the brake pipe is substantially higher than the aux res
{
if (!UniformChargingActive && AuxResPressurePSI < BrakeLine1PressurePSI - UniformChargingThresholdPSI)
UniformChargingActive = true;
else if (UniformChargingActive && AuxResPressurePSI > BrakeLine1PressurePSI - UniformChargingThresholdPSI / 2)
UniformChargingActive = false;
if (UniformChargingActive)
dpAux /= UniformChargingRatio;
}
if (AuxResPressurePSI + dpAux > BrakeLine1PressurePSI - dpAux * AuxBrakeLineVolumeRatio)
dpAux = (BrakeLine1PressurePSI - AuxResPressurePSI) / (1 + AuxBrakeLineVolumeRatio);
AuxResPressurePSI += dpAux;
Expand Down Expand Up @@ -949,7 +999,6 @@ public override void Update(float elapsedClockSeconds)
lead.BrakeOverchargeSoundOn = false;
}
}

}
prevBrakePipePressurePSI = BrakeLine1PressurePSI;
SoundTriggerCounter += elapsedClockSeconds;
Expand Down

0 comments on commit 10cd343

Please sign in to comment.