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;
}