Represents data given to the plugin in the Elapse call.
Exemple #1
0
        internal override int? Elapse(ElapseData data)
        {
            //Is train in RM?
            if(train.trainModeActual != Train.TrainModes.RestrictedManualForward && train.trainModeActual != Train.TrainModes.RestrictedManualReverse)
            {
                return null;
            }

            //Perform applications
            if (isForcedBraking && Math.Abs(data.Vehicle.Speed.KilometersPerHour) > RM_LIMITER_RESET_KMH)
            {
                return -train.specs.BrakeNotches;
            }
            else if (isForcedCoasting && Math.Abs(data.Vehicle.Speed.KilometersPerHour) > RM_LIMITER_RESET_KMH)
            {
                return 0;
            }

            //Check if applications are needed
            if (Math.Abs(data.Vehicle.Speed.KilometersPerHour) > RM_MAX_SPEED_KMH)
            {
                isForcedBraking = true;
            }
            else if (Math.Abs(data.Vehicle.Speed.KilometersPerHour) > RM_MOTOR_CUTOUT_KMH)
            {
                isForcedCoasting = true;
            }
            else
            {
                isForcedBraking = false;
                isForcedCoasting = false;
            }

            return null;
        }
Exemple #2
0
        internal override int? Elapse(ElapseData data)
        {
            if (trainModeNew != null)
            {
                train.trainModeSelected = (Train.TrainModes)trainModeNew;
                changeModeTimer = CHANGE_MODE_TIMER;
                trainModeNew = null;
            }

            if (train.trainModeActual != train.trainModeSelected)
            {
                if (IsModeChangable(data))
                {
                    if (changeModeTimer > 0)
                    {
                        changeModeTimer -= (float)data.ElapsedTime.Seconds;
                    }
                    else
                    {
                        changeModeTimer = 0.0f;
                        train.trainModeActual = train.trainModeSelected;
                    }
                }
                else
                {
                    return -train.specs.BrakeNotches;
                }
            }
            return null;
        }
        public Speed getCurrentSpeedLimit(ElapseData data)
        {
            if (decelerationControlEnabled)
            {
                double distance = System.Math.Abs(decelerationTargetDistance - (int) Math.Round(data.Vehicle.Location));
                double s = (decelerationInitSpeed.MetersPerSecond / System.Math.Sqrt(2 * decelCoeff * decelerationInitLocation)) * System.Math.Sqrt(2 * decelCoeff * distance);

                if (decelerationType == DecelerationControlType.strong)
                {
                    if (s > 4.16) /* 15 km/h */
                        return new Speed(s);
                    else
                        return new Speed(4.16);
                }
                else
                {
                    if (s > 8.33) /* 30 km/h */
                        return new Speed(s);
                    else
                        return new Speed(8.33);
                }
            }
            else
                return currentSpeedLimit;
        }
Exemple #4
0
        public override void elapse(ElapseData data)
        {
            globalTime = data.TotalTime;

            if (!applyBreak && (data.Vehicle.Speed.KilometersPerHour > 0 || securityTest))
            {
                if (!hold && (globalTime.Milliseconds - time.Milliseconds) > delayBeforeBreaking)
                {
                    soundManager.startSound(ref vacmaHorn, SoundIndex.Vacma);
                    if ((globalTime.Milliseconds - time.Milliseconds) > delayBeforeBreaking * 2)
                    {
                        applyBreak = true;
                        soundManager.stopSound(ref vacmaHorn);
                        handleManager.applyEmergencyBrake();
                    }
                }
                else if ((globalTime.Milliseconds - time.Milliseconds) > delayBeforeRinging)
                {
                    soundManager.startSound(ref vacmaRing, SoundIndex.VacmaRing);
                    if ((globalTime.Milliseconds - time.Milliseconds) > (delayBeforeRinging + delayBeforeBreaking))
                    {
                        applyBreak = true;
                        soundManager.stopSound(ref vacmaRing);
                        handleManager.applyEmergencyBrake();
                    }
                }
            }
            else
                time = globalTime;
        }
Exemple #5
0
 internal override void Elapse(ElapseData data)
 {
     #if !DEBUG
     try {
         #endif
         this.Api.Elapse(data);
         for (int i = 0; i < this.SoundHandlesCount; i++) {
             if (this.SoundHandles[i].Stopped | this.SoundHandles[i].Source.State == Sounds.SoundSourceState.Stopped) {
                 this.SoundHandles[i].Stop();
                 this.SoundHandles[i].Source.Stop();
                 this.SoundHandles[i] = this.SoundHandles[this.SoundHandlesCount - 1];
                 this.SoundHandlesCount--;
                 i--;
             } else {
                 this.SoundHandles[i].Source.Pitch = Math.Max(0.01, this.SoundHandles[i].Pitch);
                 this.SoundHandles[i].Source.Volume = Math.Max(0.0, this.SoundHandles[i].Volume);
             }
         }
         #if !DEBUG
     } catch (Exception ex) {
         base.LastException = ex;
         throw;
     }
     #endif
 }
Exemple #6
0
        internal override int? Elapse(ElapseData data)
        {
            //Calculate signalling status
            //Distance to next train
            UpdateAtpSpeeds(data, data.PrecedingVehicle);

            //Check trip count
            //Check for speed limits
            ElapseTripTimer(data);

            //Is train in RM?
            if (train.trainModeActual == Train.TrainModes.RestrictedManualForward ||
                train.trainModeActual == Train.TrainModes.RestrictedManualReverse ||
                train.trainModeActual == Train.TrainModes.Off)
            {
                atpState = AtpStates.Off;
            }

            switch (atpState)
            {
                case AtpStates.Active:
                    if (atpTripTimer <= 0.0)
                    {
                        atpState = AtpStates.Tripped;
                    }
                    return null;
                case AtpStates.Tripped:

                    return -train.specs.BrakeNotches - 1;
                default:
                    return null;
            }
        }
