Ejemplo n.º 1
0
        public ScriptedBrakeController(ScriptedBrakeController controller, MSTSLocomotive locomotive)
        {
            Simulator  = locomotive.Simulator;
            Locomotive = locomotive;

            ScriptName            = controller.ScriptName;
            MaxPressurePSI        = controller.MaxPressurePSI;
            ReleaseRatePSIpS      = controller.ReleaseRatePSIpS;
            QuickReleaseRatePSIpS = controller.QuickReleaseRatePSIpS;
            ApplyRatePSIpS        = controller.ApplyRatePSIpS;
            EmergencyRatePSIpS    = controller.EmergencyRatePSIpS;
            FullServReductionPSI  = controller.FullServReductionPSI;
            MinReductionPSI       = controller.MinReductionPSI;

            CurrentValue = controller.CurrentValue;
            MinimumValue = controller.MinimumValue;
            MaximumValue = controller.MaximumValue;
            StepSize     = controller.StepSize;

            controller.Notches.ForEach(
                (item) => { Notches.Add(new MSTSNotch(item)); }
                );

            Initialize();
        }
 public DistributedPowerInterfaceRenderer(Viewer viewer, MSTSLocomotive locomotive, CVCScreen control, CabShader shader)
     : base(viewer, locomotive, control, shader)
 {
     Position.X = (float)Control.PositionX;
     Position.Y = (float)Control.PositionY;
     DPI        = new DistributedPowerInterface((int)Control.Height, (int)Control.Width, locomotive, viewer, control);
 }
Ejemplo n.º 3
0
        public ScriptedTrainControlSystem(MSTSLocomotive locomotive)
        {
            Locomotive = locomotive;
            Simulator  = Locomotive.Simulator;

            PowerAuthorization = true;
        }
Ejemplo n.º 4
0
        public MasterKey(MSTSLocomotive locomotive)
        {
            Locomotive = locomotive;

            Timer = new Timer(Locomotive);
            Timer.Setup(DelayS);
        }
Ejemplo n.º 5
0
 public CircularSpeedGaugeRenderer(Viewer viewer, MSTSLocomotive locomotive, CabViewDigitalControl control, CabShader shader)
     : base(viewer, locomotive, control, shader)
 {
     // Height is adjusted to keep compatibility
     driverMachineInterface = new DriverMachineInterface((int)(Control.Bounds.Width * 640 / 280), (int)(Control.Bounds.Height * 480 / 300), locomotive, viewer, control);
     viewer.UserCommandController.AddEvent(CommonUserCommand.AlternatePointerPressed, MouseRightButtonPressed);
     viewer.UserCommandController.AddEvent(CommonUserCommand.AlternatePointerReleased, MouseRightButtonReleased);
 }
Ejemplo n.º 6
0
        public DriverMachineInterface(float height, float width, MSTSLocomotive locomotive, Viewer viewer, CabViewControl control)
        {
            if (control is CVCScreen)
            {
                CurrentDMIMode = DMIMode.FullSize;
                if ((control as CVCScreen).CustomParameters.TryGetValue("mode", out string mode))
                {
                    if (mode == "planningarea")
                    {
                        CurrentDMIMode = DMIMode.PlanningArea;
                    }
                    else if (mode == "speedarea")
                    {
                        CurrentDMIMode = DMIMode.SpeedArea;
                    }
                }
            }
            else
            {
                CurrentDMIMode = DMIMode.GaugeOnly;
            }
            switch (CurrentDMIMode)
            {
            case DMIMode.GaugeOnly:
                Width  = 280;
                Height = 300;
                break;

            case DMIMode.FullSize:
                Width  = 640;
                Height = 480;
                break;

            case DMIMode.PlanningArea:
            case DMIMode.SpeedArea:
                Width  = 334;
                Height = 480;
                break;
            }
            Viewer     = viewer;
            Locomotive = locomotive;
            Scale      = Math.Min(width / Width, height / Height);
            if (Scale < 0.5)
            {
                MipMapScale = 2;
            }
            else
            {
                MipMapScale = 1;
            }

            Shader                    = new DriverMachineInterfaceShader(Viewer.GraphicsDevice);
            ETCSDefaultWindow         = new ETCSDefaultWindow(this, control);
            ETCSDefaultWindow.Visible = true;

            AddToLayout(ETCSDefaultWindow, Point.Zero);
            ActiveWindow = ETCSDefaultWindow;
        }
        public AbstractPowerSupply(MSTSLocomotive locomotive)
        {
            Locomotive = locomotive;
            Simulator  = locomotive.Simulator;

            State            = PowerSupplyState.PowerOff;
            AuxiliaryState   = PowerSupplyState.PowerOff;
            PowerOnDelayS    = 0;
            AuxPowerOnDelayS = 0;
        }
Ejemplo n.º 8
0
        public ScriptedTrainControlSystem(MSTSLocomotive locomotive)
        {
            Locomotive = locomotive;
            Simulator  = Locomotive.Simulator;

            PowerAuthorization         = true;
            CircuitBreakerClosingOrder = false;
            CircuitBreakerOpeningOrder = false;
            TractionAuthorization      = true;
        }
Ejemplo n.º 9
0
        public ScriptedBrakeController(MSTSLocomotive locomotive)
        {
            Simulator  = locomotive.Simulator;
            Locomotive = locomotive;

            MaxPressurePSI        = 90;
            ReleaseRatePSIpS      = 5;
            QuickReleaseRatePSIpS = 10;
            ApplyRatePSIpS        = 2;
            EmergencyRatePSIpS    = 10;
            FullServReductionPSI  = 26;
            MinReductionPSI       = 6;
        }
Ejemplo n.º 10
0
        public ScriptedLocomotivePowerSupply(MSTSLocomotive locomotive)
        {
            Locomotive = locomotive;

            BatterySwitch             = new BatterySwitch(Locomotive);
            MasterKey                 = new MasterKey(Locomotive);
            ElectricTrainSupplySwitch = new ElectricTrainSupplySwitch(Locomotive);

            MainPowerSupplyState       = PowerSupplyState.PowerOff;
            AuxiliaryPowerSupplyState  = PowerSupplyState.PowerOff;
            LowVoltagePowerSupplyState = PowerSupplyState.PowerOff;
            CabPowerSupplyState        = PowerSupplyState.PowerOff;
        }
Ejemplo n.º 11
0
 public DriverMachineInterfaceRenderer(Viewer viewer, MSTSLocomotive locomotive, CVCScreen control, CabShader shader)
     : base(viewer, locomotive, control, shader)
 {
     Position.X = (float)Control.PositionX;
     Position.Y = (float)Control.PositionY;
     if ((int)Control.Height == 102 && (int)Control.Width == 136)
     {
         // Hack for ETR400 cab, which was built with a bugged size calculation of digital displays
         Control.Height *= 0.75f;
         Control.Width  *= 0.75f;
     }
     DMI = new DriverMachineInterface((int)Control.Height, (int)Control.Width, locomotive, viewer, control);
 }
Ejemplo n.º 12
0
 public CabViewCircularSpeedGaugeRenderer(Viewer viewer, MSTSLocomotive locomotive, CVCDigital control, CabShader shader)
     : base(viewer, locomotive, control, shader)
 {
     CircularSpeedGauge = new CircularSpeedGauge(
         (int)Control.Width,
         (int)Control.Height,
         (int)Control.MaxValue,
         Control.Units == CABViewControlUnits.KM_PER_HOUR,
         true,
         Control.MaxValue == 240 || Control.MaxValue == 260,
         (int)Control.MinValue,
         Locomotive,
         Viewer
         );
 }
