@@ -63,6 +63,8 @@ public float SelectedMaxAccelerationPercent
6363 public SpeedRegulatorMode SpeedRegMode = SpeedRegulatorMode . Manual ;
6464 public SpeedSelectorMode SpeedSelMode = SpeedSelectorMode . Neutral ;
6565 public ControllerCruiseControlLogic CruiseControlLogic = new ControllerCruiseControlLogic ( ) ;
66+ public float ? ATOSetSpeedMpS ;
67+ public float ? ATOSetAccelerationMpSS ;
6668 private float selectedSpeedMpS ;
6769 public float SelectedSpeedMpS
6870 {
@@ -82,8 +84,12 @@ public float SetSpeedMpS
8284 get
8385 {
8486 if ( ! RestrictedRegionOdometer . Started && TimeSinceLastSelectedSpeedChangeS >= DelayBeforeSelectedSpeedUpdatingS )
87+ {
8588 CurrentSelectedSpeedMpS = SelectedSpeedMpS ;
86- return CurrentSelectedSpeedMpS ;
89+ }
90+ float setSpeedMpS = CurrentSelectedSpeedMpS ;
91+ if ( ATOSetSpeedMpS < setSpeedMpS ) setSpeedMpS = ATOSetSpeedMpS . Value ;
92+ return setSpeedMpS ;
8793 }
8894 }
8995 public float SetSpeedKpHOrMpH
@@ -96,8 +102,42 @@ public float SetSpeedKpHOrMpH
96102 public int SelectedNumberOfAxles = 0 ;
97103 public float SpeedRegulatorNominalSpeedStepMpS = 0 ;
98104 public float SpeedRegulatorNominalSpeedStepKpHOrMpH = 0 ;
99- public float MaxAccelerationMpSS = 2 ;
100- public float MaxDecelerationMpSS = 0.5f ;
105+ public float maxAccelerationMpSS = 2 ;
106+ public float MaxAccelerationMpSS
107+ {
108+ get
109+ {
110+ if ( ATOSetAccelerationMpSS > 0 )
111+ {
112+ return Math . Min ( ATOSetAccelerationMpSS . Value , maxAccelerationMpSS ) ;
113+ }
114+ return maxAccelerationMpSS ;
115+ }
116+ set
117+ {
118+ maxAccelerationMpSS = value ;
119+ }
120+ }
121+ private float maxDecelerationMpSS = 0.5f ;
122+ public float MaxDecelerationMpSS
123+ {
124+ get
125+ {
126+ if ( ATOSetAccelerationMpSS < 0 )
127+ {
128+ float atoDecelMpSS = - ATOSetAccelerationMpSS . Value ;
129+ if ( ATOSetAccelerationMpSS < - maxDecelerationMpSS && ATOSetSpeedMpS <= Math . Max ( AbsWheelSpeedMpS , CurrentSelectedSpeedMpS ) )
130+ return atoDecelMpSS ;
131+ if ( ATOSetAccelerationMpSS > - maxDecelerationMpSS && Math . Max ( AbsWheelSpeedMpS , ATOSetSpeedMpS . Value ) < CurrentSelectedSpeedMpS )
132+ return atoDecelMpSS ;
133+ }
134+ return maxDecelerationMpSS ;
135+ }
136+ set
137+ {
138+ maxDecelerationMpSS = value ;
139+ }
140+ }
101141 public bool UseThrottleInCombinedControl = false ;
102142 public bool AntiWheelSpinEquipped = false ;
103143 public float AntiWheelSpinSpeedDiffThreshold = 0.5f ;
@@ -513,14 +553,14 @@ public void Update(float elapsedClockSeconds)
513553 timeFromEngineMoved = 0 ;
514554 reducingForce = true ;
515555 }
516- if ( SpeedRegulatorOptions . Contains ( "engageforceonnonzerospeed" ) && SelectedSpeedMpS > 0 && ( SpeedSelMode != SpeedSelectorMode . Parking || ! ForceResetRequiredAfterBraking || ( WasForceReset && SelectedMaxAccelerationPercent > 0 ) ) )
556+ if ( SpeedRegulatorOptions . Contains ( "engageforceonnonzerospeed" ) && SetSpeedMpS > 0 && ( SpeedSelMode != SpeedSelectorMode . Parking || ! ForceResetRequiredAfterBraking || ( WasForceReset && SelectedMaxAccelerationPercent > 0 ) ) )
517557 {
518558 SpeedSelMode = SpeedSelectorMode . On ;
519559 SpeedRegMode = SpeedRegulatorMode . Auto ;
520560 SkipThrottleDisplay = true ;
521561 reducingForce = false ;
522562 }
523- else if ( SpeedRegulatorOptions . Contains ( "engageparkingonzerospeed" ) && SelectedSpeedMpS == 0 && AbsWheelSpeedMpS <= ( SpeedIsMph ? MpS . FromMpH ( ParkingBrakeEngageSpeed ) : MpS . FromKpH ( ParkingBrakeEngageSpeed ) ) && SpeedSelMode != SpeedSelectorMode . Parking )
563+ else if ( SpeedRegulatorOptions . Contains ( "engageparkingonzerospeed" ) && SetSpeedMpS == 0 && AbsWheelSpeedMpS <= ( SpeedIsMph ? MpS . FromMpH ( ParkingBrakeEngageSpeed ) : MpS . FromKpH ( ParkingBrakeEngageSpeed ) ) && SpeedSelMode != SpeedSelectorMode . Parking )
524564 {
525565 SpeedSelMode = SpeedSelectorMode . Parking ;
526566 WasForceReset = false ;
@@ -602,14 +642,14 @@ public void Update(float elapsedClockSeconds)
602642 {
603643 ThrottlePID . SetCoefficients (
604644 100 * StartReducingSpeedDelta , 1 / StartReducingSpeedDelta / 5 , 0 ,
605- 100 / MaxThrottleAccelerationMpSS , 100 / MaxThrottleAccelerationMpSS / ThrottleFullRangeIncreaseTimeSeconds , 0
645+ 100 / MaxThrottleAccelerationMpSS , 100 / MaxThrottleAccelerationMpSS / ThrottleFullRangeIncreaseTimeSeconds
606646 ) ;
607647 }
608648 if ( MaxDynamicBrakeDecelerationMpSS > 0.1f )
609649 {
610650 DynamicBrakePID . SetCoefficients (
611651 100 * StartReducingSpeedDeltaDownwards , 1 / StartReducingSpeedDeltaDownwards / 5 , 0 ,
612- 100 / MaxDynamicBrakeDecelerationMpSS , 100 / MaxDynamicBrakeDecelerationMpSS / DynamicBrakeFullRangeIncreaseTimeSeconds , 0
652+ 100 / MaxDynamicBrakeDecelerationMpSS , 100 / MaxDynamicBrakeDecelerationMpSS / DynamicBrakeFullRangeIncreaseTimeSeconds
613653 ) ;
614654 }
615655 if ( MaxTrainBrakeDecelerationMpSS > 0.1f )
@@ -1301,6 +1341,7 @@ public class SpeedAccelerationController
13011341 {
13021342 public readonly PIDController Speed ;
13031343 public readonly PIDController Acceleration ;
1344+ public float PAccelerationCoefficient ;
13041345 public bool Active
13051346 {
13061347 get
@@ -1319,19 +1360,20 @@ public SpeedAccelerationController(PIDController speed, PIDController accel)
13191360 Speed = speed ;
13201361 Acceleration = accel ;
13211362 }
1322- public void SetCoefficients ( float pSpd , float iSpd , float dSpd , float pAccel , float iAccel , float dAccel )
1363+ public void SetCoefficients ( float pSpd , float iSpd , float dSpd , float pAccel , float iAccel )
13231364 {
13241365 Speed . SetCoefficients ( pSpd , iSpd , dSpd ) ;
1325- Acceleration . SetCoefficients ( pAccel , iAccel , dAccel ) ;
1366+ PAccelerationCoefficient = pAccel ;
1367+ Acceleration . SetCoefficients ( 0 , iAccel , 0 ) ;
13261368 }
1327- public void Update ( float elapsedClockSeconds , float deltaSpeed , float deltaAccel , float minPercent = 0 , float maxPercent = 100 )
1369+ public void Update ( float elapsedClockSeconds , float deltaSpeed , float demandedAccel , float realAccel , float minPercent = 0 , float maxPercent = 100 )
13281370 {
13291371 Speed . MinValue = minPercent ;
13301372 Speed . MaxValue = maxPercent ;
13311373 Acceleration . MinValue = minPercent ;
13321374 Acceleration . MaxValue = maxPercent ;
13331375 Speed . Update ( elapsedClockSeconds , deltaSpeed ) ;
1334- Acceleration . Update ( elapsedClockSeconds , deltaAccel ) ;
1376+ Acceleration . Update ( elapsedClockSeconds , demandedAccel - realAccel , PAccelerationCoefficient * demandedAccel ) ;
13351377 if ( Speed . Value < Acceleration . Value )
13361378 {
13371379 // Maintain speed region
@@ -1463,7 +1505,7 @@ public void UpdateForcePID(float elapsedClockSeconds, float deltaSpeedMpS, bool
14631505 float a = AccelerationTable [ ( int ) selectedMaxAccelerationStep - 1 ] ;
14641506 if ( a > 0 ) maxAccelerationMpSS = Math . Min ( maxAccelerationMpSS , a ) ;
14651507 }
1466- ThrottlePID . Update ( elapsedClockSeconds , deltaSpeedMpS , maxAccelerationMpSS - RelativeAccelerationMpSS , 0 , maxPercent ) ;
1508+ ThrottlePID . Update ( elapsedClockSeconds , deltaSpeedMpS , maxAccelerationMpSS , RelativeAccelerationMpSS , 0 , maxPercent ) ;
14671509 targetThrottle = ThrottlePID . Value ;
14681510 }
14691511 else
@@ -1474,7 +1516,7 @@ public void UpdateForcePID(float elapsedClockSeconds, float deltaSpeedMpS, bool
14741516 {
14751517 float minPercent = TrainBrakePercent > 0 ? 50 : 0 ;
14761518 float maxPercent = DynamicBrakeIsSelectedForceDependant ? SelectedMaxAccelerationPercent : 100 ;
1477- DynamicBrakePID . Update ( elapsedClockSeconds , - deltaSpeedMpS , maxDecelerationMpSS + RelativeAccelerationMpSS , minPercent , maxPercent ) ;
1519+ DynamicBrakePID . Update ( elapsedClockSeconds , - deltaSpeedMpS , maxDecelerationMpSS , - RelativeAccelerationMpSS , minPercent , maxPercent ) ;
14781520 targetDynamic = DynamicBrakePID . Value ;
14791521 }
14801522 else
@@ -1518,10 +1560,10 @@ void UpdateTrainBrakePercent(float elapsedClockSeconds, float deltaSpeedMpS)
15181560 {
15191561 target = Math . Max ( ( MaxDecelerationMpSS - MaxDynamicBrakeDecelerationMpSS ) / MaxTrainBrakeDecelerationMpSS * 100 , 0 ) ;
15201562 float accelerationDemandMpSS = ( 0.85f + Math . Min ( CCThrottleOrDynBrakePercent / 100 , 0 ) ) * MaxDynamicBrakeDecelerationMpSS - MaxDecelerationMpSS ;
1521- TrainBrakePID . MinValue = - target ;
1522- TrainBrakePID . MaxValue = TrainBrakeMaxPercentValue - target ;
1523- TrainBrakePID . Update ( elapsedClockSeconds , RelativeAccelerationMpSS - accelerationDemandMpSS ) ;
1524- target + = TrainBrakePID . Value ;
1563+ TrainBrakePID . MinValue = 0 ;
1564+ TrainBrakePID . MaxValue = TrainBrakeMaxPercentValue ;
1565+ TrainBrakePID . Update ( elapsedClockSeconds , RelativeAccelerationMpSS - accelerationDemandMpSS , target ) ;
1566+ target = TrainBrakePID . Value ;
15251567 }
15261568 if ( target <= TrainBrakeMinPercentValue ) TrainBrakePercent = 0 ;
15271569 else if ( Math . Abs ( TrainBrakePercent - target ) > 5 )
0 commit comments