From 43cbc2b7aff93f66d226df1c5ff4670c1231f3ca Mon Sep 17 00:00:00 2001 From: Marc Riera Date: Fri, 3 Jan 2025 00:48:21 +0100 Subject: [PATCH] ATC Dimetronic: New attempt at ATO braking --- src/Devices/AtcDimetronic.cs | 39 ++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/src/Devices/AtcDimetronic.cs b/src/Devices/AtcDimetronic.cs index a5fefab..25c08b5 100644 --- a/src/Devices/AtcDimetronic.cs +++ b/src/Devices/AtcDimetronic.cs @@ -87,7 +87,7 @@ namespace OpenbveFcmbTrainPlugin private readonly double AtoNotchDelay = 250; /// The deceleration considered by ATO to calculate braking curves, in m/s2. - private readonly double AtoDeceleration = 0.33; + private readonly double AtoDeceleration = 0.5; /// The counter for the ATO notch delay. private double AtoNotchDelayCounter; @@ -710,26 +710,21 @@ namespace OpenbveFcmbTrainPlugin /// Processes ATO orders. private void ProcessAto(Train train, Route route, Time elapsedTime) { - double speed = train.State.Speed.KilometersPerHour; - bool stopped = speed < 0.05; + double speed = train.State.Speed.MetersPerSecond; + bool stopped = speed < 0.01; // Set limits from speed code, unless position is unknown Speed limit = AtoPositionKnown ? CurrentSpeedCode.CurrentLimit : AtoInitSpeed; Speed target = AtoPositionKnown ? CurrentSpeedCode.TargetLimit : AtoInitSpeed; double distance = CurrentSpeedCode.TargetPosition - TrainLocation; - // Calculate required deceleration - double requiredDeceleration = 0; - if (target.KilometersPerHour < limit.KilometersPerHour) + // Calculate braking time and distance + double requiredDecelerationTime = 0; + double requiredDecelerationDistance = 0; + if (speed > target.MetersPerSecond) { - requiredDeceleration = (train.State.Speed.MetersPerSecond - target.MetersPerSecond) / (distance - 8) * 10; - } - - // Calculate time needed to reach target speed - double requiredDecelerationSeconds = 0; - if (target.KilometersPerHour < limit.KilometersPerHour) - { - requiredDecelerationSeconds = (target.MetersPerSecond - limit.MetersPerSecond) / -AtoDeceleration; + requiredDecelerationTime = (target.MetersPerSecond - speed) / -AtoDeceleration; + requiredDecelerationDistance = speed * requiredDecelerationTime + 0.5 * -AtoDeceleration * (requiredDecelerationTime * requiredDecelerationTime); } // Pitch multiplier, used to alter when state changes occur @@ -778,10 +773,10 @@ namespace OpenbveFcmbTrainPlugin // Train is near the limit, maintain speed AtoState = AtoStates.MaintainSpeed; } - if (requiredDeceleration >= AtoDeceleration) + if (requiredDecelerationDistance > distance - 50 && train.State.Speed.KilometersPerHour > target.KilometersPerHour) { - // Train is near a speed change, reduce speed - AtoState = AtoStates.ReduceSpeed; + // Train is approaching the end of the signalling block, do not accelerate further + AtoState = AtoStates.MaintainSpeed; } break; case AtoStates.MaintainSpeed: @@ -799,19 +794,19 @@ namespace OpenbveFcmbTrainPlugin AtoNotchDelayCounter = 0; } } - if (train.State.Speed.KilometersPerHour <= limit.KilometersPerHour - 7 + pitchMulti && target.KilometersPerHour >= limit.KilometersPerHour) + if (train.State.Speed.KilometersPerHour <= limit.KilometersPerHour - 7 + pitchMulti && (requiredDecelerationDistance < distance - 50 || target.KilometersPerHour >= limit.KilometersPerHour)) { // Train is far below the limit, increase speed AtoState = AtoStates.IncreaseSpeed; } - if (requiredDeceleration >= AtoDeceleration) + if (requiredDecelerationDistance >= distance - 8) { // Train is near a speed change, reduce speed AtoState = AtoStates.ReduceSpeed; } break; case AtoStates.ReduceSpeed: - if (train.Acceleration > -requiredDeceleration && AtoNotchDelayCounter >= AtoNotchDelay) + if (requiredDecelerationDistance > distance - 8 && AtoNotchDelayCounter >= AtoNotchDelay) { // Train is travelling too fast, reduce speed if (AtoPowerNotch > 0) @@ -825,7 +820,7 @@ namespace OpenbveFcmbTrainPlugin AtoNotchDelayCounter = 0; } } - else if (train.Acceleration < -requiredDeceleration && AtoNotchDelayCounter >= AtoNotchDelay) + else if (requiredDecelerationDistance < distance - 8 && AtoNotchDelayCounter >= AtoNotchDelay) { // Reducing speed too fast, release brakes if (AtoBrakeNotch > 0) @@ -834,7 +829,7 @@ namespace OpenbveFcmbTrainPlugin AtoNotchDelayCounter = 0; } } - if (train.State.Speed.KilometersPerHour <= target.KilometersPerHour - 3 + pitchMulti) + if (train.State.Speed.KilometersPerHour <= target.KilometersPerHour - 3 + pitchMulti || requiredDecelerationDistance < distance - 50) { AtoState = AtoStates.MaintainSpeed; }