@@ -61,18 +61,20 @@ public class AirSinglePipe : MSTSBrakeSystem
61
61
protected string RetainerDebugState = string . Empty ;
62
62
protected bool MRPAuxResCharging ;
63
63
protected float CylVolumeM3 ;
64
- protected bool EmergResQuickRelease = false ;
64
+ protected bool EmergResQuickRelease ;
65
65
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 ;
72
73
protected float AcceleratedApplicationLimitPSIpS = 10.0f ;
73
74
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 ;
76
78
77
79
78
80
protected bool TrainBrakePressureChanging = false ;
@@ -301,6 +303,7 @@ public override void Save(BinaryWriter outf)
301
303
outf . Write ( BleedOffValveOpen ) ;
302
304
outf . Write ( ( int ) HoldingValve ) ;
303
305
outf . Write ( CylVolumeM3 ) ;
306
+ outf . Write ( UniformChargingActive ) ;
304
307
outf . Write ( QuickServiceActive ) ;
305
308
}
306
309
@@ -324,6 +327,7 @@ public override void Restore(BinaryReader inf)
324
327
BleedOffValveOpen = inf . ReadBoolean ( ) ;
325
328
HoldingValve = ( ValveState ) inf . ReadInt32 ( ) ;
326
329
CylVolumeM3 = inf . ReadSingle ( ) ;
330
+ UniformChargingActive = inf . ReadBoolean ( ) ;
327
331
QuickServiceActive = inf . ReadBoolean ( ) ;
328
332
}
329
333
@@ -399,20 +403,27 @@ public void UpdateTripleValveState(float elapsedClockSeconds)
399
403
var prevState = TripleValveState ;
400
404
var valveType = ( Car as MSTSWagon ) . BrakeValve ;
401
405
bool disableGradient = ! ( Car . Train . LeadLocomotive is MSTSLocomotive ) && Car . Train . TrainType != Orts . Simulation . Physics . Train . TRAINTYPE . STATIC ;
406
+
402
407
if ( valveType == MSTSWagon . BrakeValveType . Distributor )
403
408
{
404
409
float targetPressurePSI = ( ControlResPressurePSI - BrakeLine1PressurePSI ) * AuxCylVolumeRatio ;
405
410
if ( ! disableGradient && EmergencyValveActuationRatePSIpS > 0 && ( prevBrakePipePressurePSI - BrakeLine1PressurePSI ) > Math . Max ( elapsedClockSeconds , 0.0001f ) * EmergencyValveActuationRatePSIpS )
406
411
{
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
+ {
408
414
QuickServiceActive = true ;
415
+ UniformChargingActive = false ;
416
+ }
409
417
TripleValveState = ValveState . Emergency ;
410
418
}
411
419
else if ( TripleValveState != ValveState . Emergency &&
412
420
targetPressurePSI > AutoCylPressurePSI + ( TripleValveState == ValveState . Release ? AuxCylVolumeRatio * InitialApplicationThresholdPSI : ( TripleValveState == ValveState . Apply ? 0.0f : 2.2f ) ) )
413
421
{
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
+ {
415
424
QuickServiceActive = true ;
425
+ UniformChargingActive = false ;
426
+ }
416
427
TripleValveState = ValveState . Apply ;
417
428
}
418
429
else if ( targetPressurePSI < AutoCylPressurePSI - ( TripleValveState == ValveState . Release ? 0.0f : 2.2f ) || targetPressurePSI < 2.2f )
@@ -428,15 +439,21 @@ public void UpdateTripleValveState(float elapsedClockSeconds)
428
439
{
429
440
if ( ! disableGradient && EmergencyValveActuationRatePSIpS > 0 && ( prevBrakePipePressurePSI - BrakeLine1PressurePSI ) > Math . Max ( elapsedClockSeconds , 0.0001f ) * EmergencyValveActuationRatePSIpS )
430
441
{
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
+ {
432
444
QuickServiceActive = true ;
445
+ UniformChargingActive = false ;
446
+ }
433
447
TripleValveState = ValveState . Emergency ;
434
448
}
435
449
else if ( TripleValveState != ValveState . Emergency &&
436
450
BrakeLine1PressurePSI < AuxResPressurePSI - ( TripleValveState == ValveState . Release ? InitialApplicationThresholdPSI : ( TripleValveState == ValveState . Apply ? 0.0f : 1.0f ) ) )
437
451
{
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
+ {
439
454
QuickServiceActive = true ;
455
+ UniformChargingActive = false ;
456
+ }
440
457
TripleValveState = ValveState . Apply ;
441
458
}
442
459
else if ( BrakeLine1PressurePSI > AuxResPressurePSI + ( TripleValveState == ValveState . Release ? 0.0f : 2.0f ) )
@@ -515,18 +532,24 @@ public override void Update(float elapsedClockSeconds)
515
532
{
516
533
dpPipe = Math . Abs ( elapsedClockSeconds * QuickServiceVentRatePSIpS ) ;
517
534
if ( CylPressurePSI > QuickServiceLimitPSI * 0.75f ) // Vent rate is reduced when quick service is nearly complete
535
+ {
518
536
dpPipe /= 3 ;
537
+ }
519
538
}
520
539
dp = elapsedClockSeconds * Math . Max ( QuickServiceApplicationRatePSIpS , MaxApplicationRatePSIpS ) ;
521
540
}
522
541
else
523
542
{
524
543
if ( TripleValveState == ValveState . Apply && AcceleratedApplicationRatio > 0 ) // Accelerated application: Air is vented from the brake pipe to speed up service applications
544
+ {
525
545
dpPipe = Math . Min ( BrakePipeChange * AcceleratedApplicationRatio , elapsedClockSeconds * AcceleratedApplicationLimitPSIpS ) ; // Amount of air vented is proportional to pressure reduction from external sources
546
+ }
526
547
dp = elapsedClockSeconds * MaxApplicationRatePSIpS ;
527
548
}
528
549
if ( BrakeLine1PressurePSI - dpPipe < 0 )
550
+ {
529
551
dpPipe = BrakeLine1PressurePSI ;
552
+ }
530
553
531
554
if ( TripleValveState != ValveState . Emergency && BrakeLine1PressurePSI < AuxResPressurePSI + 1 )
532
555
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)
556
579
{
557
580
if ( ( Car as MSTSWagon ) . EmergencyReservoirPresent )
558
581
{
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
+ }
564
607
}
608
+
565
609
if ( EmergencyDumpValveTimerS == 0 )
566
610
{
567
611
if ( BrakeLine1PressurePSI < 1 ) EmergencyDumpStartTime = null ;
@@ -636,7 +680,6 @@ public override void Update(float elapsedClockSeconds)
636
680
}
637
681
else // Quick recharge: Emergency res air used to recharge aux res on older control valves
638
682
{
639
-
640
683
float dp = elapsedClockSeconds * MaxAuxilaryChargingRatePSIpS ;
641
684
if ( AuxResPressurePSI + dp > EmergResPressurePSI - dp / EmergAuxVolumeRatio )
642
685
dp = ( EmergResPressurePSI - AuxResPressurePSI ) * EmergAuxVolumeRatio / ( 1 + EmergAuxVolumeRatio ) ;
@@ -674,8 +717,15 @@ public override void Update(float elapsedClockSeconds)
674
717
{
675
718
if ( AuxResPressurePSI < BrakeLine1PressurePSI && ( valveType == MSTSWagon . BrakeValveType . Distributor ? true : TripleValveState == ValveState . Release ) && ! BleedOffValveOpen )
676
719
{
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
+ }
679
729
if ( AuxResPressurePSI + dpAux > BrakeLine1PressurePSI - dpAux * AuxBrakeLineVolumeRatio )
680
730
dpAux = ( BrakeLine1PressurePSI - AuxResPressurePSI ) / ( 1 + AuxBrakeLineVolumeRatio ) ;
681
731
AuxResPressurePSI += dpAux ;
@@ -949,7 +999,6 @@ public override void Update(float elapsedClockSeconds)
949
999
lead . BrakeOverchargeSoundOn = false ;
950
1000
}
951
1001
}
952
-
953
1002
}
954
1003
prevBrakePipePressurePSI = BrakeLine1PressurePSI ;
955
1004
SoundTriggerCounter += elapsedClockSeconds ;
0 commit comments