Exemple #7
0
        internal void Elapse(ElapseData data)
        {
            vState = data;

            if (data.TotalTime.Milliseconds - lastTotalTimeSendElapseData >= 1000) {
                timsPipeServer.SendObject(data);
                lastTotalTimeSendElapseData = data.TotalTime.Milliseconds;
            }
        }
Exemple #8
0
 /// <summary>Is called every frame.</summary>
 /// <param name="data">The data passed to the plugin.</param>
 public void Elapse(ElapseData data)
 {
     closedSignalDevice.elapse(data);
     vacma.elapse(data);
     speedControl.elapse(data);
     handleManager.elapse(ref data);
     soundManager.elapse(data);
     cabControlManager.elapse(data);
 }
Exemple #9
0
        /// <summary>Is called every frame.</summary>
        /// <param name="data">The data passed to the plugin.</param>
        public void Elapse(ElapseData data)
        {
            ms.Elapse(data);
            tims.Elapse(data);

            Panel[PanelID.ActualHandle.Reverser] = data.Handles.Reverser;
            Panel[PanelID.ActualHandle.Power] = data.Handles.PowerNotch;
            Panel[PanelID.ActualHandle.Brake] = data.Handles.BrakeNotch;
            Panel[PanelID.ActualHandle.ConstSpd] = data.Handles.ConstSpeed ? 1 : 0;
        }
Exemple #10
0
 internal void Elapse(ElapseData vState)
 {
     Panel[PanelID.StatusLEDs.NoSignal] = 0;
     if (Stations.Count > 0) {
         if (lastCompletedDockingIndex > 0 && Stations[lastCompletedDockingIndex].TBSStart && doorCls) {
             // can operate in driverless using ATO
             OnDriverlessAvailableElapse(vState);
         }
     }
 }
Exemple #11
0
		/// <summary>Is called every frame.</summary>
		/// <param name="data">The data passed to the plugin.</param>
		public void Elapse(ElapseData data) {
			/*
			 * How to access panel variables:
			 * Panel[i] = 1;
			 * 
			 * How to access sound variables:
			 * Sound[i] = SoundInstructions.PlayOnce;
			 * */
			// TODO: Your old Elapse code goes here.
			Sound.Update();
		}
        public void elapse(ElapseData data)
        {
            globalTime = data.TotalTime;

            loopSoundsFor.ForEach(delegate (LoopSoundFor sound) {
                if (globalTime.Milliseconds - sound.start > sound.duration)
                {
                    sound.sound.Stop();
                    loopSoundsFor.Remove(sound);
                }
            });
        }
Exemple #13
0
        internal void Elapse(ElapseData data)
        {
            vState = data;

            stationsMemory.Elapse(data);

            #region Reset status LEDs
            Panel[PanelID.StatusLEDs.ATO] = 0;
            Panel[PanelID.StatusLEDs.ATP] = 0;
            Panel[PanelID.StatusLEDs.RM] = 0;
            Panel[PanelID.StatusLEDs.RM_Reverse] = 0;
            Panel[PanelID.StatusLEDs.HKHR_ATP] = 0;
            Panel[PanelID.StatusLEDs.NoSignal] = 0;
            #endregion

            #region reset ATP lamps to off if not using
            if ((int)currentMode < (int)Modes.PM)
                atp2.NotElapsing();
            #endregion
            // give privilege of controlling the train to different classes(modules) by state of mode currently using
            switch (currentMode) {
                case ModeSelector.Modes.Off:
                    vState.Handles.Reverser = 0;
                    vState.Handles.PowerNotch = 0;
                    vState.Handles.BrakeNotch = vSpec.BrakeNotches + 1;
                    driverless.Elapse(vState);
                    break;
                case ModeSelector.Modes.RM_B:
                    vState.Handles.Reverser = -1;
                    vState.Handles.PowerNotch = handlePower;
                    vState.Handles.BrakeNotch = handleBrake;
                    rm.Elapse(vState);
                    break;
                case ModeSelector.Modes.RM_F:
                    vState.Handles.Reverser = 1;
                    vState.Handles.PowerNotch = handlePower;
                    vState.Handles.BrakeNotch = handleBrake;
                    rm.Elapse(vState);
                    break;
                case ModeSelector.Modes.PM:
                    vState.Handles.Reverser = 1;
                    vState.Handles.PowerNotch = handlePower;
                    vState.Handles.BrakeNotch = handleBrake;
                    Panel[PanelID.StatusLEDs.ATP] = 1;
                    atp2.Elapse(vState);
                    break;
                case ModeSelector.Modes.AM:
                    vState.Handles.Reverser = 1;
                    Panel[PanelID.StatusLEDs.ATO] = 1;
                    ato.Elapse(atp2.Elapse(vState));
                    break;
            }
        }
Exemple #14
0
 internal override int? Elapse(ElapseData data)
 {
     if(this.train.doorState != DoorStates.None)
     {
         if(Math.Abs(data.Vehicle.Speed.KilometersPerHour) > 0.2)
         {
             return -this.train.specs.BrakeNotches - 1;
         }
         else
         {
             return -this.train.specs.BrakeNotches;
         }
     }
     return null;
 }
