Пример #1
0
 // --- constructors ---
 /// <summary>Creates a new instance of this class.</summary>
 /// <param name="vehicle">The state of the train.</param>
 /// <param name="precedingVehicle">The state of the preceding train, or a null reference if there is no preceding train.</param>
 /// <param name="handles">The virtual handles.</param>
 /// <param name="totalTime">The current absolute time.</param>
 /// <param name="elapsedTime">The elapsed time since the last call to Elapse.</param>
 public ElapseData(VehicleState vehicle, PrecedingVehicleState precedingVehicle, Handles handles, Time totalTime, Time elapsedTime)
 {
     this.Vehicle          = vehicle;
     this.PrecedingVehicle = precedingVehicle;
     this.Handles          = handles;
     this.TotalTime        = totalTime;
     this.ElapsedTime      = elapsedTime;
     this.DebugMessage     = null;
 }
Пример #2
0
        /*internal void ElapseTripTimer(ElapseData data)
         * {
         *  if (atpTripTimer != null)
         *  {
         *      atpTripTimer -= data.ElapsedTime.Seconds;
         *      atpTripTimer = Math.Max(atpTripTimer ?? 0, 0);
         *      if (data.Vehicle.Speed.KilometersPerHour <= train.atpTrackSafetySpeed)
         *      {
         *          atpTripTimer = null;
         *      }
         *  }
         *  else if (data.Vehicle.Speed.KilometersPerHour > train.atpTrackSafetySpeed)
         *  {
         *      atpTripTimer = ATP_WARNING_DURATION;
         *  }
         * }*/

        internal void UpdateAtpSpeeds(ElapseData data, PrecedingVehicleState precedingVehicle)
        {
            if (train.atpTrackNextSpeedPosition >= data.Vehicle.Location)
            {
                //Calculate braking curve to upcoming speed limit
                double newTargetSpeed = CalculateSpeedToStop(ATP_TARGET_DECELERATION_RATE, (train.atpTrackNextSpeedPosition - data.Vehicle.Location), train.atpTrackNextTargetSpeed);
                double newSafetySpeed = CalculateSpeedToStop(ATP_SAFETY_DECELERATION_RATE, (train.atpTrackNextSpeedPosition - data.Vehicle.Location), train.atpTrackNextSafetySpeed);

                //Select whichever speed is lower
                train.atpTrackTargetSpeed = Math.Min(newTargetSpeed, train.atpTrackTargetSpeed);
                train.atpTrackSafetySpeed = Math.Min(newSafetySpeed, train.atpTrackSafetySpeed);
            }

            if (ATP_FORCE_STATION_STOP)
            {
                if (upcomingStopLocation.HasValue)
                {
                    //Calculate braking curve to upcoming station stop
                    double newTargetSpeed = CalculateSpeedToStop(ATP_TARGET_DECELERATION_RATE, (upcomingStopLocation.Value + ATP_STATION_TARGET_DISTANCE - data.Vehicle.Location), 0);
                    double newSafetySpeed = CalculateSpeedToStop(ATP_SAFETY_DECELERATION_RATE, (upcomingStopLocation.Value + ATP_STATION_SAFETY_DISTANCE - data.Vehicle.Location), 0);

                    //Select whichever speed is lower
                    train.atpTargetSpeed = Math.Min(newTargetSpeed, train.atpTrackTargetSpeed);
                    train.atpSafetySpeed = Math.Min(newSafetySpeed, train.atpTrackSafetySpeed);
                }
                else
                {
                    train.atpTargetSpeed = train.atpTrackTargetSpeed;
                    train.atpSafetySpeed = train.atpTrackSafetySpeed;
                }
            }

            if (precedingVehicle != null)
            {
                if (ATP_FORCE_STATION_STOP && (upcomingStopLocation - currentLocation) > precedingVehicle.Distance)
                {
                    //Calculate distance to next train
                    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_SAFETY_DECELERATION_RATE, (precedingVehicle.Distance - ATP_SAFETY_STOPPING_DISTANCE)), train.atpTrackSafetySpeed);
                    if (Double.IsNaN(train.atpSafetySpeed))
                    {
                        throw new ApplicationException();
                    }
                }
            }
        }