Ejemplo n.º 13
0
        public override void Update(float elapsedClockSeconds)
        {
            MSTSLocomotive lead = (MSTSLocomotive)Car.Train.LeadLocomotive;
            float          demandedAutoCylPressurePSI = 0;

            // Only allow EP brake tokens to operate if car is connected to an EP system
            if (lead == null || !(lead.BrakeSystem is EPBrakeSystem))
            {
                HoldingValve = ValveState.Release;
                base.Update(elapsedClockSeconds);
                return;
            }

            // process valid EP brake tokens

            if (BrakeLine3PressurePSI >= 1000f || Car.Train.BrakeLine4 < 0)
            {
                HoldingValve = ValveState.Release;
            }
            else if (Car.Train.BrakeLine4 == 0)
            {
                HoldingValve = ValveState.Lap;
            }
            else
            {
                demandedAutoCylPressurePSI = Math.Min(Math.Max(Car.Train.BrakeLine4, 0), 1) * MaxCylPressurePSI;
                HoldingValve = AutoCylPressurePSI <= demandedAutoCylPressurePSI ? ValveState.Lap : ValveState.Release;
            }


            base.Update(elapsedClockSeconds);     // Allow processing of other valid tokens


            if (AutoCylPressurePSI < demandedAutoCylPressurePSI && !Car.WheelBrakeSlideProtectionActive)
            {
                float dp = elapsedClockSeconds * MaxApplicationRatePSIpS;
                if (BrakeLine2PressurePSI - dp * AuxBrakeLineVolumeRatio / AuxCylVolumeRatio < AutoCylPressurePSI + dp)
                {
                    dp = (BrakeLine2PressurePSI - AutoCylPressurePSI) / (1 + AuxBrakeLineVolumeRatio / AuxCylVolumeRatio);
                }
                if (dp > demandedAutoCylPressurePSI - AutoCylPressurePSI)
                {
                    dp = demandedAutoCylPressurePSI - AutoCylPressurePSI;
                }
                BrakeLine2PressurePSI -= dp * AuxBrakeLineVolumeRatio / AuxCylVolumeRatio;
                AutoCylPressurePSI    += dp;
            }
        }
Ejemplo n.º 14
0
        public ScriptedBrakeController(MSTSLocomotive locomotive)
        {
            Simulator  = locomotive.Simulator;
            Locomotive = locomotive;

            MaxPressurePSI                 = 90;
            MaxOverchargePressurePSI       = 95;
            ReleaseRatePSIpS               = 5;
            QuickReleaseRatePSIpS          = 10;
            OverchargeEliminationRatePSIpS = 0.036f;
            ApplyRatePSIpS                 = 2;
            SlowApplicationRatePSIpS       = 1;
            EmergencyRatePSIpS             = 10;
            FullServReductionPSI           = 26;
            MinReductionPSI                = 6;
        }
Ejemplo n.º 15
0
 //[CallOnThread("Loader")]
 public CabViewCircularSpeedGaugeRenderer(Viewer viewer, MSTSLocomotive locomotive, CabViewDigitalControl control, CabShader shader)
     : base(viewer, locomotive, control, shader)
 {
     CircularSpeedGauge = new CircularSpeedGauge(
         control.Bounds.Width,
         Control.Bounds.Height,
         (int)Control.ScaleRangeMax,
         Control.ControlUnit == CabViewControlUnit.Km_Per_Hour,
         true,
         Control.ScaleRangeMax == 240 || Control.ScaleRangeMax == 260,
         (int)Control.ScaleRangeMin,
         Locomotive,
         Viewer,
         shader
         );
 }
Ejemplo n.º 16
0
        public CircularSpeedGauge(int width, int height, int maxSpeed, bool unitMetric, bool unitVisible, bool dialQuarterLines, int maxVisibleScale,
                                  MSTSLocomotive locomotive, Viewer viewer, CabShader shader)
        {
            UnitVisible = unitVisible;
            SetUnit(unitMetric);

            DialQuarterLines = dialQuarterLines;
            MaxSpeed         = maxSpeed;
            MaxVisibleScale  = maxVisibleScale;
            Viewer           = viewer;
            Locomotive       = locomotive;
            cabShader        = shader;

            SizeTo(width, height);
            SetRange(MaxSpeed);

            CurrentSpeed = new TextPrimitive[3];
            for (var i = 0; i < CurrentSpeed.Length; i++)
            {
                CurrentSpeed[i] = new TextPrimitive(new Point(CurrentSpeedPosition[i], CurrentSpeedPosition[3]), Color.Black, "0", FontCurrentSpeed);
            }

            ReleaseSpeed = new TextPrimitive(ReleaseSpeedPosition, ColorGrey, String.Empty, FontReleaseSpeed);

            Shader = new DriverMachineInterfaceShader(Viewer.RenderProcess.GraphicsDevice);
            if (NeedleTextureData == null)
            {
                NeedleTextureData = new Color[128 * 16];

                // Needle texture is according to ETCS specification
                for (var v = 0; v < 128; v++)
                {
                    for (var u = 0; u < 16; u++)
                    {
                        NeedleTextureData[u + 16 * v] = (
                            v <= 15 && 5 < u && u < 9 ||
                            15 < v && v <= 23 && 5f - (float)(v - 15) / 8f * 3f < u && u < 9f + (float)(v - 15) / 8f * 3f ||
                            23 < v && v < 82 && 2 < u && u < 12
                            ) ? Color.White : Color.Transparent;
                    }
                }
            }
        }
Ejemplo n.º 17
0
        public void Initialize()
        {
            if (!Activated)
            {
                if (ScriptName != null && ScriptName != "Automatic")
                {
                    var pathArray = new string[] { Path.Combine(Path.GetDirectoryName(Locomotive.WagFilePath), "Script") };
                    Script = Simulator.ScriptManager.Load(pathArray, ScriptName) as CircuitBreaker;
                }
                if (Script == null)
                {
                    Script = new AutomaticCircuitBreaker() as CircuitBreaker;
                }

                Script.ClockTime               = () => (float)Simulator.ClockTime;
                Script.GameTime                = () => (float)Simulator.GameTime;
                Script.DistanceM               = () => Locomotive.DistanceM;
                Script.CurrentState            = () => State;
                Script.CurrentPantographState  = () => Locomotive.Pantographs.State;
                Script.CurrentPowerSupplyState = () => Locomotive.PowerSupply.State;
                Script.TCSCloseAuthorization   = () => {
                    MSTSLocomotive locomotive = Locomotive.Train.LeadLocomotive as MSTSLocomotive;
                    if (locomotive != null)
                    {
                        return(locomotive.TrainControlSystem.PowerAuthorization);
                    }
                    else
                    {
                        return(false);
                    }
                };
                Script.DriverCloseAuthorization = () => DriverCloseAuthorization;
                Script.ClosingDelayS            = () => DelayS;

                Script.SetCurrentState             = (value) => State = value;
                Script.SetDriverCloseAuthorization = (value) => DriverCloseAuthorization = value;

                Script.Initialize();
                Activated = true;
            }
        }
        public DistributedPowerInterface(float height, float width, MSTSLocomotive locomotive, Viewer viewer, CabViewControl control)
        {
            Viewer     = viewer;
            Locomotive = locomotive;
            Scale      = Math.Min(width / Width, height / Height);
            if (Scale < 0.5)
            {
                MipMapScale = 2;
            }
            else
            {
                MipMapScale = 1;
            }

            Shader                  = new DriverMachineInterfaceShader(Viewer.GraphicsDevice);
            DPDefaultWindow         = new DPDefaultWindow(this, control);
            DPDefaultWindow.Visible = true;

            AddToLayout(DPDefaultWindow, Point.Zero);
            ActiveWindow = DPDefaultWindow;
        }