Exemple #15
0
        internal int CalculateStationStopNotchChange(ElapseData data, double distanceToNextStop)
        {
            //Returns notch adjustment
            double speed = data.Vehicle.Speed.MetersPerSecond;

            if (speed > ATO_LEVELLING_SPEED)
            {
                double stoppingDistance = CalculateDecelerationDistance(data.Vehicle.Speed.MetersPerSecond, ATO_TARGET_DECELERATION_RATE) ?? 0;

                if (stoppingDistance < distanceToNextStop - ATO_LEVELLING_DISTANCE - ATO_BRAKING_TOLERANCE)
                {
                    return 1;
                }
                else if (stoppingDistance > distanceToNextStop - ATO_LEVELLING_DISTANCE + ATO_BRAKING_TOLERANCE)
                {
                    return -1;
                }
                else
                {
                    return 0;
                }
            }
            else
            {
                double stoppingDistance = CalculateDecelerationDistance(data.Vehicle.Speed.MetersPerSecond, ATO_LEVELLING_DECELERATION_RATE) ?? 0;

                if (stoppingDistance < distanceToNextStop - ATO_LEVELLING_TOLERANCE)
                {
                    if(data.Vehicle.Speed.MetersPerSecond > ATO_LEVELLING_CRAWL_SPEED && atoDemands >= 0)
                    {
                        return 0;
                    }
                    else
                    {
                        return 1;
                    }
                }
                else if (stoppingDistance > distanceToNextStop + ATO_LEVELLING_TOLERANCE)
                {
                    return -1;
                }
                else
                {
                    return 0;
                }
            }
        }
Exemple #16
0
        internal void Elapse(ElapseData data)
        {
            Panel[PanelID.StatusLEDs.NoSignal] = 1; // assume as no signal
            Panel[PanelID.StatusLEDs.RM] = 1; // in RM mode
            Panel[PanelID.StatusLEDs.RM_Reverse] = data.Handles.Reverser == -1 ? 1 : 0; // in RM-B mode?

            if (data.Vehicle.Speed.KilometersPerHour > 45 || data.Vehicle.Speed.KilometersPerHour > SignalSpeed[(int)currentSignalPost]) {
                data.Handles.PowerNotch = 0;
                data.Handles.BrakeNotch = vSpec.BrakeNotches;
                BrakeInForce = true;
            }
            else if (BrakeInForce && data.Vehicle.Speed.KilometersPerHour <= SignalCoastingSpeed[(int)currentSignalPost]) {
                data.Handles.PowerNotch = 0;
                data.Handles.BrakeNotch = 0;
            }
            else if (!BrakeInForce && data.Vehicle.Speed.KilometersPerHour > SignalCoastingSpeed[(int)currentSignalPost]) {
                data.Handles.PowerNotch = 0;
                data.Handles.BrakeNotch = 0;
            }
        }
Exemple #17
0
		// --- functions ---
		
		/// <summary>Is called every frame.</summary>
		/// <param name="data">The data.</param>
		internal void Elapse(ElapseData data) {
			foreach (Sound sound in this.LoopingSounds) {
				if (sound.IsToBePlayed) {
					if (sound.Handle == null || sound.Handle.Stopped) {
						sound.Handle = PlaySound(sound.Index, 1.0, 1.0, true);
					}
				} else {
					if (sound.Handle != null && sound.Handle.Playing) {
						sound.Handle.Stop();
					}
				}
				sound.IsToBePlayed = false;
			}
			foreach (Sound sound in this.PlayOnceSounds) {
				if (sound.IsToBePlayed) {
					PlaySound(sound.Index, 1.0, 1.0, false);
					sound.IsToBePlayed = false;
				}
			}
		}
Exemple #18
0
 /// <summary>Is called every frame.</summary>
 /// <param name="data">The data.</param>
 /// <param name="blocking">Whether the device is blocked or will block subsequent devices.</param>
 internal override void Elapse(ElapseData data, ref bool blocking)
 {
     // --- behavior ---
     if (!blocking) {
         if (Math.Abs(data.Vehicle.Speed.KilometersPerHour) > SpeedThreshold | this.Counter >= TimeUntilBell) {
             this.Counter += data.ElapsedTime.Seconds;
             if (this.Counter >= TimeUntilBrake) {
                 if (this.Train.AtsSx != null) {
                     if (this.Train.AtsSx.State != AtsSx.States.Disabled) {
                         this.Train.AtsSx.State = AtsSx.States.Emergency;
                         if (this.Train.AtsP != null && (this.Train.AtsP.State == AtsP.States.Normal | this.Train.AtsP.State == AtsP.States.Pattern | this.Train.AtsP.State == AtsP.States.Brake | this.Train.AtsP.State == AtsP.States.Service | this.Train.AtsP.State == AtsP.States.Emergency)) {
                             this.Train.AtsP.State = AtsP.States.Standby;
                         }
                         if (this.Train.Atc != null && (this.Train.Atc.State == Atc.States.Normal | this.Train.Atc.State == Atc.States.Service | this.Train.Atc.State == Atc.States.Emergency)) {
                             this.Train.Atc.State = Atc.States.Ats;
                         }
                         this.Counter = 0.0;
                     }
                 } else {
                     this.Train.Sounds.AtsBell.Play();
                     data.Handles.BrakeNotch = this.Train.Specs.BrakeNotches + 1;
                 }
             } else if (this.Counter >= TimeUntilBell) {
                 this.Train.Sounds.Eb.Play();
             }
         } else {
             this.Counter = 0.0;
         }
     } else {
         this.Counter = 0.0;
     }
     // --- panel ---
     if (this.Counter >= TimeUntilBrake) {
         int value = (int)data.TotalTime.Milliseconds % 1000 < 500 ? 1 : 0;
         this.Train.Panel[8] = value;
         this.Train.Panel[270] = value;
     } else if (this.Counter >= TimeUntilBell) {
         this.Train.Panel[8] = 1;
         this.Train.Panel[270] = 1;
     }
 }
