From 71b801c01290b1902f13022bfd35c9eb9f0ce0d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jind=C5=99ich=20Machal=C3=ADnek?= Date: Sun, 31 Jan 2021 23:03:55 +0100 Subject: [PATCH 1/7] Update Signals.cs --- Source/RunActivity/Viewer3D/Signals.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/RunActivity/Viewer3D/Signals.cs b/Source/RunActivity/Viewer3D/Signals.cs index 1fc7b5a942..2ac80bac5c 100644 --- a/Source/RunActivity/Viewer3D/Signals.cs +++ b/Source/RunActivity/Viewer3D/Signals.cs @@ -466,9 +466,11 @@ public SignalTypeData(Viewer viewer, Orts.Formats.Msts.SignalType mstsSignalType if (mstsSignalType.Semaphore) glowDay = 0.0f; + /* Jindrich + * Why is this here? I want all my lights glowing, when I have glowing on if (mstsSignalType.FnType == MstsSignalFunction.INFO || mstsSignalType.FnType == MstsSignalFunction.SHUNTING) // These are good at identifying theatre boxes. glowDay = glowNight = 0.0f; - + */ // use values from signal if defined if (mstsSignalType.DayGlow.HasValue) { From 374278662a97cbd91448871a9563d0eb8a19a3ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jind=C5=99ich=20Machal=C3=ADnek?= Date: Mon, 1 Feb 2021 01:25:02 +0100 Subject: [PATCH 2/7] CruiseControl Initial release of Cruise Control --- Source/ORTS.Common/Input/UserCommand.cs | 32 + Source/ORTS.Settings/InputSettings.cs | 38 +- Source/Orts.Formats.Msts/CabViewFile.cs | 28 +- Source/Orts.Simulation/Common/Events.cs | 13 + Source/Orts.Simulation/Orts.Simulation.csproj | 1 + .../RollingStocks/MSTSLocomotive.cs | 296 +++- .../RollingStocks/SubSystems/CruiseControl.cs | 1366 +++++++++++++++++ .../RollingStock/MSTSLocomotiveViewer.cs | 142 +- 8 files changed, 1902 insertions(+), 14 deletions(-) create mode 100644 Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs diff --git a/Source/ORTS.Common/Input/UserCommand.cs b/Source/ORTS.Common/Input/UserCommand.cs index b5e7fd587e..cf20e7b39b 100644 --- a/Source/ORTS.Common/Input/UserCommand.cs +++ b/Source/ORTS.Common/Input/UserCommand.cs @@ -203,5 +203,37 @@ public enum UserCommand [GetString("Control AI Fire Reset")] ControlAIFireReset, [GetString("Control Battery")] ControlBattery, [GetString("Control PowerKey")] ControlPowerKey, + [GetString("Control Speed Regulator Mode Increase")] ControlSpeedRegulatorModeIncrease, + [GetString("Control Speed Regulator Mode Descrease")] ControlSpeedRegulatorModeDecrease, + [GetString("Control Selected Speed Increase")] ControlSpeedRegulatorSelectedSpeedIncrease, + [GetString("Control Selected Speed Decrease")] ControlSpeedRegulatorSelectedSpeedDecrease, + [GetString("Control Speed Regulator Max Acceleration Increase")] ControlSpeedRegulatorMaxAccelerationIncrease, + [GetString("Control Speed Regulator Max Acceleration Decrease")] ControlSpeedRegulatorMaxAccelerationDecrease, + [GetString("Control Number Of Axles Increase")] ControlNumberOfAxlesIncrease, + [GetString("Control Number Of Axles Decrease")] ControlNumberOfAxlesDecrease, + [GetString("Control Restricted Speed Zone Active")] ControlRestrictedSpeedZoneActive, + [GetString("Control Cruise Control Mode Increase")] ControlCruiseControlModeIncrease, + [GetString("Control Cruise Control Mode Decrease")] ControlCruiseControlModeDecrease, + [GetString("Control Train Type Change (Passenger/Cargo)")] ControlTrainTypePaxCargo, + [GetString("Control Select Speed 10 kph")] ControlSelectSpeed10KpH, + [GetString("Control Select Speed 20 kph")] ControlSelectSpeed20KpH, + [GetString("Control Select Speed 30 kph")] ControlSelectSpeed30KpH, + [GetString("Control Select Speed 40 kph")] ControlSelectSpeed40KpH, + [GetString("Control Select Speed 50 kph")] ControlSelectSpeed50KpH, + [GetString("Control Select Speed 60 kph")] ControlSelectSpeed60KpH, + [GetString("Control Select Speed 70 kph")] ControlSelectSpeed70KpH, + [GetString("Control Select Speed 80 kph")] ControlSelectSpeed80KpH, + [GetString("Control Select Speed 90 kph")] ControlSelectSpeed90KpH, + [GetString("Control Select Speed 100 kph")] ControlSelectSpeed100KpH, + [GetString("Control Select Speed 110 kph")] ControlSelectSpeed110KpH, + [GetString("Control Select Speed 120 kph")] ControlSelectSpeed120KpH, + [GetString("Control Select Speed 130 kph")] ControlSelectSpeed130KpH, + [GetString("Control Select Speed 140 kph")] ControlSelectSpeed140KpH, + [GetString("Control Select Speed 150 kph")] ControlSelectSpeed150KpH, + [GetString("Control Select Speed 160 kph")] ControlSelectSpeed160KpH, + [GetString("Control Select Speed 170 kph")] ControlSelectSpeed170KpH, + [GetString("Control Select Speed 180 kph")] ControlSelectSpeed180KpH, + [GetString("Control Select Speed 190 kph")] ControlSelectSpeed190KpH, + [GetString("Control Select Speed 200 kph")] ControlSelectSpeed200KpH, } } diff --git a/Source/ORTS.Settings/InputSettings.cs b/Source/ORTS.Settings/InputSettings.cs index dac8536ae2..b740514273 100644 --- a/Source/ORTS.Settings/InputSettings.cs +++ b/Source/ORTS.Settings/InputSettings.cs @@ -97,7 +97,7 @@ UserCommand[] GetCommands() public override object GetDefaultValue(string name) { - return DefaultCommands[(int)GetCommand(name)].PersistentDescriptor; + return DefaultCommands[(int)GetCommand(name)].PersistentDescriptor; } protected override object GetValue(string name) @@ -434,6 +434,42 @@ static void InitializeCommands(UserCommandInput[] Commands) Commands[(int)UserCommand.ControlWaterScoop] = new UserCommandKeyInput(0x15); Commands[(int)UserCommand.ControlWiper] = new UserCommandKeyInput(0x2F); + // Jindrich + Commands[(int)UserCommand.ControlSpeedRegulatorModeIncrease] = new UserCommandKeyInput(0x11, KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSpeedRegulatorModeDecrease] = new UserCommandKeyInput(0x1F, KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSpeedRegulatorMaxAccelerationIncrease] = new UserCommandKeyInput(0x20, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSpeedRegulatorMaxAccelerationDecrease] = new UserCommandKeyInput(0x1E, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSpeedRegulatorSelectedSpeedIncrease] = new UserCommandKeyInput(0x20, KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSpeedRegulatorSelectedSpeedDecrease] = new UserCommandKeyInput(0x1E, KeyModifiers.Shift); + Commands[(int)UserCommand.ControlNumberOfAxlesIncrease] = new UserCommandKeyInput(0x48, KeyModifiers.Shift); + Commands[(int)UserCommand.ControlNumberOfAxlesDecrease] = new UserCommandKeyInput(0x50, KeyModifiers.Shift); + Commands[(int)UserCommand.ControlRestrictedSpeedZoneActive] = new UserCommandKeyInput(0x19, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlCruiseControlModeDecrease] = new UserCommandKeyInput(0x1E, KeyModifiers.Control); + Commands[(int)UserCommand.ControlCruiseControlModeIncrease] = new UserCommandKeyInput(0x20, KeyModifiers.Control); + Commands[(int)UserCommand.ControlTrainTypePaxCargo] = new UserCommandKeyInput(0x31, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed10KpH] = new UserCommandKeyInput(0x3B, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed20KpH] = new UserCommandKeyInput(0x3C, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed30KpH] = new UserCommandKeyInput(0x3D, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed40KpH] = new UserCommandKeyInput(0x3E, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed50KpH] = new UserCommandKeyInput(0x3F, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed60KpH] = new UserCommandKeyInput(0x40, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed70KpH] = new UserCommandKeyInput(0x41, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed80KpH] = new UserCommandKeyInput(0x42, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed90KpH] = new UserCommandKeyInput(0x43, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed100KpH] = new UserCommandKeyInput(0x44, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed110KpH] = new UserCommandKeyInput(0x57, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed120KpH] = new UserCommandKeyInput(0x58, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed110KpH] = new UserCommandKeyInput(0x02, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed120KpH] = new UserCommandKeyInput(0x03, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed130KpH] = new UserCommandKeyInput(0x04, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed140KpH] = new UserCommandKeyInput(0x05, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed150KpH] = new UserCommandKeyInput(0x06, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed160KpH] = new UserCommandKeyInput(0x07, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed170KpH] = new UserCommandKeyInput(0x08, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed180KpH] = new UserCommandKeyInput(0x09, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed190KpH] = new UserCommandKeyInput(0x0A, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed200KpH] = new UserCommandKeyInput(0x0B, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.DebugClockBackwards] = new UserCommandKeyInput(0x0C); Commands[(int)UserCommand.DebugClockForwards] = new UserCommandKeyInput(0x0D); Commands[(int)UserCommand.DebugDumpKeymap] = new UserCommandKeyInput(0x3B, KeyModifiers.Alt); diff --git a/Source/Orts.Formats.Msts/CabViewFile.cs b/Source/Orts.Formats.Msts/CabViewFile.cs index 7896d80d52..53c93a1ade 100644 --- a/Source/Orts.Formats.Msts/CabViewFile.cs +++ b/Source/Orts.Formats.Msts/CabViewFile.cs @@ -235,6 +235,30 @@ public enum CABViewControlTypes ORTS_TCS47, ORTS_TCS48, ORTS_ETCS, + ORTS_SELECTED_SPEED, + ORTS_SELECTED_SPEED_DISPLAY, + ORTS_SELECTED_SPEED_MODE, + ORTS_SELECTED_SPEED_REGULATOR_MODE, + ORTS_SELECTED_SPEED_MAXIMUM_ACCELERATION, + ORTS_RESTRICTED_SPEED_ZONE_ACTIVE, + ORTS_NUMBER_OF_AXES_DISPLAY_UNITS, + ORTS_NUMBER_OF_AXES_DISPLAY_TENS, + ORTS_NUMBER_OF_AXES_DISPLAY_HUNDREDS, + ORTS_TRAIN_LENGTH_METERS, + ORTS_REMAINING_TRAIN_LENGHT_SPEED_RESTRICTED, + ORTS_REMAINING_TRAIN_LENGTH_PERCENT, + ORTS_MOTIVE_FORCE, + ORTS_MOTIVE_FORCE_KILONEWTON, + ORTS_MAXIMUM_FORCE, + ORTS_FORCE_IN_PERCENT_THROTTLE_AND_DYNAMIC_BRAKE, + ORTS_TRAIN_TYPE_PAX_OR_CARGO, + ORTS_CONTROLLER_VOLTAGE, + ORTS_AMPERS_BY_CONTROLLER_VOLTAGE, + ORTS_ODOMETER, + ORTS_CC_SELECT_SPEED, + ORTS_NUMBER_OF_AXES_INCREASE, + ORTS_NUMBER_OF_AXES_DECREASE, + // Further CabViewControlTypes must be added above this line, to avoid their malfunction in 3DCabs EXTERNALWIPERS, @@ -292,7 +316,9 @@ public enum CABViewControlUnits INCHES_OF_MERCURY, MILI_AMPS, RPM, - LBS + LBS, + + KILOMETRES } public class CabViewControls : List diff --git a/Source/Orts.Simulation/Common/Events.cs b/Source/Orts.Simulation/Common/Events.cs index dddb086a0e..4458668444 100644 --- a/Source/Orts.Simulation/Common/Events.cs +++ b/Source/Orts.Simulation/Common/Events.cs @@ -204,6 +204,12 @@ public enum Event GearPosition7, GearPosition8, + // Jindrich + CruiseControlSpeedRegulator, + CruiseControlSpeedSelector, + CruiseControlMaxForce, + Alert, + Alert1, } @@ -423,6 +429,13 @@ public static Event From(bool mstsBinEnabled, Source source, int eventID) case 207: return Event.GearPosition7; case 208: return Event.GearPosition8; + // Jindrich + case 1000: return Event.CruiseControlSpeedRegulator; + case 1001: return Event.CruiseControlSpeedSelector; + case 1002: return Event.CruiseControlMaxForce; + case 1003: return Event.Alert; + case 1004: return Event.Alert1; + default: return 0; } case Source.MSTSCrossing: diff --git a/Source/Orts.Simulation/Orts.Simulation.csproj b/Source/Orts.Simulation/Orts.Simulation.csproj index c3349f8242..b9057f1e53 100644 --- a/Source/Orts.Simulation/Orts.Simulation.csproj +++ b/Source/Orts.Simulation/Orts.Simulation.csproj @@ -117,6 +117,7 @@ + diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs index 11967a2828..c88e1e05d7 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs @@ -329,7 +329,7 @@ public float OdometerM protected bool DynamicBrakeBlended; // dynamic brake blending is currently active protected bool DynamicBrakeBlendingEnabled; // dynamic brake blending is configured - protected bool DynamicBrakeAvailable; // dynamic brake is available + public bool DynamicBrakeAvailable; // dynamic brake is available AirSinglePipe airPipeSystem; public double DynamicBrakeCommandStartTime; protected bool DynamicBrakeBlendingOverride; // true when DB lever >0% should always override the blending. When false, the bigger command is applied. @@ -403,6 +403,13 @@ public float OdometerM public float PowerReduction = 0; + // Jindrich + public CruiseControl CruiseControl; + public bool SelectingSpeedPressed = false; + public bool EngineBrakePriority = false; + public bool IsAPartOfPlayerTrain = false; + public float ThrottleOverriden = 0; + public MSTSLocomotive(Simulator simulator, string wagPath) : base(simulator, wagPath) { @@ -426,6 +433,7 @@ public MSTSLocomotive(Simulator simulator, string wagPath) ThrottleController = new MSTSNotchController(); DynamicBrakeController = new MSTSNotchController(); TrainControlSystem = new ScriptedTrainControlSystem(this); + CruiseControl = new CruiseControl(this); } /// @@ -921,6 +929,59 @@ public override void Parse(string lowercasetoken, STFReader stf) case "engine(ortsmaxtracksanderboxcapacity": MaxTrackSandBoxCapacityM3 = stf.ReadFloatBlock(STFReader.UNITS.Volume, null); break; case "engine(ortsmaxtracksandersandconsumption": TrackSanderSandConsumptionM3pS = stf.ReadFloatBlock(STFReader.UNITS.Volume, null); break; case "engine(ortsmaxtracksanderairconsumption": TrackSanderAirComsumptionM3pS = stf.ReadFloatBlock(STFReader.UNITS.Volume, null); break; + case "engine(ortscruisecontrol": CruiseControl.Equipped = true; break; + case "engine(ortscruisecontrol(usethrottle": CruiseControl.UseThrottle = stf.ReadBoolBlock(false); break; + case "engine(ortscruisecontrol(throttleincreasespeed": CruiseControl.ThrottleIncreaseSpeed = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.1f); break; + case "engine(ortscruisecontrol(throttledecreasespeed": CruiseControl.ThrottleDecreaseSpeed = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.2f); break; + case "engine(ortscruisecontrol(throttlefullrangeincreasetimeseconds": CruiseControl.ThrottleFullRangeIncreaseTimeSeconds = stf.ReadFloatBlock(STFReader.UNITS.Any, 5); break; + case "engine(ortscruisecontrol(throttlefullrangedecreasetimeseconds": CruiseControl.ThrottleFullRangeDecreaseTimeSeconds = stf.ReadFloatBlock(STFReader.UNITS.Any, 5); break; + case "engine(ortscruisecontrol(dynamicbrakefullrangeincreasetimeseconds": CruiseControl.DynamicBrakeFullRangeIncreaseTimeSeconds = stf.ReadFloatBlock(STFReader.UNITS.Any, 5); break; + case "engine(ortscruisecontrol(dynamicbrakefullrangedecreasetimeseconds": CruiseControl.DynamicBrakeFullRangeDecreaseTimeSeconds = stf.ReadFloatBlock(STFReader.UNITS.Any, 5); break; + case "engine(ortscruisecontrol(parkingbrakeengagespeed": CruiseControl.ParkingBrakeEngageSpeed = stf.ReadFloatBlock(STFReader.UNITS.Speed, 0); break; + case "engine(ortscruisecontrol(parkingbrakepercent": CruiseControl.ParkingBrakePercent = stf.ReadFloatBlock(STFReader.UNITS.Any, 0); break; + case "engine(ortscruisecontrol(maxpowerthreshold": CruiseControl.MaxPowerThreshold = stf.ReadFloatBlock(STFReader.UNITS.Any, 0); break; + case "engine(ortscruisecontrol(maxforcepercentunits": CruiseControl.SpeedRegulatorMaxForcePercentUnits = stf.ReadBoolBlock(false); break; + case "engine(ortscruisecontrol(maxforcesteps": CruiseControl.SpeedRegulatorMaxForceSteps = stf.ReadIntBlock(0); break; + case "engine(ortscruisecontrol(maxforcesetsinglestep": CruiseControl.MaxForceSetSingleStep = stf.ReadBoolBlock(false); break; + case "engine(ortscruisecontrol(maxforcekeepselectedstepwhenmanualmodeset": CruiseControl.MaxForceKeepSelectedStepWhenManualModeSet = stf.ReadBoolBlock(false); break; + case "engine(ortscruisecontrol(forcestepsthrottletable": + foreach (var forceStepThrottleValue in stf.ReadStringBlock("").Replace(" ", "").Split(',')) + { + CruiseControl.ForceStepsThrottleTable.Add(int.Parse(forceStepThrottleValue)); + } + break; + case "engine(ortscruisecontrol(accelerationtable": + foreach (var accelerationValue in stf.ReadStringBlock("").Replace(" ", "").Split(',')) + { + CruiseControl.AccelerationTable.Add(float.Parse(accelerationValue)); + } + break; + case "engine(ortscruisecontrol(powerbreakoutampers": CruiseControl.PowerBreakoutAmpers = stf.ReadFloatBlock(STFReader.UNITS.Any, 100.0f); break; + case "engine(ortscruisecontrol(powerbreakoutspeeddelta": CruiseControl.PowerBreakoutSpeedDelta = stf.ReadFloatBlock(STFReader.UNITS.Any, 100.0f); break; + case "engine(ortscruisecontrol(powerresumespeeddelta": CruiseControl.PowerResumeSpeedDelta = stf.ReadFloatBlock(STFReader.UNITS.Any, 100.0f); break; + case "engine(ortscruisecontrol(powerreductiondelaypaxtrain": CruiseControl.PowerReductionDelayPaxTrain = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.0f); break; + case "engine(ortscruisecontrol(powerreductiondelaycargotrain": CruiseControl.PowerReductionDelayCargoTrain = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.0f); break; + case "engine(ortscruisecontrol(powerreductionvalue": CruiseControl.PowerReductionValue = stf.ReadFloatBlock(STFReader.UNITS.Any, 100.0f); break; + + case "engine(ortscruisecontrol(disablezeroforcestep": CruiseControl.DisableZeroForceStep = stf.ReadBoolBlock(false); break; + case "engine(ortscruisecontrol(defaultforcestep": CruiseControl.SelectedMaxAccelerationStep = stf.ReadFloatBlock(STFReader.UNITS.Any, 1.0f); break; + case "engine(ortscruisecontrol(dynamicbrakemaxforceatselectorstep": CruiseControl.DynamicBrakeMaxForceAtSelectorStep = stf.ReadFloatBlock(STFReader.UNITS.Any, 1.0f); break; + case "engine(ortscruisecontrol(startreducingspeeddelta": CruiseControl.StartReducingSpeedDelta = stf.ReadFloatBlock(STFReader.UNITS.Any, 1.0f); break; + case "engine(ortscruisecontrol(dynamicbrakedescentcoefficient": CruiseControl.DynamicBrakeDescentCoefficient = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.5f); break; + case "engine(ortscruisecontrol(climbdeltacoefficient": CruiseControl.DeltaCoefficient = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.8f); break; + case "engine(ortscruisecontrol(maxacceleration": CruiseControl.MaxAccelerationMpSS = stf.ReadFloatBlock(STFReader.UNITS.Any, 1); break; + case "engine(ortscruisecontrol(maxdeceleration": CruiseControl.MaxDecelerationMpSS = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.5f); break; + case "engine(ortscruisecontrol(antiwheelspinequipped": CruiseControl.AntiWheelSpinEquipped = stf.ReadBoolBlock(false); break; + case "engine(ortscruisecontrol(nominalspeedstep": CruiseControl.SpeedRegulatorNominalSpeedStepMpS = MpS.FromKpH(stf.ReadFloatBlock(STFReader.UNITS.Speed, 0)); break; + case "engine(ortscruisecontrol(usethrottleasspeedselector": CruiseControl.UseThrottleAsSpeedSelector = stf.ReadBoolBlock(false); break; + case "engine(ortscruisecontrol(dynamicbrakeincreasespeed": CruiseControl.DynamicBrakeIncreaseSpeed = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.5f); break; + case "engine(ortscruisecontrol(dynamicbrakedecreasespeed": CruiseControl.DynamicBrakeDecreaseSpeed = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.5f); break; + case "engine(ortscruisecontrol(options": + foreach (var speedRegulatorOption in stf.ReadStringBlock("").ToLower().Replace(" ", "").Split(',')) + { + CruiseControl.SpeedRegulatorOptions.Add(speedRegulatorOption.ToLower()); + } + break; default: base.Parse(lowercasetoken, stf); break; } @@ -1023,6 +1084,7 @@ public override void Copy(MSTSWagon copy) WaterScoopDepthM = locoCopy.WaterScoopDepthM; WaterScoopWidthM = locoCopy.WaterScoopWidthM; MoveParamsToAxle(); + CruiseControl = locoCopy.CruiseControl; } @@ -1080,11 +1142,11 @@ public override void Save(BinaryWriter outf) outf.Write(ScoopIsBroken); outf.Write(IsWaterScoopDown); outf.Write(CurrentTrackSandBoxCapacityM3); - base.Save(outf); TrainControlSystem.Save(outf); LocomotiveAxle.Save(outf); + CruiseControl.Save(outf); } /// @@ -1131,6 +1193,7 @@ public override void Restore(BinaryReader inf) TrainControlSystem.Restore(inf); LocomotiveAxle = new Axle(inf); + CruiseControl.Restore(inf); } public bool IsLeadLocomotive() @@ -1211,6 +1274,7 @@ public override void Initialize() EngineBrakeController.Initialize(); BrakemanBrakeController.Initialize(); TrainControlSystem.Initialize(); + CruiseControl.Initialize(); if (MaxSteamHeatPressurePSI == 0) // Check to see if steam heating is fitted to locomotive { @@ -1578,8 +1642,18 @@ public override void Update(float elapsedClockSeconds) if (!AdvancedAdhesionModel) // Advanced adhesion model turned off. AbsWheelSpeedMpS = AbsSpeedMpS; - - UpdateMotiveForce(elapsedClockSeconds, t, AbsSpeedMpS, AbsWheelSpeedMpS); + // Jindrich + //UpdateMotiveForce(elapsedClockSeconds, t, AbsSpeedMpS, AbsWheelSpeedMpS); + if (!IsPlayerTrain || !CruiseControl.Equipped || CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Manual || CruiseControl.UseThrottle) + UpdateMotiveForce(elapsedClockSeconds, t, AbsSpeedMpS, AbsWheelSpeedMpS); + else if (IsPlayerTrain && CruiseControl.Equipped || CruiseControl.SpeedRegulatorOptions.Contains("engageforceonnonzerospeed")) + { + CruiseControl.Update(elapsedClockSeconds, AbsWheelSpeedMpS); + } + if (IsPlayerTrain && CruiseControl.Equipped) + { + if (CruiseControl.RestrictedSpeedActive) CruiseControl.CheckRestrictedSpeedZone(); + } ApplyDirectionToMotiveForce(); @@ -2848,6 +2922,14 @@ public void StartThrottleIncrease(float? target) public void StartThrottleIncrease() { + if (CruiseControl.Equipped) + { + if (CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) + { + CruiseControl.SpeedSelectorModeStartIncrease(); + return; + } + } if (DynamicBrakeController != null && DynamicBrakeController.CurrentValue >= 0 && (DynamicBrakePercent >= 0 || !(DynamicBrakePercent == -1 && !DynamicBrake || DynamicBrakePercent >= 0 && DynamicBrake))) { if (!(CombinedControlType == CombinedControl.ThrottleDynamic @@ -2868,6 +2950,14 @@ public void StartThrottleIncrease() public void StopThrottleIncrease() { + if (CruiseControl.Equipped) + { + if (CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) + { + CruiseControl.SpeedSelectorModeStopIncrease(); + return; + } + } AlerterReset(TCSEvent.ThrottleChanged); ThrottleController.StopIncrease(); @@ -2892,8 +2982,21 @@ public void StartThrottleDecrease(float? target) CommandStartTime = Simulator.ClockTime; } + protected bool speedSelectorModeDecreasing = false; public void StartThrottleDecrease() { + if (CruiseControl.Equipped) + { + if (CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) + { + if (!speedSelectorModeDecreasing) + { + CruiseControl.SpeedSelectorModeDecrease(); + speedSelectorModeDecreasing = true; + } + return; + } + } if (CombinedControlType == CombinedControl.ThrottleDynamic && ThrottleController.CurrentValue <= 0) StartDynamicBrakeIncrease(null); else if (CombinedControlType == CombinedControl.ThrottleAir && ThrottleController.CurrentValue <= 0) @@ -2904,6 +3007,14 @@ public void StartThrottleDecrease() public void StopThrottleDecrease() { + if (CruiseControl.Equipped) + { + if (CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) + { + speedSelectorModeDecreasing = false; + return; + } + } AlerterReset(TCSEvent.ThrottleChanged); ThrottleController.StopDecrease(); @@ -3078,6 +3189,14 @@ public void SetThrottlePercentWithSound(float percent) public void ThrottleToZero() { + if (CruiseControl.SpeedRegulatorOptions.Contains("shutdownonsetthrottlezero")) + { + CruiseControl.SelectedSpeedMpS = 0; + CruiseControl.SpeedSelMode = CruiseControl.SpeedSelectorMode.Neutral; + CruiseControl.SpeedRegMode = CruiseControl.SpeedRegulatorMode.Manual; + SetThrottlePercent(0); + return; + } if (CombinedControlType == CombinedControl.ThrottleDynamic && ThrottleController.CurrentValue <= 0) StartDynamicBrakeIncrease(null); else if (CombinedControlType == CombinedControl.ThrottleAir && ThrottleController.CurrentValue <= 0) @@ -3371,6 +3490,7 @@ public void StartEngineBrakeIncrease(float? target) if (EngineBrakeController == null) return; + EngineBrakePriority = true; EngineBrakeController.StartIncrease(target); Simulator.Confirmer.Confirm(CabControl.EngineBrake, CabSetting.Increase, GetEngineBrakeStatus()); SignalEvent(Event.EngineBrakeChange); @@ -3598,6 +3718,11 @@ public override string GetBrakemanBrakeStatus() public void StartDynamicBrakeIncrease(float? target) { AlerterReset(TCSEvent.DynamicBrakeChanged); + if (CruiseControl.Equipped) + { + SetThrottlePercent(0); + CruiseControl.DynamicBrakePriority = true; + } if (!CanUseDynamicBrake()) return; @@ -3656,6 +3781,7 @@ public void StopDynamicBrakeDecrease() { DynamicBrakeController.StopDecrease(); new DynamicBrakeCommand(Simulator.Log, false, DynamicBrakeController.CurrentValue, DynamicBrakeController.CommandStartTime); + if (DynamicBrakePercent < 1) CruiseControl.DynamicBrakePriority = false; } } @@ -3926,6 +4052,13 @@ public void AlerterPressed(bool pressed) TrainControlSystem.AlerterPressed(pressed); } + public enum TrainType { Pax, Cargo }; + public TrainType SelectedTrainType = TrainType.Pax; + public void ChangeTrainTypePaxCargo() + { + SelectedTrainType = SelectedTrainType == TrainType.Pax ? SelectedTrainType = TrainType.Cargo : TrainType.Pax; + } + //put here because you can have diesel helpers and electric player locomotive public void ToggleHelpersEngine() { @@ -4089,9 +4222,10 @@ public override void SignalEvent(Event evt) } //used by remote train locomotives - /* public virtual void RemoteUpdate() - { - }*/ + /* public virtual void RemoteUpdate() + { + }*/ + private float previousSelectedSpeed = 0; public virtual float GetDataOf(CabViewControl cvc) { @@ -4464,6 +4598,7 @@ public virtual float GetDataOf(CabViewControl cvc) case CABViewControlTypes.THROTTLE_DISPLAY: case CABViewControlTypes.CPH_DISPLAY: { + if (CruiseControl.SkipThrottleDisplay) break; data = Train.TrainType == Train.TRAINTYPE.AI_PLAYERHOSTING? ThrottlePercent / 100f : LocalThrottlePercent / 100f; break; } @@ -4851,7 +4986,152 @@ public virtual float GetDataOf(CabViewControl cvc) case CABViewControlTypes.ORTS_TCS48: data = TrainControlSystem.CabDisplayControls[(int)cvc.ControlType - (int)CABViewControlTypes.ORTS_TCS1]; break; - + case CABViewControlTypes.ORTS_SELECTED_SPEED: + case CABViewControlTypes.ORTS_SELECTED_SPEED_DISPLAY: + { + bool metric = cvc.Units == CABViewControlUnits.KM_PER_HOUR; + float temp = CruiseControl.RestrictedSpeedActive ? MpS.FromMpS(CruiseControl.CurrentSelectedSpeedMpS, metric) : temp = MpS.FromMpS(CruiseControl.SelectedSpeedMpS, metric); + if (previousSelectedSpeed < temp) previousSelectedSpeed += 1f; + if (previousSelectedSpeed > temp) previousSelectedSpeed -= 1f; + data = previousSelectedSpeed; + break; + } + case CABViewControlTypes.ORTS_SELECTED_SPEED_MODE: + { + data = (float)CruiseControl.SpeedSelMode; + break; + } + case CABViewControlTypes.ORTS_SELECTED_SPEED_REGULATOR_MODE: + { + data = (float)CruiseControl.SpeedRegMode; + break; + } + case CABViewControlTypes.ORTS_SELECTED_SPEED_MAXIMUM_ACCELERATION: + { + if (CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto || CruiseControl.MaxForceKeepSelectedStepWhenManualModeSet) + data = CruiseControl.SelectedMaxAccelerationStep - 1; + else + data = 0; + break; + } + case CABViewControlTypes.ORTS_RESTRICTED_SPEED_ZONE_ACTIVE: + { + data = CruiseControl.RestrictedSpeedActive ? 1 : 0; + break; + } + case CABViewControlTypes.ORTS_NUMBER_OF_AXES_DISPLAY_UNITS: + { + data = CruiseControl.SelectedNumberOfAxles % 10; + break; + } + case CABViewControlTypes.ORTS_NUMBER_OF_AXES_DISPLAY_TENS: + { + data = (CruiseControl.SelectedNumberOfAxles / 10) % 10; + break; + } + case CABViewControlTypes.ORTS_NUMBER_OF_AXES_DISPLAY_HUNDREDS: + { + data = (CruiseControl.SelectedNumberOfAxles / 100) % 10; + break; + } + case CABViewControlTypes.ORTS_TRAIN_LENGTH_METERS: + { + data = CruiseControl.TrainLengthMeters; + break; + } + case CABViewControlTypes.ORTS_REMAINING_TRAIN_LENGHT_SPEED_RESTRICTED: + { + if (CruiseControl.RemainingTrainLengthToPassRestrictedZone == 0) + data = 0; + else + data = CruiseControl.TrainLengthMeters - CruiseControl.RemainingTrainLengthToPassRestrictedZone; + break; + } + case CABViewControlTypes.ORTS_REMAINING_TRAIN_LENGTH_PERCENT: + { + if (CruiseControl.SpeedRegMode != CruiseControl.SpeedRegulatorMode.Auto) + { + data = 0; + break; + } + if (CruiseControl.TrainLengthMeters > 0 && CruiseControl.RemainingTrainLengthToPassRestrictedZone > 0) + { + data = (((float)CruiseControl.TrainLengthMeters - (float)CruiseControl.RemainingTrainLengthToPassRestrictedZone) / (float)CruiseControl.TrainLengthMeters) * 100; + } + break; + } + case CABViewControlTypes.ORTS_MOTIVE_FORCE: + { + data = FilteredMotiveForceN; + break; + } + case CABViewControlTypes.ORTS_MOTIVE_FORCE_KILONEWTON: + { + data = (float)Math.Round(FilteredMotiveForceN / 1000, 0); + break; + } + case CABViewControlTypes.ORTS_MAXIMUM_FORCE: + { + data = MaxForceN; + break; + } + case CABViewControlTypes.ORTS_FORCE_IN_PERCENT_THROTTLE_AND_DYNAMIC_BRAKE: + { + if (CruiseControl.Equipped && CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) + { + data = CruiseControl.ForceThrottleAndDynamicBrake; + if (DynamicBrakePercent > 0 && data > -DynamicBrakePercent) data = -DynamicBrakePercent; + } + else + { + if (ThrottlePercent > 0) + { + data = ThrottlePercent; + } + else if (DynamicBrakePercent > 0 && AbsSpeedMpS > 0) + { + data = -DynamicBrakePercent; + } + else data = 0; + } + break; + } + case CABViewControlTypes.ORTS_TRAIN_TYPE_PAX_OR_CARGO: + { + data = (int)SelectedTrainType; + break; + } + case CABViewControlTypes.ORTS_CONTROLLER_VOLTAGE: + { + data = CruiseControl.controllerVolts; + break; + } + case CABViewControlTypes.ORTS_AMPERS_BY_CONTROLLER_VOLTAGE: + { + if (CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) + { + if (CruiseControl.controllerVolts < 0) data = -CruiseControl.controllerVolts / 100 * (MaxCurrentA * 0.8f); + else data = CruiseControl.controllerVolts / 100 * (MaxCurrentA * 0.8f); + if (data == 0 && DynamicBrakePercent > 0 && AbsSpeedMpS > 0) data = DynamicBrakePercent / 100 * (MaxCurrentA * 0.8f); + } + else + { + if (DynamicBrakePercent > 0 && AbsSpeedMpS > 0) data = DynamicBrakePercent / 200 * (MaxCurrentA * 0.8f); + else data = ThrottlePercent / 100 * (MaxCurrentA * 0.8f); + } + CruiseControl.Ampers = data; + break; + } + case CABViewControlTypes.ORTS_ODOMETER: + { + data = cvc.Units == CABViewControlUnits.KILOMETRES ? float.Parse(Math.Round(OdometerM / 1000, 0).ToString()) : OdometerM; + break; + } + case CABViewControlTypes.ORTS_CC_SELECT_SPEED: + { + data = SelectingSpeedPressed ? 1 : 0; + break; + } default: { data = 0; diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs new file mode 100644 index 0000000000..703f6655a9 --- /dev/null +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs @@ -0,0 +1,1366 @@ +// COPYRIGHT 2013 - 2021 by the Open Rails project. +// +// This file is part of Open Rails. +// +// Open Rails is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Open Rails is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Open Rails. If not, see . + +using Orts.Parsers.Msts; +using ORTS.Common; +using System; +using System.Collections.Generic; +using System.IO; + +namespace Orts.Simulation.RollingStocks.SubSystems +{ + public class CruiseControl + + { + public CruiseControl(MSTSLocomotive locomotive) + { + Locomotive = locomotive; + } + MSTSLocomotive Locomotive; + Simulator Simulator; + + public bool Equipped = false; + public bool SpeedRegulatorMaxForcePercentUnits = false; + public float SpeedRegulatorMaxForceSteps = 0; + public bool MaxForceSetSingleStep = false; + public bool MaxForceKeepSelectedStepWhenManualModeSet = false; + public List SpeedRegulatorOptions = new List(); + public SpeedRegulatorMode SpeedRegMode = SpeedRegulatorMode.Manual; + public SpeedSelectorMode SpeedSelMode = SpeedSelectorMode.Neutral; + public float SelectedMaxAccelerationPercent = 0; + public float SelectedMaxAccelerationStep = 0; + public float SelectedSpeedMpS = 0; + public int SelectedNumberOfAxles = 0; + public float SpeedRegulatorNominalSpeedStepMpS = 0; + public float MaxAccelerationMpSS = 0; + public float MaxDecelerationMpSS = 0; + public bool UseThrottle = false; + public bool AntiWheelSpinEquipped = false; + public float DynamicBrakeMaxForceAtSelectorStep = 0; + public float DynamicBrakeDescentCoefficient = 0; + public float DeltaCoefficient = 0; + public float ForceThrottleAndDynamicBrake = 0; + protected float maxForceN = 0; + protected float trainBrakePercent = 0; + protected float trainLength = 0; + public int TrainLengthMeters = 0; + public int RemainingTrainLengthToPassRestrictedZone = 0; + public bool RestrictedSpeedActive = false; + public float CurrentSelectedSpeedMpS = 0; + protected float nextSelectedSpeedMps = 0; + protected float restrictedRegionTravelledDistance = 0; + protected float currentThrottlePercent = 0; + protected double clockTime = 0; + protected bool dynamicBrakeSetToZero = false; + public float StartReducingSpeedDelta = 0.5f; + public float ThrottleIncreaseSpeed = 0.1f; + public float ThrottleDecreaseSpeed = 0.2f; + public bool Battery = false; + public bool DynamicBrakePriority = false; + public List ForceStepsThrottleTable = new List(); + public List AccelerationTable = new List(); + public enum SpeedRegulatorMode { Manual, Auto, Testing, AVV } + public enum SpeedSelectorMode { Parking, Neutral, On, Start } + protected float absMaxForceN = 0; + protected float brakePercent = 0; + public float DynamicBrakeIncreaseSpeed = 0; + public float DynamicBrakeDecreaseSpeed = 0; + public uint MinimumMetersToPass = 19; + protected float relativeAcceleration; + public float AccelerationRampMaxMpSSS = 0.7f; + public float AccelerationDemandMpSS; + public float AccelerationRampMinMpSSS = 0.01f; + public float ThrottleFullRangeIncreaseTimeSeconds = 0; + public float ThrottleFullRangeDecreaseTimeSeconds = 0; + public float DynamicBrakeFullRangeIncreaseTimeSeconds; + public float DynamicBrakeFullRangeDecreaseTimeSeconds; + public float ParkingBrakeEngageSpeed = 0; + public float ParkingBrakePercent = 0; + public bool SkipThrottleDisplay = false; + public bool DisableZeroForceStep = false; + public bool UseThrottleAsSpeedSelector = false; + public float Ampers = 0; + public bool ContinuousSpeedIncreasing = false; + public bool ContinuousSpeedDecreasing = false; + public float PowerBreakoutAmpers = 0; + public float PowerBreakoutSpeedDelta = 0; + public float PowerResumeSpeedDelta = 0; + public float PowerReductionDelayPaxTrain = 0; + public float PowerReductionDelayCargoTrain = 0; + public float PowerReductionValue = 100; + public float MaxPowerThreshold = 0; + public float SafeSpeedForAutomaticOperationMpS = 0; + + public float AccelerationRampMpSSS + { + get + { + if ((Locomotive.Train.MassKg > 0f) && (Locomotive.MassKG > 0)) + { + float accelerationRampMpSS = AccelerationRampMaxMpSSS / (Locomotive.Train.MassKg / Locomotive.MassKG); + accelerationRampMpSS = accelerationRampMpSS > AccelerationRampMaxMpSSS ? AccelerationRampMaxMpSSS : accelerationRampMpSS; + accelerationRampMpSS = accelerationRampMpSS < AccelerationRampMinMpSSS ? AccelerationRampMinMpSSS : accelerationRampMpSS; + return accelerationRampMpSS; + } + else + return AccelerationRampMaxMpSSS; + + + } + } + + public void Initialize() + { + Simulator = Locomotive.Simulator; + clockTime = Simulator.ClockTime * 100; + } + + public void Update(float elapsedClockSeconds, float AbsWheelSpeedMpS) + { + if (maxForceIncreasing) SpeedRegulatorMaxForceIncrease(); + if (maxForceDecreasing) SpeedRegulatorMaxForceDecrease(); + if (SpeedRegMode == SpeedRegulatorMode.Manual) + return; + + if (absMaxForceN == 0) absMaxForceN = Locomotive.MaxForceN; + + if (selectedSpeedIncreasing) SpeedRegulatorSelectedSpeedIncrease(); + if (selectedSpeedDecreasing) SpeedRegulatorSelectedSpeedDecrease(); + + if (Locomotive.DynamicBrakePercent > 0) + if (Locomotive.DynamicBrakePercent > 100) + Locomotive.DynamicBrakePercent = 100; + ForceThrottleAndDynamicBrake = Locomotive.DynamicBrakePercent; + + UpdateMotiveForce(elapsedClockSeconds, AbsWheelSpeedMpS); + } + + public void Save(BinaryWriter outf) + { + outf.Write(this.AntiWheelSpinEquipped); + outf.Write(this.applyingPneumaticBrake); + outf.Write(this.Battery); + outf.Write(this.brakeIncreasing); + outf.Write(this.clockTime); + outf.Write(this.controllerTime); + outf.Write(this.CurrentSelectedSpeedMpS); + outf.Write(this.currentThrottlePercent); + outf.Write(this.DeltaCoefficient); + outf.Write(this.DynamicBrakeDescentCoefficient); + outf.Write(this.DynamicBrakeMaxForceAtSelectorStep); + outf.Write(this.dynamicBrakeSetToZero); + outf.Write(this.fromAcceleration); + outf.Write(this.MaxAccelerationMpSS); + outf.Write(this.MaxDecelerationMpSS); + outf.Write(this.maxForceDecreasing); + outf.Write(this.maxForceIncreasing); + outf.Write(this.maxForceN); + outf.Write(this.nextSelectedSpeedMps); + outf.Write(this.restrictedRegionTravelledDistance); + outf.Write(this.RestrictedSpeedActive); + outf.Write(this.SelectedMaxAccelerationPercent); + outf.Write(this.SelectedMaxAccelerationStep); + outf.Write(this.SelectedMaxAccelerationStep); + outf.Write(this.SelectedNumberOfAxles); + outf.Write(this.SelectedSpeedMpS); + outf.Write((int)this.SpeedRegMode); + outf.Write(this.SpeedRegulatorMaxForcePercentUnits); + outf.Write(this.SpeedRegulatorMaxForceSteps); + outf.Write(this.SpeedRegulatorNominalSpeedStepMpS); + outf.Write((int)this.SpeedSelMode); + outf.Write(this.StartReducingSpeedDelta); + outf.Write(this.ThrottleDecreaseSpeed); + outf.Write(this.ThrottleIncreaseSpeed); + outf.Write(this.throttleIsZero); + outf.Write(this.trainBrakePercent); + outf.Write(this.trainLength); + outf.Write(this.UseThrottle); + outf.Write(this._AccelerationMpSS); + outf.Write(this.TrainLengthMeters); + } + + public void Restore(BinaryReader inf) + { + AntiWheelSpinEquipped = inf.ReadBoolean(); + applyingPneumaticBrake = inf.ReadBoolean(); + Battery = inf.ReadBoolean(); + brakeIncreasing = inf.ReadBoolean(); + clockTime = inf.ReadDouble(); + controllerTime = inf.ReadSingle(); + CurrentSelectedSpeedMpS = inf.ReadSingle(); + currentThrottlePercent = inf.ReadSingle(); + float deltaCoefficient = inf.ReadSingle(); + float dynamicBrakeDescentCoefficient = inf.ReadSingle(); + float dynamicBrakeMaxForceAtSelectorStep = inf.ReadSingle(); + dynamicBrakeSetToZero = inf.ReadBoolean(); + fromAcceleration = inf.ReadSingle(); + float maxAccelerationMpSS = inf.ReadSingle(); + float maxDecelerationMpSS = inf.ReadSingle(); + maxForceDecreasing = inf.ReadBoolean(); + maxForceIncreasing = inf.ReadBoolean(); + maxForceN = inf.ReadSingle(); + nextSelectedSpeedMps = inf.ReadSingle(); + restrictedRegionTravelledDistance = inf.ReadSingle(); + RestrictedSpeedActive = inf.ReadBoolean(); + SelectedMaxAccelerationPercent = inf.ReadSingle(); + SelectedMaxAccelerationStep = inf.ReadSingle(); + SelectedMaxAccelerationStep = inf.ReadSingle(); + SelectedNumberOfAxles = inf.ReadInt32(); + SelectedSpeedMpS = inf.ReadSingle(); + int fSpeedRegMode = inf.ReadInt32(); + SpeedRegMode = (SpeedRegulatorMode)fSpeedRegMode; + SpeedRegulatorMaxForcePercentUnits = inf.ReadBoolean(); + SpeedRegulatorMaxForceSteps = inf.ReadSingle(); + SpeedRegulatorNominalSpeedStepMpS = inf.ReadSingle(); + int fSpeedSelMode = inf.ReadInt32(); + SpeedSelMode = (SpeedSelectorMode)fSpeedSelMode; + float nill = inf.ReadSingle(); + ThrottleDecreaseSpeed = inf.ReadSingle(); + ThrottleIncreaseSpeed = inf.ReadSingle(); + throttleIsZero = inf.ReadBoolean(); + trainBrakePercent = inf.ReadSingle(); + trainLength = inf.ReadSingle(); + UseThrottle = inf.ReadBoolean(); + _AccelerationMpSS = inf.ReadSingle(); + TrainLengthMeters = inf.ReadInt32(); + } + + public void SpeedRegulatorModeIncrease() + { + if (!Locomotive.IsPlayerTrain) return; + Locomotive.SignalEvent(Common.Event.CruiseControlSpeedRegulator); + SpeedRegulatorMode previousMode = SpeedRegMode; + if (!Equipped) return; + if (SpeedRegMode == SpeedRegulatorMode.Testing) return; + bool test = false; + while (!test) + { + SpeedRegMode++; + switch (SpeedRegMode) + { + case SpeedRegulatorMode.Auto: + { + if (SpeedRegulatorOptions.Contains("regulatorauto")) test = true; + SelectedSpeedMpS = Locomotive.AbsSpeedMpS; + break; + } + case SpeedRegulatorMode.Testing: if (SpeedRegulatorOptions.Contains("regulatortest")) test = true; break; + } + if (!test && SpeedRegMode == SpeedRegulatorMode.Testing) // if we're here, then it means no higher option, return to previous state and get out + { + SpeedRegMode = previousMode; + return; + } + } + Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Speed regulator mode changed to") + " " + Simulator.Catalog.GetString(SpeedRegMode.ToString())); + } + public void SpeedRegulatorModeDecrease() + { + Locomotive.SignalEvent(Common.Event.CruiseControlSpeedRegulator); + if (!Equipped) return; + if (SpeedRegMode == SpeedRegulatorMode.Manual) return; + bool test = false; + while (!test) + { + SpeedRegMode--; + switch (SpeedRegMode) + { + case SpeedRegulatorMode.Auto: if (SpeedRegulatorOptions.Contains("regulatorauto")) test = true; break; + case SpeedRegulatorMode.Manual: + { + Locomotive.SetThrottlePercent(0); + currentThrottlePercent = 0; + if (SpeedRegulatorOptions.Contains("regulatormanual")) test = true; + SelectedSpeedMpS = 0; + break; + } + } + if (!test && SpeedRegMode == SpeedRegulatorMode.Manual) + return; + } + Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Speed regulator mode changed to") + " " + Simulator.Catalog.GetString(SpeedRegMode.ToString())); + } + public void SpeedSelectorModeStartIncrease() + { + Locomotive.SignalEvent(Common.Event.CruiseControlSpeedSelector); + if (!Equipped) return; + if (SpeedSelMode == SpeedSelectorMode.Start) return; + bool test = false; + while (!test) + { + SpeedSelMode++; + if (SpeedSelMode != SpeedSelectorMode.Parking && !Locomotive.EngineBrakePriority) Locomotive.SetEngineBrakePercent(0); + switch (SpeedSelMode) + { + case SpeedSelectorMode.Neutral: if (SpeedRegulatorOptions.Contains("selectorneutral")) test = true; break; + case SpeedSelectorMode.On: if (SpeedRegulatorOptions.Contains("selectoron")) test = true; break; + case SpeedSelectorMode.Start: if (SpeedRegulatorOptions.Contains("selectorstart")) test = true; break; + } + if (!test && SpeedSelMode == SpeedSelectorMode.Start) + return; + } + Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Speed selector mode changed to") + " " + Simulator.Catalog.GetString(SpeedSelMode.ToString())); + } + public void SpeedSelectorModeStopIncrease() + { + Locomotive.SignalEvent(Common.Event.CruiseControlSpeedSelector); + //Locomotive.Mirel.ResetVigilance(); + if (!Equipped) return; + if (SpeedSelMode == SpeedSelectorMode.Start) + { + bool test = false; + while (!test) + { + SpeedSelMode--; + switch (SpeedSelMode) + { + case SpeedSelectorMode.On: if (SpeedRegulatorOptions.Contains("selectoron")) test = true; break; + case SpeedSelectorMode.Neutral: if (SpeedRegulatorOptions.Contains("selectorneutral")) test = true; break; + case SpeedSelectorMode.Parking: if (SpeedRegulatorOptions.Contains("selectorparking")) test = true; break; + } + if (!test && SpeedSelMode == SpeedSelectorMode.Parking && !Locomotive.EngineBrakePriority) + return; + } + } + Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Speed selector mode changed to") + " " + Simulator.Catalog.GetString(SpeedSelMode.ToString())); + } + public void SpeedSelectorModeDecrease() + { + Locomotive.SignalEvent(Common.Event.CruiseControlSpeedSelector); + SpeedSelectorMode previousMode = SpeedSelMode; + if (!Equipped) return; + if (SpeedSelMode == SpeedSelectorMode.Parking && !Locomotive.EngineBrakePriority) return; + bool test = false; + while (!test) + { + SpeedSelMode--; + switch (SpeedSelMode) + { + case SpeedSelectorMode.On: if (SpeedRegulatorOptions.Contains("selectoron")) test = true; break; + case SpeedSelectorMode.Neutral: if (SpeedRegulatorOptions.Contains("selectorneutral")) test = true; break; + case SpeedSelectorMode.Parking: if (SpeedRegulatorOptions.Contains("selectorparking")) test = true; break; + } + if (!test && SpeedSelMode == SpeedSelectorMode.Parking && !Locomotive.EngineBrakePriority) + { + SpeedSelMode = previousMode; + return; + } + } + Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Speed selector mode changed to") + " " + Simulator.Catalog.GetString(SpeedSelMode.ToString())); + } + + bool maxForceIncreasing = false; + public void SpeedRegulatorMaxForceStartIncrease() + { + maxForceIncreasing = true; + } + public void SpeedRegulatorMaxForceStopIncrease() + { + maxForceIncreasing = false; + } + protected void SpeedRegulatorMaxForceIncrease() + { + Locomotive.SignalEvent(Common.Event.CruiseControlMaxForce); + if (MaxForceSetSingleStep) maxForceIncreasing = false; + if (SelectedMaxAccelerationStep == 0.5f) SelectedMaxAccelerationStep = 0; + if (!Equipped) return; + if (SpeedRegulatorMaxForcePercentUnits) + { + if (SelectedMaxAccelerationPercent == 100) + return; + SelectedMaxAccelerationPercent += 1f; + Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Speed regulator max acceleration percent changed to") + " " + Simulator.Catalog.GetString(SelectedMaxAccelerationPercent.ToString()) + "%"); + } + else + { + if (SelectedMaxAccelerationStep == SpeedRegulatorMaxForceSteps) + return; + SelectedMaxAccelerationStep++; + Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Speed regulator max acceleration changed to") + " " + Simulator.Catalog.GetString(SelectedMaxAccelerationStep.ToString())); + } + } + + protected bool maxForceDecreasing = false; + public void SpeedRegulatorMaxForceStartDecrease() + { + maxForceDecreasing = true; + } + public void SpeedRegulatorMaxForceStopDecrease() + { + maxForceDecreasing = false; + } + protected void SpeedRegulatorMaxForceDecrease() + { + Locomotive.SignalEvent(Common.Event.CruiseControlMaxForce); + if (MaxForceSetSingleStep) maxForceDecreasing = false; + if (!Equipped) return; + if (DisableZeroForceStep) + { + if (SelectedMaxAccelerationStep <= 1) return; + } + else + { + if (SelectedMaxAccelerationStep <= 0) return; + } + SelectedMaxAccelerationStep--; + Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Speed regulator max acceleration changed to") + " " + Simulator.Catalog.GetString(SelectedMaxAccelerationStep.ToString())); + } + + protected bool selectedSpeedIncreasing = false; + public void SpeedRegulatorSelectedSpeedStartIncrease() + { + if (!UseThrottleAsSpeedSelector) + selectedSpeedIncreasing = true; + else + SpeedSelectorModeStartIncrease(); + } + public void SpeedRegulatorSelectedSpeedStopIncrease() + { + if (!UseThrottleAsSpeedSelector) + selectedSpeedIncreasing = false; + else + SpeedSelectorModeStopIncrease(); + } + public void SpeedRegulatorSelectedSpeedIncrease() + { + if (!Equipped) return; + SelectedSpeedMpS += SpeedRegulatorNominalSpeedStepMpS; + if (SelectedSpeedMpS > Locomotive.MaxSpeedMpS) + SelectedSpeedMpS = Locomotive.MaxSpeedMpS; + Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Selected speed changed to ") + Math.Round(MpS.FromMpS(SelectedSpeedMpS, true), 0, MidpointRounding.AwayFromZero).ToString() + " km/h"); + } + + protected bool selectedSpeedDecreasing = false; + public void SpeedRegulatorSelectedSpeedStartDecrease() + { + if (!UseThrottleAsSpeedSelector) + selectedSpeedDecreasing = true; + else + SpeedSelectorModeDecrease(); + } + public void SpeedRegulatorSelectedSpeedStopDecrease() + { + selectedSpeedDecreasing = false; + } + public void SpeedRegulatorSelectedSpeedDecrease() + { + if (!Equipped) return; + SelectedSpeedMpS -= SpeedRegulatorNominalSpeedStepMpS; + if (SelectedSpeedMpS < 0) + SelectedSpeedMpS = 0f; + Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Selected speed changed to ") + Math.Round(MpS.FromMpS(SelectedSpeedMpS, true), 0, MidpointRounding.AwayFromZero).ToString() + " km/h"); + } + public void NumerOfAxlesIncrease() + { + NumerOfAxlesIncrease(1); + } + public void NumerOfAxlesIncrease(int ByAmount) + { + SelectedNumberOfAxles += ByAmount; + trainLength = SelectedNumberOfAxles * 6.6f; + TrainLengthMeters = (int)Math.Round(trainLength + 0.5, 0); + Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Number of axles increased to ") + SelectedNumberOfAxles.ToString()); + } + public void NumberOfAxlesDecrease() + { + NumberOfAxlesDecrease(1); + } + public void NumberOfAxlesDecrease(int ByAmount) + { + if ((SelectedNumberOfAxles - ByAmount) < 1) return; + SelectedNumberOfAxles -= ByAmount; + trainLength = SelectedNumberOfAxles * 6.6f; + TrainLengthMeters = (int)Math.Round(trainLength + 0.5, 0); + Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Number of axles decreased to ") + SelectedNumberOfAxles.ToString()); + } + public void ActivateRestrictedSpeedZone() + { + RemainingTrainLengthToPassRestrictedZone = TrainLengthMeters; + if (!RestrictedSpeedActive) + { + restrictedRegionTravelledDistance = Simulator.PlayerLocomotive.Train.DistanceTravelledM; + CurrentSelectedSpeedMpS = SelectedSpeedMpS; + RestrictedSpeedActive = true; + } + Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Speed restricted zone active.")); + } + + public virtual void CheckRestrictedSpeedZone() + { + RemainingTrainLengthToPassRestrictedZone = (int)Math.Round((Simulator.PlayerLocomotive.Train.DistanceTravelledM - restrictedRegionTravelledDistance)); + if (RemainingTrainLengthToPassRestrictedZone < 0) RemainingTrainLengthToPassRestrictedZone = 0; + if ((Simulator.PlayerLocomotive.Train.DistanceTravelledM - restrictedRegionTravelledDistance) >= trainLength) + { + RestrictedSpeedActive = false; + Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Speed restricted zone off.")); + Locomotive.SignalEvent(Common.Event.Alert); + } + } + + public void SetSpeed(float SpeedKpH) + { + Locomotive.SignalEvent(Common.Event.Alert1); + if (!Equipped) return; + SelectedSpeedMpS = MpS.FromKpH(SpeedKpH); + if (SelectedSpeedMpS > Locomotive.MaxSpeedMpS) + SelectedSpeedMpS = Locomotive.MaxSpeedMpS; + Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Selected speed set to ") + SpeedKpH.ToString()); + } + + protected List playerNotDriveableTrainLocomotives = new List(); + float _AccelerationMpSS = 0; + protected bool throttleIsZero = false; + protected bool brakeIncreasing = false; + protected float controllerTime = 0; + protected float fromAcceleration = 0; + protected bool applyingPneumaticBrake = false; + protected bool firstIteration = true; + protected float previousMotiveForce = 0; + protected float addPowerTimeCount = 0; + public float controllerVolts = 0; + protected float throttleChangeTime = 0; + protected bool breakout = false; + protected float timeFromEngineMoved = 0; + protected bool reducingForce = false; + protected bool canAddForce = true; + List concurrentAccelerationList = new List(); + public float TrainElevation = 0; + protected float skidSpeedDegratation = 0; + + protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWheelSpeedMpS) + { + if (DynamicBrakeFullRangeIncreaseTimeSeconds == 0) + DynamicBrakeFullRangeIncreaseTimeSeconds = 3; + if (DynamicBrakeFullRangeDecreaseTimeSeconds == 0) + DynamicBrakeFullRangeDecreaseTimeSeconds = 3; + float speedDiff = AbsWheelSpeedMpS - Locomotive.AbsSpeedMpS; + float newThrotte = 0; + // calculate new max force if MaxPowerThreshold is set + if (MaxPowerThreshold > 0) + { + float currentSpeed = MpS.ToKpH(AbsWheelSpeedMpS); + float percentComplete = (int)Math.Round((double)(100 * currentSpeed) / MaxPowerThreshold); + if (percentComplete > 100) + percentComplete = 100; + newThrotte = percentComplete; + } + + int count = 0; + TrainElevation = 0; + foreach (TrainCar tc in Locomotive.Train.Cars) + { + count++; + TrainElevation += tc.Flipped ? tc.CurrentElevationPercent : -tc.CurrentElevationPercent; + } + TrainElevation = TrainElevation / count; + + if (SpeedSelMode == SpeedSelectorMode.On || SpeedSelMode == SpeedSelectorMode.Start) + { + canAddForce = true; + } + else + { + canAddForce = false; + timeFromEngineMoved = 0; + reducingForce = true; + } + if (canAddForce) + { + if (Locomotive.AbsSpeedMpS == 0) + { + timeFromEngineMoved = 0; + reducingForce = true; + } + else if (reducingForce) + { + timeFromEngineMoved += elapsedClockSeconds; + float timeToReduce = Locomotive.SelectedTrainType == MSTSLocomotive.TrainType.Pax ? PowerReductionDelayPaxTrain : PowerReductionDelayCargoTrain; + if (timeFromEngineMoved > timeToReduce) + reducingForce = false; + } + } + if (Bar.FromPSI(Locomotive.BrakeSystem.BrakeLine1PressurePSI) < 4.98) + { + canAddForce = false; + reducingForce = true; + timeFromEngineMoved = 0; + maxForceN = 0; + if (controllerVolts > 0) + controllerVolts = 0; + Ampers = 0; + Locomotive.SetThrottlePercent(0); + return; + } + else if (Bar.FromPSI(Locomotive.BrakeSystem.BrakeLine1PressurePSI) > 4.7) + { + canAddForce = true; + } + if (SpeedRegulatorOptions.Contains("engageforceonnonzerospeed") && SelectedSpeedMpS > 0) + { + SpeedSelMode = SpeedSelectorMode.On; + SpeedRegMode = SpeedRegulatorMode.Auto; + SkipThrottleDisplay = true; + } + if (SpeedRegulatorOptions.Contains("engageforceonnonzerospeed") && SelectedSpeedMpS == 0) return; + + float t = 0; + if (SpeedRegMode == SpeedRegulatorMode.Manual) DynamicBrakePriority = false; + + if (RestrictedSpeedActive) + CheckRestrictedSpeedZone(); + if (DynamicBrakePriority) + { + Locomotive.SetThrottlePercent(0); + ForceThrottleAndDynamicBrake = -Locomotive.DynamicBrakePercent; + return; + } + + if (firstIteration) // if this is exetuted the first time, let's check all other than player engines in the consist, and record them for further throttle manipulation + { + foreach (TrainCar tc in Locomotive.Train.Cars) + { + if (tc.GetType() == typeof(MSTSLocomotive) || tc.GetType() == typeof(MSTSDieselLocomotive) || tc.GetType() == typeof(MSTSElectricLocomotive)) + { + if (tc != Locomotive) + { + try + { + playerNotDriveableTrainLocomotives.Add((MSTSLocomotive)tc); + } + catch { } + } + } + } + firstIteration = false; + } + + if (SpeedRegMode == SpeedRegulatorMode.Auto) + { + if (SpeedSelMode == SpeedSelectorMode.Parking && !Locomotive.EngineBrakePriority) + { + if (Locomotive.DynamicBrakePercent > 0) + { + if (AbsWheelSpeedMpS == 0) + { + Locomotive.SetDynamicBrakePercent(0); + Locomotive.DynamicBrakeChangeActiveState(false); + } + } + if (!UseThrottle) Locomotive.SetThrottlePercent(0); + throttleIsZero = true; + + if (AbsWheelSpeedMpS < MpS.FromKpH(ParkingBrakeEngageSpeed)) + Locomotive.SetEngineBrakePercent(ParkingBrakePercent); + } + else if (SpeedSelMode == SpeedSelectorMode.Neutral || SpeedSelMode < SpeedSelectorMode.Start && !SpeedRegulatorOptions.Contains("startfromzero") && AbsWheelSpeedMpS < SafeSpeedForAutomaticOperationMpS) + { + if (controllerVolts > 0) + { + float step = 100 / ThrottleFullRangeIncreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts -= step; + if (controllerVolts < 0) controllerVolts = 0; + if (controllerVolts > 0 && controllerVolts < 0.1) controllerVolts = 0; + } + + float delta = 0; + if (!RestrictedSpeedActive) + delta = SelectedSpeedMpS - AbsWheelSpeedMpS; + else + delta = CurrentSelectedSpeedMpS - AbsWheelSpeedMpS; + + if (delta > 0) + { + if (controllerVolts < -0.1) + { + float step = 100 / ThrottleFullRangeDecreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts += step; + } + else if (controllerVolts > 0.1) + { + + float step = 100 / ThrottleFullRangeIncreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts -= step; + } + else + { + controllerVolts = 0; + } + } + + if (delta < 0) // start braking + { + if (maxForceN > 0) + { + if (controllerVolts > 0) + { + float step = 100 / ThrottleFullRangeDecreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts -= step; + } + } + else + { + if (Locomotive.DynamicBrakeAvailable) + { + delta = 0; + if (!RestrictedSpeedActive) + delta = (SelectedSpeedMpS + (TrainElevation < -0.01 ? TrainElevation * (SelectedNumberOfAxles / 40) : 0)) - AbsWheelSpeedMpS; + else + delta = (CurrentSelectedSpeedMpS + (TrainElevation < -0.01 ? TrainElevation * (SelectedNumberOfAxles / 40) : 0)) - AbsWheelSpeedMpS; + + relativeAcceleration = (float)-Math.Sqrt(-StartReducingSpeedDelta * delta); + AccelerationDemandMpSS = (float)-Math.Sqrt(-StartReducingSpeedDelta * AccelerationRampMpSSS * delta); + if (maxForceN > 0) + { + if (controllerVolts > 0) + { + float step = 100 / ThrottleFullRangeDecreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts -= step; + } + } + if (maxForceN == 0) + { + if (!UseThrottle) Locomotive.SetThrottlePercent(0); + if (relativeAcceleration < -1) relativeAcceleration = -1; + if (Locomotive.DynamicBrakePercent < -(AccelerationDemandMpSS * 100) && AccelerationDemandMpSS < -0.05f) + { + if (controllerVolts > -100) + { + float step = 100 / DynamicBrakeFullRangeIncreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts -= step; + } + } + if (Locomotive.DynamicBrakePercent > -((AccelerationDemandMpSS - 0.05f) * 100)) + { + if (controllerVolts < 0) + { + float step = 100 / DynamicBrakeFullRangeDecreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts += step; + } + } + } + } + else // use TrainBrake + { + if (delta > -0.1) + { + if (!UseThrottle) + Locomotive.SetThrottlePercent(100); + throttleIsZero = false; + maxForceN = 0; + } + else if (delta > -1) + { + if (!UseThrottle) + Locomotive.SetThrottlePercent(0); + throttleIsZero = true; + + brakePercent = 10 + (-delta * 10); + } + else + { + Locomotive.TractiveForceN = 0; + if (!UseThrottle) + Locomotive.SetThrottlePercent(0); + throttleIsZero = true; + + if (_AccelerationMpSS > -MaxDecelerationMpSS) + brakePercent += 0.5f; + else if (_AccelerationMpSS < -MaxDecelerationMpSS) + brakePercent -= 1; + if (brakePercent > 100) + brakePercent = 100; + } + } + } + } + else + { + if (Locomotive.DynamicBrakeAvailable) + { + if (Locomotive.DynamicBrakePercent > 0) + { + if (controllerVolts < 0) + { + float step = 100 / DynamicBrakeFullRangeDecreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts += step; + } + } + } + } + } + + if ((AbsWheelSpeedMpS > SafeSpeedForAutomaticOperationMpS || SpeedSelMode == SpeedSelectorMode.Start || SpeedRegulatorOptions.Contains("startfromzero")) && (SpeedSelMode != SpeedSelectorMode.Neutral && SpeedSelMode != SpeedSelectorMode.Parking)) + { + float delta = 0; + if (!RestrictedSpeedActive) + delta = SelectedSpeedMpS - AbsWheelSpeedMpS; + else + delta = CurrentSelectedSpeedMpS - AbsWheelSpeedMpS; + + if (delta > 0.0f) + { + if (Locomotive.DynamicBrakePercent > 0) + Locomotive.SetDynamicBrakePercent(0); + if (Locomotive.DynamicBrakePercent == 0 && Locomotive.DynamicBrake) Locomotive.DynamicBrakeChangeActiveState(false); + relativeAcceleration = (float)Math.Sqrt(AccelerationRampMaxMpSSS * delta); + float coeff = 1; + float speed = MpS.ToKpH(Locomotive.WheelSpeedMpS); + if (speed > 100) + { + coeff = (speed / 100) * 1.2f; + } + else + { + coeff = 1; + } + float numAxesCoeff = 0; + numAxesCoeff = (SelectedNumberOfAxles) / 3; + AccelerationDemandMpSS = (float)Math.Sqrt((StartReducingSpeedDelta + numAxesCoeff) * coeff * coeff * AccelerationRampMpSSS * (delta)); + } + else // start braking + { + if (controllerVolts > 0) + { + float step = 100 / ThrottleFullRangeDecreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts -= step; + if (controllerVolts < 0) controllerVolts = 0; + if (controllerVolts > 0 && controllerVolts < 0.1) controllerVolts = 0; + } + + delta = 0; + if (!RestrictedSpeedActive) + delta = (SelectedSpeedMpS + (TrainElevation < -0.01 ? TrainElevation * (SelectedNumberOfAxles / 40) : 0)) - AbsWheelSpeedMpS; + else + delta = (CurrentSelectedSpeedMpS + (TrainElevation < -0.01 ? TrainElevation * (SelectedNumberOfAxles / 40) : 0)) - AbsWheelSpeedMpS; + + if (delta > 0) + { + if (controllerVolts < -0.1) + { + float step = 100 / ThrottleFullRangeDecreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts += step; + } + else if (controllerVolts > 0.1) + { + + float step = 100 / ThrottleFullRangeIncreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts -= step; + } + else + { + controllerVolts = 0; + } + } + + if (delta < 0) // start braking + { + if (maxForceN > 0) + { + if (controllerVolts > 0) + { + float step = 100 / ThrottleFullRangeDecreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts -= step; + } + } + else + { + if (Locomotive.DynamicBrakeAvailable) + { + delta = 0; + if (!RestrictedSpeedActive) + delta = (SelectedSpeedMpS + (TrainElevation < -0.01 ? TrainElevation * (SelectedNumberOfAxles / 40) : 0)) - AbsWheelSpeedMpS; + else + delta = (CurrentSelectedSpeedMpS + (TrainElevation < -0.01 ? TrainElevation * (SelectedNumberOfAxles / 40) : 0)) - AbsWheelSpeedMpS; + + relativeAcceleration = (float)-Math.Sqrt(-StartReducingSpeedDelta * delta); + AccelerationDemandMpSS = (float)-Math.Sqrt(-StartReducingSpeedDelta * AccelerationRampMpSSS * delta); + if (maxForceN > 0) + { + if (controllerVolts > 0) + { + float step = 100 / ThrottleFullRangeDecreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts -= step; + } + } + if (maxForceN == 0) + { + if (!UseThrottle) Locomotive.SetThrottlePercent(0); + if (relativeAcceleration < -1) relativeAcceleration = -1; + if (Locomotive.DynamicBrakePercent < -(AccelerationDemandMpSS * 100) && AccelerationDemandMpSS < -0.05f) + { + if (controllerVolts > -100) + { + float step = 100 / DynamicBrakeFullRangeIncreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts -= step; + } + } + if (Locomotive.DynamicBrakePercent > -((AccelerationDemandMpSS - 0.05f) * 100)) + { + if (controllerVolts < 0) + { + float step = 100 / DynamicBrakeFullRangeDecreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts += step; + } + } + } + } + else // use TrainBrake + { + if (delta > -0.1) + { + if (!UseThrottle) + Locomotive.SetThrottlePercent(100); + throttleIsZero = false; + maxForceN = 0; + } + else if (delta > -1) + { + if (!UseThrottle) + Locomotive.SetThrottlePercent(0); + throttleIsZero = true; + + brakePercent = 10 + (-delta * 10); + } + else + { + Locomotive.TractiveForceN = 0; + if (!UseThrottle) + Locomotive.SetThrottlePercent(0); + throttleIsZero = true; + + if (_AccelerationMpSS > -MaxDecelerationMpSS) + brakePercent += 0.5f; + else if (_AccelerationMpSS < -MaxDecelerationMpSS) + brakePercent -= 1; + if (brakePercent > 100) + brakePercent = 100; + } + } + } + } + else + { + if (Locomotive.DynamicBrakeAvailable) + { + if (Locomotive.DynamicBrakePercent > 0) + { + if (controllerVolts < 0) + { + float step = 100 / DynamicBrakeFullRangeDecreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts += step; + } + } + } + } + } + if (relativeAcceleration > 1.0f) + relativeAcceleration = 1.0f; + + if ((SpeedSelMode == SpeedSelectorMode.On || SpeedSelMode == SpeedSelectorMode.Start) && delta > 0) + { + if (Locomotive.DynamicBrakePercent > 0) + { + if (controllerVolts <= 0) + { + float step = 100 / DynamicBrakeFullRangeDecreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts += step; + } + } + else + { + if (!UseThrottle) + { + Locomotive.SetThrottlePercent(100); + } + throttleIsZero = false; + } + } + float a = 0; + if (Locomotive.PowerOn && Locomotive.Direction != Direction.N) + { + if (Locomotive.DynamicBrakePercent < 0) + { + if (relativeAcceleration > 0) + { + if (ForceStepsThrottleTable.Count > 0) + { + t = ForceStepsThrottleTable[(int)SelectedMaxAccelerationStep - 1]; + if (AccelerationTable.Count > 0) + a = AccelerationTable[(int)SelectedMaxAccelerationStep - 1]; + } + else + t = SelectedMaxAccelerationStep; + if (t < newThrotte) + t = newThrotte; + t /= 100; + } + else + { + if (controllerVolts > 0) + { + float step = 100 / ThrottleFullRangeIncreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts -= step; + } + } + } + if (reducingForce) + { + if (t > PowerReductionValue / 100) + t = PowerReductionValue / 100; + } + // FIFO from accelerationDemand, 20 iterations + float smoothedAccelerationDemand = 0; + concurrentAccelerationList.Add(AccelerationDemandMpSS); + if (concurrentAccelerationList.Count > 20) + { + // calculate smooth + foreach (float accel in concurrentAccelerationList) + { + smoothedAccelerationDemand += accel; + } + smoothedAccelerationDemand = smoothedAccelerationDemand / concurrentAccelerationList.Count; + concurrentAccelerationList.RemoveAt(0); + } + if (t > smoothedAccelerationDemand) t = smoothedAccelerationDemand; + float demandedVolts = t * 100; + if (demandedVolts < PowerBreakoutAmpers) + breakout = true; + if (demandedVolts > 13.5f) + breakout = false; + if (UseThrottle) // not valid for diesel engines. + breakout = false; + if ((controllerVolts != demandedVolts) && delta > 0) + { + if (a > 0 && MpS.ToKpH(Locomotive.WheelSpeedMpS) > 5) + { + if (controllerVolts < demandedVolts && Locomotive.AccelerationMpSS < a - 0.02) + { + float step = 100 / ThrottleFullRangeIncreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts += step; + } + } + else + { + if (controllerVolts < demandedVolts) + { + float step = 100 / ThrottleFullRangeIncreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts += step; + } + } + if (a > 0 && MpS.ToKpH(Locomotive.WheelSpeedMpS) > 5) + { + if (controllerVolts > demandedVolts && Locomotive.AccelerationMpSS > a + 0.02) + { + float step = 100 / ThrottleFullRangeIncreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts -= step; + } + } + else + { + if (controllerVolts > demandedVolts) + { + float step = 100 / ThrottleFullRangeIncreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts -= step; + } + } + if (controllerVolts > demandedVolts && delta < 0.8) + { + float step = 100 / ThrottleFullRangeIncreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts -= step; + } + } + if (a > 0 && MpS.ToKpH(Locomotive.WheelSpeedMpS) > 5) + { + if ((a != Locomotive.AccelerationMpSS) && delta > 0.8) + { + if (Locomotive.AccelerationMpSS < a + 0.02) + { + float step = 100 / ThrottleFullRangeIncreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts += step; + } + if (Locomotive.AccelerationMpSS > a - 0.02) + { + float step = 100 / ThrottleFullRangeIncreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts -= step; + } + } + } + + if (UseThrottle) + { + //Simulator.Confirmer.Information(Locomotive.Train.AccelerationMpSpS.SmoothedValue.ToString()); + // + if (SpeedRegMode == SpeedRegulatorMode.AVV) + { + Physics.Train train = Locomotive.Train; + Signalling.ObjectItemInfo firstObject = null; + Signalling.ObjectItemInfo nextObject = null; + float nextSpeed = -1; + if (train.SignalObjectItems.Count > 0) + { + int i = 0; + firstObject = train.SignalObjectItems[i]; + firstObject.distance_to_train = train.GetObjectDistanceToTrain(firstObject); + if (firstObject.speed_passenger < 0) + { + while (nextSpeed < 0) + { + i++; + if (i + 1 > train.SignalObjectItems.Count) + break; + nextObject = train.SignalObjectItems[i]; + nextSpeed = nextObject.speed_passenger; + nextObject.distance_to_train = train.GetObjectDistanceToTrain(nextObject); + } + } + else + { + nextSpeed = firstObject.speed_passenger; + } + if (nextSpeed < 0 && Locomotive.TrainControlSystem.CurrentSpeedLimitMpS > 0) + nextSpeed = Locomotive.TrainControlSystem.CurrentSpeedLimitMpS; + } + + // 160 km/h = 2000m; 1KpH = 12,5m + if (firstObject != null) + { + float computedMaxSpeed = 0; + float computedMaxSpeed1 = 0; + if (nextObject != null) + { + if (firstObject.speed_passenger > -1 && firstObject.speed_passenger < nextObject.speed_passenger) + { + computedMaxSpeed = (firstObject.distance_to_train - 50) / 35; + computedMaxSpeed = MpS.FromKpH(computedMaxSpeed); + computedMaxSpeed1 = firstObject.distance_to_train / 35; + computedMaxSpeed1 = MpS.FromKpH(computedMaxSpeed1); + } + else + { + computedMaxSpeed = (nextObject.distance_to_train - 50) / 35; + computedMaxSpeed = MpS.FromKpH(computedMaxSpeed); + computedMaxSpeed1 = nextObject.distance_to_train / 35; + computedMaxSpeed1 = MpS.FromKpH(computedMaxSpeed1); + } + } + else + { + computedMaxSpeed = (firstObject.distance_to_train - 50) / 35; + computedMaxSpeed = MpS.FromKpH(computedMaxSpeed); + computedMaxSpeed1 = firstObject.distance_to_train / 35; + computedMaxSpeed1 = MpS.FromKpH(computedMaxSpeed1); + } + float maxSpeedAhead = firstObject.speed_passenger; + computedMaxSpeed = computedMaxSpeed + nextSpeed; + if ((computedMaxSpeed1 + nextSpeed) > Locomotive.TrainControlSystem.CurrentSpeedLimitMpS) computedMaxSpeed = Locomotive.TrainControlSystem.CurrentSpeedLimitMpS; + if ((computedMaxSpeed1 + nextSpeed) > Locomotive.TrainControlSystem.NextSpeedLimitMpS) computedMaxSpeed = Locomotive.TrainControlSystem.NextSpeedLimitMpS; + if (nextObject != null) + { + if (nextObject.speed_passenger < 0 && firstObject.speed_passenger < 0) + { + computedMaxSpeed = Locomotive.TrainControlSystem.CurrentSpeedLimitMpS; + } + } + if (computedMaxSpeed > Locomotive.MaxSpeedMpS) computedMaxSpeed = Locomotive.MaxSpeedMpS; + if (nextObject != null) + Simulator.Confirmer.MSG(MpS.ToKpH(firstObject.speed_passenger).ToString() + ", " + MpS.ToKpH(nextObject.speed_passenger).ToString() + ", " + MpS.ToKpH(Locomotive.TrainControlSystem.NextSpeedLimitMpS) + ", " + MpS.ToKpH(computedMaxSpeed)); + else + Simulator.Confirmer.MSG(MpS.ToKpH(firstObject.speed_passenger).ToString() + ", " + MpS.ToKpH(Locomotive.TrainControlSystem.NextSpeedLimitMpS) + ", " + MpS.ToKpH(computedMaxSpeed)); + if (SelectedSpeedMpS != computedMaxSpeed) + { + SelectedSpeedMpS = computedMaxSpeed; + Simulator.Confirmer.Information("AVV - Selected max speed changed to " + MpS.ToKpH(SelectedSpeedMpS) + "kph"); + } + } + } + if (controllerVolts > 0) + Locomotive.SetThrottlePercent(controllerVolts); + //Simulator.Confirmer.MSG(controllerVolts.ToString()); + } + } + } + else if (UseThrottle) + { + if (Locomotive.ThrottlePercent > 0) + { + float newValue = (Locomotive.ThrottlePercent - 1) / 100; + if (newValue < 0) + newValue = 0; + Locomotive.StartThrottleDecrease(newValue); + } + } + + if (Locomotive.WheelSpeedMpS == 0 && controllerVolts < 0) + controllerVolts = 0; + ForceThrottleAndDynamicBrake = controllerVolts; + + if (controllerVolts > 0) + { + if (speedDiff > 0.5) + { + skidSpeedDegratation += 0.05f; + } + else if (skidSpeedDegratation > 0) + { + skidSpeedDegratation -= 0.1f; + } + if (speedDiff < 0.4) + skidSpeedDegratation = 0; + controllerVolts -= skidSpeedDegratation; + if (breakout || Bar.FromPSI(Locomotive.BrakeSystem.BrakeLine1PressurePSI) < 4.98) + { + maxForceN = 0; + controllerVolts = 0; + Ampers = 0; + if (!UseThrottle) Locomotive.SetThrottlePercent(0); + } + else + { + if (Locomotive.ThrottlePercent < 100 && SpeedSelMode != SpeedSelectorMode.Parking && !UseThrottle) + { + Locomotive.SetThrottlePercent(100); + throttleIsZero = false; + } + if (Locomotive.DynamicBrakePercent > -1) + { + Locomotive.SetDynamicBrakePercent(0); + Locomotive.DynamicBrakeChangeActiveState(false); + } + + if (Locomotive.TractiveForceCurves != null && !UseThrottle) + { + maxForceN = Locomotive.TractiveForceCurves.Get(controllerVolts / 100, AbsWheelSpeedMpS) * (1 - Locomotive.PowerReduction); + } + else + { + if (Locomotive.TractiveForceCurves == null) + maxForceN = Locomotive.MaxForceN * (controllerVolts / 100); + else + maxForceN = Locomotive.TractiveForceCurves.Get(controllerVolts / 100, AbsWheelSpeedMpS) * (1 - Locomotive.PowerReduction); + } + } + } + else if (controllerVolts < 0) + { + if (maxForceN > 0) maxForceN = 0; + if (Locomotive.ThrottlePercent > 0) Locomotive.SetThrottlePercent(0); + if (Locomotive.DynamicBrakePercent <= 0) + { + string status = Locomotive.GetDynamicBrakeStatus(); + Locomotive.DynamicBrakeChangeActiveState(true); + } + Locomotive.SetDynamicBrakePercent(-controllerVolts); + Locomotive.DynamicBrakePercent = -controllerVolts; + } + else if (controllerVolts == 0) + { + if (!breakout) + { + + /*if (Locomotive.MultiPositionController.controllerPosition == Controllers.MultiPositionController.ControllerPosition.DynamicBrakeIncrease || Locomotive.MultiPositionController.controllerPosition == Controllers.MultiPositionController.ControllerPosition.DynamicBrakeIncreaseFast) + { + controllerVolts = -Locomotive.DynamicBrakePercent; + } + else + {*/ + if (maxForceN > 0) maxForceN = 0; + if (Locomotive.ThrottlePercent > 0 && !UseThrottle) Locomotive.SetThrottlePercent(0); + if (Locomotive.DynamicBrakePercent > -1) + { + Locomotive.SetDynamicBrakePercent(0); + Locomotive.DynamicBrakeChangeActiveState(false); + } + } + } + + if (!Locomotive.PowerOn) // || Locomotive.Mirel.NZ1 || Locomotive.Mirel.NZ2 || Locomotive.Mirel.NZ3 || Locomotive.Mirel.NZ4 || Locomotive.Mirel.NZ5) + { + controllerVolts = 0; + Locomotive.SetThrottlePercent(0); + if (Locomotive.DynamicBrakePercent > 0) + Locomotive.SetDynamicBrakePercent(0); + Locomotive.DynamicBrakeIntervention = -1; + maxForceN = 0; + ForceThrottleAndDynamicBrake = 0; + Ampers = 0; + } + else + ForceThrottleAndDynamicBrake = controllerVolts; + + Locomotive.MotiveForceN = maxForceN; + Locomotive.TractiveForceN = maxForceN; + } + + if (playerNotDriveableTrainLocomotives.Count > 0) // update any other than the player's locomotive in the consist throttles to percentage of the current force and the max force + { + foreach (MSTSLocomotive lc in playerNotDriveableTrainLocomotives) + { + if (UseThrottle) + { + lc.SetThrottlePercent(Locomotive.ThrottlePercent); + } + else + { + lc.IsAPartOfPlayerTrain = true; + float locoPercent = Locomotive.MaxForceN - (Locomotive.MaxForceN - Locomotive.MotiveForceN); + lc.ThrottleOverriden = locoPercent / Locomotive.MaxForceN; + } + } + } + } + + public enum AvvSignal { + Stop, + Restricted, + Restricting40, + Clear, + Restricting60, + Restricting80, + Restricting100 + }; + public AvvSignal avvSignal = AvvSignal.Stop; + public void DrawAvvSignal(AvvSignal ToState) + { + avvSignal = ToState; + } + } +} \ No newline at end of file diff --git a/Source/RunActivity/Viewer3D/RollingStock/MSTSLocomotiveViewer.cs b/Source/RunActivity/Viewer3D/RollingStock/MSTSLocomotiveViewer.cs index 9b8c67978b..b8c881bbb9 100644 --- a/Source/RunActivity/Viewer3D/RollingStock/MSTSLocomotiveViewer.cs +++ b/Source/RunActivity/Viewer3D/RollingStock/MSTSLocomotiveViewer.cs @@ -196,6 +196,39 @@ public override void InitializeUserInputCommands() new TCSSwitchCommand(Viewer.Log, !Locomotive.TrainControlSystem.TCSCommandSwitchOn[1], 1); } }); + UserInputCommands.Add(UserCommand.ControlSpeedRegulatorMaxAccelerationDecrease, new Action[] { () => Locomotive.CruiseControl.SpeedRegulatorMaxForceStopDecrease(), () => Locomotive.CruiseControl.SpeedRegulatorMaxForceStartDecrease() }); + UserInputCommands.Add(UserCommand.ControlSpeedRegulatorMaxAccelerationIncrease, new Action[] { () => Locomotive.CruiseControl.SpeedRegulatorMaxForceStopIncrease(), () => Locomotive.CruiseControl.SpeedRegulatorMaxForceStartIncrease() }); + UserInputCommands.Add(UserCommand.ControlSpeedRegulatorModeDecrease, new Action[] { Noop, () => Locomotive.CruiseControl.SpeedRegulatorModeDecrease() }); + UserInputCommands.Add(UserCommand.ControlSpeedRegulatorModeIncrease, new Action[] { Noop, () => Locomotive.CruiseControl.SpeedRegulatorModeIncrease() }); + UserInputCommands.Add(UserCommand.ControlSpeedRegulatorSelectedSpeedDecrease, new Action[] { () => Locomotive.CruiseControl.SpeedRegulatorSelectedSpeedStopDecrease(), () => Locomotive.CruiseControl.SpeedRegulatorSelectedSpeedStartDecrease() }); + UserInputCommands.Add(UserCommand.ControlSpeedRegulatorSelectedSpeedIncrease, new Action[] { () => Locomotive.CruiseControl.SpeedRegulatorSelectedSpeedStopIncrease(), () => Locomotive.CruiseControl.SpeedRegulatorSelectedSpeedStartIncrease() }); + UserInputCommands.Add(UserCommand.ControlNumberOfAxlesDecrease, new Action[] { Noop, () => Locomotive.CruiseControl.NumberOfAxlesDecrease() }); + UserInputCommands.Add(UserCommand.ControlNumberOfAxlesIncrease, new Action[] { Noop, () => Locomotive.CruiseControl.NumerOfAxlesIncrease() }); + UserInputCommands.Add(UserCommand.ControlRestrictedSpeedZoneActive, new Action[] { Noop, () => Locomotive.CruiseControl.ActivateRestrictedSpeedZone() }); + UserInputCommands.Add(UserCommand.ControlCruiseControlModeIncrease, new Action[] { () => Locomotive.CruiseControl.SpeedSelectorModeStopIncrease(), () => Locomotive.CruiseControl.SpeedSelectorModeStartIncrease() }); + UserInputCommands.Add(UserCommand.ControlCruiseControlModeDecrease, new Action[] { Noop, () => Locomotive.CruiseControl.SpeedSelectorModeDecrease() }); + UserInputCommands.Add(UserCommand.ControlTrainTypePaxCargo, new Action[] { Noop, () => Locomotive.ChangeTrainTypePaxCargo() }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed10KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(10) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed20KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(20) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed30KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(30) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed40KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(40) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed50KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(50) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed60KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(60) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed70KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(70) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed80KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(80) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed90KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(90) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed100KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(100) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed110KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(110) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed120KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(120) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed130KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(130) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed140KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(140) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed150KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(150) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed160KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(160) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed170KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(170) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed180KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(180) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed190KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(190) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed200KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(200) }); + base.InitializeUserInputCommands(); } @@ -1931,7 +1964,14 @@ public virtual int GetDrawIndex() index = Locomotive.DynamicBrakeController != null ? Locomotive.DynamicBrakeController.CurrentNotch : 0; } else - index = PercentToIndex(dynBrakePercent); + { + if ((Locomotive.CruiseControl.SpeedRegMode == Simulation.RollingStocks.SubSystems.CruiseControl.SpeedRegulatorMode.Auto && !Locomotive.CruiseControl.DynamicBrakePriority) || Locomotive.DynamicBrakeIntervention > 0) + { + index = 0; + } + else + index = PercentToIndex(dynBrakePercent); + } } else { @@ -1955,6 +1995,9 @@ public virtual int GetDrawIndex() else index = PercentToIndex(Locomotive.GetCombinedHandleValue(false)); break; + case CABViewControlTypes.ORTS_SELECTED_SPEED_DISPLAY: + index = (int)MpS.ToKpH(Locomotive.CruiseControl.SelectedSpeedMpS) / 10; + break; case CABViewControlTypes.ALERTER_DISPLAY: case CABViewControlTypes.RESET: case CABViewControlTypes.WIPERS: @@ -2064,6 +2107,28 @@ public virtual int GetDrawIndex() case CABViewControlTypes.ORTS_TCS46: case CABViewControlTypes.ORTS_TCS47: case CABViewControlTypes.ORTS_TCS48: + + // Jindrich + case CABViewControlTypes.ORTS_RESTRICTED_SPEED_ZONE_ACTIVE: + case CABViewControlTypes.ORTS_SELECTED_SPEED_MODE: + case CABViewControlTypes.ORTS_SELECTED_SPEED_REGULATOR_MODE: + case CABViewControlTypes.ORTS_SELECTED_SPEED_MAXIMUM_ACCELERATION: + case CABViewControlTypes.ORTS_NUMBER_OF_AXES_DISPLAY_UNITS: + case CABViewControlTypes.ORTS_NUMBER_OF_AXES_DISPLAY_TENS: + case CABViewControlTypes.ORTS_NUMBER_OF_AXES_DISPLAY_HUNDREDS: + case CABViewControlTypes.ORTS_TRAIN_LENGTH_METERS: + case CABViewControlTypes.ORTS_REMAINING_TRAIN_LENGHT_SPEED_RESTRICTED: + case CABViewControlTypes.ORTS_REMAINING_TRAIN_LENGTH_PERCENT: + case CABViewControlTypes.ORTS_MOTIVE_FORCE: + case CABViewControlTypes.ORTS_MOTIVE_FORCE_KILONEWTON: + case CABViewControlTypes.ORTS_MAXIMUM_FORCE: + case CABViewControlTypes.ORTS_SELECTED_SPEED: + case CABViewControlTypes.ORTS_FORCE_IN_PERCENT_THROTTLE_AND_DYNAMIC_BRAKE: + case CABViewControlTypes.ORTS_TRAIN_TYPE_PAX_OR_CARGO: + case CABViewControlTypes.ORTS_CONTROLLER_VOLTAGE: + case CABViewControlTypes.ORTS_AMPERS_BY_CONTROLLER_VOLTAGE: + case CABViewControlTypes.ORTS_CC_SELECT_SPEED: + index = (int)data; break; } @@ -2105,6 +2170,7 @@ public string GetControlLabel() /// /// Handles cabview mouse events, and changes the corresponding locomotive control values. /// + public void HandleUserInput() { switch (Control.ControlType) @@ -2130,7 +2196,7 @@ public void HandleUserInput() break; case CABViewControlTypes.PANTOGRAPH2: var p2 = Locomotive.UsingRearCab ? 1 : 2; - new PantographCommand(Viewer.Log, p2 , ChangedValue(Locomotive.Pantographs[p2].CommandUp ? 1 : 0) > 0); + new PantographCommand(Viewer.Log, p2, ChangedValue(Locomotive.Pantographs[p2].CommandUp ? 1 : 0) > 0); break; case CABViewControlTypes.ORTS_PANTOGRAPH3: var p3 = Locomotive.UsingRearCab && Locomotive.Pantographs.List.Count > 3 ? 4 : 3; @@ -2184,8 +2250,8 @@ public void HandleUserInput() case CABViewControlTypes.ORTS_OVERCHARGE: new BrakeOverchargeCommand(Viewer.Log, ChangedValue(Locomotive.TrainBrakeController.OverchargeButtonPressed ? 1 : 0) > 0); break; case CABViewControlTypes.RESET: new AlerterCommand(Viewer.Log, ChangedValue(Locomotive.TrainControlSystem.AlerterButtonPressed ? 1 : 0) > 0); break; case CABViewControlTypes.CP_HANDLE: Locomotive.SetCombinedHandleValue(ChangedValue(Locomotive.GetCombinedHandleValue(true))); break; - - // Steam locomotives only: + + // Steam locomotives only: case CABViewControlTypes.CUTOFF: (Locomotive as MSTSSteamLocomotive).SetCutoffValue(ChangedValue((Locomotive as MSTSSteamLocomotive).CutoffController.IntermediateValue)); break; case CABViewControlTypes.BLOWER: (Locomotive as MSTSSteamLocomotive).SetBlowerValue(ChangedValue((Locomotive as MSTSSteamLocomotive).BlowerController.IntermediateValue)); break; case CABViewControlTypes.DAMPERS_FRONT: (Locomotive as MSTSSteamLocomotive).SetDamperValue(ChangedValue((Locomotive as MSTSSteamLocomotive).DamperController.IntermediateValue)); break; @@ -2307,6 +2373,74 @@ public void HandleUserInput() new TCSButtonCommand(Viewer.Log, !Locomotive.TrainControlSystem.TCSCommandButtonDown[commandIndex], commandIndex); new TCSSwitchCommand(Viewer.Log, ChangedValue(Locomotive.TrainControlSystem.TCSCommandSwitchOn[commandIndex] ? 1 : 0) > 0, commandIndex); break; + + // Jindrich + case CABViewControlTypes.ORTS_CC_SELECT_SPEED: + var p = ChangedValue(0); + if (p == 1) + { + Locomotive.CruiseControl.SetSpeed((float)Control.MaxValue); + Locomotive.SelectingSpeedPressed = true; + } + else if (p == 0) Locomotive.SelectingSpeedPressed = false; + break; + case CABViewControlTypes.ORTS_SELECTED_SPEED_REGULATOR_MODE: + p = ChangedValue(0); + if (p == 1) + { + Locomotive.CruiseControl.SpeedRegulatorModeIncrease(); + } + else if (p == -1) + { + Locomotive.CruiseControl.SpeedRegulatorModeDecrease(); + } + break; + case CABViewControlTypes.ORTS_SELECTED_SPEED_MODE: + p = ChangedValue(0); + if (p == 1) + { + Locomotive.CruiseControl.SpeedSelectorModeStartIncrease(); + } + else if (Locomotive.CruiseControl.SpeedSelMode == Simulation.RollingStocks.SubSystems.CruiseControl.SpeedSelectorMode.Start) + { + if (UserInput.IsMouseLeftButtonReleased) + { + Locomotive.CruiseControl.SpeedSelectorModeStopIncrease(); + } + } + else if (p == -1) + { + Locomotive.CruiseControl.SpeedSelectorModeDecrease(); + } + break; + case CABViewControlTypes.ORTS_RESTRICTED_SPEED_ZONE_ACTIVE: + if (ChangedValue(0) == 1) + { + Locomotive.CruiseControl.ActivateRestrictedSpeedZone(); + } + break; + case CABViewControlTypes.ORTS_NUMBER_OF_AXES_INCREASE: + if (ChangedValue(0) == 1) + { + Locomotive.CruiseControl.NumerOfAxlesIncrease(); + } + break; + case CABViewControlTypes.ORTS_NUMBER_OF_AXES_DECREASE: + if (ChangedValue(0) == 1) + { + Locomotive.CruiseControl.NumberOfAxlesDecrease(); + } + break; + case CABViewControlTypes.ORTS_SELECTED_SPEED_MAXIMUM_ACCELERATION: + if (ChangedValue(0) == 1) + { + Locomotive.CruiseControl.SelectedMaxAccelerationStep += 1; + } + if (ChangedValue(0) == -1) + { + Locomotive.CruiseControl.SelectedMaxAccelerationStep -= 1; + } + break; } } From 70689165621c111179aa874f0479b7445a560842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jind=C5=99ich=20Machal=C3=ADnek?= Date: Wed, 3 Feb 2021 04:44:56 +0100 Subject: [PATCH 3/7] Updates, fixes --- Source/ORTS.Settings/InputSettings.cs | 2 +- Source/Orts.Simulation/Common/Events.cs | 10 +- .../RollingStocks/MSTSLocomotive.cs | 88 +++-------------- .../RollingStocks/SubSystems/CruiseControl.cs | 94 +++++++++++++++++-- 4 files changed, 106 insertions(+), 88 deletions(-) diff --git a/Source/ORTS.Settings/InputSettings.cs b/Source/ORTS.Settings/InputSettings.cs index b740514273..2a69c1fe38 100644 --- a/Source/ORTS.Settings/InputSettings.cs +++ b/Source/ORTS.Settings/InputSettings.cs @@ -443,7 +443,7 @@ static void InitializeCommands(UserCommandInput[] Commands) Commands[(int)UserCommand.ControlSpeedRegulatorSelectedSpeedDecrease] = new UserCommandKeyInput(0x1E, KeyModifiers.Shift); Commands[(int)UserCommand.ControlNumberOfAxlesIncrease] = new UserCommandKeyInput(0x48, KeyModifiers.Shift); Commands[(int)UserCommand.ControlNumberOfAxlesDecrease] = new UserCommandKeyInput(0x50, KeyModifiers.Shift); - Commands[(int)UserCommand.ControlRestrictedSpeedZoneActive] = new UserCommandKeyInput(0x19, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlRestrictedSpeedZoneActive] = new UserCommandKeyInput(0x13, KeyModifiers.Control | KeyModifiers.Shift); Commands[(int)UserCommand.ControlCruiseControlModeDecrease] = new UserCommandKeyInput(0x1E, KeyModifiers.Control); Commands[(int)UserCommand.ControlCruiseControlModeIncrease] = new UserCommandKeyInput(0x20, KeyModifiers.Control); Commands[(int)UserCommand.ControlTrainTypePaxCargo] = new UserCommandKeyInput(0x31, KeyModifiers.Control | KeyModifiers.Shift); diff --git a/Source/Orts.Simulation/Common/Events.cs b/Source/Orts.Simulation/Common/Events.cs index 4458668444..f361f38379 100644 --- a/Source/Orts.Simulation/Common/Events.cs +++ b/Source/Orts.Simulation/Common/Events.cs @@ -430,11 +430,11 @@ public static Event From(bool mstsBinEnabled, Source source, int eventID) case 208: return Event.GearPosition8; // Jindrich - case 1000: return Event.CruiseControlSpeedRegulator; - case 1001: return Event.CruiseControlSpeedSelector; - case 1002: return Event.CruiseControlMaxForce; - case 1003: return Event.Alert; - case 1004: return Event.Alert1; + case 300: return Event.CruiseControlSpeedRegulator; + case 301: return Event.CruiseControlSpeedSelector; + case 302: return Event.CruiseControlMaxForce; + case 303: return Event.Alert; + case 304: return Event.Alert1; default: return 0; } diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs index c88e1e05d7..4ee26a7672 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs @@ -831,7 +831,7 @@ public override void Parse(string lowercasetoken, STFReader stf) case "engine(ortsbrakepipechargingrate": BrakePipeChargingRatePSIorInHgpS = stf.ReadFloatBlock(STFReader.UNITS.PressureRateDefaultPSIpS, null); break; case "engine(ortsbrakepipequickchargingrate": BrakePipeQuickChargingRatePSIpS = stf.ReadFloatBlock(STFReader.UNITS.PressureRateDefaultPSIpS, null); break; case "engine(ortsbrakepipedischargetimemult": BrakePipeDischargeTimeFactor = stf.ReadFloatBlock(STFReader.UNITS.None, null); break; - case "engine(ortsmaxtractiveforcecurves": TractiveForceCurves = new InterpolatorDiesel2D(stf, false); TractiveForceCurves.HasNegativeValue(); break; + case "engine(ortsmaxtractiveforcecurves": TractiveForceCurves = new InterpolatorDiesel2D(stf, false); TractiveForceCurves.HasNegativeValue(); break; case "engine(ortstractioncharacteristics": TractiveForceCurves = new InterpolatorDiesel2D(stf, true); break; case "engine(ortsdynamicbrakeforcecurves": DynamicBrakeForceCurves = new InterpolatorDiesel2D(stf, false); break; case "engine(ortscontinuousforcetimefactor": ContinuousForceTimeFactor = stf.ReadFloatBlock(STFReader.UNITS.None, null); break; @@ -873,7 +873,7 @@ public override void Parse(string lowercasetoken, STFReader stf) { switch (brakesenginecontrollers) { - case "blended": + case "blended": DynamicBrakeBlendingEnabled = true; break; case "dynamic": @@ -890,13 +890,13 @@ public override void Parse(string lowercasetoken, STFReader stf) foreach (var brakestrainbraketype in stf.ReadStringBlock("").ToLower().Replace(" ", "").Split(',')) { switch (brakestrainbraketype) - { - case "vacuum_single_pipe_eq": - VacuumBrakeEQFitted = true; - break; - default: - break; - } + { + case "vacuum_single_pipe_eq": + VacuumBrakeEQFitted = true; + break; + default: + break; + } } break; @@ -929,61 +929,7 @@ public override void Parse(string lowercasetoken, STFReader stf) case "engine(ortsmaxtracksanderboxcapacity": MaxTrackSandBoxCapacityM3 = stf.ReadFloatBlock(STFReader.UNITS.Volume, null); break; case "engine(ortsmaxtracksandersandconsumption": TrackSanderSandConsumptionM3pS = stf.ReadFloatBlock(STFReader.UNITS.Volume, null); break; case "engine(ortsmaxtracksanderairconsumption": TrackSanderAirComsumptionM3pS = stf.ReadFloatBlock(STFReader.UNITS.Volume, null); break; - case "engine(ortscruisecontrol": CruiseControl.Equipped = true; break; - case "engine(ortscruisecontrol(usethrottle": CruiseControl.UseThrottle = stf.ReadBoolBlock(false); break; - case "engine(ortscruisecontrol(throttleincreasespeed": CruiseControl.ThrottleIncreaseSpeed = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.1f); break; - case "engine(ortscruisecontrol(throttledecreasespeed": CruiseControl.ThrottleDecreaseSpeed = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.2f); break; - case "engine(ortscruisecontrol(throttlefullrangeincreasetimeseconds": CruiseControl.ThrottleFullRangeIncreaseTimeSeconds = stf.ReadFloatBlock(STFReader.UNITS.Any, 5); break; - case "engine(ortscruisecontrol(throttlefullrangedecreasetimeseconds": CruiseControl.ThrottleFullRangeDecreaseTimeSeconds = stf.ReadFloatBlock(STFReader.UNITS.Any, 5); break; - case "engine(ortscruisecontrol(dynamicbrakefullrangeincreasetimeseconds": CruiseControl.DynamicBrakeFullRangeIncreaseTimeSeconds = stf.ReadFloatBlock(STFReader.UNITS.Any, 5); break; - case "engine(ortscruisecontrol(dynamicbrakefullrangedecreasetimeseconds": CruiseControl.DynamicBrakeFullRangeDecreaseTimeSeconds = stf.ReadFloatBlock(STFReader.UNITS.Any, 5); break; - case "engine(ortscruisecontrol(parkingbrakeengagespeed": CruiseControl.ParkingBrakeEngageSpeed = stf.ReadFloatBlock(STFReader.UNITS.Speed, 0); break; - case "engine(ortscruisecontrol(parkingbrakepercent": CruiseControl.ParkingBrakePercent = stf.ReadFloatBlock(STFReader.UNITS.Any, 0); break; - case "engine(ortscruisecontrol(maxpowerthreshold": CruiseControl.MaxPowerThreshold = stf.ReadFloatBlock(STFReader.UNITS.Any, 0); break; - case "engine(ortscruisecontrol(maxforcepercentunits": CruiseControl.SpeedRegulatorMaxForcePercentUnits = stf.ReadBoolBlock(false); break; - case "engine(ortscruisecontrol(maxforcesteps": CruiseControl.SpeedRegulatorMaxForceSteps = stf.ReadIntBlock(0); break; - case "engine(ortscruisecontrol(maxforcesetsinglestep": CruiseControl.MaxForceSetSingleStep = stf.ReadBoolBlock(false); break; - case "engine(ortscruisecontrol(maxforcekeepselectedstepwhenmanualmodeset": CruiseControl.MaxForceKeepSelectedStepWhenManualModeSet = stf.ReadBoolBlock(false); break; - case "engine(ortscruisecontrol(forcestepsthrottletable": - foreach (var forceStepThrottleValue in stf.ReadStringBlock("").Replace(" ", "").Split(',')) - { - CruiseControl.ForceStepsThrottleTable.Add(int.Parse(forceStepThrottleValue)); - } - break; - case "engine(ortscruisecontrol(accelerationtable": - foreach (var accelerationValue in stf.ReadStringBlock("").Replace(" ", "").Split(',')) - { - CruiseControl.AccelerationTable.Add(float.Parse(accelerationValue)); - } - break; - case "engine(ortscruisecontrol(powerbreakoutampers": CruiseControl.PowerBreakoutAmpers = stf.ReadFloatBlock(STFReader.UNITS.Any, 100.0f); break; - case "engine(ortscruisecontrol(powerbreakoutspeeddelta": CruiseControl.PowerBreakoutSpeedDelta = stf.ReadFloatBlock(STFReader.UNITS.Any, 100.0f); break; - case "engine(ortscruisecontrol(powerresumespeeddelta": CruiseControl.PowerResumeSpeedDelta = stf.ReadFloatBlock(STFReader.UNITS.Any, 100.0f); break; - case "engine(ortscruisecontrol(powerreductiondelaypaxtrain": CruiseControl.PowerReductionDelayPaxTrain = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.0f); break; - case "engine(ortscruisecontrol(powerreductiondelaycargotrain": CruiseControl.PowerReductionDelayCargoTrain = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.0f); break; - case "engine(ortscruisecontrol(powerreductionvalue": CruiseControl.PowerReductionValue = stf.ReadFloatBlock(STFReader.UNITS.Any, 100.0f); break; - - case "engine(ortscruisecontrol(disablezeroforcestep": CruiseControl.DisableZeroForceStep = stf.ReadBoolBlock(false); break; - case "engine(ortscruisecontrol(defaultforcestep": CruiseControl.SelectedMaxAccelerationStep = stf.ReadFloatBlock(STFReader.UNITS.Any, 1.0f); break; - case "engine(ortscruisecontrol(dynamicbrakemaxforceatselectorstep": CruiseControl.DynamicBrakeMaxForceAtSelectorStep = stf.ReadFloatBlock(STFReader.UNITS.Any, 1.0f); break; - case "engine(ortscruisecontrol(startreducingspeeddelta": CruiseControl.StartReducingSpeedDelta = stf.ReadFloatBlock(STFReader.UNITS.Any, 1.0f); break; - case "engine(ortscruisecontrol(dynamicbrakedescentcoefficient": CruiseControl.DynamicBrakeDescentCoefficient = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.5f); break; - case "engine(ortscruisecontrol(climbdeltacoefficient": CruiseControl.DeltaCoefficient = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.8f); break; - case "engine(ortscruisecontrol(maxacceleration": CruiseControl.MaxAccelerationMpSS = stf.ReadFloatBlock(STFReader.UNITS.Any, 1); break; - case "engine(ortscruisecontrol(maxdeceleration": CruiseControl.MaxDecelerationMpSS = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.5f); break; - case "engine(ortscruisecontrol(antiwheelspinequipped": CruiseControl.AntiWheelSpinEquipped = stf.ReadBoolBlock(false); break; - case "engine(ortscruisecontrol(nominalspeedstep": CruiseControl.SpeedRegulatorNominalSpeedStepMpS = MpS.FromKpH(stf.ReadFloatBlock(STFReader.UNITS.Speed, 0)); break; - case "engine(ortscruisecontrol(usethrottleasspeedselector": CruiseControl.UseThrottleAsSpeedSelector = stf.ReadBoolBlock(false); break; - case "engine(ortscruisecontrol(dynamicbrakeincreasespeed": CruiseControl.DynamicBrakeIncreaseSpeed = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.5f); break; - case "engine(ortscruisecontrol(dynamicbrakedecreasespeed": CruiseControl.DynamicBrakeDecreaseSpeed = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.5f); break; - case "engine(ortscruisecontrol(options": - foreach (var speedRegulatorOption in stf.ReadStringBlock("").ToLower().Replace(" ", "").Split(',')) - { - CruiseControl.SpeedRegulatorOptions.Add(speedRegulatorOption.ToLower()); - } - break; - default: base.Parse(lowercasetoken, stf); break; - + default: base.Parse(lowercasetoken, stf); CruiseControl.Parse(lowercasetoken, stf); break; } } @@ -3189,21 +3135,12 @@ public void SetThrottlePercentWithSound(float percent) public void ThrottleToZero() { - if (CruiseControl.SpeedRegulatorOptions.Contains("shutdownonsetthrottlezero")) - { - CruiseControl.SelectedSpeedMpS = 0; - CruiseControl.SpeedSelMode = CruiseControl.SpeedSelectorMode.Neutral; - CruiseControl.SpeedRegMode = CruiseControl.SpeedRegulatorMode.Manual; - SetThrottlePercent(0); - return; - } if (CombinedControlType == CombinedControl.ThrottleDynamic && ThrottleController.CurrentValue <= 0) StartDynamicBrakeIncrease(null); else if (CombinedControlType == CombinedControl.ThrottleAir && ThrottleController.CurrentValue <= 0) StartTrainBrakeIncrease(null); else StartThrottleToZero(0.0f); - } public void StartThrottleToZero(float? target) @@ -5067,7 +5004,10 @@ public virtual float GetDataOf(CabViewControl cvc) } case CABViewControlTypes.ORTS_MOTIVE_FORCE_KILONEWTON: { - data = (float)Math.Round(FilteredMotiveForceN / 1000, 0); + if (FilteredMotiveForceN > DynamicBrakeForceN) + data = (float)Math.Round(FilteredMotiveForceN / 1000, 0); + else if (DynamicBrakeForceN > 0) + data = -(float)Math.Round(DynamicBrakeForceN / 1000, 0); break; } case CABViewControlTypes.ORTS_MAXIMUM_FORCE: diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs index 703f6655a9..2f30461720 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs @@ -38,6 +38,7 @@ public CruiseControl(MSTSLocomotive locomotive) public float SpeedRegulatorMaxForceSteps = 0; public bool MaxForceSetSingleStep = false; public bool MaxForceKeepSelectedStepWhenManualModeSet = false; + public bool ForceRegulatorAutoWhenNonZeroSpeedSelected = false; public List SpeedRegulatorOptions = new List(); public SpeedRegulatorMode SpeedRegMode = SpeedRegulatorMode.Manual; public SpeedSelectorMode SpeedSelMode = SpeedSelectorMode.Neutral; @@ -105,6 +106,66 @@ public enum SpeedSelectorMode { Parking, Neutral, On, Start } public float MaxPowerThreshold = 0; public float SafeSpeedForAutomaticOperationMpS = 0; + public void Parse(string lowercasetoken, STFReader stf) + { + switch (lowercasetoken) + { + case "engine(ortscruisecontrol": Equipped = true; break; + case "engine(ortscruisecontrol(usethrottle": UseThrottle = stf.ReadBoolBlock(false); break; + case "engine(ortscruisecontrol(throttleincreasespeed": ThrottleIncreaseSpeed = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.1f); break; + case "engine(ortscruisecontrol(throttledecreasespeed": ThrottleDecreaseSpeed = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.2f); break; + case "engine(ortscruisecontrol(throttlefullrangeincreasetimeseconds": ThrottleFullRangeIncreaseTimeSeconds = stf.ReadFloatBlock(STFReader.UNITS.Any, 5); break; + case "engine(ortscruisecontrol(throttlefullrangedecreasetimeseconds": ThrottleFullRangeDecreaseTimeSeconds = stf.ReadFloatBlock(STFReader.UNITS.Any, 5); break; + case "engine(ortscruisecontrol(dynamicbrakefullrangeincreasetimeseconds": DynamicBrakeFullRangeIncreaseTimeSeconds = stf.ReadFloatBlock(STFReader.UNITS.Any, 5); break; + case "engine(ortscruisecontrol(dynamicbrakefullrangedecreasetimeseconds": DynamicBrakeFullRangeDecreaseTimeSeconds = stf.ReadFloatBlock(STFReader.UNITS.Any, 5); break; + case "engine(ortscruisecontrol(parkingbrakeengagespeed": ParkingBrakeEngageSpeed = stf.ReadFloatBlock(STFReader.UNITS.Speed, 0); break; + case "engine(ortscruisecontrol(parkingbrakepercent": ParkingBrakePercent = stf.ReadFloatBlock(STFReader.UNITS.Any, 0); break; + case "engine(ortscruisecontrol(maxpowerthreshold": MaxPowerThreshold = stf.ReadFloatBlock(STFReader.UNITS.Any, 0); break; + case "engine(ortscruisecontrol(maxforcepercentunits": SpeedRegulatorMaxForcePercentUnits = stf.ReadBoolBlock(false); break; + case "engine(ortscruisecontrol(maxforcesteps": SpeedRegulatorMaxForceSteps = stf.ReadIntBlock(0); break; + case "engine(ortscruisecontrol(maxforcesetsinglestep": MaxForceSetSingleStep = stf.ReadBoolBlock(false); break; + case "engine(ortscruisecontrol(maxforcekeepselectedstepwhenmanualmodeset": MaxForceKeepSelectedStepWhenManualModeSet = stf.ReadBoolBlock(false); break; + case "engine(ortscruisecontrol(forceregulatorautowhennonzerospeedselected": ForceRegulatorAutoWhenNonZeroSpeedSelected = stf.ReadBoolBlock(false); break; + case "engine(ortscruisecontrol(forcestepsthrottletable": + foreach (var forceStepThrottleValue in stf.ReadStringBlock("").Replace(" ", "").Split(',')) + { + ForceStepsThrottleTable.Add(int.Parse(forceStepThrottleValue)); + } + break; + case "engine(ortscruisecontrol(accelerationtable": + foreach (var accelerationValue in stf.ReadStringBlock("").Replace(" ", "").Split(',')) + { + AccelerationTable.Add(float.Parse(accelerationValue)); + } + break; + case "engine(ortscruisecontrol(powerbreakoutampers": PowerBreakoutAmpers = stf.ReadFloatBlock(STFReader.UNITS.Any, 100.0f); break; + case "engine(ortscruisecontrol(powerbreakoutspeeddelta": PowerBreakoutSpeedDelta = stf.ReadFloatBlock(STFReader.UNITS.Any, 100.0f); break; + case "engine(ortscruisecontrol(powerresumespeeddelta": PowerResumeSpeedDelta = stf.ReadFloatBlock(STFReader.UNITS.Any, 100.0f); break; + case "engine(ortscruisecontrol(powerreductiondelaypaxtrain": PowerReductionDelayPaxTrain = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.0f); break; + case "engine(ortscruisecontrol(powerreductiondelaycargotrain": PowerReductionDelayCargoTrain = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.0f); break; + case "engine(ortscruisecontrol(powerreductionvalue": PowerReductionValue = stf.ReadFloatBlock(STFReader.UNITS.Any, 100.0f); break; + + case "engine(ortscruisecontrol(disablezeroforcestep": DisableZeroForceStep = stf.ReadBoolBlock(false); break; + case "engine(ortscruisecontrol(defaultforcestep": SelectedMaxAccelerationStep = stf.ReadFloatBlock(STFReader.UNITS.Any, 1.0f); break; + case "engine(ortscruisecontrol(dynamicbrakemaxforceatselectorstep": DynamicBrakeMaxForceAtSelectorStep = stf.ReadFloatBlock(STFReader.UNITS.Any, 1.0f); break; + case "engine(ortscruisecontrol(startreducingspeeddelta": StartReducingSpeedDelta = stf.ReadFloatBlock(STFReader.UNITS.Any, 1.0f); break; + case "engine(ortscruisecontrol(dynamicbrakedescentcoefficient": DynamicBrakeDescentCoefficient = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.5f); break; + case "engine(ortscruisecontrol(climbdeltacoefficient": DeltaCoefficient = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.8f); break; + case "engine(ortscruisecontrol(maxacceleration": MaxAccelerationMpSS = stf.ReadFloatBlock(STFReader.UNITS.Any, 1); break; + case "engine(ortscruisecontrol(maxdeceleration": MaxDecelerationMpSS = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.5f); break; + case "engine(ortscruisecontrol(antiwheelspinequipped": AntiWheelSpinEquipped = stf.ReadBoolBlock(false); break; + case "engine(ortscruisecontrol(nominalspeedstep": SpeedRegulatorNominalSpeedStepMpS = MpS.FromKpH(stf.ReadFloatBlock(STFReader.UNITS.Speed, 0)); break; + case "engine(ortscruisecontrol(usethrottleasspeedselector": stf.ReadBoolBlock(false); break; + case "engine(ortscruisecontrol(dynamicbrakeincreasespeed": DynamicBrakeIncreaseSpeed = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.5f); break; + case "engine(ortscruisecontrol(dynamicbrakedecreasespeed": DynamicBrakeDecreaseSpeed = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.5f); break; + case "engine(ortscruisecontrol(options": + foreach (var speedRegulatorOption in stf.ReadStringBlock("").ToLower().Replace(" ", "").Split(',')) + { + SpeedRegulatorOptions.Add(speedRegulatorOption.ToLower()); + } + break; + } + } public float AccelerationRampMpSSS { get @@ -423,6 +484,10 @@ protected void SpeedRegulatorMaxForceDecrease() protected bool selectedSpeedIncreasing = false; public void SpeedRegulatorSelectedSpeedStartIncrease() { + if (SpeedRegMode != SpeedRegulatorMode.Auto && ForceRegulatorAutoWhenNonZeroSpeedSelected) + { + SpeedRegMode = SpeedRegulatorMode.Auto; + } if (!UseThrottleAsSpeedSelector) selectedSpeedIncreasing = true; else @@ -462,6 +527,14 @@ public void SpeedRegulatorSelectedSpeedDecrease() SelectedSpeedMpS -= SpeedRegulatorNominalSpeedStepMpS; if (SelectedSpeedMpS < 0) SelectedSpeedMpS = 0f; + if (SpeedRegMode == SpeedRegulatorMode.Auto && ForceRegulatorAutoWhenNonZeroSpeedSelected && SelectedSpeedMpS == 0) + { + // return back to manual, clear all we have controlled before and let the driver to set up new stuff + SpeedRegMode = SpeedRegulatorMode.Manual; + Locomotive.SetThrottlePercent(0); + Locomotive.SetDynamicBrakePercent(0); + Locomotive.DynamicBrakeChangeActiveState(false); + } Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Selected speed changed to ") + Math.Round(MpS.FromMpS(SelectedSpeedMpS, true), 0, MidpointRounding.AwayFromZero).ToString() + " km/h"); } public void NumerOfAxlesIncrease() @@ -513,12 +586,14 @@ public virtual void CheckRestrictedSpeedZone() public void SetSpeed(float SpeedKpH) { + if (SpeedRegMode == SpeedRegulatorMode.Manual && ForceRegulatorAutoWhenNonZeroSpeedSelected) + SpeedRegMode = SpeedRegulatorMode.Auto; Locomotive.SignalEvent(Common.Event.Alert1); if (!Equipped) return; SelectedSpeedMpS = MpS.FromKpH(SpeedKpH); if (SelectedSpeedMpS > Locomotive.MaxSpeedMpS) SelectedSpeedMpS = Locomotive.MaxSpeedMpS; - Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Selected speed set to ") + SpeedKpH.ToString()); + Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Selected speed set to ") + SpeedKpH.ToString() + "kmh"); } protected List playerNotDriveableTrainLocomotives = new List(); @@ -721,9 +796,9 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe { delta = 0; if (!RestrictedSpeedActive) - delta = (SelectedSpeedMpS + (TrainElevation < -0.01 ? TrainElevation * (SelectedNumberOfAxles / 40) : 0)) - AbsWheelSpeedMpS; + delta = (SelectedSpeedMpS + (TrainElevation < -0.01 ? TrainElevation * (SelectedNumberOfAxles / 12) : 0)) - AbsWheelSpeedMpS; else - delta = (CurrentSelectedSpeedMpS + (TrainElevation < -0.01 ? TrainElevation * (SelectedNumberOfAxles / 40) : 0)) - AbsWheelSpeedMpS; + delta = (CurrentSelectedSpeedMpS + (TrainElevation < -0.01 ? TrainElevation * (SelectedNumberOfAxles / 12) : 0)) - AbsWheelSpeedMpS; relativeAcceleration = (float)-Math.Sqrt(-StartReducingSpeedDelta * delta); AccelerationDemandMpSS = (float)-Math.Sqrt(-StartReducingSpeedDelta * AccelerationRampMpSSS * delta); @@ -822,7 +897,10 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe if (delta > 0.0f) { if (Locomotive.DynamicBrakePercent > 0) + { Locomotive.SetDynamicBrakePercent(0); + Locomotive.DynamicBrakeChangeActiveState(false); + } if (Locomotive.DynamicBrakePercent == 0 && Locomotive.DynamicBrake) Locomotive.DynamicBrakeChangeActiveState(false); relativeAcceleration = (float)Math.Sqrt(AccelerationRampMaxMpSSS * delta); float coeff = 1; @@ -836,7 +914,7 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe coeff = 1; } float numAxesCoeff = 0; - numAxesCoeff = (SelectedNumberOfAxles) / 3; + numAxesCoeff = (SelectedNumberOfAxles) / 12; AccelerationDemandMpSS = (float)Math.Sqrt((StartReducingSpeedDelta + numAxesCoeff) * coeff * coeff * AccelerationRampMpSSS * (delta)); } else // start braking @@ -852,9 +930,9 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe delta = 0; if (!RestrictedSpeedActive) - delta = (SelectedSpeedMpS + (TrainElevation < -0.01 ? TrainElevation * (SelectedNumberOfAxles / 40) : 0)) - AbsWheelSpeedMpS; + delta = (SelectedSpeedMpS + (TrainElevation < -0.01 ? TrainElevation * (SelectedNumberOfAxles / 12) : 0)) - AbsWheelSpeedMpS; else - delta = (CurrentSelectedSpeedMpS + (TrainElevation < -0.01 ? TrainElevation * (SelectedNumberOfAxles / 40) : 0)) - AbsWheelSpeedMpS; + delta = (CurrentSelectedSpeedMpS + (TrainElevation < -0.01 ? TrainElevation * (SelectedNumberOfAxles / 12) : 0)) - AbsWheelSpeedMpS; if (delta > 0) { @@ -894,9 +972,9 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe { delta = 0; if (!RestrictedSpeedActive) - delta = (SelectedSpeedMpS + (TrainElevation < -0.01 ? TrainElevation * (SelectedNumberOfAxles / 40) : 0)) - AbsWheelSpeedMpS; + delta = (SelectedSpeedMpS + (TrainElevation < -0.01 ? TrainElevation * (SelectedNumberOfAxles / 12) : 0)) - AbsWheelSpeedMpS; else - delta = (CurrentSelectedSpeedMpS + (TrainElevation < -0.01 ? TrainElevation * (SelectedNumberOfAxles / 40) : 0)) - AbsWheelSpeedMpS; + delta = (CurrentSelectedSpeedMpS + (TrainElevation < -0.01 ? TrainElevation * (SelectedNumberOfAxles / 12) : 0)) - AbsWheelSpeedMpS; relativeAcceleration = (float)-Math.Sqrt(-StartReducingSpeedDelta * delta); AccelerationDemandMpSS = (float)-Math.Sqrt(-StartReducingSpeedDelta * AccelerationRampMpSSS * delta); From 0b1807f37cc3c823b7db5fe08bc6148684a20f83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jind=C5=99ich=20Machal=C3=ADnek?= Date: Wed, 3 Feb 2021 23:49:52 +0100 Subject: [PATCH 4/7] Make object load only when needed --- .../RollingStocks/MSTSLocomotive.cs | 148 ++++++++++++++---- .../RollingStocks/SubSystems/CruiseControl.cs | 1 - .../RollingStock/MSTSLocomotiveViewer.cs | 16 +- 3 files changed, 135 insertions(+), 30 deletions(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs index 4ee26a7672..34b3768485 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs @@ -433,7 +433,6 @@ public MSTSLocomotive(Simulator simulator, string wagPath) ThrottleController = new MSTSNotchController(); DynamicBrakeController = new MSTSNotchController(); TrainControlSystem = new ScriptedTrainControlSystem(this); - CruiseControl = new CruiseControl(this); } /// @@ -929,7 +928,8 @@ public override void Parse(string lowercasetoken, STFReader stf) case "engine(ortsmaxtracksanderboxcapacity": MaxTrackSandBoxCapacityM3 = stf.ReadFloatBlock(STFReader.UNITS.Volume, null); break; case "engine(ortsmaxtracksandersandconsumption": TrackSanderSandConsumptionM3pS = stf.ReadFloatBlock(STFReader.UNITS.Volume, null); break; case "engine(ortsmaxtracksanderairconsumption": TrackSanderAirComsumptionM3pS = stf.ReadFloatBlock(STFReader.UNITS.Volume, null); break; - default: base.Parse(lowercasetoken, stf); CruiseControl.Parse(lowercasetoken, stf); break; + case "engine(ortscruisecontrol": SetUpCruiseControl(); break; + default: base.Parse(lowercasetoken, stf); if (CruiseControl != null) CruiseControl.Parse(lowercasetoken, stf); break; } } @@ -1030,7 +1030,8 @@ public override void Copy(MSTSWagon copy) WaterScoopDepthM = locoCopy.WaterScoopDepthM; WaterScoopWidthM = locoCopy.WaterScoopWidthM; MoveParamsToAxle(); - CruiseControl = locoCopy.CruiseControl; + if (locoCopy.CruiseControl != null) + CruiseControl = locoCopy.CruiseControl; } @@ -1092,7 +1093,8 @@ public override void Save(BinaryWriter outf) TrainControlSystem.Save(outf); LocomotiveAxle.Save(outf); - CruiseControl.Save(outf); + if (CruiseControl != null) + CruiseControl.Save(outf); } /// @@ -1139,7 +1141,8 @@ public override void Restore(BinaryReader inf) TrainControlSystem.Restore(inf); LocomotiveAxle = new Axle(inf); - CruiseControl.Restore(inf); + if (CruiseControl != null) + CruiseControl.Restore(inf); } public bool IsLeadLocomotive() @@ -1220,7 +1223,6 @@ public override void Initialize() EngineBrakeController.Initialize(); BrakemanBrakeController.Initialize(); TrainControlSystem.Initialize(); - CruiseControl.Initialize(); if (MaxSteamHeatPressurePSI == 0) // Check to see if steam heating is fitted to locomotive { @@ -1438,6 +1440,16 @@ public override void Initialize() DrvWheelWeightKg = InitialDrvWheelWeightKg; } + /// + /// Make instance of Cruise Control and Initialize it + /// + public void SetUpCruiseControl() + { + CruiseControl = new CruiseControl(this); + CruiseControl.Initialize(); + CruiseControl.Equipped = true; + } + //================================================================================================// /// /// Set starting conditions when initial speed > 0 @@ -1590,16 +1602,15 @@ public override void Update(float elapsedClockSeconds) AbsWheelSpeedMpS = AbsSpeedMpS; // Jindrich //UpdateMotiveForce(elapsedClockSeconds, t, AbsSpeedMpS, AbsWheelSpeedMpS); - if (!IsPlayerTrain || !CruiseControl.Equipped || CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Manual || CruiseControl.UseThrottle) - UpdateMotiveForce(elapsedClockSeconds, t, AbsSpeedMpS, AbsWheelSpeedMpS); - else if (IsPlayerTrain && CruiseControl.Equipped || CruiseControl.SpeedRegulatorOptions.Contains("engageforceonnonzerospeed")) + if (CruiseControl != null) { - CruiseControl.Update(elapsedClockSeconds, AbsWheelSpeedMpS); - } - if (IsPlayerTrain && CruiseControl.Equipped) - { - if (CruiseControl.RestrictedSpeedActive) CruiseControl.CheckRestrictedSpeedZone(); + if (!IsPlayerTrain || CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Manual || CruiseControl.UseThrottle) + UpdateMotiveForce(elapsedClockSeconds, t, AbsSpeedMpS, AbsWheelSpeedMpS); + else if (IsPlayerTrain || CruiseControl.SpeedRegulatorOptions.Contains("engageforceonnonzerospeed")) + CruiseControl.Update(elapsedClockSeconds, AbsWheelSpeedMpS); } + else + UpdateMotiveForce(elapsedClockSeconds, t, AbsSpeedMpS, AbsWheelSpeedMpS); ApplyDirectionToMotiveForce(); @@ -2868,7 +2879,7 @@ public void StartThrottleIncrease(float? target) public void StartThrottleIncrease() { - if (CruiseControl.Equipped) + if (CruiseControl != null) { if (CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) { @@ -2896,7 +2907,7 @@ public void StartThrottleIncrease() public void StopThrottleIncrease() { - if (CruiseControl.Equipped) + if (CruiseControl != null) { if (CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) { @@ -2931,7 +2942,7 @@ public void StartThrottleDecrease(float? target) protected bool speedSelectorModeDecreasing = false; public void StartThrottleDecrease() { - if (CruiseControl.Equipped) + if (CruiseControl != null) { if (CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) { @@ -2953,7 +2964,7 @@ public void StartThrottleDecrease() public void StopThrottleDecrease() { - if (CruiseControl.Equipped) + if (CruiseControl != null) { if (CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) { @@ -3655,7 +3666,7 @@ public override string GetBrakemanBrakeStatus() public void StartDynamicBrakeIncrease(float? target) { AlerterReset(TCSEvent.DynamicBrakeChanged); - if (CruiseControl.Equipped) + if (CruiseControl != null) { SetThrottlePercent(0); CruiseControl.DynamicBrakePriority = true; @@ -4926,6 +4937,11 @@ public virtual float GetDataOf(CabViewControl cvc) case CABViewControlTypes.ORTS_SELECTED_SPEED: case CABViewControlTypes.ORTS_SELECTED_SPEED_DISPLAY: { + if (CruiseControl == null) + { + data = 0; + break; + } bool metric = cvc.Units == CABViewControlUnits.KM_PER_HOUR; float temp = CruiseControl.RestrictedSpeedActive ? MpS.FromMpS(CruiseControl.CurrentSelectedSpeedMpS, metric) : temp = MpS.FromMpS(CruiseControl.SelectedSpeedMpS, metric); if (previousSelectedSpeed < temp) previousSelectedSpeed += 1f; @@ -4935,16 +4951,31 @@ public virtual float GetDataOf(CabViewControl cvc) } case CABViewControlTypes.ORTS_SELECTED_SPEED_MODE: { + if (CruiseControl == null) + { + data = 0; + break; + } data = (float)CruiseControl.SpeedSelMode; break; } case CABViewControlTypes.ORTS_SELECTED_SPEED_REGULATOR_MODE: { + if (CruiseControl == null) + { + data = 0; + break; + } data = (float)CruiseControl.SpeedRegMode; break; } case CABViewControlTypes.ORTS_SELECTED_SPEED_MAXIMUM_ACCELERATION: { + if (CruiseControl == null) + { + data = 0; + break; + } if (CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto || CruiseControl.MaxForceKeepSelectedStepWhenManualModeSet) data = CruiseControl.SelectedMaxAccelerationStep - 1; else @@ -4953,31 +4984,61 @@ public virtual float GetDataOf(CabViewControl cvc) } case CABViewControlTypes.ORTS_RESTRICTED_SPEED_ZONE_ACTIVE: { + if (CruiseControl == null) + { + data = 0; + break; + } data = CruiseControl.RestrictedSpeedActive ? 1 : 0; break; } case CABViewControlTypes.ORTS_NUMBER_OF_AXES_DISPLAY_UNITS: { + if (CruiseControl == null) + { + data = 0; + break; + } data = CruiseControl.SelectedNumberOfAxles % 10; break; } case CABViewControlTypes.ORTS_NUMBER_OF_AXES_DISPLAY_TENS: { + if (CruiseControl == null) + { + data = 0; + break; + } data = (CruiseControl.SelectedNumberOfAxles / 10) % 10; break; } case CABViewControlTypes.ORTS_NUMBER_OF_AXES_DISPLAY_HUNDREDS: { + if (CruiseControl == null) + { + data = 0; + break; + } data = (CruiseControl.SelectedNumberOfAxles / 100) % 10; break; } case CABViewControlTypes.ORTS_TRAIN_LENGTH_METERS: { + if (CruiseControl == null) + { + data = 0; + break; + } data = CruiseControl.TrainLengthMeters; break; } case CABViewControlTypes.ORTS_REMAINING_TRAIN_LENGHT_SPEED_RESTRICTED: { + if (CruiseControl == null) + { + data = 0; + break; + } if (CruiseControl.RemainingTrainLengthToPassRestrictedZone == 0) data = 0; else @@ -4986,6 +5047,11 @@ public virtual float GetDataOf(CabViewControl cvc) } case CABViewControlTypes.ORTS_REMAINING_TRAIN_LENGTH_PERCENT: { + if (CruiseControl == null) + { + data = 0; + break; + } if (CruiseControl.SpeedRegMode != CruiseControl.SpeedRegulatorMode.Auto) { data = 0; @@ -5017,10 +5083,25 @@ public virtual float GetDataOf(CabViewControl cvc) } case CABViewControlTypes.ORTS_FORCE_IN_PERCENT_THROTTLE_AND_DYNAMIC_BRAKE: { - if (CruiseControl.Equipped && CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) + if (CruiseControl != null) { - data = CruiseControl.ForceThrottleAndDynamicBrake; - if (DynamicBrakePercent > 0 && data > -DynamicBrakePercent) data = -DynamicBrakePercent; + if (CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) + { + data = CruiseControl.ForceThrottleAndDynamicBrake; + if (DynamicBrakePercent > 0 && data > -DynamicBrakePercent) data = -DynamicBrakePercent; + } + else + { + if (ThrottlePercent > 0) + { + data = ThrottlePercent; + } + else if (DynamicBrakePercent > 0 && AbsSpeedMpS > 0) + { + data = -DynamicBrakePercent; + } + else data = 0; + } } else { @@ -5043,23 +5124,36 @@ public virtual float GetDataOf(CabViewControl cvc) } case CABViewControlTypes.ORTS_CONTROLLER_VOLTAGE: { + if (CruiseControl == null) + { + data = 0; + break; + } data = CruiseControl.controllerVolts; break; } case CABViewControlTypes.ORTS_AMPERS_BY_CONTROLLER_VOLTAGE: { - if (CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) + if (CruiseControl != null) { - if (CruiseControl.controllerVolts < 0) data = -CruiseControl.controllerVolts / 100 * (MaxCurrentA * 0.8f); - else data = CruiseControl.controllerVolts / 100 * (MaxCurrentA * 0.8f); - if (data == 0 && DynamicBrakePercent > 0 && AbsSpeedMpS > 0) data = DynamicBrakePercent / 100 * (MaxCurrentA * 0.8f); + if (CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) + { + if (CruiseControl.controllerVolts < 0) data = -CruiseControl.controllerVolts / 100 * (MaxCurrentA * 0.8f); + else data = CruiseControl.controllerVolts / 100 * (MaxCurrentA * 0.8f); + if (data == 0 && DynamicBrakePercent > 0 && AbsSpeedMpS > 0) data = DynamicBrakePercent / 100 * (MaxCurrentA * 0.8f); + } + else + { + if (DynamicBrakePercent > 0 && AbsSpeedMpS > 0) data = DynamicBrakePercent / 200 * (MaxCurrentA * 0.8f); + else data = ThrottlePercent / 100 * (MaxCurrentA * 0.8f); + } + CruiseControl.Ampers = data; } else { if (DynamicBrakePercent > 0 && AbsSpeedMpS > 0) data = DynamicBrakePercent / 200 * (MaxCurrentA * 0.8f); else data = ThrottlePercent / 100 * (MaxCurrentA * 0.8f); } - CruiseControl.Ampers = data; break; } case CABViewControlTypes.ORTS_ODOMETER: diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs index 2f30461720..e6c9a5ff85 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs @@ -110,7 +110,6 @@ public void Parse(string lowercasetoken, STFReader stf) { switch (lowercasetoken) { - case "engine(ortscruisecontrol": Equipped = true; break; case "engine(ortscruisecontrol(usethrottle": UseThrottle = stf.ReadBoolBlock(false); break; case "engine(ortscruisecontrol(throttleincreasespeed": ThrottleIncreaseSpeed = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.1f); break; case "engine(ortscruisecontrol(throttledecreasespeed": ThrottleDecreaseSpeed = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.2f); break; diff --git a/Source/RunActivity/Viewer3D/RollingStock/MSTSLocomotiveViewer.cs b/Source/RunActivity/Viewer3D/RollingStock/MSTSLocomotiveViewer.cs index b8c881bbb9..010d9abfd0 100644 --- a/Source/RunActivity/Viewer3D/RollingStock/MSTSLocomotiveViewer.cs +++ b/Source/RunActivity/Viewer3D/RollingStock/MSTSLocomotiveViewer.cs @@ -1965,9 +1965,14 @@ public virtual int GetDrawIndex() } else { - if ((Locomotive.CruiseControl.SpeedRegMode == Simulation.RollingStocks.SubSystems.CruiseControl.SpeedRegulatorMode.Auto && !Locomotive.CruiseControl.DynamicBrakePriority) || Locomotive.DynamicBrakeIntervention > 0) + if (Locomotive.CruiseControl != null) { - index = 0; + if ((Locomotive.CruiseControl.SpeedRegMode == Simulation.RollingStocks.SubSystems.CruiseControl.SpeedRegulatorMode.Auto && !Locomotive.CruiseControl.DynamicBrakePriority) || Locomotive.DynamicBrakeIntervention > 0) + { + index = 0; + } + else + index = PercentToIndex(dynBrakePercent); } else index = PercentToIndex(dynBrakePercent); @@ -1996,6 +2001,11 @@ public virtual int GetDrawIndex() index = PercentToIndex(Locomotive.GetCombinedHandleValue(false)); break; case CABViewControlTypes.ORTS_SELECTED_SPEED_DISPLAY: + if (Locomotive.CruiseControl == null) + { + index = 0; + break; + } index = (int)MpS.ToKpH(Locomotive.CruiseControl.SelectedSpeedMpS) / 10; break; case CABViewControlTypes.ALERTER_DISPLAY: @@ -2376,6 +2386,8 @@ public void HandleUserInput() // Jindrich case CABViewControlTypes.ORTS_CC_SELECT_SPEED: + if (Locomotive.CruiseControl == null) + break; var p = ChangedValue(0); if (p == 1) { From f8536bd6d6068b30b0b9d5d257061186ada5349b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jind=C5=99ich=20Machal=C3=ADnek?= Date: Fri, 5 Feb 2021 03:10:09 +0100 Subject: [PATCH 5/7] Changes to 464 + MultiPositionControler initial commit --- Source/ORTS.Common/Input/UserCommand.cs | 40 +- Source/ORTS.Settings/InputSettings.cs | 44 +- Source/Orts.Simulation/Orts.Simulation.csproj | 1 + .../RollingStocks/MSTSLocomotive.cs | 98 ++- .../Controllers/MultiPositionController.cs | 828 ++++++++++++++++++ .../RollingStocks/SubSystems/CruiseControl.cs | 77 +- .../RollingStock/MSTSLocomotiveViewer.cs | 57 +- 7 files changed, 1037 insertions(+), 108 deletions(-) create mode 100644 Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Controllers/MultiPositionController.cs diff --git a/Source/ORTS.Common/Input/UserCommand.cs b/Source/ORTS.Common/Input/UserCommand.cs index cf20e7b39b..3aba61f06b 100644 --- a/Source/ORTS.Common/Input/UserCommand.cs +++ b/Source/ORTS.Common/Input/UserCommand.cs @@ -215,25 +215,25 @@ public enum UserCommand [GetString("Control Cruise Control Mode Increase")] ControlCruiseControlModeIncrease, [GetString("Control Cruise Control Mode Decrease")] ControlCruiseControlModeDecrease, [GetString("Control Train Type Change (Passenger/Cargo)")] ControlTrainTypePaxCargo, - [GetString("Control Select Speed 10 kph")] ControlSelectSpeed10KpH, - [GetString("Control Select Speed 20 kph")] ControlSelectSpeed20KpH, - [GetString("Control Select Speed 30 kph")] ControlSelectSpeed30KpH, - [GetString("Control Select Speed 40 kph")] ControlSelectSpeed40KpH, - [GetString("Control Select Speed 50 kph")] ControlSelectSpeed50KpH, - [GetString("Control Select Speed 60 kph")] ControlSelectSpeed60KpH, - [GetString("Control Select Speed 70 kph")] ControlSelectSpeed70KpH, - [GetString("Control Select Speed 80 kph")] ControlSelectSpeed80KpH, - [GetString("Control Select Speed 90 kph")] ControlSelectSpeed90KpH, - [GetString("Control Select Speed 100 kph")] ControlSelectSpeed100KpH, - [GetString("Control Select Speed 110 kph")] ControlSelectSpeed110KpH, - [GetString("Control Select Speed 120 kph")] ControlSelectSpeed120KpH, - [GetString("Control Select Speed 130 kph")] ControlSelectSpeed130KpH, - [GetString("Control Select Speed 140 kph")] ControlSelectSpeed140KpH, - [GetString("Control Select Speed 150 kph")] ControlSelectSpeed150KpH, - [GetString("Control Select Speed 160 kph")] ControlSelectSpeed160KpH, - [GetString("Control Select Speed 170 kph")] ControlSelectSpeed170KpH, - [GetString("Control Select Speed 180 kph")] ControlSelectSpeed180KpH, - [GetString("Control Select Speed 190 kph")] ControlSelectSpeed190KpH, - [GetString("Control Select Speed 200 kph")] ControlSelectSpeed200KpH, + [GetString("Control Select Speed 10 kph/mph")] ControlSelectSpeed10, + [GetString("Control Select Speed 20 kph/mph")] ControlSelectSpeed20, + [GetString("Control Select Speed 30 kph/mph")] ControlSelectSpeed30, + [GetString("Control Select Speed 40 kph/mph")] ControlSelectSpeed40, + [GetString("Control Select Speed 50 kph/mph")] ControlSelectSpeed50, + [GetString("Control Select Speed 60 kph/mph")] ControlSelectSpeed60, + [GetString("Control Select Speed 70 kph/mph")] ControlSelectSpeed70, + [GetString("Control Select Speed 80 kph/mph")] ControlSelectSpeed80, + [GetString("Control Select Speed 90 kph/mph")] ControlSelectSpeed90, + [GetString("Control Select Speed 100 kph/mph")] ControlSelectSpeed100, + [GetString("Control Select Speed 110 kph/mph")] ControlSelectSpeed110, + [GetString("Control Select Speed 120 kph/mph")] ControlSelectSpeed120, + [GetString("Control Select Speed 130 kph/mph")] ControlSelectSpeed130, + [GetString("Control Select Speed 140 kph/mph")] ControlSelectSpeed140, + [GetString("Control Select Speed 150 kph/mph")] ControlSelectSpeed150, + [GetString("Control Select Speed 160 kph/mph")] ControlSelectSpeed160, + [GetString("Control Select Speed 170 kph/mph")] ControlSelectSpeed170, + [GetString("Control Select Speed 180 kph/mph")] ControlSelectSpeed180, + [GetString("Control Select Speed 190 kph/mph")] ControlSelectSpeed190, + [GetString("Control Select Speed 200 kph/mph")] ControlSelectSpeed200, } } diff --git a/Source/ORTS.Settings/InputSettings.cs b/Source/ORTS.Settings/InputSettings.cs index 2a69c1fe38..3564274c63 100644 --- a/Source/ORTS.Settings/InputSettings.cs +++ b/Source/ORTS.Settings/InputSettings.cs @@ -447,28 +447,28 @@ static void InitializeCommands(UserCommandInput[] Commands) Commands[(int)UserCommand.ControlCruiseControlModeDecrease] = new UserCommandKeyInput(0x1E, KeyModifiers.Control); Commands[(int)UserCommand.ControlCruiseControlModeIncrease] = new UserCommandKeyInput(0x20, KeyModifiers.Control); Commands[(int)UserCommand.ControlTrainTypePaxCargo] = new UserCommandKeyInput(0x31, KeyModifiers.Control | KeyModifiers.Shift); - Commands[(int)UserCommand.ControlSelectSpeed10KpH] = new UserCommandKeyInput(0x3B, KeyModifiers.Control | KeyModifiers.Shift); - Commands[(int)UserCommand.ControlSelectSpeed20KpH] = new UserCommandKeyInput(0x3C, KeyModifiers.Control | KeyModifiers.Shift); - Commands[(int)UserCommand.ControlSelectSpeed30KpH] = new UserCommandKeyInput(0x3D, KeyModifiers.Control | KeyModifiers.Shift); - Commands[(int)UserCommand.ControlSelectSpeed40KpH] = new UserCommandKeyInput(0x3E, KeyModifiers.Control | KeyModifiers.Shift); - Commands[(int)UserCommand.ControlSelectSpeed50KpH] = new UserCommandKeyInput(0x3F, KeyModifiers.Control | KeyModifiers.Shift); - Commands[(int)UserCommand.ControlSelectSpeed60KpH] = new UserCommandKeyInput(0x40, KeyModifiers.Control | KeyModifiers.Shift); - Commands[(int)UserCommand.ControlSelectSpeed70KpH] = new UserCommandKeyInput(0x41, KeyModifiers.Control | KeyModifiers.Shift); - Commands[(int)UserCommand.ControlSelectSpeed80KpH] = new UserCommandKeyInput(0x42, KeyModifiers.Control | KeyModifiers.Shift); - Commands[(int)UserCommand.ControlSelectSpeed90KpH] = new UserCommandKeyInput(0x43, KeyModifiers.Control | KeyModifiers.Shift); - Commands[(int)UserCommand.ControlSelectSpeed100KpH] = new UserCommandKeyInput(0x44, KeyModifiers.Control | KeyModifiers.Shift); - Commands[(int)UserCommand.ControlSelectSpeed110KpH] = new UserCommandKeyInput(0x57, KeyModifiers.Control | KeyModifiers.Shift); - Commands[(int)UserCommand.ControlSelectSpeed120KpH] = new UserCommandKeyInput(0x58, KeyModifiers.Control | KeyModifiers.Shift); - Commands[(int)UserCommand.ControlSelectSpeed110KpH] = new UserCommandKeyInput(0x02, KeyModifiers.Control | KeyModifiers.Shift); - Commands[(int)UserCommand.ControlSelectSpeed120KpH] = new UserCommandKeyInput(0x03, KeyModifiers.Control | KeyModifiers.Shift); - Commands[(int)UserCommand.ControlSelectSpeed130KpH] = new UserCommandKeyInput(0x04, KeyModifiers.Control | KeyModifiers.Shift); - Commands[(int)UserCommand.ControlSelectSpeed140KpH] = new UserCommandKeyInput(0x05, KeyModifiers.Control | KeyModifiers.Shift); - Commands[(int)UserCommand.ControlSelectSpeed150KpH] = new UserCommandKeyInput(0x06, KeyModifiers.Control | KeyModifiers.Shift); - Commands[(int)UserCommand.ControlSelectSpeed160KpH] = new UserCommandKeyInput(0x07, KeyModifiers.Control | KeyModifiers.Shift); - Commands[(int)UserCommand.ControlSelectSpeed170KpH] = new UserCommandKeyInput(0x08, KeyModifiers.Control | KeyModifiers.Shift); - Commands[(int)UserCommand.ControlSelectSpeed180KpH] = new UserCommandKeyInput(0x09, KeyModifiers.Control | KeyModifiers.Shift); - Commands[(int)UserCommand.ControlSelectSpeed190KpH] = new UserCommandKeyInput(0x0A, KeyModifiers.Control | KeyModifiers.Shift); - Commands[(int)UserCommand.ControlSelectSpeed200KpH] = new UserCommandKeyInput(0x0B, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed10] = new UserCommandKeyInput(0x3B, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed20] = new UserCommandKeyInput(0x3C, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed30] = new UserCommandKeyInput(0x3D, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed40] = new UserCommandKeyInput(0x3E, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed50] = new UserCommandKeyInput(0x3F, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed60] = new UserCommandKeyInput(0x40, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed70] = new UserCommandKeyInput(0x41, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed80] = new UserCommandKeyInput(0x42, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed90] = new UserCommandKeyInput(0x43, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed100] = new UserCommandKeyInput(0x44, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed110] = new UserCommandKeyInput(0x57, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed120] = new UserCommandKeyInput(0x58, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed110] = new UserCommandKeyInput(0x02, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed120] = new UserCommandKeyInput(0x03, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed130] = new UserCommandKeyInput(0x04, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed140] = new UserCommandKeyInput(0x05, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed150] = new UserCommandKeyInput(0x06, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed160] = new UserCommandKeyInput(0x07, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed170] = new UserCommandKeyInput(0x08, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed180] = new UserCommandKeyInput(0x09, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed190] = new UserCommandKeyInput(0x0A, KeyModifiers.Control | KeyModifiers.Shift); + Commands[(int)UserCommand.ControlSelectSpeed200] = new UserCommandKeyInput(0x0B, KeyModifiers.Control | KeyModifiers.Shift); Commands[(int)UserCommand.DebugClockBackwards] = new UserCommandKeyInput(0x0C); Commands[(int)UserCommand.DebugClockForwards] = new UserCommandKeyInput(0x0D); diff --git a/Source/Orts.Simulation/Orts.Simulation.csproj b/Source/Orts.Simulation/Orts.Simulation.csproj index b9057f1e53..772838dd74 100644 --- a/Source/Orts.Simulation/Orts.Simulation.csproj +++ b/Source/Orts.Simulation/Orts.Simulation.csproj @@ -117,6 +117,7 @@ + diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs index 34b3768485..31e15fd4ac 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs @@ -405,6 +405,7 @@ public float OdometerM // Jindrich public CruiseControl CruiseControl; + public MultiPositionController MultiPositionController; public bool SelectingSpeedPressed = false; public bool EngineBrakePriority = false; public bool IsAPartOfPlayerTrain = false; @@ -929,6 +930,7 @@ public override void Parse(string lowercasetoken, STFReader stf) case "engine(ortsmaxtracksandersandconsumption": TrackSanderSandConsumptionM3pS = stf.ReadFloatBlock(STFReader.UNITS.Volume, null); break; case "engine(ortsmaxtracksanderairconsumption": TrackSanderAirComsumptionM3pS = stf.ReadFloatBlock(STFReader.UNITS.Volume, null); break; case "engine(ortscruisecontrol": SetUpCruiseControl(); break; + case "engine(multipositioncontroller": SetUpMPC(); break; default: base.Parse(lowercasetoken, stf); if (CruiseControl != null) CruiseControl.Parse(lowercasetoken, stf); break; } } @@ -1450,6 +1452,14 @@ public void SetUpCruiseControl() CruiseControl.Equipped = true; } + /// + /// Make instance of multi position controller + /// + public void SetUpMPC() + { + MultiPositionController = new MultiPositionController(this); + } + //================================================================================================// /// /// Set starting conditions when initial speed > 0 @@ -2881,11 +2891,19 @@ public void StartThrottleIncrease() { if (CruiseControl != null) { - if (CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) + if (CruiseControl.UseThrottleAsForceSelector && CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) { - CruiseControl.SpeedSelectorModeStartIncrease(); + CruiseControl.SpeedRegulatorMaxForceStartIncrease(); return; } + else + { + if (CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) + { + CruiseControl.SpeedSelectorModeStartIncrease(); + return; + } + } } if (DynamicBrakeController != null && DynamicBrakeController.CurrentValue >= 0 && (DynamicBrakePercent >= 0 || !(DynamicBrakePercent == -1 && !DynamicBrake || DynamicBrakePercent >= 0 && DynamicBrake))) { @@ -2909,11 +2927,19 @@ public void StopThrottleIncrease() { if (CruiseControl != null) { - if (CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) + if (CruiseControl.UseThrottleAsForceSelector && CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) { - CruiseControl.SpeedSelectorModeStopIncrease(); + CruiseControl.SpeedRegulatorMaxForceStopIncrease(); return; } + else + { + if (CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) + { + CruiseControl.SpeedSelectorModeStopIncrease(); + return; + } + } } AlerterReset(TCSEvent.ThrottleChanged); ThrottleController.StopIncrease(); @@ -2944,14 +2970,22 @@ public void StartThrottleDecrease() { if (CruiseControl != null) { - if (CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) + if (CruiseControl.UseThrottleAsForceSelector && CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) { - if (!speedSelectorModeDecreasing) + CruiseControl.SpeedRegulatorMaxForceStartDecrease(); + return; + } + else + { + if (CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) { - CruiseControl.SpeedSelectorModeDecrease(); - speedSelectorModeDecreasing = true; + if (!speedSelectorModeDecreasing) + { + CruiseControl.SpeedSelectorModeDecrease(); + speedSelectorModeDecreasing = true; + } + return; } - return; } } if (CombinedControlType == CombinedControl.ThrottleDynamic && ThrottleController.CurrentValue <= 0) @@ -2966,11 +3000,19 @@ public void StopThrottleDecrease() { if (CruiseControl != null) { - if (CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) + if (CruiseControl.UseThrottleAsForceSelector && CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) { - speedSelectorModeDecreasing = false; + CruiseControl.SpeedRegulatorMaxForceStopDecrease(); return; } + else + { + if (CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) + { + speedSelectorModeDecreasing = false; + return; + } + } } AlerterReset(TCSEvent.ThrottleChanged); ThrottleController.StopDecrease(); @@ -3115,6 +3157,14 @@ public void AdjustNotchedThrottle(bool increase) public void SetThrottleValue(float value) { + if (CruiseControl != null) + { + if (CruiseControl.UseThrottleAsForceSelector && CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) + { + CruiseControl.SetMaxForcePercent((float)Math.Round(value * 100, 0)); + return; + } + } var controller = ThrottleController; var oldValue = controller.IntermediateValue; var change = controller.SetValue(value); @@ -3133,7 +3183,18 @@ public void SetThrottleValue(float value) public void SetThrottlePercent(float percent) { - ThrottleController.SetPercent(percent); + if (CruiseControl != null) + { + if (CruiseControl.UseThrottleAsForceSelector && CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) + { + CruiseControl.SetMaxForcePercent(percent); + return; + } + else + ThrottleController.SetPercent(percent); + } + else + ThrottleController.SetPercent(percent); } public void SetThrottlePercentWithSound(float percent) @@ -3729,7 +3790,11 @@ public void StopDynamicBrakeDecrease() { DynamicBrakeController.StopDecrease(); new DynamicBrakeCommand(Simulator.Log, false, DynamicBrakeController.CurrentValue, DynamicBrakeController.CommandStartTime); - if (DynamicBrakePercent < 1) CruiseControl.DynamicBrakePriority = false; + if (CruiseControl != null) + { + if (DynamicBrakePercent < 1) + CruiseControl.DynamicBrakePriority = false; + } } } @@ -4546,7 +4611,8 @@ public virtual float GetDataOf(CabViewControl cvc) case CABViewControlTypes.THROTTLE_DISPLAY: case CABViewControlTypes.CPH_DISPLAY: { - if (CruiseControl.SkipThrottleDisplay) break; + if (CruiseControl != null) + if (CruiseControl.SkipThrottleDisplay) break; data = Train.TrainType == Train.TRAINTYPE.AI_PLAYERHOSTING? ThrottlePercent / 100f : LocalThrottlePercent / 100f; break; } @@ -4977,7 +5043,9 @@ public virtual float GetDataOf(CabViewControl cvc) break; } if (CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto || CruiseControl.MaxForceKeepSelectedStepWhenManualModeSet) - data = CruiseControl.SelectedMaxAccelerationStep - 1; + { + data = (CruiseControl.SelectedMaxAccelerationStep - 1) * (float)cvc.MaxValue / 100; + } else data = 0; break; diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Controllers/MultiPositionController.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Controllers/MultiPositionController.cs new file mode 100644 index 0000000000..e407d2313b --- /dev/null +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Controllers/MultiPositionController.cs @@ -0,0 +1,828 @@ +// COPYRIGHT 2010 - 2021 by the Open Rails project. +// +// This file is part of Open Rails. +// +// Open Rails is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Open Rails is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Open Rails. If not, see . + +using System; +using System.Collections.Generic; +using System.IO; +using ORTS.Common; + +namespace Orts.Simulation.RollingStocks.SubSystems.Controllers +{ + public class MultiPositionController + { + public MultiPositionController(MSTSLocomotive locomotive) + { + Locomotive = locomotive; + Simulator = Locomotive.Simulator; + controllerPosition = ControllerPosition.Neutral; + } + MSTSLocomotive Locomotive; + Simulator Simulator; + + public Dictionary PositionsList = new Dictionary(); + + public bool Equipped = false; + public bool StateChanged = false; + + public ControllerPosition controllerPosition = new ControllerPosition(); + public ControllerCruiseControlLogic cruiseControlLogic = new ControllerCruiseControlLogic(); + protected float elapsedSecondsFromLastChange = 0; + protected bool checkNeutral = false; + protected bool noKeyPressed = true; + protected string currentPosition = ""; + protected bool emergencyBrake = false; + protected bool previousDriveModeWasAddPower = false; + protected bool isBraking = false; + protected bool needPowerUpAfterBrake = false; + public bool CanControlTrainBrake = false; + protected bool initialized = false; + protected bool movedForward = false; + protected bool movedAft = false; + + public void Save(BinaryWriter outf) + { + outf.Write(this.checkNeutral); + outf.Write((int)this.controllerPosition); + outf.Write(this.currentPosition); + outf.Write(this.elapsedSecondsFromLastChange); + outf.Write(this.emergencyBrake); + outf.Write(this.Equipped); + outf.Write(this.isBraking); + outf.Write(this.needPowerUpAfterBrake); + outf.Write(this.noKeyPressed); + outf.Write(this.previousDriveModeWasAddPower); + outf.Write(this.StateChanged); + } + + public void Restore(BinaryReader inf) + { + initialized = true; + checkNeutral = inf.ReadBoolean(); + int fControllerPosition = inf.ReadInt32(); + controllerPosition = (ControllerPosition)fControllerPosition; + currentPosition = inf.ReadString(); + elapsedSecondsFromLastChange = inf.ReadSingle(); + emergencyBrake = inf.ReadBoolean(); + Equipped = inf.ReadBoolean(); + isBraking = inf.ReadBoolean(); + needPowerUpAfterBrake = inf.ReadBoolean(); + noKeyPressed = inf.ReadBoolean(); + previousDriveModeWasAddPower = inf.ReadBoolean(); + StateChanged = inf.ReadBoolean(); + } + + public void Update(float elapsedClockSeconds) + { + if (!initialized) + { + foreach (KeyValuePair pair in PositionsList) + { + if (pair.Value.ToLower() == "default") + { + currentPosition = pair.Key; + break; + } + } + initialized = true; + } + if (!Locomotive.IsPlayerTrain) return; + + if (Locomotive.CruiseControl.DynamicBrakePriority) return; + ReloadPositions(); + if (!Locomotive.Battery) return; + if (Locomotive.AbsSpeedMpS > 0) + { + if (emergencyBrake) + { + Locomotive.TrainBrakeController.TCSEmergencyBraking = true; + return; + } + } + else + { + emergencyBrake = false; + } + if (Locomotive.TrainBrakeController.TCSEmergencyBraking) + Locomotive.TrainBrakeController.TCSEmergencyBraking = false; + elapsedSecondsFromLastChange += elapsedClockSeconds; + // Simulator.Confirmer.MSG(currentPosition.ToString()); + if (checkNeutral) + { + if (elapsedSecondsFromLastChange > 0.2f) + { + CheckNeutralPosition(); + checkNeutral = false; + } + } + if (!Locomotive.CruiseControl.Equipped || Locomotive.CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Manual) + { + if (controllerPosition == ControllerPosition.ThrottleIncrease) + { + if (Locomotive.DynamicBrakePercent < 1) + { + if (Locomotive.ThrottlePercent < 100) + { + float step = 100 / Locomotive.CruiseControl.ThrottleFullRangeIncreaseTimeSeconds; + step *= elapsedClockSeconds; + Locomotive.SetThrottlePercent(Locomotive.ThrottlePercent + step); + } + } + } + if (controllerPosition == ControllerPosition.ThrottleIncreaseFast) + { + if (Locomotive.DynamicBrakePercent < 1) + { + if (Locomotive.ThrottlePercent < 100) + { + float step = 100 / Locomotive.CruiseControl.ThrottleFullRangeIncreaseTimeSeconds * 2; + step *= elapsedClockSeconds; + Locomotive.SetThrottlePercent(Locomotive.ThrottlePercent + step); + } + } + } + if (controllerPosition == ControllerPosition.ThrottleDecrease) + { + if (Locomotive.ThrottlePercent > 0) + { + float step = 100 / Locomotive.CruiseControl.ThrottleFullRangeDecreaseTimeSeconds; + step *= elapsedClockSeconds; + Locomotive.SetThrottlePercent(Locomotive.ThrottlePercent - step); + } + } + if (controllerPosition == ControllerPosition.ThrottleDecreaseFast) + { + if (Locomotive.ThrottlePercent > 0) + { + float step = 100 / Locomotive.CruiseControl.ThrottleFullRangeDecreaseTimeSeconds * 2; + step *= elapsedClockSeconds; + Locomotive.SetThrottlePercent(Locomotive.ThrottlePercent - step); + } + } + if (controllerPosition == ControllerPosition.Neutral || controllerPosition == ControllerPosition.DynamicBrakeHold) + { + if (CanControlTrainBrake) + { + if (Locomotive.TrainBrakeController.GetStatus().ToLower() == "apply") + { + Locomotive.StartTrainBrakeDecrease(null); + } + if (Locomotive.TrainBrakeController.GetStatus().ToLower() == "neutral") + { + Locomotive.StopTrainBrakeDecrease(); + } + } + if (Locomotive.ThrottlePercent < 2) + { + if (Locomotive.ThrottlePercent != 0) + Locomotive.SetThrottlePercent(0); + } + if (Locomotive.ThrottlePercent > 1) + { + Locomotive.SetThrottlePercent(Locomotive.ThrottlePercent - 1f); + } + if (Locomotive.ThrottlePercent > 100) + { + Locomotive.ThrottlePercent = 100; + } + + } + if (controllerPosition == ControllerPosition.DynamicBrakeIncrease) + { + if (CanControlTrainBrake) + { + if (Locomotive.TrainBrakeController.GetStatus().ToLower() == "apply") + { + Locomotive.StartTrainBrakeDecrease(null); + } + if (Locomotive.TrainBrakeController.GetStatus().ToLower() == "neutral") + { + Locomotive.StopTrainBrakeDecrease(); + } + } + if (Locomotive.DynamicBrakePercent == -1) Locomotive.SetDynamicBrakePercent(0); + if (Locomotive.ThrottlePercent < 1 && Locomotive.DynamicBrakePercent < 100) + { + Locomotive.SetDynamicBrakePercent(Locomotive.DynamicBrakePercent + 2f); + } + } + if (controllerPosition == ControllerPosition.DynamicBrakeIncreaseFast) + { + if (CanControlTrainBrake) + { + if (Locomotive.TrainBrakeController.GetStatus().ToLower() == "apply") + { + Locomotive.StartTrainBrakeDecrease(null); + } + if (Locomotive.TrainBrakeController.GetStatus().ToLower() == "neutral") + { + Locomotive.StopTrainBrakeDecrease(); + } + } + if (Locomotive.DynamicBrakePercent == -1) Locomotive.SetDynamicBrakePercent(0); + if (Locomotive.ThrottlePercent < 1 && Locomotive.DynamicBrakePercent < 100) + { + Locomotive.SetDynamicBrakePercent(Locomotive.DynamicBrakePercent + 2f); + } + } + if (controllerPosition == ControllerPosition.DynamicBrakeDecrease) + { + if (Locomotive.DynamicBrakePercent > 0) + { + Locomotive.SetDynamicBrakePercent(Locomotive.DynamicBrakePercent - 1); + } + } + if (controllerPosition == ControllerPosition.Drive || controllerPosition == ControllerPosition.ThrottleHold) + { + if (Locomotive.DynamicBrakePercent < 2) + { + Locomotive.SetDynamicBrakePercent(-1); + } + if (Locomotive.DynamicBrakePercent > 1) + { + Locomotive.SetDynamicBrakePercent(Locomotive.DynamicBrakePercent - 1); + } + } + if (controllerPosition == ControllerPosition.TrainBrakeIncrease) + { + if (CanControlTrainBrake) + { + if (Locomotive.TrainBrakeController.GetStatus().ToLower() != "apply") + { + String test = Locomotive.TrainBrakeController.GetStatus().ToLower(); + Locomotive.StartTrainBrakeIncrease(null); + } + else + { + Locomotive.StopTrainBrakeIncrease(); + } + } + } + else if (controllerPosition == ControllerPosition.Drive) + { + if (CanControlTrainBrake) + { + if (Locomotive.TrainBrakeController.GetStatus().ToLower() != "release") + { + String boom = Locomotive.TrainBrakeController.GetStatus().ToString(); + Locomotive.StartTrainBrakeDecrease(null); + } + else + Locomotive.StopTrainBrakeDecrease(); + } + } + if (controllerPosition == ControllerPosition.TrainBrakeDecrease) + { + if (CanControlTrainBrake) + { + if (Locomotive.TrainBrakeController.GetStatus().ToLower() != "release") + { + String boom = Locomotive.TrainBrakeController.GetStatus().ToString(); + Locomotive.StartTrainBrakeDecrease(null); + } + else + Locomotive.StopTrainBrakeDecrease(); + } + } + if (controllerPosition == ControllerPosition.EmergencyBrake) + { + EmergencyBrakes(); + emergencyBrake = true; + } + if (controllerPosition == ControllerPosition.ThrottleIncreaseOrDynamicBrakeDecrease) + { + if (Locomotive.DynamicBrakePercent > 0) + { + Locomotive.SetDynamicBrakePercent(Locomotive.DynamicBrakePercent - 0.2f); + if (Locomotive.DynamicBrakePercent < 2) + { + Locomotive.SetDynamicBrakePercent(0); + Locomotive.DynamicBrakeChangeActiveState(false); + } + } + else + { + if (Locomotive.ThrottlePercent < 100) + Locomotive.SetThrottlePercent(Locomotive.ThrottlePercent + 0.2f); + if (Locomotive.ThrottlePercent > 100) + Locomotive.SetThrottlePercent(100); + } + } + if (controllerPosition == ControllerPosition.ThrottleIncreaseOrDynamicBrakeDecreaseFast) + { + if (Locomotive.DynamicBrakePercent > 0) + { + Locomotive.SetDynamicBrakePercent(Locomotive.DynamicBrakePercent - 1); + if (Locomotive.DynamicBrakePercent < 2) + { + Locomotive.SetDynamicBrakePercent(0); + Locomotive.DynamicBrakeChangeActiveState(false); + } + } + else + { + if (Locomotive.ThrottlePercent < 100) + Locomotive.SetThrottlePercent(Locomotive.ThrottlePercent + 1); + if (Locomotive.ThrottlePercent > 100) + Locomotive.SetThrottlePercent(100); + } + } + + if (controllerPosition == ControllerPosition.DynamicBrakeIncreaseOrThrottleDecrease) + { + if (Locomotive.ThrottlePercent > 0) + { + Locomotive.SetThrottlePercent(Locomotive.ThrottlePercent - 0.2f); + if (Locomotive.ThrottlePercent < 0) + Locomotive.ThrottlePercent = 0; + } + else + { + if (Locomotive.DynamicBrakePercent < 100) + { + Locomotive.SetDynamicBrakePercent(Locomotive.DynamicBrakePercent + 0.2f); + } + if (Locomotive.DynamicBrakePercent > 100) + Locomotive.SetDynamicBrakePercent(100); + } + } + if (controllerPosition == ControllerPosition.DynamicBrakeIncreaseOrThrottleDecreaseFast) + { + if (Locomotive.ThrottlePercent > 0) + { + Locomotive.SetThrottlePercent(Locomotive.ThrottlePercent - 1); + if (Locomotive.ThrottlePercent < 0) + Locomotive.ThrottlePercent = 0; + } + else + { + if (Locomotive.DynamicBrakePercent < 100) + { + Locomotive.SetDynamicBrakePercent(Locomotive.DynamicBrakePercent + 1); + } + if (Locomotive.DynamicBrakePercent > 100) + Locomotive.SetDynamicBrakePercent(100); + } + } + } + else if (Locomotive.CruiseControl.Equipped && Locomotive.CruiseControl.SpeedRegMode == CruiseControl.SpeedRegulatorMode.Auto) + { + if (cruiseControlLogic == ControllerCruiseControlLogic.SpeedOnly) + { + if (controllerPosition == ControllerPosition.ThrottleIncrease || controllerPosition == ControllerPosition.ThrottleIncreaseFast) + { + if (!Locomotive.CruiseControl.ContinuousSpeedIncreasing && movedForward) return; + movedForward = true; + Locomotive.CruiseControl.SelectedSpeedMpS = Locomotive.CruiseControl.SelectedSpeedMpS + Locomotive.CruiseControl.SpeedRegulatorNominalSpeedStepMpS; + if (Locomotive.CruiseControl.SelectedSpeedMpS > Locomotive.MaxSpeedMpS) Locomotive.CruiseControl.SelectedSpeedMpS = Locomotive.MaxSpeedMpS; + } + if (controllerPosition == ControllerPosition.ThrottleDecrease || controllerPosition == ControllerPosition.ThrottleDecreaseFast) + { + if (!Locomotive.CruiseControl.ContinuousSpeedDecreasing && movedAft) return; + movedAft = true; + Locomotive.CruiseControl.SelectedSpeedMpS = Locomotive.CruiseControl.SelectedSpeedMpS - Locomotive.CruiseControl.SpeedRegulatorNominalSpeedStepMpS; + if (Locomotive.CruiseControl.SelectedSpeedMpS < 0) Locomotive.CruiseControl.SelectedSpeedMpS = 0; + } + return; + } + if (controllerPosition == ControllerPosition.ThrottleIncrease) + { + isBraking = false; + Locomotive.CruiseControl.SpeedSelMode = CruiseControl.SpeedSelectorMode.Start; + previousDriveModeWasAddPower = true; + } + if (controllerPosition == ControllerPosition.Neutral) + { + Locomotive.CruiseControl.SpeedSelMode = CruiseControl.SpeedSelectorMode.Neutral; + } + if (controllerPosition == ControllerPosition.Drive) + { + bool applyPower = true; + if (isBraking && needPowerUpAfterBrake) + { + if (Locomotive.DynamicBrakePercent < 2) + { + Locomotive.SetDynamicBrakePercent(-1); + } + if (Locomotive.DynamicBrakePercent > 1) + { + Locomotive.SetDynamicBrakePercent(Locomotive.DynamicBrakePercent - 1); + } + if (CanControlTrainBrake) + { + if (Locomotive.TrainBrakeController.GetStatus().ToLower() != "release") + { + Locomotive.StartTrainBrakeDecrease(null); + } + else + Locomotive.StopTrainBrakeDecrease(); + } + applyPower = false; + } + if (applyPower) Locomotive.CruiseControl.SpeedSelMode = CruiseControl.SpeedSelectorMode.On; + } + if (controllerPosition == ControllerPosition.DynamicBrakeIncrease) + { + isBraking = true; + previousDriveModeWasAddPower = false; + Locomotive.CruiseControl.SpeedSelMode = CruiseControl.SpeedSelectorMode.Neutral; + if (CanControlTrainBrake) + { + if (Locomotive.TrainBrakeController.GetStatus().ToLower() == "apply") + { + Locomotive.StartTrainBrakeDecrease(null); + } + if (Locomotive.TrainBrakeController.GetStatus().ToLower() == "neutral") + { + Locomotive.StopTrainBrakeDecrease(); + } + } + if (Locomotive.ThrottlePercent < 1 && Locomotive.DynamicBrakePercent < 100) + { + if (Locomotive.DynamicBrakePercent < 0) + Locomotive.DynamicBrakeChangeActiveState(true); + Locomotive.SetDynamicBrakePercent(Locomotive.DynamicBrakePercent + 1f); + } + } + if (controllerPosition == ControllerPosition.DynamicBrakeIncreaseFast) + { + isBraking = true; + previousDriveModeWasAddPower = false; + Locomotive.CruiseControl.SpeedSelMode = CruiseControl.SpeedSelectorMode.Neutral; + if (CanControlTrainBrake) + { + if (Locomotive.TrainBrakeController.GetStatus().ToLower() == "apply") + { + Locomotive.StartTrainBrakeDecrease(null); + } + if (Locomotive.TrainBrakeController.GetStatus().ToLower() == "neutral") + { + Locomotive.StopTrainBrakeDecrease(); + } + } + if (Locomotive.ThrottlePercent < 1 && Locomotive.DynamicBrakePercent < 100) + { + Locomotive.SetDynamicBrakePercent(Locomotive.DynamicBrakePercent + 2f); + } + } + if (controllerPosition == ControllerPosition.TrainBrakeIncrease) + { + isBraking = true; + previousDriveModeWasAddPower = false; + Locomotive.CruiseControl.SpeedSelMode = CruiseControl.SpeedSelectorMode.Neutral; + if (CanControlTrainBrake) + { + if (Locomotive.TrainBrakeController.GetStatus().ToLower() != "apply") + { + String test = Locomotive.TrainBrakeController.GetStatus().ToLower(); + Locomotive.StartTrainBrakeIncrease(null); + } + else + { + Locomotive.StopTrainBrakeIncrease(); + } + } + } + if (controllerPosition == ControllerPosition.EmergencyBrake) + { + isBraking = true; + previousDriveModeWasAddPower = false; + Locomotive.CruiseControl.SpeedSelMode = CruiseControl.SpeedSelectorMode.Neutral; + EmergencyBrakes(); + emergencyBrake = true; + } + if (controllerPosition == ControllerPosition.CruiseControlSpeedIncrease) + { + Locomotive.CruiseControl.SelectedSpeedMpS = MpS.FromKpH((MpS.ToKpH(Locomotive.CruiseControl.SelectedSpeedMpS) + 1)); + } + if (controllerPosition == ControllerPosition.CruiseControlSpeedDecrease) + { + Locomotive.CruiseControl.SelectedSpeedMpS = MpS.FromKpH((MpS.ToKpH(Locomotive.CruiseControl.SelectedSpeedMpS) + 1)); + } + if (controllerPosition == ControllerPosition.CruiseControlSpeedSetZero) + { + Locomotive.CruiseControl.SelectedSpeedMpS = 0; + } + } + } + + private bool messageDisplayed = false; + public void DoMovement(Movement movement) + { + if (movement == Movement.Aft) movedForward = false; + if (movement == Movement.Forward) movedAft = false; + if (movement == Movement.Neutral) movedForward = movedAft = false; + messageDisplayed = false; + if (String.IsNullOrEmpty(currentPosition)) + { + foreach (KeyValuePair pair in PositionsList) + { + if (pair.Value.ToLower() == "default") + { + currentPosition = pair.Key; + break; + } + } + } + if (movement == Movement.Forward) + { + noKeyPressed = false; + checkNeutral = false; + bool isFirst = true; + string previous = ""; + foreach (KeyValuePair pair in PositionsList) + { + if (pair.Key == currentPosition) + { + if (isFirst) + break; + currentPosition = previous; + break; + } + isFirst = false; + previous = pair.Key; + } + } + if (movement == Movement.Aft) + { + noKeyPressed = false; + checkNeutral = false; + bool selectNext = false; + foreach (KeyValuePair pair in PositionsList) + { + if (selectNext) + { + currentPosition = pair.Key; + break; + } + if (pair.Key == currentPosition) selectNext = true; + } + } + if (movement == Movement.Neutral) + { + noKeyPressed = true; + foreach (KeyValuePair pair in PositionsList) + { + if (pair.Key == currentPosition) + { + if (pair.Value.ToLower() == "springloadedbackwards" || pair.Value.ToLower() == "springloadedforwards") + { + checkNeutral = true; + elapsedSecondsFromLastChange = 0; + } + if (pair.Value.ToLower() == "springloadedbackwardsimmediatelly" || pair.Value.ToLower() == "springloadedforwardsimmediatelly") + { + CheckNeutralPosition(); + ReloadPositions(); + } + } + } + } + + } + + protected void ReloadPositions() + { + if (noKeyPressed) + { + foreach (KeyValuePair pair in PositionsList) + { + if (pair.Key == currentPosition) + { + if (pair.Value.ToLower() == "cruisecontrol.needincreaseafteranybrake") + { + needPowerUpAfterBrake = true; + } + if (pair.Value.ToLower() == "springloadedforwards" || pair.Value.ToLower() == "springloadedbackwards") + { + if (elapsedSecondsFromLastChange > 0.2f) + { + elapsedSecondsFromLastChange = 0; + checkNeutral = true; + } + } + } + } + } + switch (currentPosition) + { + case "ThrottleIncrease": + { + if (!messageDisplayed) Simulator.Confirmer.Information("Controller: S"); + controllerPosition = ControllerPosition.ThrottleIncrease; + break; + } + case "ThrottleIncreaseFast": + { + if (!messageDisplayed) Simulator.Confirmer.Information("Controller: S"); + controllerPosition = ControllerPosition.ThrottleIncreaseFast; + break; + } + case "ThrottleIncreaseOrDynamicBrakeDecrease": + { + if (!messageDisplayed) Simulator.Confirmer.Information("Controller: +"); + controllerPosition = ControllerPosition.ThrottleIncreaseOrDynamicBrakeDecrease; + break; + } + case "ThrottleIncreaseOrDynamicBrakeDecreaseFast": + { + if (!messageDisplayed) Simulator.Confirmer.Information("Controller: ++"); + controllerPosition = ControllerPosition.ThrottleIncreaseOrDynamicBrakeDecreaseFast; + break; + } + case "DynamicBrakeIncreaseOrThrottleDecrease": + { + if (!messageDisplayed) Simulator.Confirmer.Information("Controller: -"); + controllerPosition = ControllerPosition.DynamicBrakeIncreaseOrThrottleDecrease; + break; + } + case "DynamicBrakeIncreaseOrThrottleDecreaseFast": + { + if (!messageDisplayed) Simulator.Confirmer.Information("Controller: --"); + controllerPosition = ControllerPosition.DynamicBrakeIncreaseOrThrottleDecreaseFast; + break; + } + case "ThrottleDecrease": + { + if (!messageDisplayed) Simulator.Confirmer.Information("Controller: V"); + controllerPosition = ControllerPosition.ThrottleDecrease; + break; + } + case "ThrottleDecreaseFast": + { + if (!messageDisplayed) Simulator.Confirmer.Information("Controller: V"); + controllerPosition = ControllerPosition.ThrottleDecreaseFast; + break; + } + case "Drive": + { + //Locomotive.TrainBrakePriority = false; + if (!messageDisplayed) Simulator.Confirmer.Information("Controller: J"); + controllerPosition = ControllerPosition.Drive; + break; + } + case "ThrottleHold": + { + if (!messageDisplayed) Simulator.Confirmer.Information("Controller: J"); + controllerPosition = ControllerPosition.ThrottleHold; + break; + } + case "Neutral": + { + if (!messageDisplayed) Simulator.Confirmer.Information("Controller: V"); + controllerPosition = ControllerPosition.Neutral; + break; + } + case "KeepCurrent": + { + if (!messageDisplayed) Simulator.Confirmer.Information("Controller: 0"); + controllerPosition = ControllerPosition.KeepCurrent; + break; + } + case "DynamicBrakeHold": + { + if (!messageDisplayed) Simulator.Confirmer.Information("Controller: V"); + controllerPosition = ControllerPosition.DynamicBrakeHold; + break; + } + case "DynamicBrakeIncrease": + { + if (!messageDisplayed) Simulator.Confirmer.Information("Controller: BE"); + controllerPosition = ControllerPosition.DynamicBrakeIncrease; + break; + } + case "DynamicBrakeIncreaseFast": + { + if (!messageDisplayed) Simulator.Confirmer.Information("Controller: BE2"); + controllerPosition = ControllerPosition.DynamicBrakeIncreaseFast; + break; + } + case "DynamicBrakeDecrease": + { + if (!messageDisplayed) Simulator.Confirmer.Information("Controller: V"); + controllerPosition = ControllerPosition.DynamicBrakeDecrease; + break; + } + case "TrainBrakeIncrease": + { + //Locomotive.TrainBrakePriority = true; + if (!messageDisplayed) Simulator.Confirmer.Information("Controller: BP"); + controllerPosition = ControllerPosition.TrainBrakeIncrease; + break; + } + case "TrainBrakeDecrease": + { + if (!messageDisplayed) Simulator.Confirmer.Information("Controller: V"); + controllerPosition = ControllerPosition.TrainBrakeDecrease; + break; + } + case "EmergencyBrake": + { + //Locomotive.TrainBrakePriority = true; + if (!messageDisplayed) Simulator.Confirmer.Information("Controller: R"); + controllerPosition = ControllerPosition.EmergencyBrake; + break; + } + case "CruiseControlSpeedIncrease": + { + controllerPosition = ControllerPosition.CruiseControlSpeedIncrease; + break; + } + case "CruiseControlSpeedDecrease": + { + controllerPosition = ControllerPosition.CruiseControlSpeedIncrease; + break; + } + case "CruiseControlSpeedSetZero": + { + controllerPosition = ControllerPosition.CruiseControlSpeedSetZero; + break; + } + } + messageDisplayed = true; + } + + protected void CheckNeutralPosition() + { + bool setNext = false; + String previous = ""; + foreach (KeyValuePair pair in PositionsList) + { + if (setNext) + { + currentPosition = pair.Key; + break; + } + if (pair.Key == currentPosition) + { + if (pair.Value.ToLower() == "springloadedbackwards" || pair.Value.ToLower() == "springloadedbackwardsimmediatelly") + { + setNext = true; + } + if (pair.Value.ToLower() == "springloadedforwards" || pair.Value.ToLower() == "springloadedforwardsimmediatelly") + { + currentPosition = previous; + break; + } + } + previous = pair.Key; + } + } + + protected void EmergencyBrakes() + { + Locomotive.SetThrottlePercent(0); + Locomotive.SetDynamicBrakePercent(100); + Locomotive.TrainBrakeController.TCSEmergencyBraking = true; + } + public enum Movement + { + Forward, + Neutral, + Aft + }; + public enum ControllerPosition + { + Neutral, + Drive, + ThrottleIncrease, + ThrottleDecrease, + ThrottleIncreaseFast, + ThrottleDecreaseFast, + DynamicBrakeIncrease, DynamicBrakeDecrease, + DynamicBrakeIncreaseFast, + TrainBrakeIncrease, + TrainBrakeDecrease, + EmergencyBrake, + ThrottleHold, + DynamicBrakeHold, + ThrottleIncreaseOrDynamicBrakeDecreaseFast, + ThrottleIncreaseOrDynamicBrakeDecrease, + DynamicBrakeIncreaseOrThrottleDecreaseFast, + DynamicBrakeIncreaseOrThrottleDecrease, + KeepCurrent, + CruiseControlSpeedIncrease, + CruiseControlSpeedDecrease, + CruiseControlSpeedSetZero + }; + public enum ControllerCruiseControlLogic + { + None, + Full, + SpeedOnly + } + } +} \ No newline at end of file diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs index e6c9a5ff85..103ef36f87 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs @@ -34,6 +34,7 @@ public CruiseControl(MSTSLocomotive locomotive) Simulator Simulator; public bool Equipped = false; + public bool SpeedIsMph = false; public bool SpeedRegulatorMaxForcePercentUnits = false; public float SpeedRegulatorMaxForceSteps = 0; public bool MaxForceSetSingleStep = false; @@ -94,6 +95,7 @@ public enum SpeedSelectorMode { Parking, Neutral, On, Start } public bool SkipThrottleDisplay = false; public bool DisableZeroForceStep = false; public bool UseThrottleAsSpeedSelector = false; + public bool UseThrottleAsForceSelector = false; public float Ampers = 0; public bool ContinuousSpeedIncreasing = false; public bool ContinuousSpeedDecreasing = false; @@ -110,6 +112,7 @@ public void Parse(string lowercasetoken, STFReader stf) { switch (lowercasetoken) { + case "engine(ortscruisecontrol(speedismph": SpeedIsMph = stf.ReadBoolBlock(false); break; case "engine(ortscruisecontrol(usethrottle": UseThrottle = stf.ReadBoolBlock(false); break; case "engine(ortscruisecontrol(throttleincreasespeed": ThrottleIncreaseSpeed = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.1f); break; case "engine(ortscruisecontrol(throttledecreasespeed": ThrottleDecreaseSpeed = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.2f); break; @@ -153,8 +156,9 @@ public void Parse(string lowercasetoken, STFReader stf) case "engine(ortscruisecontrol(maxacceleration": MaxAccelerationMpSS = stf.ReadFloatBlock(STFReader.UNITS.Any, 1); break; case "engine(ortscruisecontrol(maxdeceleration": MaxDecelerationMpSS = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.5f); break; case "engine(ortscruisecontrol(antiwheelspinequipped": AntiWheelSpinEquipped = stf.ReadBoolBlock(false); break; - case "engine(ortscruisecontrol(nominalspeedstep": SpeedRegulatorNominalSpeedStepMpS = MpS.FromKpH(stf.ReadFloatBlock(STFReader.UNITS.Speed, 0)); break; - case "engine(ortscruisecontrol(usethrottleasspeedselector": stf.ReadBoolBlock(false); break; + case "engine(ortscruisecontrol(nominalspeedstep": SpeedRegulatorNominalSpeedStepMpS = SpeedIsMph ? MpS.FromMpH(stf.ReadFloatBlock(STFReader.UNITS.Speed, 0)) : MpS.FromKpH(stf.ReadFloatBlock(STFReader.UNITS.Speed, 0)); break; + case "engine(ortscruisecontrol(usethrottleasspeedselector": UseThrottleAsSpeedSelector = stf.ReadBoolBlock(false); break; + case "engine(ortscruisecontrol(usethrottleasforceselector": UseThrottleAsForceSelector = stf.ReadBoolBlock(false); break; case "engine(ortscruisecontrol(dynamicbrakeincreasespeed": DynamicBrakeIncreaseSpeed = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.5f); break; case "engine(ortscruisecontrol(dynamicbrakedecreasespeed": DynamicBrakeDecreaseSpeed = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.5f); break; case "engine(ortscruisecontrol(options": @@ -342,7 +346,7 @@ public void SpeedRegulatorModeDecrease() case SpeedRegulatorMode.Auto: if (SpeedRegulatorOptions.Contains("regulatorauto")) test = true; break; case SpeedRegulatorMode.Manual: { - Locomotive.SetThrottlePercent(0); + Locomotive.ThrottleController.SetPercent(0); currentThrottlePercent = 0; if (SpeedRegulatorOptions.Contains("regulatormanual")) test = true; SelectedSpeedMpS = 0; @@ -423,6 +427,14 @@ public void SpeedSelectorModeDecrease() Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Speed selector mode changed to") + " " + Simulator.Catalog.GetString(SpeedSelMode.ToString())); } + public void SetMaxForcePercent(float percent) + { + if (SelectedMaxAccelerationPercent == percent) return; + SelectedMaxAccelerationPercent = percent; + SelectedMaxAccelerationPercent = (float)Math.Round(SelectedMaxAccelerationStep, 0); + Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Speed regulator max acceleration percent changed to") + " " + Simulator.Catalog.GetString(SelectedMaxAccelerationPercent.ToString()) + "%"); + } + bool maxForceIncreasing = false; public void SpeedRegulatorMaxForceStartIncrease() { @@ -443,6 +455,7 @@ protected void SpeedRegulatorMaxForceIncrease() if (SelectedMaxAccelerationPercent == 100) return; SelectedMaxAccelerationPercent += 1f; + SelectedMaxAccelerationPercent = (float)Math.Round(SelectedMaxAccelerationStep, 0); Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Speed regulator max acceleration percent changed to") + " " + Simulator.Catalog.GetString(SelectedMaxAccelerationPercent.ToString()) + "%"); } else @@ -450,6 +463,7 @@ protected void SpeedRegulatorMaxForceIncrease() if (SelectedMaxAccelerationStep == SpeedRegulatorMaxForceSteps) return; SelectedMaxAccelerationStep++; + SelectedMaxAccelerationStep = (float)Math.Round(SelectedMaxAccelerationStep, 0); Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Speed regulator max acceleration changed to") + " " + Simulator.Catalog.GetString(SelectedMaxAccelerationStep.ToString())); } } @@ -477,6 +491,7 @@ protected void SpeedRegulatorMaxForceDecrease() if (SelectedMaxAccelerationStep <= 0) return; } SelectedMaxAccelerationStep--; + SelectedMaxAccelerationStep = (float)Math.Round(SelectedMaxAccelerationStep, 0); Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Speed regulator max acceleration changed to") + " " + Simulator.Catalog.GetString(SelectedMaxAccelerationStep.ToString())); } @@ -530,7 +545,7 @@ public void SpeedRegulatorSelectedSpeedDecrease() { // return back to manual, clear all we have controlled before and let the driver to set up new stuff SpeedRegMode = SpeedRegulatorMode.Manual; - Locomotive.SetThrottlePercent(0); + Locomotive.ThrottleController.SetPercent(0); Locomotive.SetDynamicBrakePercent(0); Locomotive.DynamicBrakeChangeActiveState(false); } @@ -583,16 +598,16 @@ public virtual void CheckRestrictedSpeedZone() } } - public void SetSpeed(float SpeedKpH) + public void SetSpeed(float Speed) { if (SpeedRegMode == SpeedRegulatorMode.Manual && ForceRegulatorAutoWhenNonZeroSpeedSelected) SpeedRegMode = SpeedRegulatorMode.Auto; Locomotive.SignalEvent(Common.Event.Alert1); if (!Equipped) return; - SelectedSpeedMpS = MpS.FromKpH(SpeedKpH); + SelectedSpeedMpS = SpeedIsMph ? MpS.FromMpH(Speed) : MpS.FromKpH(Speed); if (SelectedSpeedMpS > Locomotive.MaxSpeedMpS) SelectedSpeedMpS = Locomotive.MaxSpeedMpS; - Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Selected speed set to ") + SpeedKpH.ToString() + "kmh"); + Simulator.Confirmer.Message(ConfirmLevel.Information, Simulator.Catalog.GetString("Selected speed set to ") + Speed.ToString() + (SpeedIsMph? "mph" : "kmh")); } protected List playerNotDriveableTrainLocomotives = new List(); @@ -626,7 +641,7 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe // calculate new max force if MaxPowerThreshold is set if (MaxPowerThreshold > 0) { - float currentSpeed = MpS.ToKpH(AbsWheelSpeedMpS); + float currentSpeed = SpeedIsMph ? MpS.ToMpH(AbsWheelSpeedMpS) : MpS.ToKpH(AbsWheelSpeedMpS); float percentComplete = (int)Math.Round((double)(100 * currentSpeed) / MaxPowerThreshold); if (percentComplete > 100) percentComplete = 100; @@ -676,7 +691,7 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe if (controllerVolts > 0) controllerVolts = 0; Ampers = 0; - Locomotive.SetThrottlePercent(0); + Locomotive.ThrottleController.SetPercent(0); return; } else if (Bar.FromPSI(Locomotive.BrakeSystem.BrakeLine1PressurePSI) > 4.7) @@ -698,7 +713,7 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe CheckRestrictedSpeedZone(); if (DynamicBrakePriority) { - Locomotive.SetThrottlePercent(0); + Locomotive.ThrottleController.SetPercent(0); ForceThrottleAndDynamicBrake = -Locomotive.DynamicBrakePercent; return; } @@ -734,10 +749,10 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe Locomotive.DynamicBrakeChangeActiveState(false); } } - if (!UseThrottle) Locomotive.SetThrottlePercent(0); + if (!UseThrottle) Locomotive.ThrottleController.SetPercent(0); throttleIsZero = true; - if (AbsWheelSpeedMpS < MpS.FromKpH(ParkingBrakeEngageSpeed)) + if (AbsWheelSpeedMpS < (SpeedIsMph ? MpS.FromMpH(ParkingBrakeEngageSpeed) : MpS.FromKpH(ParkingBrakeEngageSpeed))) Locomotive.SetEngineBrakePercent(ParkingBrakePercent); } else if (SpeedSelMode == SpeedSelectorMode.Neutral || SpeedSelMode < SpeedSelectorMode.Start && !SpeedRegulatorOptions.Contains("startfromzero") && AbsWheelSpeedMpS < SafeSpeedForAutomaticOperationMpS) @@ -812,7 +827,7 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe } if (maxForceN == 0) { - if (!UseThrottle) Locomotive.SetThrottlePercent(0); + if (!UseThrottle) Locomotive.ThrottleController.SetPercent(0); if (relativeAcceleration < -1) relativeAcceleration = -1; if (Locomotive.DynamicBrakePercent < -(AccelerationDemandMpSS * 100) && AccelerationDemandMpSS < -0.05f) { @@ -839,14 +854,14 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe if (delta > -0.1) { if (!UseThrottle) - Locomotive.SetThrottlePercent(100); + Locomotive.ThrottleController.SetPercent(100); throttleIsZero = false; maxForceN = 0; } else if (delta > -1) { if (!UseThrottle) - Locomotive.SetThrottlePercent(0); + Locomotive.ThrottleController.SetPercent(0); throttleIsZero = true; brakePercent = 10 + (-delta * 10); @@ -855,7 +870,7 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe { Locomotive.TractiveForceN = 0; if (!UseThrottle) - Locomotive.SetThrottlePercent(0); + Locomotive.ThrottleController.SetPercent(0); throttleIsZero = true; if (_AccelerationMpSS > -MaxDecelerationMpSS) @@ -903,7 +918,7 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe if (Locomotive.DynamicBrakePercent == 0 && Locomotive.DynamicBrake) Locomotive.DynamicBrakeChangeActiveState(false); relativeAcceleration = (float)Math.Sqrt(AccelerationRampMaxMpSSS * delta); float coeff = 1; - float speed = MpS.ToKpH(Locomotive.WheelSpeedMpS); + float speed = SpeedIsMph ? MpS.ToMpH(Locomotive.WheelSpeedMpS) : MpS.ToKpH(Locomotive.WheelSpeedMpS); if (speed > 100) { coeff = (speed / 100) * 1.2f; @@ -988,7 +1003,7 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe } if (maxForceN == 0) { - if (!UseThrottle) Locomotive.SetThrottlePercent(0); + if (!UseThrottle) Locomotive.ThrottleController.SetPercent(0); if (relativeAcceleration < -1) relativeAcceleration = -1; if (Locomotive.DynamicBrakePercent < -(AccelerationDemandMpSS * 100) && AccelerationDemandMpSS < -0.05f) { @@ -1015,14 +1030,14 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe if (delta > -0.1) { if (!UseThrottle) - Locomotive.SetThrottlePercent(100); + Locomotive.ThrottleController.SetPercent(100); throttleIsZero = false; maxForceN = 0; } else if (delta > -1) { if (!UseThrottle) - Locomotive.SetThrottlePercent(0); + Locomotive.ThrottleController.SetPercent(0); throttleIsZero = true; brakePercent = 10 + (-delta * 10); @@ -1031,7 +1046,7 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe { Locomotive.TractiveForceN = 0; if (!UseThrottle) - Locomotive.SetThrottlePercent(0); + Locomotive.ThrottleController.SetPercent(0); throttleIsZero = true; if (_AccelerationMpSS > -MaxDecelerationMpSS) @@ -1078,7 +1093,7 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe { if (!UseThrottle) { - Locomotive.SetThrottlePercent(100); + Locomotive.ThrottleController.SetPercent(100); } throttleIsZero = false; } @@ -1140,7 +1155,7 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe breakout = false; if ((controllerVolts != demandedVolts) && delta > 0) { - if (a > 0 && MpS.ToKpH(Locomotive.WheelSpeedMpS) > 5) + if (a > 0 && (SpeedIsMph ? MpS.ToMpH(Locomotive.WheelSpeedMpS) : MpS.ToKpH(Locomotive.WheelSpeedMpS)) > 5) { if (controllerVolts < demandedVolts && Locomotive.AccelerationMpSS < a - 0.02) { @@ -1158,7 +1173,7 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe controllerVolts += step; } } - if (a > 0 && MpS.ToKpH(Locomotive.WheelSpeedMpS) > 5) + if (a > 0 && (SpeedIsMph ? MpS.ToMpH(Locomotive.WheelSpeedMpS) : MpS.ToKpH(Locomotive.WheelSpeedMpS)) > 5) { if (controllerVolts > demandedVolts && Locomotive.AccelerationMpSS > a + 0.02) { @@ -1183,7 +1198,7 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe controllerVolts -= step; } } - if (a > 0 && MpS.ToKpH(Locomotive.WheelSpeedMpS) > 5) + if (a > 0 && (SpeedIsMph ? MpS.ToMpH(Locomotive.WheelSpeedMpS) : MpS.ToKpH(Locomotive.WheelSpeedMpS)) > 5) { if ((a != Locomotive.AccelerationMpSS) && delta > 0.8) { @@ -1290,7 +1305,7 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe } } if (controllerVolts > 0) - Locomotive.SetThrottlePercent(controllerVolts); + Locomotive.ThrottleController.SetPercent(controllerVolts); //Simulator.Confirmer.MSG(controllerVolts.ToString()); } } @@ -1328,13 +1343,13 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe maxForceN = 0; controllerVolts = 0; Ampers = 0; - if (!UseThrottle) Locomotive.SetThrottlePercent(0); + if (!UseThrottle) Locomotive.ThrottleController.SetPercent(0); } else { if (Locomotive.ThrottlePercent < 100 && SpeedSelMode != SpeedSelectorMode.Parking && !UseThrottle) { - Locomotive.SetThrottlePercent(100); + Locomotive.ThrottleController.SetPercent(100); throttleIsZero = false; } if (Locomotive.DynamicBrakePercent > -1) @@ -1359,7 +1374,7 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe else if (controllerVolts < 0) { if (maxForceN > 0) maxForceN = 0; - if (Locomotive.ThrottlePercent > 0) Locomotive.SetThrottlePercent(0); + if (Locomotive.ThrottlePercent > 0) Locomotive.ThrottleController.SetPercent(0); if (Locomotive.DynamicBrakePercent <= 0) { string status = Locomotive.GetDynamicBrakeStatus(); @@ -1380,7 +1395,7 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe else {*/ if (maxForceN > 0) maxForceN = 0; - if (Locomotive.ThrottlePercent > 0 && !UseThrottle) Locomotive.SetThrottlePercent(0); + if (Locomotive.ThrottlePercent > 0 && !UseThrottle) Locomotive.ThrottleController.SetPercent(0); if (Locomotive.DynamicBrakePercent > -1) { Locomotive.SetDynamicBrakePercent(0); @@ -1392,7 +1407,7 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe if (!Locomotive.PowerOn) // || Locomotive.Mirel.NZ1 || Locomotive.Mirel.NZ2 || Locomotive.Mirel.NZ3 || Locomotive.Mirel.NZ4 || Locomotive.Mirel.NZ5) { controllerVolts = 0; - Locomotive.SetThrottlePercent(0); + Locomotive.ThrottleController.SetPercent(0); if (Locomotive.DynamicBrakePercent > 0) Locomotive.SetDynamicBrakePercent(0); Locomotive.DynamicBrakeIntervention = -1; diff --git a/Source/RunActivity/Viewer3D/RollingStock/MSTSLocomotiveViewer.cs b/Source/RunActivity/Viewer3D/RollingStock/MSTSLocomotiveViewer.cs index 010d9abfd0..dd6c8a8093 100644 --- a/Source/RunActivity/Viewer3D/RollingStock/MSTSLocomotiveViewer.cs +++ b/Source/RunActivity/Viewer3D/RollingStock/MSTSLocomotiveViewer.cs @@ -208,26 +208,26 @@ public override void InitializeUserInputCommands() UserInputCommands.Add(UserCommand.ControlCruiseControlModeIncrease, new Action[] { () => Locomotive.CruiseControl.SpeedSelectorModeStopIncrease(), () => Locomotive.CruiseControl.SpeedSelectorModeStartIncrease() }); UserInputCommands.Add(UserCommand.ControlCruiseControlModeDecrease, new Action[] { Noop, () => Locomotive.CruiseControl.SpeedSelectorModeDecrease() }); UserInputCommands.Add(UserCommand.ControlTrainTypePaxCargo, new Action[] { Noop, () => Locomotive.ChangeTrainTypePaxCargo() }); - UserInputCommands.Add(UserCommand.ControlSelectSpeed10KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(10) }); - UserInputCommands.Add(UserCommand.ControlSelectSpeed20KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(20) }); - UserInputCommands.Add(UserCommand.ControlSelectSpeed30KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(30) }); - UserInputCommands.Add(UserCommand.ControlSelectSpeed40KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(40) }); - UserInputCommands.Add(UserCommand.ControlSelectSpeed50KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(50) }); - UserInputCommands.Add(UserCommand.ControlSelectSpeed60KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(60) }); - UserInputCommands.Add(UserCommand.ControlSelectSpeed70KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(70) }); - UserInputCommands.Add(UserCommand.ControlSelectSpeed80KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(80) }); - UserInputCommands.Add(UserCommand.ControlSelectSpeed90KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(90) }); - UserInputCommands.Add(UserCommand.ControlSelectSpeed100KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(100) }); - UserInputCommands.Add(UserCommand.ControlSelectSpeed110KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(110) }); - UserInputCommands.Add(UserCommand.ControlSelectSpeed120KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(120) }); - UserInputCommands.Add(UserCommand.ControlSelectSpeed130KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(130) }); - UserInputCommands.Add(UserCommand.ControlSelectSpeed140KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(140) }); - UserInputCommands.Add(UserCommand.ControlSelectSpeed150KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(150) }); - UserInputCommands.Add(UserCommand.ControlSelectSpeed160KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(160) }); - UserInputCommands.Add(UserCommand.ControlSelectSpeed170KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(170) }); - UserInputCommands.Add(UserCommand.ControlSelectSpeed180KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(180) }); - UserInputCommands.Add(UserCommand.ControlSelectSpeed190KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(190) }); - UserInputCommands.Add(UserCommand.ControlSelectSpeed200KpH, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(200) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed10, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(10) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed20, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(20) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed30, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(30) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed40, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(40) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed50, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(50) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed60, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(60) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed70, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(70) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed80, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(80) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed90, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(90) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed100, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(100) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed110, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(110) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed120, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(120) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed130, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(130) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed140, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(140) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed150, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(150) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed160, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(160) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed170, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(170) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed180, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(180) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed190, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(190) }); + UserInputCommands.Add(UserCommand.ControlSelectSpeed200, new Action[] { Noop, () => Locomotive.CruiseControl.SetSpeed(200) }); base.InitializeUserInputCommands(); } @@ -1994,6 +1994,14 @@ public virtual int GetDrawIndex() index = PercentToIndex(Locomotive.GetCombinedHandleValue(false)); break; case CABViewControlTypes.CP_HANDLE: + if (Locomotive.CruiseControl != null) + { + if (Locomotive.CruiseControl.SpeedRegMode == Simulation.RollingStocks.SubSystems.CruiseControl.SpeedRegulatorMode.Auto) + { + index = PercentToIndex(50); + break; + } + } if (Locomotive.CombinedControlType == MSTSLocomotive.CombinedControl.ThrottleDynamic && Locomotive.DynamicBrakePercent >= 0 || Locomotive.CombinedControlType == MSTSLocomotive.CombinedControl.ThrottleAir && Locomotive.TrainBrakeController.CurrentValue > 0) index = PercentToIndex(Locomotive.GetCombinedHandleValue(false)); @@ -2452,6 +2460,15 @@ public void HandleUserInput() { Locomotive.CruiseControl.SelectedMaxAccelerationStep -= 1; } + if (ChangedValue(0) != 0) + { + Locomotive.CruiseControl.SelectedMaxAccelerationStep += ChangedValue(0) * (float)Control.MaxValue; + if (Locomotive.CruiseControl.SelectedMaxAccelerationStep > 100) + Locomotive.CruiseControl.SelectedMaxAccelerationStep = 100; + if (Locomotive.CruiseControl.SelectedMaxAccelerationStep < 0) + Locomotive.CruiseControl.SelectedMaxAccelerationStep = 0; + Locomotive.Simulator.Confirmer.Information("Selected maximum acceleration was changed to " + Math.Round(Locomotive.CruiseControl.SelectedMaxAccelerationStep, 0).ToString() + " percent"); + } break; } From dcadfaabf0215d2a67844e3bfc751ef9d8a03dc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jind=C5=99ich=20Machal=C3=ADnek?= Date: Sat, 6 Feb 2021 22:01:30 +0100 Subject: [PATCH 6/7] Update CruiseControl.cs --- .../RollingStocks/SubSystems/CruiseControl.cs | 261 ++++-------------- 1 file changed, 50 insertions(+), 211 deletions(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs index 103ef36f87..d0f649a63d 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs @@ -107,6 +107,8 @@ public enum SpeedSelectorMode { Parking, Neutral, On, Start } public float PowerReductionValue = 100; public float MaxPowerThreshold = 0; public float SafeSpeedForAutomaticOperationMpS = 0; + protected float SpeedSelectorStepTimeSeconds = 0; + protected float elapsedTime = 0; public void Parse(string lowercasetoken, STFReader stf) { @@ -115,6 +117,7 @@ public void Parse(string lowercasetoken, STFReader stf) case "engine(ortscruisecontrol(speedismph": SpeedIsMph = stf.ReadBoolBlock(false); break; case "engine(ortscruisecontrol(usethrottle": UseThrottle = stf.ReadBoolBlock(false); break; case "engine(ortscruisecontrol(throttleincreasespeed": ThrottleIncreaseSpeed = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.1f); break; + case "engine(ortscruisecontrol(speedselectorsteptimeseconds": SpeedSelectorStepTimeSeconds = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.1f); break; case "engine(ortscruisecontrol(throttledecreasespeed": ThrottleDecreaseSpeed = stf.ReadFloatBlock(STFReader.UNITS.Any, 0.2f); break; case "engine(ortscruisecontrol(throttlefullrangeincreasetimeseconds": ThrottleFullRangeIncreaseTimeSeconds = stf.ReadFloatBlock(STFReader.UNITS.Any, 5); break; case "engine(ortscruisecontrol(throttlefullrangedecreasetimeseconds": ThrottleFullRangeDecreaseTimeSeconds = stf.ReadFloatBlock(STFReader.UNITS.Any, 5); break; @@ -195,6 +198,7 @@ public void Initialize() public void Update(float elapsedClockSeconds, float AbsWheelSpeedMpS) { + elapsedTime += elapsedClockSeconds; if (maxForceIncreasing) SpeedRegulatorMaxForceIncrease(); if (maxForceDecreasing) SpeedRegulatorMaxForceDecrease(); if (SpeedRegMode == SpeedRegulatorMode.Manual) @@ -215,7 +219,6 @@ public void Update(float elapsedClockSeconds, float AbsWheelSpeedMpS) public void Save(BinaryWriter outf) { - outf.Write(this.AntiWheelSpinEquipped); outf.Write(this.applyingPneumaticBrake); outf.Write(this.Battery); outf.Write(this.brakeIncreasing); @@ -223,13 +226,8 @@ public void Save(BinaryWriter outf) outf.Write(this.controllerTime); outf.Write(this.CurrentSelectedSpeedMpS); outf.Write(this.currentThrottlePercent); - outf.Write(this.DeltaCoefficient); - outf.Write(this.DynamicBrakeDescentCoefficient); - outf.Write(this.DynamicBrakeMaxForceAtSelectorStep); outf.Write(this.dynamicBrakeSetToZero); outf.Write(this.fromAcceleration); - outf.Write(this.MaxAccelerationMpSS); - outf.Write(this.MaxDecelerationMpSS); outf.Write(this.maxForceDecreasing); outf.Write(this.maxForceIncreasing); outf.Write(this.maxForceN); @@ -238,28 +236,17 @@ public void Save(BinaryWriter outf) outf.Write(this.RestrictedSpeedActive); outf.Write(this.SelectedMaxAccelerationPercent); outf.Write(this.SelectedMaxAccelerationStep); - outf.Write(this.SelectedMaxAccelerationStep); outf.Write(this.SelectedNumberOfAxles); outf.Write(this.SelectedSpeedMpS); outf.Write((int)this.SpeedRegMode); - outf.Write(this.SpeedRegulatorMaxForcePercentUnits); - outf.Write(this.SpeedRegulatorMaxForceSteps); - outf.Write(this.SpeedRegulatorNominalSpeedStepMpS); outf.Write((int)this.SpeedSelMode); - outf.Write(this.StartReducingSpeedDelta); - outf.Write(this.ThrottleDecreaseSpeed); - outf.Write(this.ThrottleIncreaseSpeed); outf.Write(this.throttleIsZero); outf.Write(this.trainBrakePercent); - outf.Write(this.trainLength); - outf.Write(this.UseThrottle); - outf.Write(this._AccelerationMpSS); outf.Write(this.TrainLengthMeters); } public void Restore(BinaryReader inf) { - AntiWheelSpinEquipped = inf.ReadBoolean(); applyingPneumaticBrake = inf.ReadBoolean(); Battery = inf.ReadBoolean(); brakeIncreasing = inf.ReadBoolean(); @@ -267,13 +254,8 @@ public void Restore(BinaryReader inf) controllerTime = inf.ReadSingle(); CurrentSelectedSpeedMpS = inf.ReadSingle(); currentThrottlePercent = inf.ReadSingle(); - float deltaCoefficient = inf.ReadSingle(); - float dynamicBrakeDescentCoefficient = inf.ReadSingle(); - float dynamicBrakeMaxForceAtSelectorStep = inf.ReadSingle(); dynamicBrakeSetToZero = inf.ReadBoolean(); fromAcceleration = inf.ReadSingle(); - float maxAccelerationMpSS = inf.ReadSingle(); - float maxDecelerationMpSS = inf.ReadSingle(); maxForceDecreasing = inf.ReadBoolean(); maxForceIncreasing = inf.ReadBoolean(); maxForceN = inf.ReadSingle(); @@ -287,19 +269,10 @@ public void Restore(BinaryReader inf) SelectedSpeedMpS = inf.ReadSingle(); int fSpeedRegMode = inf.ReadInt32(); SpeedRegMode = (SpeedRegulatorMode)fSpeedRegMode; - SpeedRegulatorMaxForcePercentUnits = inf.ReadBoolean(); - SpeedRegulatorMaxForceSteps = inf.ReadSingle(); - SpeedRegulatorNominalSpeedStepMpS = inf.ReadSingle(); int fSpeedSelMode = inf.ReadInt32(); SpeedSelMode = (SpeedSelectorMode)fSpeedSelMode; - float nill = inf.ReadSingle(); - ThrottleDecreaseSpeed = inf.ReadSingle(); - ThrottleIncreaseSpeed = inf.ReadSingle(); throttleIsZero = inf.ReadBoolean(); trainBrakePercent = inf.ReadSingle(); - trainLength = inf.ReadSingle(); - UseThrottle = inf.ReadBoolean(); - _AccelerationMpSS = inf.ReadSingle(); TrainLengthMeters = inf.ReadInt32(); } @@ -514,9 +487,16 @@ public void SpeedRegulatorSelectedSpeedStopIncrease() else SpeedSelectorModeStopIncrease(); } + + protected double selectedSpeedLeverHoldTime = 0; public void SpeedRegulatorSelectedSpeedIncrease() { if (!Equipped) return; + + if (selectedSpeedLeverHoldTime + SpeedSelectorStepTimeSeconds > elapsedTime) + return; + selectedSpeedLeverHoldTime = elapsedTime; + SelectedSpeedMpS += SpeedRegulatorNominalSpeedStepMpS; if (SelectedSpeedMpS > Locomotive.MaxSpeedMpS) SelectedSpeedMpS = Locomotive.MaxSpeedMpS; @@ -538,6 +518,11 @@ public void SpeedRegulatorSelectedSpeedStopDecrease() public void SpeedRegulatorSelectedSpeedDecrease() { if (!Equipped) return; + + if (selectedSpeedLeverHoldTime + SpeedSelectorStepTimeSeconds > elapsedTime) + return; + selectedSpeedLeverHoldTime = elapsedTime; + SelectedSpeedMpS -= SpeedRegulatorNominalSpeedStepMpS; if (SelectedSpeedMpS < 0) SelectedSpeedMpS = 0f; @@ -629,13 +614,14 @@ public void SetSpeed(float Speed) List concurrentAccelerationList = new List(); public float TrainElevation = 0; protected float skidSpeedDegratation = 0; + protected float previousAccelerationDemand = 0; protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWheelSpeedMpS) { if (DynamicBrakeFullRangeIncreaseTimeSeconds == 0) - DynamicBrakeFullRangeIncreaseTimeSeconds = 3; + DynamicBrakeFullRangeIncreaseTimeSeconds = 4; if (DynamicBrakeFullRangeDecreaseTimeSeconds == 0) - DynamicBrakeFullRangeDecreaseTimeSeconds = 3; + DynamicBrakeFullRangeDecreaseTimeSeconds = 6; float speedDiff = AbsWheelSpeedMpS - Locomotive.AbsSpeedMpS; float newThrotte = 0; // calculate new max force if MaxPowerThreshold is set @@ -720,6 +706,7 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe if (firstIteration) // if this is exetuted the first time, let's check all other than player engines in the consist, and record them for further throttle manipulation { + SelectedNumberOfAxles = (int)(Locomotive.Train.Length / 6.6f); // also set the axles, for better delta computing, if user omits to set it foreach (TrainCar tc in Locomotive.Train.Cars) { if (tc.GetType() == typeof(MSTSLocomotive) || tc.GetType() == typeof(MSTSDieselLocomotive) || tc.GetType() == typeof(MSTSElectricLocomotive)) @@ -907,29 +894,33 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe delta = SelectedSpeedMpS - AbsWheelSpeedMpS; else delta = CurrentSelectedSpeedMpS - AbsWheelSpeedMpS; - - if (delta > 0.0f) + float coeff = 1; + float speed = SpeedIsMph ? MpS.ToMpH(Locomotive.WheelSpeedMpS) : MpS.ToKpH(Locomotive.WheelSpeedMpS); + if (speed > 100) + { + coeff = (speed / 100) * 1.2f; + } + else + { + coeff = 1; + } + float numAxesCoeff = 0; + numAxesCoeff = (SelectedNumberOfAxles) / 12; + AccelerationDemandMpSS = (float)Math.Sqrt((StartReducingSpeedDelta + numAxesCoeff) * coeff * coeff * AccelerationRampMpSSS * (delta)); + if (delta > 0.0f && Locomotive.DynamicBrakePercent < 1) { if (Locomotive.DynamicBrakePercent > 0) + { + float step = 100 / DynamicBrakeFullRangeDecreaseTimeSeconds; + step *= elapsedClockSeconds; + controllerVolts += step; + } + if (Locomotive.DynamicBrakePercent < 0.5f && Locomotive.DynamicBrake) { Locomotive.SetDynamicBrakePercent(0); Locomotive.DynamicBrakeChangeActiveState(false); } - if (Locomotive.DynamicBrakePercent == 0 && Locomotive.DynamicBrake) Locomotive.DynamicBrakeChangeActiveState(false); relativeAcceleration = (float)Math.Sqrt(AccelerationRampMaxMpSSS * delta); - float coeff = 1; - float speed = SpeedIsMph ? MpS.ToMpH(Locomotive.WheelSpeedMpS) : MpS.ToKpH(Locomotive.WheelSpeedMpS); - if (speed > 100) - { - coeff = (speed / 100) * 1.2f; - } - else - { - coeff = 1; - } - float numAxesCoeff = 0; - numAxesCoeff = (SelectedNumberOfAxles) / 12; - AccelerationDemandMpSS = (float)Math.Sqrt((StartReducingSpeedDelta + numAxesCoeff) * coeff * coeff * AccelerationRampMpSSS * (delta)); } else // start braking { @@ -942,33 +933,6 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe if (controllerVolts > 0 && controllerVolts < 0.1) controllerVolts = 0; } - delta = 0; - if (!RestrictedSpeedActive) - delta = (SelectedSpeedMpS + (TrainElevation < -0.01 ? TrainElevation * (SelectedNumberOfAxles / 12) : 0)) - AbsWheelSpeedMpS; - else - delta = (CurrentSelectedSpeedMpS + (TrainElevation < -0.01 ? TrainElevation * (SelectedNumberOfAxles / 12) : 0)) - AbsWheelSpeedMpS; - - if (delta > 0) - { - if (controllerVolts < -0.1) - { - float step = 100 / ThrottleFullRangeDecreaseTimeSeconds; - step *= elapsedClockSeconds; - controllerVolts += step; - } - else if (controllerVolts > 0.1) - { - - float step = 100 / ThrottleFullRangeIncreaseTimeSeconds; - step *= elapsedClockSeconds; - controllerVolts -= step; - } - else - { - controllerVolts = 0; - } - } - if (delta < 0) // start braking { if (maxForceN > 0) @@ -984,42 +948,30 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe { if (Locomotive.DynamicBrakeAvailable) { - delta = 0; - if (!RestrictedSpeedActive) - delta = (SelectedSpeedMpS + (TrainElevation < -0.01 ? TrainElevation * (SelectedNumberOfAxles / 12) : 0)) - AbsWheelSpeedMpS; - else - delta = (CurrentSelectedSpeedMpS + (TrainElevation < -0.01 ? TrainElevation * (SelectedNumberOfAxles / 12) : 0)) - AbsWheelSpeedMpS; - relativeAcceleration = (float)-Math.Sqrt(-StartReducingSpeedDelta * delta); AccelerationDemandMpSS = (float)-Math.Sqrt(-StartReducingSpeedDelta * AccelerationRampMpSSS * delta); - if (maxForceN > 0) - { - if (controllerVolts > 0) - { - float step = 100 / ThrottleFullRangeDecreaseTimeSeconds; - step *= elapsedClockSeconds; - controllerVolts -= step; - } - } if (maxForceN == 0) { if (!UseThrottle) Locomotive.ThrottleController.SetPercent(0); - if (relativeAcceleration < -1) relativeAcceleration = -1; - if (Locomotive.DynamicBrakePercent < -(AccelerationDemandMpSS * 100) && AccelerationDemandMpSS < -0.05f) + if (Locomotive.AccelerationMpSS > AccelerationDemandMpSS) { if (controllerVolts > -100) { float step = 100 / DynamicBrakeFullRangeIncreaseTimeSeconds; step *= elapsedClockSeconds; + if (step > (Locomotive.AccelerationMpSS - AccelerationDemandMpSS) * 2) + step = (Locomotive.AccelerationMpSS - AccelerationDemandMpSS) * 2; controllerVolts -= step; } } - if (Locomotive.DynamicBrakePercent > -((AccelerationDemandMpSS - 0.05f) * 100)) + if (Locomotive.AccelerationMpSS + 0.01f < AccelerationDemandMpSS) { if (controllerVolts < 0) { float step = 100 / DynamicBrakeFullRangeDecreaseTimeSeconds; step *= elapsedClockSeconds; + if (step > (AccelerationDemandMpSS - Locomotive.AccelerationMpSS) * 2) + step = (AccelerationDemandMpSS - Locomotive.AccelerationMpSS) * 2; controllerVolts += step; } } @@ -1059,21 +1011,6 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe } } } - else - { - if (Locomotive.DynamicBrakeAvailable) - { - if (Locomotive.DynamicBrakePercent > 0) - { - if (controllerVolts < 0) - { - float step = 100 / DynamicBrakeFullRangeDecreaseTimeSeconds; - step *= elapsedClockSeconds; - controllerVolts += step; - } - } - } - } } if (relativeAcceleration > 1.0f) relativeAcceleration = 1.0f; @@ -1086,6 +1023,8 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe { float step = 100 / DynamicBrakeFullRangeDecreaseTimeSeconds; step *= elapsedClockSeconds; + if (step > (AccelerationDemandMpSS - Locomotive.AccelerationMpSS) * 2) + step = (AccelerationDemandMpSS - Locomotive.AccelerationMpSS) * 2; controllerVolts += step; } } @@ -1103,7 +1042,7 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe { if (Locomotive.DynamicBrakePercent < 0) { - if (relativeAcceleration > 0) + if (Locomotive.AccelerationMpSS < AccelerationDemandMpSS) { if (ForceStepsThrottleTable.Count > 0) { @@ -1132,20 +1071,6 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe if (t > PowerReductionValue / 100) t = PowerReductionValue / 100; } - // FIFO from accelerationDemand, 20 iterations - float smoothedAccelerationDemand = 0; - concurrentAccelerationList.Add(AccelerationDemandMpSS); - if (concurrentAccelerationList.Count > 20) - { - // calculate smooth - foreach (float accel in concurrentAccelerationList) - { - smoothedAccelerationDemand += accel; - } - smoothedAccelerationDemand = smoothedAccelerationDemand / concurrentAccelerationList.Count; - concurrentAccelerationList.RemoveAt(0); - } - if (t > smoothedAccelerationDemand) t = smoothedAccelerationDemand; float demandedVolts = t * 100; if (demandedVolts < PowerBreakoutAmpers) breakout = true; @@ -1166,7 +1091,7 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe } else { - if (controllerVolts < demandedVolts) + if (controllerVolts < demandedVolts && controllerVolts >= 0) { float step = 100 / ThrottleFullRangeIncreaseTimeSeconds; step *= elapsedClockSeconds; @@ -1219,94 +1144,8 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe if (UseThrottle) { - //Simulator.Confirmer.Information(Locomotive.Train.AccelerationMpSpS.SmoothedValue.ToString()); - // - if (SpeedRegMode == SpeedRegulatorMode.AVV) - { - Physics.Train train = Locomotive.Train; - Signalling.ObjectItemInfo firstObject = null; - Signalling.ObjectItemInfo nextObject = null; - float nextSpeed = -1; - if (train.SignalObjectItems.Count > 0) - { - int i = 0; - firstObject = train.SignalObjectItems[i]; - firstObject.distance_to_train = train.GetObjectDistanceToTrain(firstObject); - if (firstObject.speed_passenger < 0) - { - while (nextSpeed < 0) - { - i++; - if (i + 1 > train.SignalObjectItems.Count) - break; - nextObject = train.SignalObjectItems[i]; - nextSpeed = nextObject.speed_passenger; - nextObject.distance_to_train = train.GetObjectDistanceToTrain(nextObject); - } - } - else - { - nextSpeed = firstObject.speed_passenger; - } - if (nextSpeed < 0 && Locomotive.TrainControlSystem.CurrentSpeedLimitMpS > 0) - nextSpeed = Locomotive.TrainControlSystem.CurrentSpeedLimitMpS; - } - - // 160 km/h = 2000m; 1KpH = 12,5m - if (firstObject != null) - { - float computedMaxSpeed = 0; - float computedMaxSpeed1 = 0; - if (nextObject != null) - { - if (firstObject.speed_passenger > -1 && firstObject.speed_passenger < nextObject.speed_passenger) - { - computedMaxSpeed = (firstObject.distance_to_train - 50) / 35; - computedMaxSpeed = MpS.FromKpH(computedMaxSpeed); - computedMaxSpeed1 = firstObject.distance_to_train / 35; - computedMaxSpeed1 = MpS.FromKpH(computedMaxSpeed1); - } - else - { - computedMaxSpeed = (nextObject.distance_to_train - 50) / 35; - computedMaxSpeed = MpS.FromKpH(computedMaxSpeed); - computedMaxSpeed1 = nextObject.distance_to_train / 35; - computedMaxSpeed1 = MpS.FromKpH(computedMaxSpeed1); - } - } - else - { - computedMaxSpeed = (firstObject.distance_to_train - 50) / 35; - computedMaxSpeed = MpS.FromKpH(computedMaxSpeed); - computedMaxSpeed1 = firstObject.distance_to_train / 35; - computedMaxSpeed1 = MpS.FromKpH(computedMaxSpeed1); - } - float maxSpeedAhead = firstObject.speed_passenger; - computedMaxSpeed = computedMaxSpeed + nextSpeed; - if ((computedMaxSpeed1 + nextSpeed) > Locomotive.TrainControlSystem.CurrentSpeedLimitMpS) computedMaxSpeed = Locomotive.TrainControlSystem.CurrentSpeedLimitMpS; - if ((computedMaxSpeed1 + nextSpeed) > Locomotive.TrainControlSystem.NextSpeedLimitMpS) computedMaxSpeed = Locomotive.TrainControlSystem.NextSpeedLimitMpS; - if (nextObject != null) - { - if (nextObject.speed_passenger < 0 && firstObject.speed_passenger < 0) - { - computedMaxSpeed = Locomotive.TrainControlSystem.CurrentSpeedLimitMpS; - } - } - if (computedMaxSpeed > Locomotive.MaxSpeedMpS) computedMaxSpeed = Locomotive.MaxSpeedMpS; - if (nextObject != null) - Simulator.Confirmer.MSG(MpS.ToKpH(firstObject.speed_passenger).ToString() + ", " + MpS.ToKpH(nextObject.speed_passenger).ToString() + ", " + MpS.ToKpH(Locomotive.TrainControlSystem.NextSpeedLimitMpS) + ", " + MpS.ToKpH(computedMaxSpeed)); - else - Simulator.Confirmer.MSG(MpS.ToKpH(firstObject.speed_passenger).ToString() + ", " + MpS.ToKpH(Locomotive.TrainControlSystem.NextSpeedLimitMpS) + ", " + MpS.ToKpH(computedMaxSpeed)); - if (SelectedSpeedMpS != computedMaxSpeed) - { - SelectedSpeedMpS = computedMaxSpeed; - Simulator.Confirmer.Information("AVV - Selected max speed changed to " + MpS.ToKpH(SelectedSpeedMpS) + "kph"); - } - } - } if (controllerVolts > 0) Locomotive.ThrottleController.SetPercent(controllerVolts); - //Simulator.Confirmer.MSG(controllerVolts.ToString()); } } } From 8e0314f2c2faa99be11b82697db001600f6831d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jind=C5=99ich=20Machal=C3=ADnek?= Date: Mon, 8 Feb 2021 00:01:19 +0100 Subject: [PATCH 7/7] Update CruiseControl.cs --- .../Simulation/RollingStocks/SubSystems/CruiseControl.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs index d0f649a63d..955dc21993 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/CruiseControl.cs @@ -264,7 +264,6 @@ public void Restore(BinaryReader inf) RestrictedSpeedActive = inf.ReadBoolean(); SelectedMaxAccelerationPercent = inf.ReadSingle(); SelectedMaxAccelerationStep = inf.ReadSingle(); - SelectedMaxAccelerationStep = inf.ReadSingle(); SelectedNumberOfAxles = inf.ReadInt32(); SelectedSpeedMpS = inf.ReadSingle(); int fSpeedRegMode = inf.ReadInt32(); @@ -907,7 +906,7 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe float numAxesCoeff = 0; numAxesCoeff = (SelectedNumberOfAxles) / 12; AccelerationDemandMpSS = (float)Math.Sqrt((StartReducingSpeedDelta + numAxesCoeff) * coeff * coeff * AccelerationRampMpSSS * (delta)); - if (delta > 0.0f && Locomotive.DynamicBrakePercent < 1) + if (delta > 0.0f) { if (Locomotive.DynamicBrakePercent > 0) { @@ -915,7 +914,7 @@ protected virtual void UpdateMotiveForce(float elapsedClockSeconds, float AbsWhe step *= elapsedClockSeconds; controllerVolts += step; } - if (Locomotive.DynamicBrakePercent < 0.5f && Locomotive.DynamicBrake) + if (Locomotive.DynamicBrakePercent < 2 && Locomotive.DynamicBrake) { Locomotive.SetDynamicBrakePercent(0); Locomotive.DynamicBrakeChangeActiveState(false);