diff --git a/src/Devices/AtcDimetronic.cs b/src/Devices/AtcDimetronic.cs
index aa4ad61..f5490a2 100644
--- a/src/Devices/AtcDimetronic.cs
+++ b/src/Devices/AtcDimetronic.cs
@@ -57,6 +57,7 @@ namespace OpenbveFcmbTrainPlugin
private enum AtoStates
{
Inactive,
+ Alarm,
AwaitingStartup,
IncreaseSpeed,
MaintainSpeed,
@@ -70,6 +71,18 @@ namespace OpenbveFcmbTrainPlugin
/// Whether ATO knows the precise position of the train or not.
private bool AtoPositionKnown;
+ /// The distance travelled in ATO mode since the latest startup.
+ private double AtoStartupPosition;
+
+ /// The power notch to be applied by ATO.
+ private int AtoPowerNotch;
+
+ /// The brake notch to be applied by ATO.
+ private int AtoBrakeNotch;
+
+ /// Whether ATO is available or not on the train.
+ private readonly bool AtoAvailable;
+
/// The current position of the train.
private double TrainLocation;
@@ -94,9 +107,6 @@ namespace OpenbveFcmbTrainPlugin
/// The distance after which the rollforward protection is triggered.
private readonly double RollforwardDistance;
- /// Whether ATO is available or not on the train.
- private readonly bool AtoAvailable;
-
/// The index of the alarm sound.
private readonly int AlarmSoundIndex;
@@ -241,15 +251,15 @@ namespace OpenbveFcmbTrainPlugin
RollforwardLocation = train.State.Location;
}
- // Update train location
- TrainLocation = train.State.Location;
-
- // If ATO is not the current mode, it should be in inactive state
+ // Reset ATO status outside ATO mode
if (DeviceState != DeviceStates.ATO)
{
- AtoState = AtoStates.Inactive;
+ AtoState = AtoState == AtoStates.Alarm ? AtoStates.Alarm : AtoStates.Inactive;
}
+ // Update train location
+ TrainLocation = train.State.Location;
+
double speed = train.State.Speed.KilometersPerHour;
bool stopped = speed < 0.05;
@@ -285,7 +295,7 @@ namespace OpenbveFcmbTrainPlugin
}
// Rollforward protection
- if (train.PhysicalHandles.BrakeNotch > 0 || train.PhysicalHandles.PowerNotch > 0)
+ if (train.PhysicalHandles.BrakeNotch > 0 || train.PhysicalHandles.PowerNotch > 0 || RequestedBrakeNotch > 0 || RequestedPowerNotch > 0)
{
// The train has a power/brake notch applied, movement is expected
RollforwardTrigger = false;
@@ -339,6 +349,9 @@ namespace OpenbveFcmbTrainPlugin
train.VigilanceOverride = false;
// Release control of the brakes and power
AtcControlState = AtcControlStates.Released;
+ // Reset ATO data
+ AtoPositionKnown = false;
+ AtoState = AtoStates.Inactive;
break;
// ATC device is initialized and a driving mode is required
case DeviceStates.NoMode:
@@ -462,6 +475,10 @@ namespace OpenbveFcmbTrainPlugin
// ATO start button
if (!OpenbveFcmbTrainPlugin.KeysPressed[(int)key])
{
+ if (AtoState == AtoStates.AwaitingStartup)
+ {
+ AtoState = AtoStates.IncreaseSpeed;
+ }
}
break;
case VirtualKeys.B1:
@@ -683,12 +700,14 @@ namespace OpenbveFcmbTrainPlugin
Speed target = CurrentSpeedCode.TargetLimit;
double distance = CurrentSpeedCode.TargetPosition - TrainLocation;
+ // Calculate notches according to state
switch (AtoState)
{
case AtoStates.Inactive:
// Keep train still
- RequestedPowerNotch = 0;
- RequestedBrakeNotch = train.Specs.BrakeNotches + 1;
+ AtoPowerNotch = 0;
+ AtoBrakeNotch = train.Specs.BrakeNotches + 1;
+ AtoStartupPosition = TrainLocation;
// If the train is stopped, doors are closed and signal is clear, change to startup state
if (stopped && train.DoorState == DoorStates.None && target.KilometersPerHour > 0)
@@ -696,6 +715,32 @@ namespace OpenbveFcmbTrainPlugin
AtoState = AtoStates.AwaitingStartup;
}
break;
+ case AtoStates.Alarm:
+ case AtoStates.AwaitingStartup:
+ // Keep train still
+ AtoPowerNotch = 0;
+ AtoBrakeNotch = train.Specs.BrakeNotches + 1;
+ AtoStartupPosition = TrainLocation;
+ break;
+ case AtoStates.IncreaseSpeed:
+ AtoBrakeNotch = 0;
+ if (train.Acceleration < 0.2 && AtoPowerNotch < train.Specs.PowerNotches)
+ {
+ // TODO: Add delay
+ AtoPowerNotch++;
+ }
+ break;
+ }
+
+ // Apply notches
+ RequestedPowerNotch = AtoPowerNotch;
+ RequestedBrakeNotch = AtoBrakeNotch;
+
+ // ATO is driving but does not know the position of the train, unselect driving mode and set alarm state
+ if (TrainLocation - AtoStartupPosition > 400 && !AtoPositionKnown)
+ {
+ AtoState = AtoStates.Alarm;
+ DeviceState = DeviceStates.NoMode;
}
}
}