Exemple #19
0
			// --- functions ---
			/// <summary>Updates the pattern.</summary>
			/// <param name="system">The current ATS-P system.</param>
			/// <param name="data">The elapse data.</param>
			internal void Perform(AtsP system, ElapseData data) {
				if (this.Position == double.MaxValue | this.TargetSpeed == double.MaxValue) {
					this.WarningPattern = double.MaxValue;
					this.BrakePattern = double.MaxValue;
				} else if (this.Position == double.MinValue) {
					this.WarningPattern = this.TargetSpeed - this.Device.PatternSpeedDifference;
					this.BrakePattern = Math.Max(this.TargetSpeed, this.Device.ReleaseSpeed);
				} else {
					const double earthGravity = 9.81;
                    double accelerationDueToGravity = earthGravity * this.Gradient / Math.Sqrt(1.0 + this.Gradient * this.Gradient);
					double deceleration = this.Device.DesignDeceleration + accelerationDueToGravity;
					double distance = this.Position - system.Position;
					/*
					 * Calculate the warning pattern.
					 * */
					{
						double sqrtTerm = 2.0 * deceleration * (distance - 50.0) + deceleration * deceleration * this.Device.ReactionDelay * this.Device.ReactionDelay + this.TargetSpeed * this.TargetSpeed;
						if (sqrtTerm <= 0.0) {
							this.WarningPattern = this.TargetSpeed - this.Device.PatternSpeedDifference;
						} else {
							this.WarningPattern = Math.Max(Math.Sqrt(sqrtTerm) - deceleration * this.Device.ReactionDelay, this.TargetSpeed - this.Device.PatternSpeedDifference);
						}
					}
					/*
					 * Calculate the brake pattern.
					 * */
					{
						double sqrtTerm = 2.0 * deceleration * distance + this.TargetSpeed * this.TargetSpeed;
						if (sqrtTerm <= 0.0) {
							this.BrakePattern = this.TargetSpeed;
						} else {
							this.BrakePattern = Math.Max(Math.Sqrt(sqrtTerm), TargetSpeed);
						}
						if (this.BrakePattern < this.Device.ReleaseSpeed) {
							this.BrakePattern = this.Device.ReleaseSpeed;
						}
					}
					
				}
			}
Exemple #20
0
		/// <summary>Is called every frame.</summary>
		/// <param name="data">The data.</param>
		/// <param name="blocking">Whether the device is blocked or will block subsequent devices.</param>
		internal override void Elapse(ElapseData data, ref bool blocking) {
			// --- behavior ---
			if (this.State == States.Suppressed) {
				if (data.Handles.BrakeNotch <= this.Train.Specs.BrakeNotches) {
					this.AlarmCountdown = DurationOfInitialization;
					this.State = States.Initializing;
				}
			}
			if (this.State == States.Initializing) {
				this.AlarmCountdown -= data.ElapsedTime.Seconds;
				if (this.AlarmCountdown <= 0.0) {
					this.State = States.Chime;
				} else {
					data.Handles.BrakeNotch = this.Train.Specs.BrakeNotches + 1;
					this.Train.Sounds.AtsBell.Play();
				}
			}
			if (blocking) {
				if (this.State != States.Disabled & this.State != States.Suppressed) {
					this.State = States.Normal;
				}
			} else {
				if (this.State == States.Chime) {
					this.Train.Sounds.AtsChime.Play();
				} else if (this.State == States.Alarm) {
					this.Train.Sounds.AtsBell.Play();
					this.AlarmCountdown -= data.ElapsedTime.Seconds;
					if (this.AlarmCountdown <= 0.0) {
						this.State = States.Emergency;
					}
				} else if (this.State == States.Emergency) {
					this.Train.Sounds.AtsBell.Play();
					data.Handles.BrakeNotch = this.Train.Specs.BrakeNotches + 1;
				}
				if (this.SpeedCheckCountdown > 0.0 & data.ElapsedTime.Seconds > 0.0) {
					this.SpeedCheckCountdown -= data.ElapsedTime.Seconds;
				}
				if (this.CompatibilityDistanceAccumulator != 0.0) {
					this.CompatibilityDistanceAccumulator += data.Vehicle.Speed.MetersPerSecond * data.ElapsedTime.Seconds;
					if (this.CompatibilityDistanceAccumulator > 27.7) {
						this.CompatibilityDistanceAccumulator = 0.0;
					}
				}
				if (this.State != States.Disabled & (this.Train.Doors != DoorStates.None | data.Handles.BrakeNotch > 0)) {
					data.Handles.PowerNotch = 0;
				}
			}
			// --- panel ---
			if ((this.State == States.Chime | this.State == States.Normal) & !blocking) {
				this.Train.Panel[256] = 1;
			}
			if (this.State == States.Initializing | this.State == States.Alarm) {
				this.Train.Panel[257] = 1;
				this.Train.Panel[258] = 1;
			} else if (this.State == States.Emergency) {
				int value = (int)data.TotalTime.Milliseconds % 1000 < 500 ? 1 : 0;
				this.Train.Panel[257] = 2;
				this.Train.Panel[258] = value;
			}
		}
Exemple #21
0
			/// <summary>Called every frame to update the plugin.</summary>
			/// <param name="data">The data passed to the plugin on Elapse.</param>
			/// <remarks>This function should not be called directly. Call UpdatePlugin instead.</remarks>
			internal abstract void Elapse(ElapseData data);