Ejemplo n.º 19
0
        public override void Initialize(bool handbrakeOn, float maxPressurePSI, float fullServPressurePSI, bool immediateRelease)
        {
            // reducing size of Emergency Reservoir for short (fake) cars
            if (Car.Simulator.Settings.CorrectQuestionableBrakingParams && Car.CarLengthM <= 1)
            {
                EmergResVolumeM3 = Math.Min(0.02f, EmergResVolumeM3);
            }
            BrakeLine1PressurePSI = Car.Train.BrakeLine1PressurePSIorInHg;
            BrakeLine2PressurePSI = Car.Train.BrakeLine2PressurePSI;
            BrakeLine3PressurePSI = 0;
            AuxResPressurePSI     = maxPressurePSI > BrakeLine1PressurePSI ? maxPressurePSI : BrakeLine1PressurePSI;
            if ((Car as MSTSWagon).EmergencyReservoirPresent || maxPressurePSI > 0)
            {
                EmergResPressurePSI = maxPressurePSI;
            }
            FullServPressurePSI = fullServPressurePSI;
            AutoCylPressurePSI  = immediateRelease ? 0 : Math.Min((maxPressurePSI - BrakeLine1PressurePSI) * AuxCylVolumeRatio, MaxCylPressurePSI);
            TripleValveState    = ValveState.Lap;
            HoldingValve        = ValveState.Release;
            HandbrakePercent    = handbrakeOn & (Car as MSTSWagon).HandBrakePresent ? 100 : 0;
            SetRetainer(RetainerSetting.Exhaust);
            MSTSLocomotive loco = Car as MSTSLocomotive;

            if (loco != null)
            {
                loco.MainResPressurePSI = loco.MaxMainResPressurePSI;
            }

            if (EmergResVolumeM3 > 0 && EmergAuxVolumeRatio > 0 && BrakePipeVolumeM3 > 0)
            {
                AuxBrakeLineVolumeRatio = EmergResVolumeM3 / EmergAuxVolumeRatio / BrakePipeVolumeM3;
            }
            else
            {
                AuxBrakeLineVolumeRatio = 3.1f;
            }

            //FullCylAirConsumedM3 = MaxCylPressurePSI * MaxBrakeForceN * 0.00000059733491f; //an average volume (M3) of air used in brake cylinder for 1 N brake force.;
            CylVolumeM3 = EmergResVolumeM3 / EmergAuxVolumeRatio / AuxCylVolumeRatio;
        }
Ejemplo n.º 20
0
        void buttonTogglePower_Click(Control arg1, Point arg2)
        {
            if ((Viewer.PlayerTrain.Cars[CarPosition] is MSTSElectricLocomotive) ||
                (Viewer.PlayerTrain.Cars[CarPosition] is MSTSDieselLocomotive))
            {
                MSTSLocomotive locomotive = Viewer.PlayerTrain.Cars[CarPosition] as MSTSLocomotive;

                new PowerCommand(Viewer.Log, locomotive, !locomotive.LocomotivePowerSupply.MainPowerSupplyOn);
                if (locomotive.LocomotivePowerSupply.MainPowerSupplyOn)
                {
                    Viewer.Simulator.Confirmer.Information(Viewer.Catalog.GetString("Power OFF command sent"));
                }
                else
                {
                    Viewer.Simulator.Confirmer.Information(Viewer.Catalog.GetString("Power ON command sent"));
                }
            }
            else
            {
                Viewer.Simulator.Confirmer.Warning(Viewer.Catalog.GetString("No power command for this type of car!"));
            }
        }
Ejemplo n.º 21
0
        public DriverMachineInterface(float height, float width, MSTSLocomotive locomotive, Viewer viewer, CabViewControl control)
        {
            Viewer     = viewer;
            Locomotive = locomotive;
            Scale      = Math.Min(width / Width, height / Height);
            if (Scale < 0.5)
            {
                MipMapScale = 2;
            }
            else
            {
                MipMapScale = 1;
            }
            GaugeOnly = control is CVCDigital;

            Shader                    = new DriverMachineInterfaceShader(Viewer.GraphicsDevice);
            ETCSDefaultWindow         = new ETCSDefaultWindow(this, control);
            ETCSDefaultWindow.Visible = true;

            AddToLayout(ETCSDefaultWindow, Point.Zero);
            ActiveWindow = ETCSDefaultWindow;
        }
Ejemplo n.º 22
0
        void buttonToggleMU_Click(Control arg1, Point arg2)
        {
            if ((Viewer.PlayerTrain.Cars[CarPosition] is MSTSElectricLocomotive) ||
                (Viewer.PlayerTrain.Cars[CarPosition] is MSTSDieselLocomotive))
            {
                MSTSLocomotive locomotive = Viewer.PlayerTrain.Cars[CarPosition] as MSTSLocomotive;

                new ToggleMUCommand(Viewer.Log, locomotive, locomotive.RemoteControlGroup < 0);
                if (locomotive.RemoteControlGroup >= 0)
                {
                    Viewer.Simulator.Confirmer.Information(Viewer.Catalog.GetString("MU signal connected"));
                }
                else
                {
                    Viewer.Simulator.Confirmer.Information(Viewer.Catalog.GetString("MU signal disconnected"));
                }
            }
            else
            {
                Viewer.Simulator.Confirmer.Warning(Viewer.Catalog.GetString("No MU command for this type of car!"));
            }
        }
Ejemplo n.º 23
0
 /// Propagate brake pressure
 protected void PropagateBrakePressure(double elapsedClockSeconds)
 {
     if (LeadLocomotiveIndex >= 0)
     {
         MSTSLocomotive lead = (MSTSLocomotive)Cars[LeadLocomotiveIndex];
         if (lead.TrainBrakeController != null)
         {
             (double pressurePSI, double epControllerState) = lead.TrainBrakeController.UpdatePressure(EqualReservoirPressurePSIorInHg, BrakeLine4, elapsedClockSeconds);
             EqualReservoirPressurePSIorInHg = (float)pressurePSI;
             BrakeLine4 = (float)epControllerState;
         }
         if (lead.EngineBrakeController != null)
         {
             BrakeLine3PressurePSI = (float)lead.EngineBrakeController.UpdateEngineBrakePressure(BrakeLine3PressurePSI, elapsedClockSeconds);
         }
         lead.BrakeSystem.PropagateBrakePressure(elapsedClockSeconds);
     }
     else if (TrainType == TrainType.Static)
     {
         // Propagate brake pressure of locomotiveless static consists in the advanced way,
         // to allow proper shunting operations.
         Cars[0].BrakeSystem.PropagateBrakePressure(elapsedClockSeconds);
     }
     else
     {
         // Propagate brake pressure of AI trains simplified
         /// AI trains simplyfied brake control is done by setting their Train.BrakeLine1PressurePSIorInHg,
         /// that is propagated promptly to each car directly.
         foreach (TrainCar car in Cars)
         {
             car.BrakeSystem.BrakeLine1PressurePSI = car.BrakeSystem.InternalPressure(EqualReservoirPressurePSIorInHg);
             car.BrakeSystem.BrakeLine2PressurePSI = BrakeLine2PressurePSI;
             car.BrakeSystem.BrakeLine3PressurePSI = 0;
         }
     }
 }
