@@ -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