// --- constructors --- /// <summary>Creates a new pattern.</summary> /// <param name="device">A reference to the underlying ATS-P device.</param> internal Pattern(AtsP device) { this.Device = device; this.Position = double.MaxValue; this.WarningPattern = double.MaxValue; this.BrakePattern = double.MaxValue; this.TargetSpeed = double.MaxValue; this.Gradient = 0.0; }
// --- static functions --- public static bool IsSuperfluous(AtsP device, CompatibilityLimit current, CompatibilityLimit next) { double distance = next.Location - current.Location; double targetSpeed = next.Limit; double sqrtTerm = 2.0 * device.DesignDeceleration * (distance - device.BrakePatternOffset) + device.DesignDeceleration * device.DesignDeceleration * device.BrakePatternDelay * device.BrakePatternDelay + targetSpeed * targetSpeed; double brakePattern = (sqrtTerm > 0.0 ? Math.Sqrt(sqrtTerm) : 0.0) - device.DesignDeceleration * device.BrakePatternDelay; return(brakePattern <= current.Limit); }
// --- constructors --- /// <summary>Creates a new pattern.</summary> /// <param name="device">A reference to the underlying ATS-P device.</param> internal Pattern(AtsP device) { this.Device = device; this.Position = double.MaxValue; this.WarningPattern = double.MaxValue; this.BrakePattern = double.MaxValue; this.TargetSpeed = double.MaxValue; this.Persistent = false; }
// --- functions --- /// <summary>Updates the pattern.</summary> /// <param name="system">The current ATS-P system.</param> /// <param name="data">The elapse data.</param> internal void Perform(AtsP system, ElapseData data) { if (this.Position == double.MaxValue | this.TargetSpeed == double.MaxValue) { this.WarningPattern = double.MaxValue; this.BrakePattern = double.MaxValue; } else if (this.Position == double.MinValue) { this.WarningPattern = this.TargetSpeed - this.Device.PatternSpeedDifference; this.BrakePattern = Math.Max(this.TargetSpeed, this.Device.ReleaseSpeed); } else { const double earthGravity = 9.81; double accelerationDueToGravity = earthGravity * this.Gradient / Math.Sqrt(1.0 + this.Gradient * this.Gradient); double deceleration = this.Device.DesignDeceleration + accelerationDueToGravity; double distance = this.Position - system.Position; /* * Calculate the warning pattern. * */ { double sqrtTerm = 2.0 * deceleration * (distance - 50.0) + deceleration * deceleration * this.Device.ReactionDelay * this.Device.ReactionDelay + this.TargetSpeed * this.TargetSpeed; if (sqrtTerm <= 0.0) { this.WarningPattern = this.TargetSpeed - this.Device.PatternSpeedDifference; } else { this.WarningPattern = Math.Max(Math.Sqrt(sqrtTerm) - deceleration * this.Device.ReactionDelay, this.TargetSpeed - this.Device.PatternSpeedDifference); } } /* * Calculate the brake pattern. * */ { double sqrtTerm = 2.0 * deceleration * distance + this.TargetSpeed * this.TargetSpeed; if (sqrtTerm <= 0.0) { this.BrakePattern = this.TargetSpeed; } else { this.BrakePattern = Math.Max(Math.Sqrt(sqrtTerm), TargetSpeed); } if (this.BrakePattern < this.Device.ReleaseSpeed) { this.BrakePattern = this.Device.ReleaseSpeed; } } } }
public static void Sort(AtsP device, List <CompatibilityLimit> compatibilityLimits) { compatibilityLimits.Sort(); for (int i = 0; i < compatibilityLimits.Count - 1; i++) { if (IsSuperfluous(device, compatibilityLimits[i], compatibilityLimits[i + 1])) { compatibilityLimits.RemoveAt(i); i--; } } }
private void UpdateCompatibilityTemporarySpeedPattern() { if (this.CompatibilityLimits.Count != 0) { if (this.CompatibilityTemporaryPattern.Position != double.MaxValue) { if (this.CompatibilityTemporaryPattern.BrakePattern < this.Train.State.Speed.MetersPerSecond) { return; } double position = this.CompatibilityTemporaryPattern.Position - this.Train.State.Location; if (position >= -50 & position <= 0) { return; } } while (this.CompatibilityLimitPointer > 0) { if (this.CompatibilityLimits[this.CompatibilityLimitPointer].Location > this.Train.State.Location) { AtsP compatibilityLimitPointer = this; compatibilityLimitPointer.CompatibilityLimitPointer = compatibilityLimitPointer.CompatibilityLimitPointer - 1; } else { break; } } while (this.CompatibilityLimitPointer < this.CompatibilityLimits.Count - 1 && this.CompatibilityLimits[this.CompatibilityLimitPointer + 1].Location <= this.Train.State.Location) { AtsP atsP = this; atsP.CompatibilityLimitPointer = atsP.CompatibilityLimitPointer + 1; } if (this.CompatibilityLimitPointer == 0 && this.CompatibilityLimits[0].Location > this.Train.State.Location) { this.CompatibilityTemporaryPattern.SetLimit(this.CompatibilityLimits[0].Limit, this.CompatibilityLimits[0].Location); return; } if (this.CompatibilityLimitPointer < this.CompatibilityLimits.Count - 1) { this.CompatibilityTemporaryPattern.SetLimit(this.CompatibilityLimits[this.CompatibilityLimitPointer + 1].Limit, this.CompatibilityLimits[this.CompatibilityLimitPointer + 1].Location); return; } this.CompatibilityTemporaryPattern.Clear(); } }
// --- functions --- /// <summary>Sets up the devices from the specified train.dat file.</summary> /// <param name="file">The train.dat file.</param> /// <returns>Whether loading the train.dat file was successful.</returns> internal bool LoadTrainDatFile(string file) { string[] lines = File.ReadAllLines(file, Encoding.UTF8); for (int i = 0; i < lines.Length; i++) { int semicolon = lines[i].IndexOf(';'); if (semicolon >= 0) { lines[i] = lines[i].Substring(0, semicolon).Trim(); } else { lines[i] = lines[i].Trim(); } } for (int i = 0; i < lines.Length; i++) { if (lines[i].Equals("#DEVICE", StringComparison.OrdinalIgnoreCase)) { if (i < lines.Length - 1) { int value = int.Parse(lines[i + 1], NumberStyles.Integer, CultureInfo.InvariantCulture); if (value == 0) { this.AtsSx = new AtsSx(this); } else if (value == 1) { this.AtsSx = new AtsSx(this); this.AtsP = new AtsP(this); } } if (i < lines.Length - 2) { int value = int.Parse(lines[i + 2], NumberStyles.Integer, CultureInfo.InvariantCulture); if (value == 1) { this.Atc = new Atc(this, false); } else if (value == 2) { this.Atc = new Atc(this, true); } } if (i < lines.Length - 3) { int value = int.Parse(lines[i + 3], NumberStyles.Integer, CultureInfo.InvariantCulture); if (value == 1) { this.Eb = new Eb(this); } } } } // --- devices --- List <Device> devices = new List <Device>(); 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.AtsSx != null) { devices.Add(this.AtsSx); } this.Devices = devices.ToArray(); return(true); }
// --- functions --- /// <summary>Sets up the devices from the specified train.dat file.</summary> /// <param name="file">The train.dat file.</param> /// <returns>Whether loading the train.dat file was successful.</returns> internal bool LoadTrainDatFile(string file) { string[] lines = File.ReadAllLines(file, Encoding.UTF8); for (int i = 0; i < lines.Length; i++) { int semicolon = lines[i].IndexOf(';'); if (semicolon >= 0) { lines[i] = lines[i].Substring(0, semicolon).Trim(); } else { lines[i] = lines[i].Trim(); } } for (int i = 0; i < lines.Length; i++) { if (lines[i].Equals("#DEVICE", StringComparison.OrdinalIgnoreCase)) { if (i < lines.Length - 1) { int value = int.Parse(lines[i + 1], NumberStyles.Integer, CultureInfo.InvariantCulture); if (value == 0) { this.AtsSx = new AtsSx(this); } else if (value == 1) { this.AtsSx = new AtsSx(this); this.AtsP = new AtsP(this); } } if (i < lines.Length - 2) { int value = int.Parse(lines[i + 2], NumberStyles.Integer, CultureInfo.InvariantCulture); if (value == 1) { this.Atc = new Atc(this, false); } else if (value == 2) { this.Atc = new Atc(this, true); } } if (i < lines.Length - 3) { int value = int.Parse(lines[i + 3], NumberStyles.Integer, CultureInfo.InvariantCulture); if (value == 1) { this.Eb = new Eb(this); } } } } // --- devices --- List<Device> devices = new List<Device>(); 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.AtsSx != null) { devices.Add(this.AtsSx); } this.Devices = devices.ToArray(); return true; }
// --- functions --- /// <summary>Updates the pattern.</summary> /// <param name="system">The current ATS-P system.</param> internal void Perform(AtsP system) { if (this.Position == double.MaxValue | this.TargetSpeed == double.MaxValue) { this.WarningPattern = double.MaxValue; this.BrakePattern = double.MaxValue; } else if (this.Position == double.MinValue) { if (this.TargetSpeed > 1.0 / 3.6) { this.WarningPattern = this.TargetSpeed + this.Device.WarningPatternTolerance; this.BrakePattern = this.TargetSpeed + this.Device.BrakePatternTolerance; } else { this.WarningPattern = this.TargetSpeed; this.BrakePattern = this.TargetSpeed; } if (this.BrakePattern < this.Device.ReleaseSpeed) { this.BrakePattern = this.Device.ReleaseSpeed; } } else { double distance = this.Position - system.Position; // --- calculate the warning pattern --- { double sqrtTerm = 2.0 * this.Device.DesignDeceleration * (distance - this.Device.WarningPatternOffset) + this.Device.DesignDeceleration * this.Device.DesignDeceleration * this.Device.WarningPatternDelay * this.Device.WarningPatternDelay + this.TargetSpeed * this.TargetSpeed; this.WarningPattern = (sqrtTerm > 0.0 ? Math.Sqrt(sqrtTerm) : 0.0) - this.Device.DesignDeceleration * this.Device.WarningPatternDelay; if (this.TargetSpeed > 1.0 / 3.6) { if (this.WarningPattern < this.TargetSpeed + this.Device.WarningPatternTolerance) { this.WarningPattern = this.TargetSpeed + this.Device.WarningPatternTolerance; } } else { if (this.WarningPattern < this.TargetSpeed) { this.WarningPattern = this.TargetSpeed; } } } // --- calculate the brake pattern --- { double sqrtTerm = 2.0 * this.Device.DesignDeceleration * (distance - this.Device.BrakePatternOffset) + this.Device.DesignDeceleration * this.Device.DesignDeceleration * this.Device.BrakePatternDelay * this.Device.BrakePatternDelay + this.TargetSpeed * this.TargetSpeed; this.BrakePattern = (sqrtTerm > 0.0 ? Math.Sqrt(sqrtTerm) : 0.0) - this.Device.DesignDeceleration * this.Device.BrakePatternDelay; if (this.TargetSpeed > 1.0 / 3.6) { if (this.BrakePattern < this.TargetSpeed + this.Device.BrakePatternTolerance) { this.BrakePattern = this.TargetSpeed + this.Device.BrakePatternTolerance; } } else { if (this.BrakePattern < this.TargetSpeed) { this.BrakePattern = this.TargetSpeed; } } if (this.BrakePattern < this.Device.ReleaseSpeed) { this.BrakePattern = this.Device.ReleaseSpeed; } } } }
internal override void Elapse(ElapseData data, ref bool blocking) { this.Blocked = blocking; if (this.State == AtsP.States.Suppressed && this.Train.TractionManager.CurrentInterventionBrakeNotch <= this.Train.Specs.BrakeNotches) { this.InitializationCountdown = this.DurationOfInitialization; this.State = AtsP.States.Initializing; } if (this.State == AtsP.States.Initializing) { AtsP initializationCountdown = this; initializationCountdown.InitializationCountdown = initializationCountdown.InitializationCountdown - data.ElapsedTime.Seconds; if (this.InitializationCountdown <= 0) { this.State = AtsP.States.Standby; this.BrakeRelease = false; this.SwitchToAtsSxPosition = double.MaxValue; AtsP.Pattern[] patterns = this.Patterns; for (int i = 0; i < (int)patterns.Length; i++) { AtsP.Pattern pattern = patterns[i]; if (Math.Abs(data.Vehicle.Speed.MetersPerSecond) >= pattern.WarningPattern) { pattern.Clear(); } } if (!SoundManager.IsPlaying(CommonSounds.ATSPBell)) { SoundManager.Play(CommonSounds.ATSPBell, 1.0, 1.0, false); } } } if (this.BrakeRelease) { AtsP brakeReleaseCountdown = this; brakeReleaseCountdown.BrakeReleaseCountdown = brakeReleaseCountdown.BrakeReleaseCountdown - data.ElapsedTime.Seconds; if (this.BrakeReleaseCountdown <= 0) { this.BrakeRelease = false; if (!SoundManager.IsPlaying(CommonSounds.ATSPBell)) { SoundManager.Play(CommonSounds.ATSPBell, 1.0, 1.0, false); } } } if (this.State != AtsP.States.Disabled & this.State != AtsP.States.Initializing) { AtsP position = this; position.Position = position.Position + data.Vehicle.Speed.MetersPerSecond * data.ElapsedTime.Seconds; } if (!blocking) { if (this.DAtsPSupported && this.DAtsPFirstSignalPattern.Position - this.Train.State.Location < 0) { this.DAtsPZerothSignalPattern.Position = this.DAtsPFirstSignalPattern.Position; this.DAtsPZerothSignalPattern.TargetSpeed = this.DAtsPFirstSignalPattern.TargetSpeed; this.DAtsPFirstSignalPattern.Position = this.DAtsPSecondSignalPattern.Position; this.DAtsPFirstSignalPattern.TargetSpeed = this.DAtsPSecondSignalPattern.TargetSpeed; this.DAtsPSecondSignalPattern.Position = double.MaxValue; this.DAtsPSecondSignalPattern.TargetSpeed = double.MaxValue; } if (this.DAtsPActive & this.DAtsPContinuous) { switch (this.DAtsPAspect) { case 1: { this.DAtsPFirstSignalPattern.TargetSpeed = 6.94444444444444; break; } case 2: { this.DAtsPFirstSignalPattern.TargetSpeed = 12.5; break; } case 3: { this.DAtsPFirstSignalPattern.TargetSpeed = 20.8333333333333; break; } case 4: case 5: case 6: { this.DAtsPFirstSignalPattern.TargetSpeed = double.MaxValue; break; } default: { this.DAtsPFirstSignalPattern.TargetSpeed = 0; break; } } if (this.DAtsPZerothSignalPattern.TargetSpeed < this.DAtsPFirstSignalPattern.TargetSpeed) { this.DAtsPZerothSignalPattern.TargetSpeed = this.DAtsPFirstSignalPattern.TargetSpeed; } } if (this.State == AtsP.States.Normal | this.State == AtsP.States.Pattern | this.State == AtsP.States.Brake) { bool flag = false; bool flag1 = false; bool flag2 = true; if (this.DivergencePattern.Position > double.MinValue & this.DivergencePattern.Position < double.MaxValue && Math.Abs(data.Vehicle.Speed.MetersPerSecond) < this.DivergencePattern.BrakePattern && this.DivergencePattern.Position - this.Position < -50) { this.DivergencePattern.Clear(); } this.UpdateCompatibilityTemporarySpeedPattern(); AtsP.Pattern[] patternArray = this.Patterns; for (int j = 0; j < (int)patternArray.Length; j++) { AtsP.Pattern pattern1 = patternArray[j]; pattern1.Perform(this, data); if (Math.Abs(data.Vehicle.Speed.MetersPerSecond) >= pattern1.WarningPattern - 0.277777777777778) { flag2 = false; } if (Math.Abs(data.Vehicle.Speed.MetersPerSecond) >= pattern1.WarningPattern) { flag1 = true; } if (Math.Abs(data.Vehicle.Speed.MetersPerSecond) >= pattern1.BrakePattern) { flag = true; } } if (this.BrakeRelease) { flag = false; } if (flag & this.State != AtsP.States.Brake) { this.State = AtsP.States.Brake; if (!SoundManager.IsPlaying(CommonSounds.ATSPBell)) { SoundManager.Play(CommonSounds.ATSPBell, 1.0, 1.0, false); } } else if (flag1 & this.State == AtsP.States.Normal) { this.State = AtsP.States.Pattern; if (!SoundManager.IsPlaying(CommonSounds.ATSPBell)) { SoundManager.Play(CommonSounds.ATSPBell, 1.0, 1.0, false); } } else if (!flag & !flag1 & flag2 & (this.State == AtsP.States.Pattern | this.State == AtsP.States.Brake)) { this.State = AtsP.States.Normal; if (!SoundManager.IsPlaying(CommonSounds.ATSPBell)) { SoundManager.Play(CommonSounds.ATSPBell, 1.0, 1.0, false); } } if (this.State == AtsP.States.Brake) { Train.TractionManager.DemandBrakeApplication(this.Train.Specs.BrakeNotches, "Brake application demanded by ATS-P"); } if (this.Position > this.SwitchToAtsSxPosition & this.State != AtsP.States.Brake & this.State != AtsP.States.Service & this.State != AtsP.States.Emergency) { this.SwitchToSx(); } } else if (this.State == AtsP.States.Service) { Train.TractionManager.DemandBrakeApplication(this.Train.Specs.BrakeNotches, "Brake application demanded by ATS-P"); } else if (this.State == AtsP.States.Emergency) { Train.TractionManager.DemandBrakeApplication(this.Train.Specs.BrakeNotches + 1, "Brake application demanded by ATS-P"); } if (!this.AtsSxPMode & (this.State == AtsP.States.Normal | this.State == AtsP.States.Pattern | this.State == AtsP.States.Brake | this.State == AtsP.States.Service | this.State == AtsP.States.Emergency)) { blocking = true; } } else if (this.State != AtsP.States.Disabled & this.State != AtsP.States.Suppressed) { this.State = AtsP.States.Standby; } if (this.State != AtsP.States.Disabled & this.State != AtsP.States.Suppressed) { this.Train.Panel[2] = 1; this.Train.Panel[259] = 1; } if (this.State == AtsP.States.Pattern | this.State == AtsP.States.Brake | this.State == AtsP.States.Service | this.State == AtsP.States.Emergency) { this.Train.Panel[3] = 1; this.Train.Panel[260] = 1; } if (this.State == AtsP.States.Brake | this.State == AtsP.States.Service | this.State == AtsP.States.Emergency) { this.Train.Panel[5] = 1; this.Train.Panel[262] = 1; } if (this.State != AtsP.States.Disabled & this.State != AtsP.States.Suppressed & this.State != AtsP.States.Standby) { this.Train.Panel[6] = 1; this.Train.Panel[263] = 1; } if (this.State == AtsP.States.Initializing) { this.Train.Panel[7] = 1; this.Train.Panel[264] = 1; } if (this.State == AtsP.States.Disabled) { this.Train.Panel[50] = 1; } if (this.State != AtsP.States.Disabled & this.State != AtsP.States.Suppressed & this.State != AtsP.States.Standby & this.BrakeRelease) { this.Train.Panel[4] = 1; this.Train.Panel[261] = 1; } if (this.State == AtsP.States.Normal | this.State == AtsP.States.Pattern | this.State == AtsP.States.Brake | this.State == AtsP.States.Service | this.State == AtsP.States.Emergency) { StringBuilder stringBuilder = new StringBuilder(); for (int k = 0; k < (int)this.SignalPatterns.Length; k++) { this.SignalPatterns[k].AddToStringBuilder(string.Concat(k.ToString(), ":"), stringBuilder); } this.DivergencePattern.AddToStringBuilder("分岐/D:", stringBuilder); this.TemporaryPattern.AddToStringBuilder("臨時/T:", stringBuilder); this.CurvePattern.AddToStringBuilder("曲線/C:", stringBuilder); this.DownslopePattern.AddToStringBuilder("勾配/S:", stringBuilder); this.RoutePermanentPattern.AddToStringBuilder("P:", stringBuilder); this.TrainPermanentPattern.AddToStringBuilder("M:", stringBuilder); if (this.SwitchToAtsSxPosition != double.MaxValue) { if (stringBuilder.Length != 0) { stringBuilder.Append(", "); } double switchToAtsSxPosition = this.SwitchToAtsSxPosition - this.Position; stringBuilder.Append(string.Concat("Sx@", switchToAtsSxPosition.ToString("0"))); } if (stringBuilder.Length == 0) { data.DebugMessage = this.State.ToString(); return; } data.DebugMessage = string.Concat(this.State.ToString(), " - ", stringBuilder.ToString()); } }
internal void Perform(AtsP system, ElapseData data) { if (this.Position == double.MaxValue | this.TargetSpeed == double.MaxValue) { this.WarningPattern = double.MaxValue; this.BrakePattern = double.MaxValue; return; } if (this.Position != double.MinValue) { double designDeceleration = this.Device.DesignDeceleration + 9.81 * this.Gradient; double position = this.Position - system.Position; double warningPatternOffset = 2 * designDeceleration * (position - this.Device.WarningPatternOffset) + designDeceleration * designDeceleration * this.Device.WarningPatternDelay * this.Device.WarningPatternDelay + this.TargetSpeed * this.TargetSpeed; if (warningPatternOffset > 0) { this.WarningPattern = Math.Sqrt(warningPatternOffset) - designDeceleration * this.Device.WarningPatternDelay; } else { this.WarningPattern = -designDeceleration * this.Device.WarningPatternDelay; } if (this.TargetSpeed > 0.277777777777778) { if (this.WarningPattern < this.TargetSpeed + this.Device.WarningPatternTolerance) { this.WarningPattern = this.TargetSpeed + this.Device.WarningPatternTolerance; } } else if (this.WarningPattern < this.TargetSpeed) { this.WarningPattern = this.TargetSpeed; } double brakePatternOffset = 2 * designDeceleration * (position - this.Device.BrakePatternOffset) + designDeceleration * designDeceleration * this.Device.BrakePatternDelay * this.Device.BrakePatternDelay + this.TargetSpeed * this.TargetSpeed; if (brakePatternOffset > 0) { this.BrakePattern = Math.Sqrt(brakePatternOffset) - designDeceleration * this.Device.BrakePatternDelay; } else { this.BrakePattern = -designDeceleration * this.Device.BrakePatternDelay; } if (this.TargetSpeed > 0.277777777777778) { if (this.BrakePattern < this.TargetSpeed + this.Device.BrakePatternTolerance) { this.BrakePattern = this.TargetSpeed + this.Device.BrakePatternTolerance; } } else if (this.BrakePattern < this.TargetSpeed) { this.BrakePattern = this.TargetSpeed; } if (this.BrakePattern < this.Device.ReleaseSpeed) { this.BrakePattern = this.Device.ReleaseSpeed; } } else { if (this.TargetSpeed <= 0.277777777777778) { this.WarningPattern = this.TargetSpeed; this.BrakePattern = this.TargetSpeed; } else { this.WarningPattern = this.TargetSpeed + this.Device.WarningPatternTolerance; this.BrakePattern = this.TargetSpeed + this.Device.BrakePatternTolerance; } if (this.BrakePattern < this.Device.ReleaseSpeed) { this.BrakePattern = this.Device.ReleaseSpeed; return; } } }
// --- 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(); }