Ejemplo n.º 24
0
        /// <summary>
        /// Retrieve a formatted list <see cref="ListLabel"/>s to be displayed as an in-browser Track Monitor.
        /// </summary>
        /// <param name="viewer">The Viewer to read train data from.</param>
        /// <returns>A list of <see cref="ListLabel"/>s, one per row of the popup.</returns>
        public static IEnumerable <ListLabel> TrainDrivingDisplayList(this Viewer viewer, bool normalTextMode = true)
        {
            bool useMetric = viewer.MilepostUnitsMetric;
            var  labels    = new List <ListLabel>();

            void AddLabel(ListLabel label)
            {
                CheckLabel(ref label, normalTextMode);
                labels.Add(label);
            }

            void AddSeparator() => AddLabel(new ListLabel
            {
                FirstCol = Viewer.Catalog.GetString("Sprtr"),
            });

            TrainCar       trainCar            = viewer.PlayerLocomotive;
            Train          train               = trainCar.Train;
            string         trainBrakeStatus    = trainCar.GetTrainBrakeStatus();
            string         dynamicBrakeStatus  = trainCar.GetDynamicBrakeStatus();
            string         engineBrakeStatus   = trainCar.GetEngineBrakeStatus();
            MSTSLocomotive locomotive          = (MSTSLocomotive)trainCar;
            string         locomotiveStatus    = locomotive.GetStatus();
            bool           combinedControlType = locomotive.CombinedControlType == MSTSLocomotive.CombinedControl.ThrottleDynamic;
            bool           showMUReverser      = Math.Abs(train.MUReverserPercent) != 100f;
            bool           showRetainers       = train.RetainerSetting != RetainerSetting.Exhaust;
            bool           stretched           = train.Cars.Count > 1 && train.NPull == train.Cars.Count - 1;
            bool           bunched             = !stretched && train.Cars.Count > 1 && train.NPush == train.Cars.Count - 1;

            Train.TrainInfo trainInfo = train.GetTrainInfo();

            // First Block
            // Client and server may have a time difference.
            AddLabel(new ListLabel
            {
                FirstCol = Viewer.Catalog.GetString("Time"),
                LastCol  = FormatStrings.FormatTime(viewer.Simulator.ClockTime + (MultiPlayer.MPManager.IsClient() ? MultiPlayer.MPManager.Instance().serverTimeDifference : 0)),
            });
            if (viewer.Simulator.IsReplaying)
            {
                AddLabel(new ListLabel
                {
                    FirstCol = Viewer.Catalog.GetString("Replay"),
                    LastCol  = FormatStrings.FormatTime(viewer.Log.ReplayEndsAt - viewer.Simulator.ClockTime),
                });
            }

            Color speedColor;

            if (locomotive.SpeedMpS < trainInfo.allowedSpeedMpS - 1f)
            {
                speedColor = Color.White;
            }
            else if (locomotive.SpeedMpS < trainInfo.allowedSpeedMpS)
            {
                speedColor = Color.PaleGreen;
            }
            else if (locomotive.SpeedMpS < trainInfo.allowedSpeedMpS + 5f)
            {
                speedColor = Color.Orange;
            }
            else
            {
                speedColor = Color.OrangeRed;
            }
            AddLabel(new ListLabel
            {
                FirstCol = Viewer.Catalog.GetString("Speed"),
                LastCol  = $"{FormatStrings.FormatSpeedDisplay(locomotive.SpeedMpS, useMetric)}{ColorCode[speedColor]}",
            });

            // Gradient info
            if (normalTextMode)
            {
                float       gradient = -trainInfo.currentElevationPercent;
                const float minSlope = 0.00015f;
                string      gradientIndicator;
                if (gradient < -minSlope)
                {
                    gradientIndicator = $"{gradient:F1}%{Symbols.GradientDown}{ColorCode[Color.LightSkyBlue]}";
                }
                else if (gradient > minSlope)
                {
                    gradientIndicator = $"{gradient:F1}%{Symbols.GradientUp}{ColorCode[Color.Yellow]}";
                }
                else
                {
                    gradientIndicator = $"{gradient:F1}%";
                }
                AddLabel(new ListLabel
                {
                    FirstCol = Viewer.Catalog.GetString("Gradient"),
                    LastCol  = gradientIndicator,
                });
            }
            // Separator
            AddSeparator();

            // Second block
            // Direction
            {
                UserCommand?reverserCommand = GetPressedKey(UserCommand.ControlBackwards, UserCommand.ControlForwards);
                string      reverserKey;
                bool        moving      = Math.Abs(trainCar.SpeedMpS) > 1;
                bool        nonSteamEnd = trainCar.EngineType != TrainCar.EngineTypes.Steam && trainCar.Direction == Direction.N && (trainCar.ThrottlePercent >= 1 || moving);
                bool        steamEnd    = locomotive is MSTSSteamLocomotive steamLocomotive2 && steamLocomotive2.CutoffController.MaximumValue == Math.Abs(train.MUReverserPercent / 100);
                if (reverserCommand != null && (nonSteamEnd || steamEnd))
                {
                    reverserKey = Symbols.End + ColorCode[Color.Yellow];
                }
                else if (reverserCommand == UserCommand.ControlBackwards)
                {
                    reverserKey = Symbols.ArrowDown + ColorCode[Color.Yellow];
                }
                else if (reverserCommand == UserCommand.ControlForwards)
                {
                    reverserKey = Symbols.ArrowUp + ColorCode[Color.Yellow];
                }
                else
                {
                    reverserKey = "";
                }

                string reverserIndicator = showMUReverser ? $"{Round(Math.Abs(train.MUReverserPercent))}% " : "";
                AddLabel(new ListLabel
                {
                    FirstCol   = Viewer.Catalog.GetString(locomotive.EngineType == TrainCar.EngineTypes.Steam ? "Reverser" : "Direction"),
                    LastCol    = $"{reverserIndicator}{FormatStrings.Catalog.GetParticularString("Reverser", GetStringAttribute.GetPrettyName(locomotive.Direction))}",
                    KeyPressed = reverserKey,
                    SymbolCol  = reverserKey,
                });
            }

            // Throttle
            {
                UserCommand?throttleCommand = GetPressedKey(UserCommand.ControlThrottleDecrease, UserCommand.ControlThrottleIncrease);
                string      throttleKey;
                bool        upperLimit = throttleCommand == UserCommand.ControlThrottleIncrease && locomotive.ThrottleController.MaximumValue == trainCar.ThrottlePercent / 100;
                bool        lowerLimit = throttleCommand == UserCommand.ControlThrottleDecrease && trainCar.ThrottlePercent == 0;
                if (locomotive.DynamicBrakePercent < 1 && (upperLimit || lowerLimit))
                {
                    throttleKey = Symbols.End + ColorCode[Color.Yellow];
                }
                else if (locomotive.DynamicBrakePercent > -1)
                {
                    throttleKey = Symbols.EndLower + ColorCode[Color.Yellow];
                }
                else if (throttleCommand == UserCommand.ControlThrottleIncrease)
                {
                    throttleKey = Symbols.ArrowUp + ColorCode[Color.Yellow];
                }
                else if (throttleCommand == UserCommand.ControlThrottleDecrease)
                {
                    throttleKey = Symbols.ArrowDown + ColorCode[Color.Yellow];
                }
                else
                {
                    throttleKey = "";
                }

                AddLabel(new ListLabel
                {
                    FirstCol   = Viewer.Catalog.GetString(locomotive is MSTSSteamLocomotive ? "Regulator" : "Throttle"),
                    LastCol    = $"{Round(locomotive.ThrottlePercent)}%",
                    KeyPressed = throttleKey,
                    SymbolCol  = throttleKey,
                });
            }

            // Cylinder Cocks
            if (locomotive is MSTSSteamLocomotive steamLocomotive)
            {
                string cocksIndicator, cocksKey;
                if (steamLocomotive.CylinderCocksAreOpen)
                {
                    cocksIndicator = Viewer.Catalog.GetString("Open") + ColorCode[Color.Orange];
                    cocksKey       = Symbols.ArrowToRight + ColorCode[Color.Yellow];
                }
                else
                {
                    cocksIndicator = Viewer.Catalog.GetString("Closed") + ColorCode[Color.White];
                    cocksKey       = "";
                }
                AddLabel(new ListLabel
                {
                    FirstCol   = Viewer.Catalog.GetString("Cylinder cocks"),
                    LastCol    = cocksIndicator,
                    KeyPressed = cocksKey,
                    SymbolCol  = cocksKey,
                });
            }

            // Sander
            if (locomotive.GetSanderOn())
            {
                bool   sanderBlocked = locomotive.AbsSpeedMpS > locomotive.SanderSpeedOfMpS;
                string sanderKey     = Symbols.ArrowToRight + ColorCode[Color.Yellow];
                AddLabel(new ListLabel
                {
                    FirstCol   = Viewer.Catalog.GetString("Sander"),
                    LastCol    = sanderBlocked ? Viewer.Catalog.GetString("Blocked") + ColorCode[Color.OrangeRed] : Viewer.Catalog.GetString("On") + ColorCode[Color.Orange],
                    KeyPressed = sanderKey,
                    SymbolCol  = sanderKey,
                });
            }
            else
            {
                AddLabel(new ListLabel
                {
                    FirstCol   = Viewer.Catalog.GetString("Sander"),
                    LastCol    = Viewer.Catalog.GetString("Off"),
                    KeyPressed = "",
                    SymbolCol  = "",
                });
            }

            AddSeparator();

            // Train Brake multi-lines
            // TODO: A better algorithm
            //var brakeStatus = Owner.Viewer.PlayerLocomotive.GetTrainBrakeStatus();
            //steam loco
            string brakeInfoValue = "";
            int    index          = 0;

            if (trainBrakeStatus.Contains(Viewer.Catalog.GetString("EQ")))
            {
                string brakeKey;
                switch (GetPressedKey(UserCommand.ControlTrainBrakeDecrease, UserCommand.ControlTrainBrakeIncrease))
                {
                case UserCommand.ControlTrainBrakeDecrease:
                    brakeKey = Symbols.ArrowDown + ColorCode[Color.Yellow];
                    break;

                case UserCommand.ControlTrainBrakeIncrease:
                    brakeKey = Symbols.ArrowUp + ColorCode[Color.Yellow];
                    break;

                default:
                    brakeKey = "";
                    break;
                }
                brakeInfoValue = trainBrakeStatus.Substring(0, trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("EQ"))).TrimEnd();
                AddLabel(new ListLabel
                {
                    FirstCol   = Viewer.Catalog.GetString("Train brake"),
                    LastCol    = $"{brakeInfoValue}{ColorCode[Color.Cyan]}",
                    KeyPressed = brakeKey,
                    SymbolCol  = brakeKey,
                });

                index          = trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("EQ"));
                brakeInfoValue = trainBrakeStatus.Substring(index, trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("BC")) - index).TrimEnd();

                AddLabel(new ListLabel
                {
                    LastCol = brakeInfoValue,
                });
                if (trainBrakeStatus.Contains(Viewer.Catalog.GetString("EOT")))
                {
                    int indexOffset = Viewer.Catalog.GetString("EOT").Length + 1;
                    index          = trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("BC"));
                    brakeInfoValue = trainBrakeStatus.Substring(index, trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("EOT")) - index).TrimEnd();
                    AddLabel(new ListLabel
                    {
                        LastCol = brakeInfoValue,
                    });
                    index          = trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("EOT")) + indexOffset;
                    brakeInfoValue = trainBrakeStatus.Substring(index, trainBrakeStatus.Length - index).TrimStart();
                    AddLabel(new ListLabel
                    {
                        LastCol = brakeInfoValue,
                    });
                }
                else
                {
                    index          = trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("BC"));
                    brakeInfoValue = trainBrakeStatus.Substring(index, trainBrakeStatus.Length - index).TrimEnd();
                    AddLabel(new ListLabel
                    {
                        LastCol = brakeInfoValue,
                    });
                }
            }
            else if (trainBrakeStatus.Contains(Viewer.Catalog.GetString("Lead")))
            {
                int indexOffset = Viewer.Catalog.GetString("Lead").Length + 1;
                brakeInfoValue = trainBrakeStatus.Substring(0, trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("Lead"))).TrimEnd();
                AddLabel(new ListLabel
                {
                    FirstCol = Viewer.Catalog.GetString("Train brake"),
                    LastCol  = $"{brakeInfoValue}{ColorCode[Color.Cyan]}",
                });

                index = trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("Lead")) + indexOffset;
                if (trainBrakeStatus.Contains(Viewer.Catalog.GetString("EOT")))
                {
                    brakeInfoValue = trainBrakeStatus.Substring(index, trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("EOT")) - index).TrimEnd();
                    AddLabel(new ListLabel
                    {
                        LastCol = brakeInfoValue,
                    });

                    index          = trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("EOT")) + indexOffset;
                    brakeInfoValue = trainBrakeStatus.Substring(index, trainBrakeStatus.Length - index).TrimEnd();
                    AddLabel(new ListLabel
                    {
                        LastCol = brakeInfoValue,
                    });
                }
                else
                {
                    brakeInfoValue = trainBrakeStatus.Substring(index, trainBrakeStatus.Length - index).TrimEnd();
                    AddLabel(new ListLabel
                    {
                        LastCol = brakeInfoValue,
                    });
                }
            }
            else if (trainBrakeStatus.Contains(Viewer.Catalog.GetString("BC")))
            {
                brakeInfoValue = trainBrakeStatus.Substring(0, trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("BC"))).TrimEnd();
                AddLabel(new ListLabel
                {
                    FirstCol = Viewer.Catalog.GetString("Train brake"),
                    LastCol  = $"{brakeInfoValue}{ColorCode[Color.Cyan]}",
                });

                index          = trainBrakeStatus.IndexOf(Viewer.Catalog.GetString("BC"));
                brakeInfoValue = trainBrakeStatus.Substring(index, trainBrakeStatus.Length - index).TrimEnd();

                AddLabel(new ListLabel
                {
                    LastCol = brakeInfoValue,
                });
            }

            if (showRetainers)
            {
                AddLabel(new ListLabel
                {
                    FirstCol = Viewer.Catalog.GetString("Retainers"),
                    LastCol  = $"{train.RetainerPercent} {Viewer.Catalog.GetString(GetStringAttribute.GetPrettyName(train.RetainerSetting))}",
                });
            }

            if (engineBrakeStatus.Contains(Viewer.Catalog.GetString("BC")))
            {
                AddLabel(new ListLabel
                {
                    FirstCol = Viewer.Catalog.GetString("Engine brake"),
                    LastCol  = engineBrakeStatus.Substring(0, engineBrakeStatus.IndexOf("BC")) + ColorCode[Color.Cyan],
                });
                index          = engineBrakeStatus.IndexOf(Viewer.Catalog.GetString("BC"));
                brakeInfoValue = engineBrakeStatus.Substring(index, engineBrakeStatus.Length - index).TrimEnd();
                AddLabel(new ListLabel
                {
                    FirstCol = Viewer.Catalog.GetString(""),
                    LastCol  = $"{brakeInfoValue}{ColorCode[Color.White]}",
                });
            }
            else
            {
                AddLabel(new ListLabel
                {
                    FirstCol = Viewer.Catalog.GetString("Engine brake"),
                    LastCol  = $"{engineBrakeStatus}{ColorCode[Color.Cyan]}",
                });
            }

            if (dynamicBrakeStatus != null && locomotive.IsLeadLocomotive())
            {
                if (locomotive.DynamicBrakePercent >= 0)
                {
                    AddLabel(new ListLabel
                    {
                        FirstCol = Viewer.Catalog.GetString("Dynamic brake"),
                        LastCol  = locomotive.DynamicBrake ? dynamicBrakeStatus : Viewer.Catalog.GetString("Setup") + ColorCode[Color.Cyan],
                    });
                }
                else
                {
                    AddLabel(new ListLabel
                    {
                        FirstCol = Viewer.Catalog.GetString("Dynamic brake"),
                        LastCol  = Viewer.Catalog.GetString("Off"),
                    });
                }
            }

            AddSeparator();

            if (locomotiveStatus != null)
            {
                foreach (string data in locomotiveStatus.Split('\n').Where((string d) => !string.IsNullOrWhiteSpace(d)))
                {
                    string[] parts     = data.Split(new string[] { " = " }, 2, StringSplitOptions.None);
                    string   keyPart   = parts[0];
                    string   valuePart = parts?[1];
                    if (Viewer.Catalog.GetString(keyPart).StartsWith(Viewer.Catalog.GetString("Boiler pressure")))
                    {
                        MSTSSteamLocomotive steamLocomotive2 = (MSTSSteamLocomotive)locomotive;
                        float bandUpper = steamLocomotive2.PreviousBoilerHeatOutBTUpS * 1.025f; // find upper bandwidth point
                        float bandLower = steamLocomotive2.PreviousBoilerHeatOutBTUpS * 0.975f; // find lower bandwidth point - gives a total 5% bandwidth

                        string heatIndicator;
                        if (steamLocomotive2.BoilerHeatInBTUpS > bandLower && steamLocomotive2.BoilerHeatInBTUpS < bandUpper)
                        {
                            heatIndicator = $"{Symbols.SmallDiamond}{ColorCode[Color.White]}";
                        }
                        else if (steamLocomotive2.BoilerHeatInBTUpS < bandLower)
                        {
                            heatIndicator = $"{Symbols.SmallArrowDown}{ColorCode[Color.Cyan]}";
                        }
                        else if (steamLocomotive2.BoilerHeatInBTUpS > bandUpper)
                        {
                            heatIndicator = $"{Symbols.SmallArrowUp}{ColorCode[Color.Orange]}";
                        }
                        else
                        {
                            heatIndicator = ColorCode[Color.White];
                        }

                        AddLabel(new ListLabel
                        {
                            FirstCol  = Viewer.Catalog.GetString("Boiler pressure"),
                            LastCol   = Viewer.Catalog.GetString(valuePart),
                            SymbolCol = heatIndicator,
                        });
                    }
                    else if (!normalTextMode && Viewer.Catalog.GetString(parts[0]).StartsWith(Viewer.Catalog.GetString("Fuel levels")))
                    {
                        AddLabel(new ListLabel
                        {
                            FirstCol = keyPart.EndsWith("?") || keyPart.EndsWith("!") ? Viewer.Catalog.GetString(keyPart.Substring(0, keyPart.Length - 3)) : Viewer.Catalog.GetString(keyPart),
                            LastCol  = valuePart.Length > 1 ? Viewer.Catalog.GetString(valuePart.Replace(" ", string.Empty)) : "",
                        });
                    }
                    else if (keyPart.StartsWith(Viewer.Catalog.GetString("Gear")))
                    {
                        string gearKey;
                        switch (GetPressedKey(UserCommand.ControlGearDown, UserCommand.ControlGearUp))
                        {
                        case UserCommand.ControlGearDown:
                            gearKey = Symbols.ArrowDown + ColorCode[Color.Yellow];
                            break;

                        case UserCommand.ControlGearUp:
                            gearKey = Symbols.ArrowUp + ColorCode[Color.Yellow];
                            break;

                        default:
                            gearKey = "";
                            break;
                        }

                        AddLabel(new ListLabel
                        {
                            FirstCol   = Viewer.Catalog.GetString(keyPart),
                            LastCol    = valuePart != null ? Viewer.Catalog.GetString(valuePart) : "",
                            KeyPressed = gearKey,
                            SymbolCol  = gearKey,
                        });
                    }
                    else if (parts.Contains(Viewer.Catalog.GetString("Pantographs")))
                    {
                        string pantoKey;
                        switch (GetPressedKey(UserCommand.ControlPantograph1))
                        {
                        case UserCommand.ControlPantograph1:
                            string arrow = parts[1].StartsWith(Viewer.Catalog.GetString("Up")) ? Symbols.ArrowUp : Symbols.ArrowDown;
                            pantoKey = arrow + ColorCode[Color.Yellow];
                            break;

                        default:
                            pantoKey = "";
                            break;
                        }

                        AddLabel(new ListLabel
                        {
                            FirstCol   = Viewer.Catalog.GetString(keyPart),
                            LastCol    = valuePart != null ? Viewer.Catalog.GetString(valuePart) : "",
                            KeyPressed = pantoKey,
                            SymbolCol  = pantoKey,
                        });
                    }
                    else if (parts.Contains(Viewer.Catalog.GetString("Engine")))
                    {
                        AddLabel(new ListLabel
                        {
                            FirstCol = Viewer.Catalog.GetString(keyPart),
                            LastCol  = valuePart != null ? $"{Viewer.Catalog.GetString(valuePart)}{ColorCode[Color.White]}" : "",
                        });
                    }
                    else
                    {
                        AddLabel(new ListLabel
                        {
                            FirstCol = keyPart.EndsWith("?") || keyPart.EndsWith("!") ? Viewer.Catalog.GetString(keyPart.Substring(0, keyPart.Length - 3)) : Viewer.Catalog.GetString(keyPart),
                            LastCol  = valuePart != null ? Viewer.Catalog.GetString(valuePart) : "",
                        });
                    }
                }
            }

            AddSeparator();

            if (normalTextMode)
            {
                AddLabel(new ListLabel
                {
                    FirstCol = Viewer.Catalog.GetString("FPS"),
                    LastCol  = $"{Math.Floor(viewer.RenderProcess.FrameRate.SmoothedValue)}",
                });
            }

            // Messages
            // Autopilot
            bool autopilot = locomotive.Train.TrainType == Train.TRAINTYPE.AI_PLAYERHOSTING;

            AddLabel(new ListLabel
            {
                FirstCol = Viewer.Catalog.GetString("Autopilot"),
                LastCol  = autopilot ? Viewer.Catalog.GetString("On") + ColorCode[Color.Yellow] : Viewer.Catalog.GetString("Off"),
            });

            // Grate limit
            if (locomotive is MSTSSteamLocomotive steamLocomotive1)
            {
                if (steamLocomotive1.IsGrateLimit && steamLocomotive1.GrateCombustionRateLBpFt2 > steamLocomotive1.GrateLimitLBpFt2)
                {
                    AddLabel(new ListLabel
                    {
                        FirstCol = Viewer.Catalog.GetString("Grate limit"),
                        LastCol  = Viewer.Catalog.GetString("Exceeded") + ColorCode[Color.OrangeRed],
                    });
                }
                else
                {
                    AddLabel(new ListLabel
                    {
                        FirstCol = Viewer.Catalog.GetString("Grate limit") + ColorCode[Color.Black],
                        LastCol  = Viewer.Catalog.GetString("Normal") + ColorCode[Color.Black],
                    });
                }
            }
            else
            {
                AddLabel(new ListLabel
                {
                    FirstCol = Viewer.Catalog.GetString("Grate limit") + ColorCode[Color.Black],
                    LastCol  = Viewer.Catalog.GetString("-") + ColorCode[Color.Black],
                });
            }

            // Wheel
            if (train.IsWheelSlip)
            {
                AddLabel(new ListLabel
                {
                    FirstCol = Viewer.Catalog.GetString("Wheel"),
                    LastCol  = Viewer.Catalog.GetString("slip") + ColorCode[Color.OrangeRed],
                });
            }
            else if (train.IsWheelSlipWarninq)
            {
                AddLabel(new ListLabel
                {
                    FirstCol = Viewer.Catalog.GetString("Wheel"),
                    LastCol  = Viewer.Catalog.GetString("slip warning") + ColorCode[Color.Yellow],
                });
            }
            else if (train.IsBrakeSkid)
            {
                AddLabel(new ListLabel
                {
                    FirstCol = Viewer.Catalog.GetString("Wheel"),
                    LastCol  = Viewer.Catalog.GetString("skid") + ColorCode[Color.OrangeRed],
                });
            }
            else
            {
                AddLabel(new ListLabel
                {
                    FirstCol = Viewer.Catalog.GetString("Wheel") + ColorCode[Color.Black],
                    LastCol  = Viewer.Catalog.GetString("Normal") + ColorCode[Color.Black],
                });
            }

            // Doors
            var wagon = (MSTSWagon)locomotive;

            if (wagon.DoorLeftOpen || wagon.DoorRightOpen)
            {
                var  status  = new List <string>();
                bool flipped = locomotive.GetCabFlipped();
                if (wagon.DoorLeftOpen)
                {
                    status.Add(Viewer.Catalog.GetString(Viewer.Catalog.GetString(flipped ? "Right" : "Left")));
                }
                if (wagon.DoorRightOpen)
                {
                    status.Add(Viewer.Catalog.GetString(Viewer.Catalog.GetString(flipped ? "Left" : "Right")));
                }

                AddLabel(new ListLabel
                {
                    FirstCol = Viewer.Catalog.GetString("Doors open"),
                    LastCol  = string.Join(" ", status) + ColorCode[locomotive.AbsSpeedMpS > 0.1f ? Color.OrangeRed : Color.Yellow],
                });
            }
            else
            {
                AddLabel(new ListLabel
                {
                    FirstCol = Viewer.Catalog.GetString("Doors open") + ColorCode[Color.Black],
                    LastCol  = Viewer.Catalog.GetString("Closed") + ColorCode[Color.Black],
                });
            }

            AddLabel(new ListLabel());
            return(labels);
        }