Exemple #22
0
			/// <summary>Called every frame to update the plugin.</summary>
			internal void UpdatePlugin() {
				/*
				 * Prepare the vehicle state.
				 * */
				double location = this.Train.Cars[0].FrontAxle.Follower.TrackPosition - this.Train.Cars[0].FrontAxlePosition + 0.5 * this.Train.Cars[0].Length;
			    //Curve Radius, Cant and Pitch Added
                double CurrentRadius = this.Train.Cars[0].FrontAxle.Follower.CurveRadius;
                double CurrentCant = this.Train.Cars[0].FrontAxle.Follower.CurveCant;
			    double CurrentPitch = this.Train.Cars[0].FrontAxle.Follower.Pitch;
                //If the list of stations has not been loaded, do so
			    if (!StationsLoaded)
			    {
                    currentRouteStations = new List<Station>();
			        foreach (Game.Station selectedStation in Game.Stations)
			        {
				        Station i = new Station
				        {
					        Name = selectedStation.Name,
					        ArrivalTime = selectedStation.ArrivalTime,
					        DepartureTime = selectedStation.DepartureTime,
					        StopTime = selectedStation.StopTime,
					        OpenLeftDoors = selectedStation.OpenLeftDoors,
					        OpenRightDoors = selectedStation.OpenRightDoors,
					        ForceStopSignal = selectedStation.ForceStopSignal,
					        DefaultTrackPosition = selectedStation.DefaultTrackPosition
				        };
				        currentRouteStations.Add(i);
			        }
			        StationsLoaded = true;
			    }
			    //End of additions
				double speed = this.Train.Cars[this.Train.DriverCar].Specs.CurrentPerceivedSpeed;
				double bcPressure = this.Train.Cars[this.Train.DriverCar].Specs.AirBrake.BrakeCylinderCurrentPressure;
				double mrPressure = this.Train.Cars[this.Train.DriverCar].Specs.AirBrake.MainReservoirCurrentPressure;
				double erPressure = this.Train.Cars[this.Train.DriverCar].Specs.AirBrake.EqualizingReservoirCurrentPressure;
				double bpPressure = this.Train.Cars[this.Train.DriverCar].Specs.AirBrake.BrakePipeCurrentPressure;
				double sapPressure = this.Train.Cars[this.Train.DriverCar].Specs.AirBrake.StraightAirPipeCurrentPressure;
				VehicleState vehicle = new VehicleState(location, new Speed(speed), bcPressure, mrPressure, erPressure, bpPressure, sapPressure, CurrentRadius, CurrentCant, CurrentPitch);
				/*
				 * Prepare the preceding vehicle state.
				 * */
				double bestLocation = double.MaxValue;
				double bestSpeed = 0.0;
				for (int i = 0; i < TrainManager.Trains.Length; i++) {
					if (TrainManager.Trains[i] != this.Train & TrainManager.Trains[i].State == TrainManager.TrainState.Available) {
						int c = TrainManager.Trains[i].Cars.Length - 1;
						double z = TrainManager.Trains[i].Cars[c].RearAxle.Follower.TrackPosition - TrainManager.Trains[i].Cars[c].RearAxlePosition - 0.5 * TrainManager.Trains[i].Cars[c].Length;
						if (z >= location & z < bestLocation) {
							bestLocation = z;
							bestSpeed = TrainManager.Trains[i].Specs.CurrentAverageSpeed;
						}
					}
				}
				var precedingVehicle = bestLocation != double.MaxValue ? new PrecedingVehicleState(bestLocation, bestLocation - location, new Speed(bestSpeed)) : null;
				/*
				 * Get the driver handles.
				 * */
				Handles handles = GetHandles();
				/*
				 * Update the plugin.
				 * */
				double totalTime = Game.SecondsSinceMidnight;
				double elapsedTime = Game.SecondsSinceMidnight - LastTime;
                /* 
                 * Set the current camera view mode
                 * Could probably do away with the CurrentCameraViewMode and use a direct cast??
                 * 
                 */
			    CurrentCameraViewMode = (OpenBveApi.Runtime.CameraViewMode)World.CameraMode;
				ElapseData data = new ElapseData(vehicle, precedingVehicle, handles, new Time(totalTime), new Time(elapsedTime), currentRouteStations, CurrentCameraViewMode, Interface.CurrentLanguageCode);
				LastTime = Game.SecondsSinceMidnight;
				Elapse(data);
				this.PluginMessage = data.DebugMessage;
			    DisableTimeAcceleration = data.DisableTimeAcceleration;
				/*
				 * Set the virtual handles.
				 * */
				this.PluginValid = true;
				SetHandles(data.Handles, true);
			}
Exemple #23
0
		/// <summary>Is called every frame.</summary>
		/// <param name="data">The data.</param>
		internal void Elapse(ElapseData data) {
			this.PluginInitializing = false;
			if (data.ElapsedTime.Seconds > 0.0 & data.ElapsedTime.Seconds < 1.0) {
				// --- panel ---
				for (int i = 0; i < this.Panel.Length; i++) {
					this.Panel[i] = 0;
				}
				// --- devices ---
				this.State = data.Vehicle;
				this.Handles = new ReadOnlyHandles(data.Handles);
				bool blocking = false;
				foreach (Device device in this.Devices) {
					device.Elapse(data, ref blocking);
				}
				// --- panel ---
				int seconds = (int)Math.Floor(data.TotalTime.Seconds);
				this.Panel[10] = (seconds / 3600) % 24;
				this.Panel[11] = (seconds / 60) % 60;
				this.Panel[12] = seconds % 60;
				this.Panel[269] = data.Handles.ConstSpeed ? 1 : 0;
				if (data.Handles.Reverser != 0 & (this.Handles.PowerNotch > 0 & this.Handles.BrakeNotch == 0 | this.Handles.PowerNotch == 0 & this.Handles.BrakeNotch == 1 & this.Specs.HasHoldBrake)) {
					this.Panel[100] = 1;
				}
				if (data.Handles.BrakeNotch >= this.Specs.AtsNotch & data.Handles.BrakeNotch <= this.Specs.BrakeNotches | data.Handles.Reverser != 0 & data.Handles.BrakeNotch == 1 & this.Specs.HasHoldBrake) {
					this.Panel[101] = 1;
				}
				// --- sound ---
				this.Sounds.Elapse(data);
			}
		}
