ATC Dimetronic: New attempt at ATO braking

This commit is contained in:
Marc Riera 2025-01-03 00:48:21 +01:00
parent 390e894a56
commit 43cbc2b7af

View file

@ -87,7 +87,7 @@ namespace OpenbveFcmbTrainPlugin
private readonly double AtoNotchDelay = 250; private readonly double AtoNotchDelay = 250;
/// <summary>The deceleration considered by ATO to calculate braking curves, in m/s2.</summary> /// <summary>The deceleration considered by ATO to calculate braking curves, in m/s2.</summary>
private readonly double AtoDeceleration = 0.33; private readonly double AtoDeceleration = 0.5;
/// <summary>The counter for the ATO notch delay.</summary> /// <summary>The counter for the ATO notch delay.</summary>
private double AtoNotchDelayCounter; private double AtoNotchDelayCounter;
@ -710,26 +710,21 @@ namespace OpenbveFcmbTrainPlugin
/// <summary>Processes ATO orders.</summary> /// <summary>Processes ATO orders.</summary>
private void ProcessAto(Train train, Route route, Time elapsedTime) private void ProcessAto(Train train, Route route, Time elapsedTime)
{ {
double speed = train.State.Speed.KilometersPerHour; double speed = train.State.Speed.MetersPerSecond;
bool stopped = speed < 0.05; bool stopped = speed < 0.01;
// Set limits from speed code, unless position is unknown // Set limits from speed code, unless position is unknown
Speed limit = AtoPositionKnown ? CurrentSpeedCode.CurrentLimit : AtoInitSpeed; Speed limit = AtoPositionKnown ? CurrentSpeedCode.CurrentLimit : AtoInitSpeed;
Speed target = AtoPositionKnown ? CurrentSpeedCode.TargetLimit : AtoInitSpeed; Speed target = AtoPositionKnown ? CurrentSpeedCode.TargetLimit : AtoInitSpeed;
double distance = CurrentSpeedCode.TargetPosition - TrainLocation; double distance = CurrentSpeedCode.TargetPosition - TrainLocation;
// Calculate required deceleration // Calculate braking time and distance
double requiredDeceleration = 0; double requiredDecelerationTime = 0;
if (target.KilometersPerHour < limit.KilometersPerHour) double requiredDecelerationDistance = 0;
if (speed > target.MetersPerSecond)
{ {
requiredDeceleration = (train.State.Speed.MetersPerSecond - target.MetersPerSecond) / (distance - 8) * 10; requiredDecelerationTime = (target.MetersPerSecond - speed) / -AtoDeceleration;
} requiredDecelerationDistance = speed * requiredDecelerationTime + 0.5 * -AtoDeceleration * (requiredDecelerationTime * requiredDecelerationTime);
// Calculate time needed to reach target speed
double requiredDecelerationSeconds = 0;
if (target.KilometersPerHour < limit.KilometersPerHour)
{
requiredDecelerationSeconds = (target.MetersPerSecond - limit.MetersPerSecond) / -AtoDeceleration;
} }
// Pitch multiplier, used to alter when state changes occur // Pitch multiplier, used to alter when state changes occur
@ -778,10 +773,10 @@ namespace OpenbveFcmbTrainPlugin
// Train is near the limit, maintain speed // Train is near the limit, maintain speed
AtoState = AtoStates.MaintainSpeed; AtoState = AtoStates.MaintainSpeed;
} }
if (requiredDeceleration >= AtoDeceleration) if (requiredDecelerationDistance > distance - 50 && train.State.Speed.KilometersPerHour > target.KilometersPerHour)
{ {
// Train is near a speed change, reduce speed // Train is approaching the end of the signalling block, do not accelerate further
AtoState = AtoStates.ReduceSpeed; AtoState = AtoStates.MaintainSpeed;
} }
break; break;
case AtoStates.MaintainSpeed: case AtoStates.MaintainSpeed:
@ -799,19 +794,19 @@ namespace OpenbveFcmbTrainPlugin
AtoNotchDelayCounter = 0; 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 // Train is far below the limit, increase speed
AtoState = AtoStates.IncreaseSpeed; AtoState = AtoStates.IncreaseSpeed;
} }
if (requiredDeceleration >= AtoDeceleration) if (requiredDecelerationDistance >= distance - 8)
{ {
// Train is near a speed change, reduce speed // Train is near a speed change, reduce speed
AtoState = AtoStates.ReduceSpeed; AtoState = AtoStates.ReduceSpeed;
} }
break; break;
case AtoStates.ReduceSpeed: case AtoStates.ReduceSpeed:
if (train.Acceleration > -requiredDeceleration && AtoNotchDelayCounter >= AtoNotchDelay) if (requiredDecelerationDistance > distance - 8 && AtoNotchDelayCounter >= AtoNotchDelay)
{ {
// Train is travelling too fast, reduce speed // Train is travelling too fast, reduce speed
if (AtoPowerNotch > 0) if (AtoPowerNotch > 0)
@ -825,7 +820,7 @@ namespace OpenbveFcmbTrainPlugin
AtoNotchDelayCounter = 0; AtoNotchDelayCounter = 0;
} }
} }
else if (train.Acceleration < -requiredDeceleration && AtoNotchDelayCounter >= AtoNotchDelay) else if (requiredDecelerationDistance < distance - 8 && AtoNotchDelayCounter >= AtoNotchDelay)
{ {
// Reducing speed too fast, release brakes // Reducing speed too fast, release brakes
if (AtoBrakeNotch > 0) if (AtoBrakeNotch > 0)
@ -834,7 +829,7 @@ namespace OpenbveFcmbTrainPlugin
AtoNotchDelayCounter = 0; 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; AtoState = AtoStates.MaintainSpeed;
} }