Ejemplo n.º 25
0
 public ToggleMUCommand(CommandLog log, MSTSLocomotive receiver, bool toState)
     : base(log, toState)
 {
     Receiver = receiver;
     Redo();
 }
Ejemplo n.º 26
0
 public ScriptedBrakeController Clone(MSTSLocomotive locomotive)
 {
     return(new ScriptedBrakeController(this, locomotive));
 }
Ejemplo n.º 27
0
 public override void CorrectMaxCylPressurePSI(MSTSLocomotive loco)
 {
 }
Ejemplo n.º 28
0
        public override void Update(float elapsedClockSeconds)
        {
            MSTSLocomotive lead = (MSTSLocomotive)Car.Train.LeadLocomotive;
            float          BrakemanBrakeSettingValue = 0;
            float          EngineBrakeSettingValue   = 0;

            ManualBrakingDesiredFraction = 0;

            SteamBrakeCompensation = 1.0f;

            // Process manual braking on all cars
            if (lead != null)
            {
                BrakemanBrakeSettingValue = lead.BrakemanBrakeController.CurrentValue;
            }

            ManualBrakingDesiredFraction = BrakemanBrakeSettingValue * ManualMaxBrakeValue;

            if (ManualBrakingCurrentFraction < ManualBrakingDesiredFraction)
            {
                ManualBrakingCurrentFraction += ManualMaxApplicationRateValuepS;
                if (ManualBrakingCurrentFraction > ManualBrakingDesiredFraction)
                {
                    ManualBrakingCurrentFraction = ManualBrakingDesiredFraction;
                }
            }
            else if (ManualBrakingCurrentFraction > ManualBrakingDesiredFraction)
            {
                ManualBrakingCurrentFraction -= ManualReleaseRateValuepS;
                if (ManualBrakingCurrentFraction < 0)
                {
                    ManualBrakingCurrentFraction = 0;
                }
            }

            BrakeForceFraction = ManualBrakingCurrentFraction / ManualMaxBrakeValue;

            // If car is a locomotive or tender, then process engine brake
            if (Car.WagonType == MSTSWagon.WagonTypes.Engine || Car.WagonType == MSTSWagon.WagonTypes.Tender) // Engine brake
            {
                if (lead != null)
                {
                    EngineBrakeSettingValue = lead.EngineBrakeController.CurrentValue;
                    if (lead.SteamEngineBrakeFitted)
                    {
                        LocomotiveSteamBrakeFitted = true;
                        EngineBrakeDesiredFraction = EngineBrakeSettingValue * lead.MaxBoilerPressurePSI;
                    }
                    else
                    {
                        EngineBrakeDesiredFraction = EngineBrakeSettingValue * ManualMaxBrakeValue;
                    }


                    if (EngineBrakingCurrentFraction < EngineBrakeDesiredFraction)
                    {
                        EngineBrakingCurrentFraction += elapsedClockSeconds * lead.EngineBrakeController.ApplyRatePSIpS;
                        if (EngineBrakingCurrentFraction > EngineBrakeDesiredFraction)
                        {
                            EngineBrakingCurrentFraction = EngineBrakeDesiredFraction;
                        }
                    }
                    else if (EngineBrakingCurrentFraction > EngineBrakeDesiredFraction)
                    {
                        EngineBrakingCurrentFraction -= elapsedClockSeconds * lead.EngineBrakeController.ReleaseRatePSIpS;
                        if (EngineBrakingCurrentFraction < 0)
                        {
                            EngineBrakingCurrentFraction = 0;
                        }
                    }

                    if (lead.SteamEngineBrakeFitted)
                    {
                        SteamBrakeCompensation        = lead.BoilerPressurePSI / lead.MaxBoilerPressurePSI;
                        SteamBrakePressurePSI         = EngineBrakeSettingValue * SteamBrakeCompensation * lead.MaxBoilerPressurePSI;
                        SteamBrakeCylinderPressurePSI = EngineBrakingCurrentFraction * SteamBrakeCompensation;    // For display purposes
                        BrakeForceFraction            = EngineBrakingCurrentFraction / lead.MaxBoilerPressurePSI; // Manual braking value overwritten by engine calculated value
                    }
                    else
                    {
                        BrakeForceFraction = EngineBrakingCurrentFraction / ManualMaxBrakeValue;
                    }
                }
            }

            float f;

            if (!Car.BrakesStuck)
            {
                f = Car.MaxBrakeForceN * Math.Min(BrakeForceFraction, 1);
                if (f < Car.MaxHandbrakeForceN * HandbrakePercent / 100)
                {
                    f = Car.MaxHandbrakeForceN * HandbrakePercent / 100;
                }
            }
            else
            {
                f = Math.Max(Car.MaxBrakeForceN, Car.MaxHandbrakeForceN / 2);
            }
            Car.BrakeRetardForceN = f * Car.BrakeShoeRetardCoefficientFrictionAdjFactor; // calculates value of force applied to wheel, independent of wheel skid
            if (Car.BrakeSkid)                                                           // Test to see if wheels are skiding to excessive brake force
            {
                Car.BrakeForceN = f * Car.SkidFriction;                                  // if excessive brakeforce, wheel skids, and loses adhesion
            }
            else
            {
                Car.BrakeForceN = f * Car.BrakeShoeCoefficientFrictionAdjFactor; // In advanced adhesion model brake shoe coefficient varies with speed, in simple model constant force applied as per value in WAG file, will vary with wheel skid.
            }
        }