Exemple #24
0
 /// <summary>Creates a new ElapseProxy from an ElapseData</summary>
 public ElapseProxy(ElapseData data, int[] panel, int[] sound)
 {
     this.Data = data;
     Panel     = panel;
     Sound     = sound;
 }
Exemple #25
0
        internal double UpdateAcceleration(ElapseData data)
        {
            double speedPrev = accelerationLastSpeed;
            double speedNow = data.Vehicle.Speed.MetersPerSecond;
            double time = (data.TotalTime.Seconds - accelerationLastPoll.Seconds);

            accelerationRate = (speedNow - speedPrev) / time;

            accelerationLastPoll = data.TotalTime;
            accelerationLastSpeed = speedNow;

            return accelerationRate;
        }
Exemple #26
0
        internal void UpdateAtpSpeeds(ElapseData data, PrecedingVehicleState precedingVehicle)
        {
            if(precedingVehicle == null)
            {
                train.atpTargetSpeed = train.atpTrackTargetSpeed;
                train.atpSafetySpeed = train.atpTrackSafetySpeed;
            }
            else
            {
                double distanceToStop = precedingVehicle.Distance - ATP_TARGET_STOPPING_DISTANCE;
                train.atpTargetSpeed = Math.Max(Math.Min(CalculateSpeedToStop(ATP_TARGET_DECELERATION_RATE, distanceToStop), train.atpTrackTargetSpeed), 0.0);
                if(Double.IsNaN(train.atpTargetSpeed))
                {
                    throw new ApplicationException();
                }

                train.atpSafetySpeed = Math.Min(CalculateSpeedToStop(ATP_TARGET_DECELERATION_RATE, (precedingVehicle.Distance - ATP_SAFETY_STOPPING_DISTANCE)), train.atpTrackSafetySpeed);
                if (Double.IsNaN(train.atpSafetySpeed))
                {
                    throw new ApplicationException();
                }
            }
        }
Exemple #27
0
        internal override int? Elapse(ElapseData data)
        {
            train.debugMessage = "";
            //Is train in Auto?
            if (train.trainModeActual != Train.TrainModes.Auto)
            {
                atoState = AtoStates.Stopped;
                return null;
            }

            //Calculate current acceleration rate
            if (data.TotalTime.Seconds - accelerationLastPoll.Seconds >= ACCELERATION_POLL_RATE)
            {
                UpdateAcceleration(data);
            }

            //Calculate distance to stop
            double? distanceToNextStop = null;
            if (atoStoppingPosition != null)
            {
                distanceToNextStop = atoStoppingPosition - data.Vehicle.Location;
            }

            train.debugMessage = $"{atoState}";

            if (atoState == AtoStates.Ready)
            {
                //At station counting down to departure
                atoDemands = -train.specs.BrakeNotches;

                readyTimer -= data.ElapsedTime.Seconds;
                if (train.doorState != DoorStates.None)
                {
                    atoState = AtoStates.Stopped;
                }
                else if (readyTimer <= 0.0)
                {
                    atoState = AtoStates.Enroute;
                }
            }
            else if (atoState == AtoStates.Enroute)
            {
                //Travelling to next station

                //Get the train to stick to the ATP Target Speed
                int atoTargetSpeedDemand = CalculateTargetSpeedNotchChange(data);

                //Run function for stopping at station
                int? atoStoppingDemand = null;
                if (atoStoppingPosition != null)
                {
                    //Call a function that returns the desired brake/power notch (or null if none)
                    atoStoppingDemand = CalculateStationStopNotchChange(data, distanceToNextStop ?? 0);
                }

                //Select the lowest notch between "TASC" and the target speed code above
                int notch = (atoDemands ?? 0) + Math.Min(atoStoppingDemand ?? train.specs.PowerNotches, atoTargetSpeedDemand);

                //Call ChangeAtoDemands with appropriate time between notch
                ChangeAtoDemands(data, notch, ATO_TIME_BETWEEN_NOTCH_CHANGE, true, true);

                train.debugMessage = $"Enroute. TS {atoTargetSpeedDemand}, TASC {atoStoppingDemand}. Req {notch}. Actual {atoDemands}. Target speed {train.atpTargetSpeed}";

                //If doors open
                if (train.doorState != DoorStates.None)
                {
                    atoState = AtoStates.Stopped;
                }
            }
            else if (atoState == AtoStates.Stopped)
            {
                atoStoppingPosition = null;
                atoDemands = -train.specs.BrakeNotches;

                if (train.doorState == DoorStates.None)
                {
                    atoState = AtoStates.Ready;
                    readyTimer = ATO_READY_TIMER;
                }
            }

            if (atoReceivedData != null)
            {
                atoStoppingPosition = atoReceivedData + data.Vehicle.Location;
                atoReceivedData = null;
            }

            //train.debugMessage = $" Ato: {atoState} demanding {atoDemands} for {train.atpTargetSpeed}";
            return atoDemands;
        }
Exemple #28
0
        /*internal int CalculateStationStop(ElapseData data, double tolerence, double targetStoppingPosition)
        {
            double projectedStoppingPosition = data.Vehicle.Location +
                CalculateDistanceToStop(accelerationRate, data.Vehicle.Speed.MetersPerSecond);

            if (projectedStoppingPosition > targetStoppingPosition || accelerationRate > 0)
            {
                return -1;
            }
            else if (projectedStoppingPosition < (targetStoppingPosition - tolerence))
            {
                return 1;
            }
            else
            {
                return 0;
            }
        }*/
        internal bool ChangeAtoDemands(ElapseData data, int newNotch, double frequency, bool clampToServiceBraking = true, bool clampToTargetDecelerationRate = false)
        {
            double currentTime = data.TotalTime.Seconds;

            if (currentTime - notchLastChange >= frequency)
            {
                int newDemand = Math.Max((int)atoDemands - 1, Math.Min((int)atoDemands + 1, newNotch));
                if (clampToTargetDecelerationRate && accelerationRate < ATO_TARGET_DECELERATION_RATE)
                {
                    newDemand++;
                }

                int min = -train.specs.BrakeNotches;
                if (!clampToServiceBraking)
                {
                    min -= 1;
                }
                int max = train.specs.PowerNotches;
                atoDemands = Math.Max(min, Math.Min(max, newDemand));
                notchLastChange = currentTime;
                train.debugMessage += $" {newNotch}";
                return true;
            }
            return false;
        }
