internal override void Elapse(ElapseData data, ref bool blocking) { int BrakeNotch = 0; if (this.Train.Doors != DoorStates.None & this.AutomaticallyDeactivates) { this.State = Ato.States.Disabled; } if (this.State == Ato.States.Disabled) { this.Notch = 0; } else if (this.Train.Atc == null || !(this.Train.Atc.State == Atc.States.Normal | this.Train.Atc.State == Atc.States.ServiceHalf | this.Train.Atc.State == Atc.States.ServiceFull | this.Train.Atc.State == Atc.States.Emergency)) { this.Notch = 0; BrakeNotch = Train.Specs.BrakeNotches + 1; } else if (!(this.Train.Atc.State == Atc.States.Normal & data.Handles.Reverser == 1 & this.Train.TractionManager.CurrentInterventionBrakeNotch == 0)) { this.Notch = 0; //Set maximum power notch to zero via the Traction Manager Train.TractionManager.SetMaxPowerNotch(0, true); } else { double metersPerSecond = this.Train.State.Speed.MetersPerSecond; double currentSpeed = this.Train.Atc.Pattern.CurrentSpeed; if (this.Train.Tasc != null && this.Train.Tasc.State == Tasc.States.Pattern && !this.Train.Tasc.Override && 6.94444444444444 < currentSpeed) { currentSpeed = 6.94444444444444; } double num = currentSpeed - 4.16666666666667; double num1 = currentSpeed - 1.38888888888889; if (metersPerSecond <= num) { this.State = Ato.States.Power; } else if (metersPerSecond >= num1) { this.State = Ato.States.Idle; } if (this.State != Ato.States.Power) { this.Notch = 0; //Set maximum power notch to zero via the Traction Manager Train.TractionManager.SetMaxPowerNotch(0, true); } else { int powerNotches = (int)Math.Ceiling((num1 - metersPerSecond) / 1.38888888888889 * (double)this.Train.Specs.PowerNotches); if (powerNotches < 1) { powerNotches = 1; } else if (powerNotches > this.Train.Specs.PowerNotches) { powerNotches = this.Train.Specs.PowerNotches; } if (this.Notch >= powerNotches) { this.Notch = powerNotches; } else if (this.Countdown <= 0) { Ato notch = this; notch.Notch = notch.Notch + 1; this.Countdown = this.PowerApplicationTime / (double)this.Train.Specs.PowerNotches; } //Pass the calculated maximum power notch to the traction manager Train.TractionManager.SetMaxPowerNotch(this.Notch, true); } } if (this.Countdown > 0) { Ato countdown = this; countdown.Countdown = countdown.Countdown - data.ElapsedTime.Seconds; } Train.TractionManager.SetBrakeNotch(BrakeNotch); if (this.State != Ato.States.Disabled) { this.Train.Panel[91] = 1; if (this.Train.Atc == null || this.Train.Atc.State != Atc.States.Normal & this.Train.Atc.State != Atc.States.ServiceHalf | this.Train.Atc.State == Atc.States.ServiceFull & this.Train.Atc.State != Atc.States.Emergency) { this.Train.Panel[92] = 1; } } }
// --- functions --- /// <summary>Sets up the devices from the specified configuration file.</summary> /// <param name="file">The configuration file.</param> internal void LoadConfigurationFile(string file) { string[] lines = File.ReadAllLines(file, Encoding.UTF8); string section = string.Empty; for (int i = 0; i < lines.Length; i++) { string line = lines[i]; int semicolon = line.IndexOf(';'); if (semicolon >= 0) { line = line.Substring(0, semicolon).Trim(); } else { line = line.Trim(); } if (line.Length != 0) { if (line[0] == '[' & line[line.Length - 1] == ']') { section = line.Substring(1, line.Length - 2).ToLowerInvariant(); switch (section) { case "ats-sx": this.AtsSx = new AtsSx(this); break; case "ats-ps": this.AtsPs = new AtsPs(this); break; case "ats-p": this.AtsP = new AtsP(this); break; case "atc": this.Atc = new Atc(this); break; case "eb": this.Eb = new Eb(this); break; case "tasc": this.Tasc = new Tasc(this); break; case "ato": this.Ato = new Ato(this); break; default: throw new InvalidDataException("The section " + line[0] + " is not supported."); } } else { int equals = line.IndexOf('='); if (equals >= 0) { string key = line.Substring(0, equals).Trim().ToLowerInvariant(); string value = line.Substring(equals + 1).Trim(); switch (section) { case "ats-sx": switch (key) { case "durationofalarm": this.AtsSx.DurationOfAlarm = double.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); break; case "durationofinitialization": this.AtsSx.DurationOfInitialization = double.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); break; case "durationofspeedcheck": this.AtsSx.DurationOfSpeedCheck = double.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); break; default: throw new InvalidDataException("The parameter " + key + " is not supported."); } break; case "ats-ps": switch (key) { case "maximumspeed": this.AtsPs.TrainPermanentPattern.SetPersistentLimit((1.0 / 3.6) * double.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture)); break; default: throw new InvalidDataException("The parameter " + key + " is not supported."); } break; case "ats-p": switch (key) { case "durationofinitialization": this.AtsP.DurationOfInitialization = double.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); break; case "durationofbrakerelease": this.AtsP.DurationOfBrakeRelease = double.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); break; case "designdeceleration": this.AtsP.DesignDeceleration = (1.0 / 3.6) * double.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); break; case "brakepatterndelay": this.AtsP.BrakePatternDelay = double.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); break; case "brakepatternoffset": case "signaloffset": this.AtsP.BrakePatternOffset = double.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); break; case "brakepatterntolerance": this.AtsP.BrakePatternTolerance = (1.0 / 3.6) * double.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); break; case "warningpatterndelay": case "reactiondelay": this.AtsP.WarningPatternDelay = double.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); break; case "warningpatternoffset": this.AtsP.WarningPatternOffset = double.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); break; case "warningpatterntolerance": this.AtsP.WarningPatternTolerance = (1.0 / 3.6) * double.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); break; case "patternspeeddifference": this.AtsP.WarningPatternTolerance = (-1.0 / 3.6) * double.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); break; case "releasespeed": this.AtsP.ReleaseSpeed = (1.0 / 3.6) * double.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); break; case "maximumspeed": this.AtsP.TrainPermanentPattern.SetPersistentLimit((1.0 / 3.6) * double.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture)); break; default: throw new InvalidDataException("The parameter " + key + " is not supported."); } break; case "atc": switch (key) { case "automaticswitch": this.Atc.AutomaticSwitch = value.Equals("true", StringComparison.OrdinalIgnoreCase); break; case "emergencyoperation": if (value.Equals("false", StringComparison.OrdinalIgnoreCase)) { this.Atc.EmergencyOperationSignal = null; } else { double limit = (1.0 / 3.6) * double.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); if (limit <= 0.0) { this.Atc.EmergencyOperationSignal = null; } else { this.Atc.EmergencyOperationSignal = Atc.Signal.CreateEmergencyOperationSignal(limit); } } break; default: int aspect; if (int.TryParse(key, NumberStyles.Integer, CultureInfo.InvariantCulture, out aspect)) { if (aspect >= 10) { Atc.Signal signal = ParseAtcCode(aspect, value); if (signal != null) { this.Atc.Signals.Add(signal); break; } else { throw new InvalidDataException("The ATC code " + value + " is not supported."); } } } throw new InvalidDataException("The parameter " + key + " is not supported."); } break; case "eb": switch (key) { case "timeuntilbell": this.Eb.TimeUntilBell = double.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); break; case "timeuntilbrake": this.Eb.TimeUntilBrake = double.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); break; case "speedthreshold": this.Eb.SpeedThreshold = double.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); break; default: throw new InvalidDataException("The parameter " + key + " is not supported."); } break; case "tasc": switch (key) { case "designdeceleration": this.Tasc.TascBrakeDeceleration = (1.0 / 3.6) * double.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture); break; default: throw new InvalidDataException("The parameter " + key + " is not supported."); } break; } } } } } // --- devices --- List <Device> devices = new List <Device>(); if (this.Ato != null) { devices.Add(this.Ato); } if (this.Tasc != null) { devices.Add(this.Tasc); } if (this.Eb != null) { devices.Add(this.Eb); } if (this.Atc != null) { devices.Add(this.Atc); } if (this.AtsP != null) { devices.Add(this.AtsP); } if (this.AtsPs != null) { devices.Add(this.AtsPs); if (this.AtsSx == null) { this.AtsSx = new AtsSx(this); } } if (this.AtsSx != null) { devices.Add(this.AtsSx); } this.Devices = devices.ToArray(); }