Пример #3
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 ---
     this.PrecedingTrain = data.PrecedingVehicle;
     if (this.StateSwitch)
     {
         this.State       = States.Normal;
         this.StateSwitch = false;
     }
     if (this.State == States.Suppressed)
     {
         if (data.Handles.BrakeNotch <= this.Train.Specs.BrakeNotches)
         {
             if (this.Train.AtsSx != null | this.Train.AtsP != null)
             {
                 this.State = States.Ats;
             }
             else
             {
                 this.State = States.Normal;
             }
         }
     }
     if (blocking)
     {
         if (this.State != States.Disabled & this.State != States.Suppressed)
         {
             this.State = States.Ats;
         }
     }
     else
     {
         if (this.State == States.Normal | this.State == States.Service | this.State == States.Emergency)
         {
             var speed = GetCurrentAtcSpeed();
             if (speed != this.CurrentAtcSpeed)
             {
                 this.Train.Sounds.AtcBell.Play();
             }
             this.CurrentAtcSpeed = speed;
             if (speed < 0.0)
             {
                 if (this.State != States.Emergency)
                 {
                     this.State = States.Emergency;
                     this.Train.Sounds.AtcBell.Play();
                 }
             }
             else if (Math.Abs(data.Vehicle.Speed.MetersPerSecond) > speed)
             {
                 if (this.State != States.Service)
                 {
                     this.State = States.Service;
                     this.Train.Sounds.AtcBell.Play();
                 }
             }
             else if (Math.Abs(data.Vehicle.Speed.MetersPerSecond) < speed - 1.0 / 3.6)
             {
                 if (this.State != States.Normal)
                 {
                     this.State = States.Normal;
                     this.Train.Sounds.AtcBell.Play();
                 }
             }
             if (this.State == States.Service)
             {
                 if (data.Handles.BrakeNotch < this.Train.Specs.BrakeNotches)
                 {
                     data.Handles.BrakeNotch = this.Train.Specs.BrakeNotches;
                 }
             }
             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.Ats)
     {
         this.Train.Panel[271] = 12;
     }
     else if (this.State == States.Normal | this.State == States.Service | this.State == States.Emergency)
     {
         this.Train.Panel[265] = 1;
         if (this.CurrentAtcSpeed < 0.0)
         {
             this.Train.Panel[271] = 0;
         }
         else
         {
             int value = this.CompatibilitySpeeds.Length - 1;
             for (int i = 2; i < this.CompatibilitySpeeds.Length; i++)
             {
                 if (this.CompatibilitySpeeds[i] > this.CurrentAtcSpeed)
                 {
                     value = i - 1;
                     break;
                 }
             }
             this.Train.Panel[271] = value;
         }
     }
     if (this.State == States.Service)
     {
         this.Train.Panel[267] = 1;
     }
     else if (this.State == States.Emergency)
     {
         this.Train.Panel[268] = 1;
     }
     if (this.State != States.Disabled & this.State != States.Suppressed)
     {
         this.Train.Panel[266] = 1;
     }
     // --- manual or automatic switch ---
     if (ShouldSwitchToAts())
     {
         if (this.AutomaticSwitch & Math.Abs(data.Vehicle.Speed.MetersPerSecond) < 1.0 / 3.6)
         {
             KeyDown(VirtualKeys.C1);
         }
     }
     else if (ShouldSwitchToAtc())
     {
         if (this.AutomaticSwitch & Math.Abs(data.Vehicle.Speed.MetersPerSecond) < 1.0 / 3.6)
         {
             KeyDown(VirtualKeys.C2);
         }
     }
 }
Пример #4
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;
                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);

                /*
                 * 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;
                        }
                    }
                }
                PrecedingVehicleState precedingVehicle;

                if (bestLocation != double.MaxValue)
                {
                    precedingVehicle = new PrecedingVehicleState(bestLocation, bestLocation - location, new Speed(bestSpeed));
                }
                else
                {
                    precedingVehicle = null;
                }

                /*
                 * Get the driver handles.
                 * */
                Handles handles = GetHandles();

                /*
                 * Update the plugin.
                 * */
                double     totalTime   = Game.SecondsSinceMidnight;
                double     elapsedTime = Game.SecondsSinceMidnight - LastTime;
                ElapseData data        = new ElapseData(vehicle, precedingVehicle, handles, new Time(totalTime), new Time(elapsedTime));

                LastTime = Game.SecondsSinceMidnight;
                Elapse(data);
                this.PluginMessage = data.DebugMessage;

                /*
                 * Set the virtual handles.
                 * */
                this.PluginValid = true;
                SetHandles(data.Handles, true);
            }