Exemple #29
0
        internal int CalculateTargetSpeedNotchChange(ElapseData data)
        {
            double speedDifference = train.atpTargetSpeed - data.Vehicle.Speed.KilometersPerHour;

            if (train.atpTargetSpeed <= 3.0 && data.Vehicle.Speed.KilometersPerHour <= 3.0)
            {
                return -1;
            }
            else if (train.atpTargetSpeed < data.Vehicle.Speed.KilometersPerHour)
            {
                int notch = Math.Min(0, (int)(speedDifference / ATO_BRAKING_AMOUNT) - 1);
                return notch - atoDemands??0;
            }
            else
            {
                int notch = Math.Max(0, (int)(speedDifference / ATO_POWERING_AMOUNT));
                return notch - atoDemands??0;
            }
        }
        public void Elapse(ElapseData data)
        {
            vState = data;

            // if stop mem has data
            if (Stations.Count > 0) {
                // if next stop is in range
                if (lastCompletedDockingIndex + 1 < Stations.Count) {
                    // if next stop is passing stop
                    if (Stations[lastCompletedDockingIndex + 1].DoorOpen == -2
                        && vState.Vehicle.Location >= Stations[lastCompletedDockingIndex + 1].StopPosition)
                    {
                        lastCompletedDockingIndex++;
                    }
                    // if next stop is a stop which does not need to open doors
                    else if (vState.Vehicle.Speed.KilometersPerHour == 0
                            && Stations[lastCompletedDockingIndex + 1].DoorOpen == 0
                            && vState.Vehicle.Location >= Stations[lastCompletedDockingIndex + 1].StopPosition - StopAndDepartStopsErrorRange
                            && vState.Vehicle.Location <= Stations[lastCompletedDockingIndex + 1].StopPosition + StopAndDepartStopsErrorRange)
                    {
                        lastCompletedDockingIndex++;
                    }

                    // passed a station/stop which should stop
                    if (vState.Vehicle.Location > Stations[lastCompletedDockingIndex + 1].StopPosition + IllegalPassStopForceJumpRange) {
            //					System.Windows.Forms.MessageBox.Show("passed a stop");
                        lastCompletedDockingIndex++;
                    }
                }

                // display distance to next stop
                double distance = lastCompletedDockingIndex < Stations.Count ? Stations[lastCompletedDockingIndex + 1].StopPosition - vState.Vehicle.Location : -999;
                if (distance == -999) {
                    Panel[PanelID.DistanceToNextStation.FirstDigit] = 12;
                    Panel[PanelID.DistanceToNextStation.SecondDigit] = 12;
                    Panel[PanelID.DistanceToNextStation.ThirdDigit] = 11;
                    Panel[PanelID.DistanceToNextStation.ForthDigit] = 12;
                    Panel[PanelID.DistanceToNextStation.Unit] = 1;
                } else if (distance >= 1000) {
                    if (distance >= 10000) {
                        string kmStr = Math.Round(distance/1000).ToString().PadLeft(4);
                        Panel[PanelID.DistanceToNextStation.FirstDigit] = kmStr.Substring(0,1) == " " ? 11 : Convert.ToInt32(kmStr.Substring(0,1));
                        Panel[PanelID.DistanceToNextStation.SecondDigit] = kmStr.Substring(1,1) == " " ? 11 : Convert.ToInt32(kmStr.Substring(1,1));
                        Panel[PanelID.DistanceToNextStation.ThirdDigit] = kmStr.Substring(2,1) == " " ? 11 : Convert.ToInt32(kmStr.Substring(2,1));
                        Panel[PanelID.DistanceToNextStation.ForthDigit] = Convert.ToInt32(kmStr.Substring(3,1));
                    } else {
                        string kmStr = Math.Round(distance/1000, 1).ToString().PadLeft(4);
                        Panel[PanelID.DistanceToNextStation.FirstDigit] = kmStr.Substring(0,1) == " " ? 11 : Convert.ToInt32(kmStr.Substring(0,1));
                        Panel[PanelID.DistanceToNextStation.SecondDigit] = kmStr.Substring(1,1) == " " ? 11 : Convert.ToInt32(kmStr.Substring(1,1));
                        Panel[PanelID.DistanceToNextStation.ThirdDigit] = kmStr.Substring(2,1) == " " ? 11 : kmStr.Substring(2,1) == "." ? 10 : Convert.ToInt32(kmStr.Substring(2,1));
                        Panel[PanelID.DistanceToNextStation.ForthDigit] = Convert.ToInt32(kmStr.Substring(3,1));
                    }

                    Panel[PanelID.DistanceToNextStation.Unit] = 1;
                } else if (Math.Abs(distance) < 10) {
                    string mStr = Math.Round(distance, 1).ToString("0.0").PadLeft(4);
                    Panel[PanelID.DistanceToNextStation.FirstDigit] = mStr.Substring(0,1) == "-" ? 12 : 11;
                    Panel[PanelID.DistanceToNextStation.SecondDigit] = mStr.Substring(1,1) == "-" ? 12 : mStr.Substring(1,1) == " " ? 11 : Convert.ToInt32(mStr.Substring(1,1));
                    Panel[PanelID.DistanceToNextStation.ThirdDigit] = mStr.Substring(1,1) == "-" ? 12 : 10;
                    Panel[PanelID.DistanceToNextStation.ForthDigit] = mStr.Substring(3,1) == " " ? 11 : Convert.ToInt32(mStr.Substring(3,1));

                    Panel[PanelID.DistanceToNextStation.Unit] = 0;
                } else {
                    string mStr = Math.Round(distance).ToString().PadLeft(4);
                    Panel[PanelID.DistanceToNextStation.FirstDigit] = 11;
                    Panel[PanelID.DistanceToNextStation.SecondDigit] = mStr.Substring(1,1) == "-" ? 12 : mStr.Substring(1,1) == " " ? 11 : Convert.ToInt32(mStr.Substring(1,1));
                    Panel[PanelID.DistanceToNextStation.ThirdDigit] = Convert.ToInt32(mStr.Substring(2,1));
                    Panel[PanelID.DistanceToNextStation.ForthDigit] = Convert.ToInt32(mStr.Substring(3,1));

                    Panel[PanelID.DistanceToNextStation.Unit] = 0;
                }
            }
        }
