Пример #1
0
        /// <summary>
        /// This function updates periodically the locomotive's motive force.
        /// </summary>
        protected override void UpdateMotiveForce(float elapsedClockSeconds, float t, float AbsSpeedMpS, float AbsWheelSpeedMpS)
        {
            if (PowerOn)
            {
                if (TractiveForceCurves == null)
                {
                    float maxForceN = Math.Min(t * MaxForceN * (1 - PowerReduction), AbsWheelSpeedMpS == 0.0f ? (t * MaxForceN * (1 - PowerReduction)) : (t * DieselEngines.CurrentRailOutputPowerW / AbsWheelSpeedMpS));
                    float maxPowerW = 0.98f * DieselEngines.MaximumRailOutputPowerW;      //0.98 added to let the diesel engine handle the adhesion-caused jittering

                    if (DieselEngines.HasGearBox)
                    {
                        MotiveForceN = DieselEngines.MotiveForceN;
                    }
                    else
                    {
                        if (maxForceN * AbsWheelSpeedMpS > maxPowerW)
                        {
                            maxForceN = maxPowerW / AbsWheelSpeedMpS;
                        }
                        if (AbsSpeedMpS > MaxSpeedMpS - 0.05f)
                        {
                            maxForceN = 20 * (MaxSpeedMpS - AbsSpeedMpS) * maxForceN;
                        }
                        if (AbsSpeedMpS > (MaxSpeedMpS))
                        {
                            maxForceN = 0;
                        }
                        MotiveForceN = maxForceN;
                    }
                }
                else
                {
                    if (t > (DieselEngines.MaxOutputPowerW / DieselEngines.MaxPowerW))
                    {
                        t = (DieselEngines.MaxOutputPowerW / DieselEngines.MaxPowerW);
                    }
                    MotiveForceN = TractiveForceCurves.Get(t, AbsWheelSpeedMpS) * (1 - PowerReduction);
                    if (MotiveForceN < 0 && !TractiveForceCurves.AcceptsNegativeValues())
                    {
                        MotiveForceN = 0;
                    }
                }

                DieselFlowLps           = DieselEngines.DieselFlowLps;
                partialFuelConsumption += DieselEngines.DieselFlowLps * elapsedClockSeconds;
                if (partialFuelConsumption >= 0.1)
                {
                    DieselLevelL          -= partialFuelConsumption;
                    partialFuelConsumption = 0;
                }
                if (DieselLevelL <= 0.0f)
                {
                    PowerOn = false;
                    SignalEvent(Event.EnginePowerOff);
                    foreach (DieselEngine de in DieselEngines)
                    {
                        if (de.EngineStatus != DieselEngine.Status.Stopping || de.EngineStatus != DieselEngine.Status.Stopped)
                        {
                            de.Stop();
                        }
                    }
                }
                //               MassKG = InitialMassKg - MaxDieselLevelL * DieselWeightKgpL + DieselLevelL * DieselWeightKgpL;
            }

            if (MaxForceN > 0 && MaxContinuousForceN > 0 && PowerReduction < 1)
            {
                MotiveForceN *= 1 - (MaxForceN - MaxContinuousForceN) / (MaxForceN * MaxContinuousForceN) * AverageForceN * (1 - PowerReduction);
                float w = (ContinuousForceTimeFactor - elapsedClockSeconds) / ContinuousForceTimeFactor;
                if (w < 0)
                {
                    w = 0;
                }
                AverageForceN = w * AverageForceN + (1 - w) * MotiveForceN;
            }
        }
Пример #2
0
        /// <summary>
        /// This function updates periodically the locomotive's motive force.
        /// </summary>
        protected override void UpdateMotiveForce(float elapsedClockSeconds, float t, float AbsSpeedMpS, float AbsWheelSpeedMpS)
        {
            // This section calculates the motive force of the locomotive as follows:
            // Basic configuration (no TF table) - uses P = F /speed  relationship - requires power and force parameters to be set in the ENG file.
            // Advanced configuration (TF table) - use a user defined tractive force table
            // With Simple adhesion apart from correction for rail adhesion, there is no further variation to the motive force.
            // With Advanced adhesion the raw motive force is fed into the advanced (axle) adhesion model, and is corrected for wheel slip and rail adhesion
            if (PowerOn)
            {
                if (TractiveForceCurves == null)
                {
                    float maxForceN = Math.Min(t * MaxForceN * (1 - PowerReduction), AbsSpeedMpS == 0.0f ? (t * MaxForceN * (1 - PowerReduction)) : (t * LocomotiveMaxRailOutputPowerW / AbsSpeedMpS));

                    float maxPowerW = LocomotiveMaxRailOutputPowerW * (DieselEngines.ApparentThrottleSetting / 100.0f);

                    if (DieselEngines.HasGearBox)
                    {
                        MotiveForceN = DieselEngines.MotiveForceN;
                    }
                    else
                    {
                        if (maxForceN * AbsSpeedMpS > maxPowerW)
                        {
                            maxForceN = maxPowerW / AbsSpeedMpS;
                        }

                        // CTN - Not sure what impact that these following have???
                        if (AbsSpeedMpS > MaxSpeedMpS - 0.05f)
                        {
                            maxForceN = 20 * (MaxSpeedMpS - AbsSpeedMpS) * maxForceN;
                        }

                        // CTN - Sets power to zero, which I don't think is correct
                        if (AbsSpeedMpS > (MaxSpeedMpS))
                        {
                            maxForceN = 0;
                        }

                        MotiveForceN = maxForceN;
                    }
                }
                else
                {
                    MotiveForceN = TractiveForceCurves.Get((DieselEngines.ApparentThrottleSetting / 100.0f), AbsSpeedMpS) * (1 - PowerReduction);
                    if (MotiveForceN < 0 && !TractiveForceCurves.AcceptsNegativeValues())
                    {
                        MotiveForceN = 0;
                    }
                }

                DieselFlowLps           = DieselEngines.DieselFlowLps;
                partialFuelConsumption += DieselEngines.DieselFlowLps * elapsedClockSeconds;
                if (partialFuelConsumption >= 0.1)
                {
                    DieselLevelL          -= partialFuelConsumption;
                    partialFuelConsumption = 0;
                }
                if (DieselLevelL <= 0.0f)
                {
                    PowerOn = false;
                    SignalEvent(Event.EnginePowerOff);
                    foreach (DieselEngine de in DieselEngines)
                    {
                        if (de.EngineStatus != DieselEngine.Status.Stopping || de.EngineStatus != DieselEngine.Status.Stopped)
                        {
                            de.Stop();
                        }
                    }
                }
            }

            if (MaxForceN > 0 && MaxContinuousForceN > 0 && PowerReduction < 1)
            {
                MotiveForceN *= 1 - (MaxForceN - MaxContinuousForceN) / (MaxForceN * MaxContinuousForceN) * AverageForceN * (1 - PowerReduction);
                float w = (ContinuousForceTimeFactor - elapsedClockSeconds) / ContinuousForceTimeFactor;
                if (w < 0)
                {
                    w = 0;
                }
                AverageForceN = w * AverageForceN + (1 - w) * MotiveForceN;
            }
        }