protected void UpdateTVM430COVIT() { if (TVM430TrainSpeedLimitMpS == MpS.FromKpH(320f)) { TVM430CurrentSpeedLimitMpS = MpS.FromKpH(TVM430S320CurrentSpeedLimitsKph[NextSignalAspect(0)]); TVM430NextSpeedLimitMpS = MpS.FromKpH(TVM430S320NextSpeedLimitsKph[NextSignalAspect(0)]); } else { TVM430CurrentSpeedLimitMpS = MpS.FromKpH(TVM430S300CurrentSpeedLimitsKph[NextSignalAspect(0)]); TVM430NextSpeedLimitMpS = MpS.FromKpH(TVM430S300NextSpeedLimitsKph[NextSignalAspect(0)]); } SetNextSpeedLimitMpS(TVM430NextSpeedLimitMpS); SetCurrentSpeedLimitMpS(TVM430CurrentSpeedLimitMpS); TVM430CurrentEmergencySpeedMpS = TVM430GetEmergencySpeed(TVM430CurrentSpeedLimitMpS); TVM430NextEmergencySpeedMpS = TVM430GetEmergencySpeed(TVM430NextSpeedLimitMpS); if (SignalPassed) { TVM430EmergencyDecelerationMpS2 = Deceleration( TVM430CurrentSpeedLimitMpS + TVM430CurrentEmergencySpeedMpS, TVM430NextSpeedLimitMpS + TVM430NextEmergencySpeedMpS, NextSignalDistanceM(0) ); TVM430ResetDecelerationMpS2 = Deceleration( TVM430CurrentSpeedLimitMpS, TVM430NextSpeedLimitMpS, NextSignalDistanceM(0) ); } TVM430EmergencySpeedCurveMpS = SpeedCurve( NextSignalDistanceM(0), TVM430NextSpeedLimitMpS + TVM430NextEmergencySpeedMpS, 0, 0, TVM430EmergencyDecelerationMpS2 ); TVM430ResetSpeedCurveMpS = SpeedCurve( NextSignalDistanceM(0), TVM430NextSpeedLimitMpS, 0, 0, TVM430ResetDecelerationMpS2 ); if (!TVMCOVITEmergencyBraking && SpeedMpS() > TVM430EmergencySpeedCurveMpS) { TVMCOVITEmergencyBraking = true; } if (TVMCOVITEmergencyBraking && SpeedMpS() <= TVM430ResetSpeedCurveMpS) { TVMCOVITEmergencyBraking = false; } }
protected void UpdateTVM() { if (TVM300Present && IsSpeedControlEnabled()) { // Automatic arming if (NextPostSpeedLimitMpS(0) > MpS.FromKpH(221f) && NextPostDistanceM(0) < 5f && PreviousLineSpeed <= MpS.FromKpH(221f) && SpeedMpS() > 0f && !TVMArmed) { TVMArmed = true; UpdateTVMAspect(NextSignalAspect(0), false); } // Automatic dearming if (CurrentPostSpeedLimitMpS() <= MpS.FromKpH(221f) && PreviousLineSpeed > MpS.FromKpH(221f) && SpeedMpS() > 0f && TVMArmed) { TVMArmed = false; } if (TVMArmed) { // TVM mask SetCabDisplayControl(TVM_Mask, 1); UpdateTVM300Display(); UpdateTVM300COVIT(); } else { // TVM mask SetCabDisplayControl(TVM_Mask, 0); TVMAspect = Aspect.None; TVMPreviousAspect = Aspect.None; } } }
protected void UpdateTVM300COVIT() { if (TVMCOVITInhibited) { TVMCOVITEmergencyBraking = false; } else { TVM300CurrentSpeedLimitMpS = MpS.FromKpH(TVM300CurrentSpeedLimitsKph[NextSignalAspect(0)]); TVM300NextSpeedLimitMpS = MpS.FromKpH(TVM300NextSpeedLimitsKph[NextSignalAspect(0)]); SetNextSpeedLimitMpS(TVM300NextSpeedLimitMpS); SetCurrentSpeedLimitMpS(TVM300CurrentSpeedLimitMpS); TVM300EmergencySpeedMpS = TVM300GetEmergencySpeed(TVM300CurrentSpeedLimitMpS); if (!TVMCOVITEmergencyBraking && SpeedMpS() > TVM300CurrentSpeedLimitMpS + TVM300EmergencySpeedMpS) { TVMCOVITEmergencyBraking = true; } if (TVMCOVITEmergencyBraking && SpeedMpS() <= TVM300CurrentSpeedLimitMpS) { TVMCOVITEmergencyBraking = false; } } }
public static void InverseRelations() { Assert.Equal(1.2f, Me.FromMi(Me.ToMi(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, Me.FromKiloM(Me.ToKiloM(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, Me.FromYd(Me.ToYd(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, Me.FromFt(Me.ToFt(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, Me.FromIn(Me.ToIn(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, Me2.FromFt2(Me2.ToFt2(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, Me2.FromIn2(Me2.ToIn2(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, Me3.FromFt3(Me3.ToFt3(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, Me3.FromIn3(Me3.ToIn3(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, MpS.FromMpH(MpS.ToMpH(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, MpS.FromKpH(MpS.ToKpH(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, Kg.FromLb(Kg.ToLb(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, Kg.FromTUS(Kg.ToTUS(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, Kg.FromTUK(Kg.ToTUK(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, Kg.FromTonne(Kg.ToTonne(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, N.FromLbf(N.ToLbf(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, KgpS.FromLbpH(KgpS.ToLbpH(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, W.FromKW(W.ToKW(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, W.FromHp(W.ToHp(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, W.FromBTUpS(W.ToBTUpS(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, KPa.FromPSI(KPa.ToPSI(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, KPa.FromInHg(KPa.ToInHg(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, KPa.FromBar(KPa.ToBar(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, KPa.FromKgfpCm2(KPa.ToKgfpCm2(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, Bar.FromKPa(Bar.ToKPa(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, Bar.FromPSI(Bar.ToPSI(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, Bar.FromInHg(Bar.ToInHg(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, Bar.FromKgfpCm2(Bar.ToKgfpCm2(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, BarpS.FromPSIpS(BarpS.ToPSIpS(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, KJpKg.FromBTUpLb(KJpKg.ToBTUpLb(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, L.FromGUK(L.ToGUK(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, L.FromGUS(L.ToGUS(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, pS.FrompM(pS.TopM(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, pS.FrompH(pS.TopH(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, S.FromM(S.ToM(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, S.FromH(S.ToH(1.2f)), RequestedAccuracy); Assert.Equal(1.2f, C.FromF(C.ToF(1.2f)), RequestedAccuracy); Assert.Equal(12f, C.FromK(C.ToK(12f)), RequestedAccuracy); // we loose accuracy because of the large 273.15 }
public override void Initialize() { // General section VACMAPresent = GetBoolParameter("General", "VACMAPresent", true); RSPresent = GetBoolParameter("General", "RSPresent", true); DAATPresent = GetBoolParameter("General", "DAATPresent", false); TVM300Present = GetBoolParameter("General", "TVM300Present", false); // RS section RSDelayBeforeEmergencyBrakingS = GetFloatParameter("RS", "DelayBeforeEmergencyBrakingS", 4f); RSBlinkerFrequencyHz = GetFloatParameter("RS", "BlinkerFrequencyHz", 1f); // TVM common section TVMCOVITInhibited = GetBoolParameter("TVM", "CovitInhibited", false); // TVM300 section TVM300TrainSpeedLimitMpS = MpS.FromKpH(GetFloatParameter("TVM300", "TrainSpeedLimitKpH", 300f)); // VACMA section VACMAActivationSpeedMpS = MpS.FromKpH(GetFloatParameter("VACMA", "ActivationSpeedKpH", 3f)); VACMAReleasedAlertDelayS = GetFloatParameter("VACMA", "ReleasedAlertDelayS", 2.5f); VACMAReleasedEmergencyDelayS = GetFloatParameter("VACMA", "ReleasedEmergencyDelayS", 5f); VACMAPressedAlertDelayS = GetFloatParameter("VACMA", "PressedAlertDelayS", 55f); VACMAPressedEmergencyDelayS = GetFloatParameter("VACMA", "PressedEmergencyDelayS", 60f); // Variables initialization RSBlinker = new Blinker(this); RSBlinker.Setup(RSBlinkerFrequencyHz); RSBlinker.Start(); RSEmergencyTimer = new Timer(this); RSEmergencyTimer.Setup(RSDelayBeforeEmergencyBrakingS); VACMAPressedAlertTimer = new Timer(this); VACMAPressedAlertTimer.Setup(VACMAPressedAlertDelayS); VACMAPressedEmergencyTimer = new Timer(this); VACMAPressedEmergencyTimer.Setup(VACMAPressedEmergencyDelayS); VACMAReleasedAlertTimer = new Timer(this); VACMAReleasedAlertTimer.Setup(VACMAReleasedAlertDelayS); VACMAReleasedEmergencyTimer = new Timer(this); VACMAReleasedEmergencyTimer.Setup(VACMAReleasedEmergencyDelayS); // Cabview control names initialization SetCustomizedCabviewControlName(BP_AC_SF, "BP (AC) SF : Acquittement / Acknowledge"); SetCustomizedCabviewControlName(BP_A_LS_SF, "BP (A) LS (SF) : Annulation LS (SF) / Cancel LS (SF)"); SetCustomizedCabviewControlName(Z_ES_VA, "Z (ES) VA : Essai VACMA / Alerter test"); SetCustomizedCabviewControlName(BP_AM_V1, "BP AM V1 : Armement manuel TVM voie 1 / TVM manual arming track 1"); SetCustomizedCabviewControlName(BP_AM_V2, "BP AM V2 : Armement manuel TVM voie 2 / TVM manual arming track 2"); SetCustomizedCabviewControlName(BP_DM, "BP DM : Désarmement manuel TVM / TVM manual dearming"); SetCustomizedCabviewControlName(LS_SF, "LS (SF) : Signal Fermé / Closed Signal"); SetCustomizedCabviewControlName(TVM_Mask, "Masque TVM / TVM mask"); Activated = true; SetNextSignalAspect(Aspect.Clear_1); }
public override void InitializeMoving() { RSState = RSStateType.Off; RSEmergencyBraking = false; VACMAEmergencyBraking = false; if (CurrentPostSpeedLimitMpS() > MpS.FromKpH(221f)) { TVMArmed = true; UpdateTVMAspect(NextSignalAspect(0), false); } }
private float TVM300GetEmergencySpeed(float speedLimit) { float emergencySpeed = 0f; if (speedLimit <= MpS.FromKpH(80f)) { emergencySpeed = MpS.FromKpH(5f); } else if (speedLimit <= MpS.FromKpH(160f)) { emergencySpeed = MpS.FromKpH(10f); } else { emergencySpeed = MpS.FromKpH(15f); } return(emergencySpeed); }
public static void MultiUnitConversions() { Assert.Equal(1.2f, MpS.FromMpS(MpS.FromKpH(1.2f), true), RequestedAccuracy); Assert.Equal(1.2f, MpS.FromMpS(MpS.FromMpH(1.2f), false), RequestedAccuracy); Assert.Equal(1.2f, MpS.ToMpS(MpS.ToKpH(1.2f), true), RequestedAccuracy); Assert.Equal(1.2f, MpS.ToMpS(MpS.ToMpH(1.2f), false), RequestedAccuracy); Assert.Equal(1.2f, KPa.FromKPa(1.2f, PressureUnit.KPa), RequestedAccuracy); Assert.Equal(1.2f, KPa.FromBar(KPa.FromKPa(1.2f, PressureUnit.Bar)), RequestedAccuracy); Assert.Equal(1.2f, KPa.FromInHg(KPa.FromKPa(1.2f, PressureUnit.InHg)), RequestedAccuracy); Assert.Equal(1.2f, KPa.FromKgfpCm2(KPa.FromKPa(1.2f, PressureUnit.KgfpCm2)), RequestedAccuracy); Assert.Equal(1.2f, KPa.FromPSI(KPa.FromKPa(1.2f, PressureUnit.PSI)), RequestedAccuracy); Assert.Throws <ArgumentOutOfRangeException>(() => KPa.FromKPa(1.2f, PressureUnit.None)); Assert.Equal(1.2f, KPa.ToKPa(1.2f, PressureUnit.KPa), RequestedAccuracy); Assert.Equal(1.2f, KPa.ToBar(KPa.ToKPa(1.2f, PressureUnit.Bar)), RequestedAccuracy); Assert.Equal(1.2f, KPa.ToInHg(KPa.ToKPa(1.2f, PressureUnit.InHg)), RequestedAccuracy); Assert.Equal(1.2f, KPa.ToKgfpCm2(KPa.ToKPa(1.2f, PressureUnit.KgfpCm2)), RequestedAccuracy); Assert.Equal(1.2f, KPa.ToPSI(KPa.ToKPa(1.2f, PressureUnit.PSI)), RequestedAccuracy); Assert.Throws <ArgumentOutOfRangeException>(() => KPa.ToKPa(1.2f, PressureUnit.None)); }
/// <summary> /// Default constructor used during file parsing. /// </summary> /// <param name="stf">The STFreader containing the file stream</param> public SignalAspect(STFReader stf) { SpeedMpS = -1; stf.MustMatch("("); string aspectName = stf.ReadString(); try { Aspect = (MstsSignalAspect)Enum.Parse(typeof(MstsSignalAspect), aspectName, true); } catch (ArgumentException) { STFException.TraceInformation(stf, "Skipped unknown signal aspect " + aspectName); Aspect = MstsSignalAspect.UNKNOWN; } DrawStateName = stf.ReadString().ToLowerInvariant(); stf.ParseBlock(new STFReader.TokenProcessor[] { new STFReader.TokenProcessor("speedmph", () => { SpeedMpS = MpS.FromMpH(stf.ReadFloatBlock(STFReader.UNITS.None, 0)); }), new STFReader.TokenProcessor("speedkph", () => { SpeedMpS = MpS.FromKpH(stf.ReadFloatBlock(STFReader.UNITS.None, 0)); }), new STFReader.TokenProcessor("signalflags", () => { stf.MustMatch("("); while (!stf.EndOfBlock()) { switch (stf.ReadString().ToLower()) { case "asap": Asap = true; break; case "or_speedreset": Reset = true; break; case "or_nospeedreduction": NoSpeedReduction = true; break; default: stf.StepBackOneItem(); STFException.TraceInformation(stf, "Skipped unknown DrawLight flag " + stf.ReadString()); break; } } }), }); }
public override float Update(float elapsedSeconds) { if (TCSEmergencyBraking()) { allowConnect = true; } if (client == null && allowConnect) { TcpClient c = new TcpClient(); c.Connect("127.0.0.1", 5090); client = new TCPClient(c); client.WriteLine("register(train_brake)"); client.WriteLine("register(emergency_pushb)"); client.WriteLine("register(power)"); client.WriteLine("register(speed)"); } if (client != null) { string line = client.ReadLine(); while (line != null) { string val = line.Substring(line.IndexOf('=') + 1); if (line.StartsWith("train_brake=")) { Value = float.Parse(val.Replace('.', ',')); } else if (line.StartsWith("emergency_pushb=")) { EBPB = val != "0" && val != "false"; } else if (line.StartsWith("power=")) { power = val == "1" || val == "true"; } else if (line.StartsWith("speed=")) { speed = MpS.FromKpH(float.Parse(val.Replace('.', ','))); } line = client.ReadLine(); } } if (UpdateValue() == 1) { if (Value > 0.9) { Value = 1; SetUpdateValue(0); } else { float prev = Value; Value += elapsedSeconds / 3; if (Value >= 0.9 && prev < 0.9) { Value = 0.93f; SetUpdateValue(0); } } } if (UpdateValue() == -1) { float prev = Value; Value -= elapsedSeconds / 3; if (Value <= 0) { Value = 0; SetUpdateValue(0); } } if (speed < 6 || !power) { dynavail = false; } else if (Value == 0) { dynavail = true; } if (EBPB || EmergencyBrakingPushButton() || TCSEmergencyBraking() || Value > 0.95f) { CurrentState = State.Emergency; } else if (TCSFullServiceBraking() || Value > 0.90f) { CurrentState = State.FullBrake; } else if (Value > 0.01) { CurrentState = State.Apply; } else { CurrentState = State.Release; } if (Value < 0.01) { applyValue = 0; } else { applyValue = Math.Min(Math.Max((Value - 0.01f) / 0.89f * 0.85f + 0.15f, 0.15f), 1); } float MaxDynForce = DynamicBrakeForce(speed); float TargetForce = applyValue; float TargetDynamicForce = CurrentState == State.Emergency ? 0 : Math.Min(TargetForce, MaxDynForce); float TargetAirForce = TargetForce - TargetDynamicForce; dynamicBrakeValue = MaxDynForce == 0 ? 0 : TargetDynamicForce / MaxDynForce; airBrakeValue = Math.Max(TargetAirForce, 0); if (client != null) { client.WriteLine("dynamic_brake=" + dynamicBrakeValue.ToString().Replace(',', '.')); } SetCurrentValue(Value); return(CurrentValue()); }
public override float Update(float elapsedSeconds) { if (TCSEmergencyBraking()) { allowConnect = true; } if (client == null && allowConnect) { TcpClient c = new TcpClient(); c.Connect("127.0.0.1", 5090); client = new TCPClient(c); client.WriteLine("register(train_brake)"); client.WriteLine("register(emergency_pushb)"); client.WriteLine("register(power)"); client.WriteLine("register(speed)"); } if (client != null) { string line = client.ReadLine(); while (line != null) { string val = line.Substring(line.IndexOf('=') + 1); if (line.StartsWith("train_brake=")) { Value = float.Parse(val.Replace('.', ',')); } else if (line.StartsWith("emergency_pushb=")) { EBPB = val != "0" && val != "false"; } else if (line.StartsWith("power=")) { power = val == "1" || val == "true"; } else if (line.StartsWith("speed=")) { speed = MpS.FromKpH(float.Parse(val.Replace('.', ','))); } line = client.ReadLine(); } } if (UpdateValue() == 1) { if (Value > 0.9) { Value = 1; SetUpdateValue(0); } else { float prev = Value; Value += elapsedSeconds / 3; if (Value >= 0.9 && prev < 0.9) { Value = 0.93f; SetUpdateValue(0); } } } if (UpdateValue() == -1) { float prev = Value; Value -= elapsedSeconds / 3; if (Value <= 0) { Value = 0; SetUpdateValue(0); } } if (EBPB || EmergencyBrakingPushButton() || TCSEmergencyBraking() || Value > 0.95f) { CurrentState = State.Emergency; } else if (TCSFullServiceBraking() || Value > 0.90f) { CurrentState = State.FullBrake; } else if (Value > 0.01) { CurrentState = State.Apply; } else { CurrentState = State.Release; } if (Value < 0.01) { applyValue = 0; } else { applyValue = Math.Min(Math.Max(Value * 0.9f, 0), 1); } airBrakeValue = applyValue; SetCurrentValue(Value); return(CurrentValue()); }
protected void UpdateKVB() { KVBTrainLengthM = (float)Math.Ceiling((double)(TrainLengthM() / 100f)) * 100f; if (ElectroPneumaticBrake) { KVBDelayBeforeBrakingEstablishedS = 2f; } else if (HeavyFreightTrain) { KVBDelayBeforeBrakingEstablishedS = 12f + KVBTrainLengthM / 200f; } else { KVBDelayBeforeBrakingEstablishedS = 2f + 2f * KVBTrainLengthM * KVBTrainLengthM * 0.00001f; } // Decode signal aspect switch (NextSignalAspect(0)) { case Aspect.Stop: KVBSignalTargetDistanceM = NextSignalDistanceM(0); if (SignalPassed) { KVBNextSignalSpeedLimitMpS = MpS.FromKpH(10f); KVBSignalTargetSpeedMpS = 0f; KVBNextAlertSpeedMpS = MpS.FromKpH(2.5f); KVBNextEBSpeedMpS = MpS.FromKpH(5f); } break; case Aspect.StopAndProceed: KVBSignalTargetDistanceM = NextSignalDistanceM(0); if (SignalPassed) { KVBNextSignalSpeedLimitMpS = MpS.FromKpH(30f); KVBSignalTargetSpeedMpS = 0f; KVBNextAlertSpeedMpS = MpS.FromKpH(5f); KVBNextEBSpeedMpS = MpS.FromKpH(10f); } break; // Approach : Check if the 2nd signal is red (a yellow blinking aspect may have been crossed) case Aspect.Approach_1: case Aspect.Approach_2: case Aspect.Approach_3: switch (NextSignalAspect(1)) { case Aspect.Stop: KVBSignalTargetDistanceM = NextSignalDistanceM(1); if (SignalPassed) { if (NextSignalSpeedLimitMpS(0) > 0f && NextSignalSpeedLimitMpS(0) < KVBTrainSpeedLimitMpS) { KVBNextSignalSpeedLimitMpS = NextSignalSpeedLimitMpS(0); } else { KVBNextSignalSpeedLimitMpS = KVBTrainSpeedLimitMpS; } KVBSignalTargetSpeedMpS = 0f; KVBNextAlertSpeedMpS = MpS.FromKpH(2.5f); KVBNextEBSpeedMpS = MpS.FromKpH(5f); } break; case Aspect.StopAndProceed: KVBSignalTargetDistanceM = NextSignalDistanceM(1); if (SignalPassed) { if (NextSignalSpeedLimitMpS(0) > 0f && NextSignalSpeedLimitMpS(0) < KVBTrainSpeedLimitMpS) { KVBNextSignalSpeedLimitMpS = NextSignalSpeedLimitMpS(0); } else { KVBNextSignalSpeedLimitMpS = KVBTrainSpeedLimitMpS; } KVBSignalTargetSpeedMpS = 0f; KVBNextAlertSpeedMpS = MpS.FromKpH(5f); KVBNextEBSpeedMpS = MpS.FromKpH(10f); } break; default: KVBSignalTargetDistanceM = NextSignalDistanceM(0); if (SignalPassed) { if (NextSignalSpeedLimitMpS(0) > 0f && NextSignalSpeedLimitMpS(0) < KVBTrainSpeedLimitMpS) { KVBNextSignalSpeedLimitMpS = NextSignalSpeedLimitMpS(0); } else { KVBNextSignalSpeedLimitMpS = KVBTrainSpeedLimitMpS; } KVBSignalTargetSpeedMpS = KVBNextSignalSpeedLimitMpS; KVBNextAlertSpeedMpS = MpS.FromKpH(5f); KVBNextEBSpeedMpS = MpS.FromKpH(10f); } break; } break; // Clear default: KVBSignalTargetDistanceM = NextSignalDistanceM(0); if (SignalPassed) { if (NextSignalSpeedLimitMpS(0) > 0f && NextSignalSpeedLimitMpS(0) < KVBTrainSpeedLimitMpS) { KVBNextSignalSpeedLimitMpS = NextSignalSpeedLimitMpS(0); } else { KVBNextSignalSpeedLimitMpS = KVBTrainSpeedLimitMpS; } KVBSignalTargetSpeedMpS = KVBNextSignalSpeedLimitMpS; KVBNextAlertSpeedMpS = MpS.FromKpH(5f); KVBNextEBSpeedMpS = MpS.FromKpH(10f); } break; } // Update current speed limit when speed is below the target or when the train approaches the signal if (NextSignalDistanceM(0) <= 5f) { if (NextSignalSpeedLimitMpS(0) > 0f && NextSignalSpeedLimitMpS(0) < KVBTrainSpeedLimitMpS) { KVBCurrentSignalSpeedLimitMpS = NextSignalSpeedLimitMpS(0); } else { KVBCurrentSignalSpeedLimitMpS = KVBTrainSpeedLimitMpS; } } // Speed post speed limit preparation KVBNextSpeedPostSpeedLimitMpS = (NextPostSpeedLimitMpS(0) > 0 ? NextPostSpeedLimitMpS(0) : KVBTrainSpeedLimitMpS); KVBCurrentSpeedPostSpeedLimitMpS = CurrentPostSpeedLimitMpS(); KVBSpeedPostTargetSpeedMpS = KVBNextSpeedPostSpeedLimitMpS; KVBSpeedPostTargetDistanceM = NextPostDistanceM(0); SetNextSpeedLimitMpS(Math.Min(KVBNextSignalSpeedLimitMpS, KVBNextSpeedPostSpeedLimitMpS)); SetCurrentSpeedLimitMpS(Math.Min(KVBCurrentSignalSpeedLimitMpS, KVBCurrentSpeedPostSpeedLimitMpS)); UpdateKVBSpeedCurve(); // Pre-announce aspect => KVB beep if (KVBCurrentSpeedPostSpeedLimitMpS > MpS.FromKpH(160f)) { if (KVBPreAnnounceActive) { if ( SignalPassed && KVBCurrentSignalSpeedLimitMpS > MpS.FromKpH(160f) && KVBNextSignalSpeedLimitMpS <= MpS.FromKpH(160f) ) { KVBPreAnnounceActive = false; } else if ( KVBNextSpeedPostSpeedLimitMpS <= MpS.FromKpH(160f) && KVBSpeedPostTargetDistanceM <= 3000f ) { KVBPreAnnounceActive = false; } } else if ( SignalPassed && KVBCurrentSignalSpeedLimitMpS > MpS.FromKpH(160f) && KVBNextSignalSpeedLimitMpS > MpS.FromKpH(160f) && ( KVBNextSpeedPostSpeedLimitMpS > MpS.FromKpH(160f) || KVBSpeedPostTargetDistanceM > 3000f ) ) { KVBPreAnnounceActive = true; } } else { KVBPreAnnounceActive = false; } if (!KVBPreAnnounceActive && KVBPreviousPreAnnounceActive) { TriggerSoundInfo2(); } KVBPreviousPreAnnounceActive = KVBPreAnnounceActive; }
protected void UpdateKVBSpeedCurve() { bool KVBOverspeed = false; KVBSignalEmergencySpeedCurveMpS = Math.Min( Math.Min( Math.Max( SpeedCurve( KVBSignalTargetDistanceM, KVBSignalTargetSpeedMpS, KVBDeclivity, KVBDelayBeforeBrakingEstablishedS, SafeDecelerationMpS2 ), KVBNextSignalSpeedLimitMpS + KVBNextEBSpeedMpS ), KVBTrainSpeedLimitMpS + MpS.FromKpH(10f) ), KVBCurrentSignalSpeedLimitMpS + KVBCurrentEBSpeedMpS ); KVBSignalAlertSpeedCurveMpS = Math.Min( Math.Min( Math.Max( SpeedCurve( KVBSignalTargetDistanceM, KVBSignalTargetSpeedMpS, KVBDeclivity, KVBDelayBeforeBrakingEstablishedS + KVBDelayBeforeEmergencyBrakingS, SafeDecelerationMpS2 ), KVBNextSignalSpeedLimitMpS + KVBNextAlertSpeedMpS ), KVBTrainSpeedLimitMpS + MpS.FromKpH(5f) ), KVBCurrentSignalSpeedLimitMpS + KVBCurrentAlertSpeedMpS ); KVBSpeedPostEmergencySpeedCurveMpS = Math.Min( Math.Min( Math.Max( SpeedCurve( KVBSpeedPostTargetDistanceM, KVBSpeedPostTargetSpeedMpS, KVBDeclivity, KVBDelayBeforeBrakingEstablishedS, SafeDecelerationMpS2 ), KVBNextSpeedPostSpeedLimitMpS + MpS.FromKpH(10f) ), KVBTrainSpeedLimitMpS + MpS.FromKpH(10f) ), KVBCurrentSpeedPostSpeedLimitMpS + MpS.FromKpH(10f) ); KVBSpeedPostAlertSpeedCurveMpS = Math.Min( Math.Min( Math.Max( SpeedCurve( KVBSpeedPostTargetDistanceM, KVBSpeedPostTargetSpeedMpS, KVBDeclivity, KVBDelayBeforeBrakingEstablishedS + KVBDelayBeforeEmergencyBrakingS, SafeDecelerationMpS2 ), KVBNextSpeedPostSpeedLimitMpS + MpS.FromKpH(5f) ), KVBTrainSpeedLimitMpS + MpS.FromKpH(5f) ), KVBCurrentSpeedPostSpeedLimitMpS + MpS.FromKpH(5f) ); if (SpeedMpS() > KVBSignalAlertSpeedCurveMpS) { KVBOverspeed = true; if (SpeedMpS() > KVBSignalEmergencySpeedCurveMpS) { KVBEmergencyBraking = true; } } if (SpeedMpS() > KVBSpeedPostAlertSpeedCurveMpS) { KVBOverspeed = true; if (SpeedMpS() > KVBSpeedPostEmergencySpeedCurveMpS) { KVBEmergencyBraking = true; } } if (KVBEmergencyBraking && SpeedMpS() < 0.1f) { KVBEmergencyBraking = false; } SetOverspeedWarningDisplay(KVBOverspeed); if (KVBOverspeed && !KVBPreviousOverspeed) { TriggerSoundPenalty1(); } KVBPreviousOverspeed = KVBOverspeed; if (KVBEmergencyBraking && !KVBPreviousEmergencyBraking) { TriggerSoundPenalty2(); } KVBPreviousEmergencyBraking = KVBEmergencyBraking; }
protected void UpdateRSO() { if (NextSignalDistanceM(0) < 2f && (ActiveCCS == CCS.RSO || ActiveCCS == CCS.DAAT || ActiveCCS == CCS.KVB) && SpeedMpS() > 0) { if (NextSignalAspect(0) == Aspect.Stop || NextSignalAspect(0) == Aspect.StopAndProceed || NextSignalAspect(0) == Aspect.Restricted) { RSOClosedSignal = true; } else if (NextSignalAspect(1) == Aspect.Stop || NextSignalAspect(1) == Aspect.StopAndProceed) { RSOClosedSignal = true; } else if (NextSignalSpeedLimitMpS(1) >= 0f && NextSignalSpeedLimitMpS(1) < MpS.FromKpH(160f)) { RSOClosedSignal = true; } else { RSOOpenedSignal = true; } } if (SignalPassed) { RSOClosedSignal = RSOOpenedSignal = false; } if (RSOClosedSignal && !RSOPreviousClosedSignal && !RSOType1Inhibition) { TriggerSoundInfo1(); } RSOPreviousClosedSignal = RSOClosedSignal; if ((TVM300Present || TVM430Present) && TVMClosedSignal && !TVMPreviousClosedSignal) { TriggerSoundInfo1(); } if ((TVM300Present || TVM430Present) && TVMOpenedSignal && !TVMPreviousOpenedSignal) { TriggerSoundInfo1(); } TVMPreviousClosedSignal = TVMClosedSignal; TVMPreviousOpenedSignal = TVMOpenedSignal; }
public override void Update() { UpdateSignalPassed(); if (IsAlerterEnabled() && VACMAPresent) { UpdateVACMA(); } if (IsTrainControlEnabled()) { if (RSOPresent) { UpdateRSO(); } if (CurrentPostSpeedLimitMpS() <= MpS.FromKpH(220f)) { if (KVBPresent) { // Classic line = KVB active ActiveCCS = CCS.KVB; if (SignalPassed) { SetNextSignalAspect(NextSignalAspect(0)); } UpdateKVB(); } else { if (!DAATPresent) { ActiveCCS = CCS.RSO; } else { ActiveCCS = CCS.DAAT; } SetNextSignalAspect(Aspect.Clear_1); } } else { // High speed line = TVM active // Activation control (KAr) in KVB system if (TVM300Present) { ActiveCCS = CCS.TVM300; UpdateTVM300Display(); UpdateTVM300COVIT(); } else if (TVM430Present) { ActiveCCS = CCS.TVM430; UpdateTVM430Display(); UpdateTVM430COVIT(); } else if (KVBPresent) { // TVM not activated because not present ActiveCCS = CCS.KVB; if (SignalPassed) { SetNextSignalAspect(NextSignalAspect(0)); } KVBEmergencyBraking = true; } } SetEmergencyBrake( RSOEmergencyBraking || KVBEmergencyBraking || TVMCOVITEmergencyBraking || VACMAEmergencyBraking || ExternalEmergencyBraking ); SetPenaltyApplicationDisplay(IsBrakeEmergency()); SetPowerAuthorization(!RSOEmergencyBraking && !KVBEmergencyBraking && !TVMCOVITEmergencyBraking && !VACMAEmergencyBraking ); if (ActiveCCS != CCS.TVM300 && ActiveCCS != CCS.TVM430) { TVMAspect = Aspect.None; TVMPreviousAspect = Aspect.None; } RSOType1Inhibition = IsDirectionReverse(); RSOType2Inhibition = !KVBInhibited && ((TVM300Present && ActiveCCS == CCS.TVM300) || (TVM430Present && ActiveCCS == CCS.TVM430)); RSOType3Inhibition = (TVM300Present || TVM430Present) && !TVMCOVITInhibited; PreviousCCS = ActiveCCS; } }
public override void Initialize() { // General section VACMAPresent = GetBoolParameter("General", "VACMAPresent", true); RSOPresent = GetBoolParameter("General", "RSOPresent", true); DAATPresent = GetBoolParameter("General", "DAATPresent", false); KVBPresent = GetBoolParameter("General", "KVBPresent", false); TVM300Present = GetBoolParameter("General", "TVM300Present", false); TVM430Present = GetBoolParameter("General", "TVM430Present", false); ETCSPresent = GetBoolParameter("General", "ETCSPresent", false); ElectroPneumaticBrake = GetBoolParameter("General", "ElectroPneumaticBrake", false); HeavyFreightTrain = GetBoolParameter("General", "HeavyFreightTrain", false); SafeDecelerationMpS2 = GetFloatParameter("General", "SafeDecelerationMpS2", 0.7f); // KVB section KVBInhibited = GetBoolParameter("KVB", "Inhibited", false); KVBTrainSpeedLimitMpS = MpS.FromKpH(GetFloatParameter("KVB", "TrainSpeedLimitKpH", 160f)); // TVM common section TVMCOVITInhibited = GetBoolParameter("TVM", "CovitInhibited", false); // TVM300 section TVM300TrainSpeedLimitMpS = MpS.FromKpH(GetFloatParameter("TVM300", "TrainSpeedLimitKpH", 300f)); // TVM430 section TVM430TrainSpeedLimitMpS = MpS.FromKpH(GetFloatParameter("TVM430", "TrainSpeedLimitKpH", 320f)); // VACMA section VACMAActivationSpeedMpS = MpS.FromKpH(GetFloatParameter("VACMA", "ActivationSpeedKpH", 3f)); VACMAReleasedAlertDelayS = GetFloatParameter("VACMA", "ReleasedAlertDelayS", 2.5f); VACMAReleasedEmergencyDelayS = GetFloatParameter("VACMA", "ReleasedEmergencyDelayS", 5f); VACMAPressedAlertDelayS = GetFloatParameter("VACMA", "PressedAlertDelayS", 55f); VACMAPressedEmergencyDelayS = GetFloatParameter("VACMA", "PressedEmergencyDelayS", 60f); // Variables initialization KVBCurrentSignalSpeedLimitMpS = KVBTrainSpeedLimitMpS; KVBNextSignalSpeedLimitMpS = KVBTrainSpeedLimitMpS; KVBSignalTargetSpeedMpS = KVBTrainSpeedLimitMpS; KVBSignalTargetDistanceM = 0f; KVBCurrentSpeedPostSpeedLimitMpS = KVBTrainSpeedLimitMpS; KVBNextSpeedPostSpeedLimitMpS = KVBTrainSpeedLimitMpS; KVBSpeedPostTargetSpeedMpS = KVBTrainSpeedLimitMpS; KVBSpeedPostTargetDistanceM = 0f; KVBCurrentAlertSpeedMpS = MpS.FromKpH(5f); KVBCurrentEBSpeedMpS = MpS.FromKpH(10f); KVBNextAlertSpeedMpS = MpS.FromKpH(5f); KVBNextEBSpeedMpS = MpS.FromKpH(10f); VACMAPressedAlertTimer = new Timer(this); VACMAPressedAlertTimer.Setup(VACMAPressedAlertDelayS); VACMAPressedEmergencyTimer = new Timer(this); VACMAPressedEmergencyTimer.Setup(VACMAPressedEmergencyDelayS); VACMAReleasedAlertTimer = new Timer(this); VACMAReleasedAlertTimer.Setup(VACMAReleasedAlertDelayS); VACMAReleasedEmergencyTimer = new Timer(this); VACMAReleasedEmergencyTimer.Setup(VACMAReleasedEmergencyDelayS); TVM430AspectChangeTimer = new Timer(this); TVM430AspectChangeTimer.Setup(4.7f); Activated = true; PreviousSignalDistanceM = 0f; }
void UpdateSpeedControl() { var interventionSpeedMpS = CurrentSpeedLimitMpS + MpS.FromKpH(5.0f); // Default margin : 5 km/h if (OverspeedMonitor.TriggerOnTrackOverspeed) { interventionSpeedMpS = CurrentSpeedLimitMpS + OverspeedMonitor.TriggerOnTrackOverspeedMarginMpS; } SetInterventionSpeedLimitMpS(interventionSpeedMpS); switch (OverspeedMonitorState) { case MonitorState.Disabled: if (SpeedControlSystemEnabled) { OverspeedMonitorState = MonitorState.StandBy; } break; case MonitorState.StandBy: if (!SpeedControlSystemEnabled) { OverspeedMonitorState = MonitorState.Disabled; } else { if (Overspeed) { OverspeedMonitorState = MonitorState.Alarm; } } break; case MonitorState.Alarm: if (!SpeedControlSystemEnabled) { OverspeedMonitorState = MonitorState.Disabled; } else { if (!OverspeedEmergencyTimer.Started) { OverspeedEmergencyTimer.Start(); } if (!Overspeed) { OverspeedEmergencyTimer.Stop(); OverspeedMonitorState = MonitorState.StandBy; } else if (OverspeedEmergencyTimer.Triggered) { OverspeedEmergencyTimer.Stop(); OverspeedMonitorState = MonitorState.Emergency; } } break; case MonitorState.Emergency: if (!OverspeedPenaltyTimer.Started) { OverspeedPenaltyTimer.Start(); } if (OverspeedPenaltyTimer.Triggered && OverspeedReset) { OverspeedPenaltyTimer.Stop(); OverspeedMonitorState = MonitorState.StandBy; } break; } SetOverspeedWarningDisplay(OverspeedMonitorState >= MonitorState.Alarm); }
public ApproachControlLimits(STFReader stf) { stf.ParseBlock(new STFReader.TokenProcessor[] { new STFReader.TokenProcessor("positionmiles", () => { ApproachControlPositionM = Me.FromMi(stf.ReadFloatBlock(STFReader.UNITS.None, 0)); }), new STFReader.TokenProcessor("positionkm", () => { ApproachControlPositionM = (stf.ReadFloatBlock(STFReader.UNITS.None, 0) * 1000); }), new STFReader.TokenProcessor("positionm", () => { ApproachControlPositionM = stf.ReadFloatBlock(STFReader.UNITS.None, 0); }), new STFReader.TokenProcessor("positionyd", () => { ApproachControlPositionM = Me.FromYd(stf.ReadFloatBlock(STFReader.UNITS.None, 0)); }), new STFReader.TokenProcessor("speedmph", () => { ApproachControlSpeedMpS = MpS.FromMpH(stf.ReadFloatBlock(STFReader.UNITS.None, 0)); }), new STFReader.TokenProcessor("speedkph", () => { ApproachControlSpeedMpS = MpS.FromKpH(stf.ReadFloatBlock(STFReader.UNITS.None, 0)); }), }); }