Exemple #31
0
 /// <summary>Is called every frame.</summary>
 /// <param name="data">The data.</param>
 /// <param name="blocking">Whether the device is blocked or will block subsequent devices.</param>
 internal override void Elapse(ElapseData data, ref bool blocking)
 {
     // --- behavior ---
     if (this.State == States.Suppressed) {
         if (data.Handles.BrakeNotch <= this.Train.Specs.BrakeNotches) {
             this.InitializationCountdown = DurationOfInitialization;
             this.State = States.Initializing;
         }
     }
     if (this.State == States.Initializing) {
         this.InitializationCountdown -= data.ElapsedTime.Seconds;
         if (this.InitializationCountdown <= 0.0) {
             this.State = States.Standby;
             foreach (Pattern pattern in this.Patterns) {
                 if (Math.Abs(data.Vehicle.Speed.MetersPerSecond) >= pattern.WarningPattern) {
                     pattern.Clear();
                 }
             }
             this.Train.Sounds.AtsPBell.Play();
         }
     }
     if (this.BrakeRelease) {
         this.BrakeReleaseCountdown -= data.ElapsedTime.Seconds;
         if (this.BrakeReleaseCountdown <= 0.0) {
             this.BrakeRelease = false;
             this.Train.Sounds.AtsPBell.Play();
         }
     }
     if (this.State != States.Disabled & this.State != States.Initializing) {
         this.Position += data.Vehicle.Speed.MetersPerSecond * data.ElapsedTime.Seconds;
     }
     if (blocking) {
         if (this.State != States.Disabled & this.State != States.Suppressed) {
             this.State = States.Standby;
         }
     } else {
         if (this.State == States.Normal | this.State == States.Pattern | this.State == States.Brake) {
             bool brake = false;
             bool warning = false;
             UpdateCompatibilityTemporarySpeedPattern();
             foreach (Pattern pattern in this.Patterns) {
                 pattern.Perform(this, data);
                 if (Math.Abs(data.Vehicle.Speed.MetersPerSecond) >= pattern.WarningPattern) {
                     warning = true;
                 }
                 if (Math.Abs(data.Vehicle.Speed.MetersPerSecond) >= pattern.BrakePattern) {
                     brake = true;
                 }
             }
             if (BrakeRelease) {
                 brake = false;
             }
             if (brake & this.State != States.Brake) {
                 this.State = States.Brake;
                 this.Train.Sounds.AtsPBell.Play();
             } else if (warning & this.State == States.Normal) {
                 this.State = States.Pattern;
                 this.Train.Sounds.AtsPBell.Play();
             } else if (!brake & !warning & (this.State == States.Pattern | this.State == States.Brake)) {
                 this.State = States.Normal;
                 this.Train.Sounds.AtsPBell.Play();
             }
             if (this.State == States.Brake) {
                 if (data.Handles.BrakeNotch < this.Train.Specs.BrakeNotches) {
                     data.Handles.BrakeNotch = this.Train.Specs.BrakeNotches;
                 }
             }
             blocking = true;
         } else if (this.State == States.Service) {
             if (data.Handles.BrakeNotch < this.Train.Specs.BrakeNotches) {
                 data.Handles.BrakeNotch = this.Train.Specs.BrakeNotches;
             }
             blocking = true;
         } else if (this.State == States.Emergency) {
             data.Handles.BrakeNotch = this.Train.Specs.BrakeNotches + 1;
             blocking = true;
         }
         if (this.State != States.Disabled & (this.Train.Doors != DoorStates.None | data.Handles.BrakeNotch > 0)) {
             data.Handles.PowerNotch = 0;
         }
     }
     // --- panel ---
     if (this.State != States.Disabled & this.State != States.Suppressed) {
         this.Train.Panel[2] = 1;
         this.Train.Panel[259] = 1;
     }
     if (this.State == States.Pattern | this.State == States.Brake | this.State == States.Service | this.State == States.Emergency) {
         this.Train.Panel[3] = 1;
         this.Train.Panel[260] = 1;
     }
     if (this.State == States.Brake | this.State == States.Service | this.State == States.Emergency) {
         this.Train.Panel[5] = 1;
         this.Train.Panel[262] = 1;
     }
     if (this.State != States.Disabled & this.State != States.Suppressed & this.State != States.Standby) {
         this.Train.Panel[6] = 1;
         this.Train.Panel[263] = 1;
     }
     if (this.State == States.Initializing) {
         this.Train.Panel[7] = 1;
         this.Train.Panel[264] = 1;
     }
     if (this.State == States.Disabled) {
         this.Train.Panel[50] = 1;
     }
     if (this.BrakeRelease) {
         this.Train.Panel[4] = 1;
         this.Train.Panel[261] = 1;
     }
 }