Ejemplo n.º 29
0
        /// Initializes brakes also if Speed != 0; directly used by keyboard command
        internal void UnconditionalInitializeBrakes()
        {
            if (simulator.Settings.SimpleControlPhysics && LeadLocomotiveIndex >= 0) // If brake and control set to simple, and a locomotive present, then set all cars to same brake system as the locomotive
            {
                MSTSLocomotive lead = (MSTSLocomotive)Cars[LeadLocomotiveIndex];
                if (lead.TrainBrakeController != null)
                {
                    foreach (MSTSWagon car in Cars)
                    {
                        if (lead.CarBrakeSystemType != car.CarBrakeSystemType) // Test to see if car brake system is the same as the locomotive
                        {
                            // If not, change so that they are compatible
                            car.CarBrakeSystemType = lead.CarBrakeSystemType;
                            if (lead.BrakeSystem is VacuumSinglePipe)
                            {
                                car.MSTSBrakeSystem = new VacuumSinglePipe(car);
                            }
                            else if (lead.BrakeSystem is AirTwinPipe)
                            {
                                car.MSTSBrakeSystem = new AirTwinPipe(car);
                            }
                            else if (lead.BrakeSystem is AirSinglePipe)
                            {
                                car.MSTSBrakeSystem = new AirSinglePipe(car);
                                // if emergency reservoir has been set on lead locomotive then also set on trailing cars
                                if (lead.EmergencyReservoirPresent)
                                {
                                    car.EmergencyReservoirPresent = lead.EmergencyReservoirPresent;
                                }
                            }
                            else if (lead.BrakeSystem is EPBrakeSystem)
                            {
                                car.MSTSBrakeSystem = new EPBrakeSystem(car);
                            }
                            else if (lead.BrakeSystem is SingleTransferPipe)
                            {
                                car.MSTSBrakeSystem = new SingleTransferPipe(car);
                            }
                            else
                            {
                                throw new Exception("Unknown brake type");
                            }

                            car.MSTSBrakeSystem.InitializeFromCopy(lead.BrakeSystem);
                            Trace.TraceInformation("Car and Locomotive Brake System Types Incompatible on Car {0} - Car brakesystem type changed to {1}", car.CarID, car.CarBrakeSystemType);
                        }
                    }
                }
            }

            simulator.Confirmer?.Confirm(CabControl.InitializeBrakes, CabSetting.Off);

            float maxPressurePSI      = 90;
            float fullServPressurePSI = 64;

            if (FirstCar?.BrakeSystem is VacuumSinglePipe)
            {
                maxPressurePSI      = 21;
                fullServPressurePSI = 16;
            }

            if (LeadLocomotiveIndex >= 0)
            {
                MSTSLocomotive lead = (MSTSLocomotive)Cars[LeadLocomotiveIndex];
                if (lead.TrainBrakeController != null)
                {
                    maxPressurePSI                  = lead.TrainBrakeController.MaxPressurePSI;
                    fullServPressurePSI             = lead.BrakeSystem is VacuumSinglePipe ? 16 : maxPressurePSI - lead.TrainBrakeController.FullServReductionPSI;
                    EqualReservoirPressurePSIorInHg = Math.Min(maxPressurePSI, EqualReservoirPressurePSIorInHg);
                    (double pressurePSI, double epControllerState) = lead.TrainBrakeController.UpdatePressure(EqualReservoirPressurePSIorInHg, BrakeLine4, 1000);
                    BrakeLine4 = (float)epControllerState;
                    EqualReservoirPressurePSIorInHg = (float)Math.Max(pressurePSI, fullServPressurePSI);
                }
                if (lead.EngineBrakeController != null)
                {
                    BrakeLine3PressurePSI = (float)lead.EngineBrakeController.UpdateEngineBrakePressure(BrakeLine3PressurePSI, 1000);
                }
                if (lead.DynamicBrakeController != null)
                {
                    MUDynamicBrakePercent = lead.DynamicBrakeController.Update(1000) * 100;
                    if (MUDynamicBrakePercent == 0)
                    {
                        MUDynamicBrakePercent = -1;
                    }
                }
                BrakeLine2PressurePSI = lead.MaximumMainReservoirPipePressurePSI;
                ConnectBrakeHoses();
            }
            else
            {
                EqualReservoirPressurePSIorInHg = BrakeLine2PressurePSI = BrakeLine3PressurePSI = 0;
                // Initialize static consists airless for allowing proper shunting operations,
                // but set AI trains pumped up with air.
                if (TrainType == TrainType.Static)
                {
                    maxPressurePSI = 0;
                }
                BrakeLine4 = -1;
            }
            foreach (TrainCar car in Cars)
            {
                car.BrakeSystem.Initialize(LeadLocomotiveIndex < 0, maxPressurePSI, fullServPressurePSI, false);
            }
        }
Ejemplo n.º 30
0
 public abstract bool IsBraking();                                   // return true if the wagon is braking above a certain threshold
 public abstract void CorrectMaxCylPressurePSI(MSTSLocomotive loco); // corrects max cyl pressure when too high