Skip to content

Commit

Permalink
Change: Abstract Acceleration logic
Browse files Browse the repository at this point in the history
Cherry-pick of changes from #154
  • Loading branch information
leezer3 committed Nov 18, 2017
1 parent 75548dc commit 0b4200b
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 59 deletions.
2 changes: 1 addition & 1 deletion makefile
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ create_resource_tmp = $(eval $(call resource_rule_impl, $(firstword $(subst ^, ,
# OpenBve #
###########

OPEN_BVE_FOLDERS := . Audio Game Game/Events Game/Events/EventTypes Game/ObjectManager Game/ObjectManager/AnimatedObjects Game/TrackManager Graphics Graphics/Renderer Interface OldCode Parsers Parsers/Object/BVE Parsers/Object/Generic Parsers/Object/Loksim3D Parsers/Panel Parsers/Routes Parsers/Route/BVE Parsers/Script Parsers/SoundConfiguration Parsers/Train Properties OldParsers OldParsers/BveRouteParser Simulation/TrainManager Simulation/TrainManager/Car Simulation/TrainManager/Train Simulation/World System System/Functions System/Input System/Logging System/Plugins System/Program System/Translations UserInterface
OPEN_BVE_FOLDERS := . Audio Game Game/Events Game/Events/EventTypes Game/ObjectManager Game/ObjectManager/AnimatedObjects Game/TrackManager Graphics Graphics/Renderer Interface OldCode Parsers Parsers/Object/BVE Parsers/Object/Generic Parsers/Object/Loksim3D Parsers/Panel Parsers/Routes Parsers/Route/BVE Parsers/Script Parsers/SoundConfiguration Parsers/Train Properties OldParsers OldParsers/BveRouteParser Simulation/TrainManager Simulation/TrainManager/Car Simulation/TrainManager/Motor Simulation/TrainManager/Train Simulation/World System System/Functions System/Input System/Logging System/Plugins System/Program System/Translations UserInterface
OPEN_BVE_FOLDERS := $(addprefix $(OPEN_BVE_ROOT)/, $(OPEN_BVE_FOLDERS))
OPEN_BVE_SRC := $(filter-out "$(OPEN_BVE_ROOT)/Properties/AssemblyInfo.cs",$(patsubst %, "%", $(foreach sdir, $(OPEN_BVE_FOLDERS), $(wildcard $(sdir)/*.cs))))
OPEN_BVE_DOC := $(addprefix /doc:, $(foreach sdir, $(OPEN_BVE_FOLDERS), $(wildcard $(sdir)/*.xml)))
Expand Down
2 changes: 1 addition & 1 deletion source/OpenBVE/Game/AI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ private void PerformDefault(TrainManager.Train Train)
double decelerationCruise; /* power below this deceleration, cruise above */
double decelerationStart; /* brake above this deceleration, cruise below */
double decelerationStep; /* the deceleration step per brake notch */
double BrakeDeceleration = Train.Cars[Train.DriverCar].Specs.BrakeDecelerationAtServiceMaximumPressure;
double BrakeDeceleration = Train.Cars[Train.DriverCar].Specs.BrakeDecelerationAtServiceMaximumPressure(Train.Specs.CurrentBrakeNotch.Actual);
for (int i = 0; i < Train.Cars.Length; i++)
{
if (Train.Cars[i].Specs.IsMotorCar)
Expand Down
44 changes: 2 additions & 42 deletions source/OpenBVE/OldCode/TrainManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,6 @@ namespace OpenBve
/// <summary>The TrainManager is the root class containing functions to load and manage trains within the simulation world.</summary>
public static partial class TrainManager
{

// cars

internal struct AccelerationCurve
{
internal double StageZeroAcceleration;
internal double StageOneSpeed;
internal double StageOneAcceleration;
internal double StageTwoSpeed;
internal double StageTwoExponent;
}
internal enum CarBrakeType
{
ElectromagneticStraightAirBrake = 0,
Expand Down Expand Up @@ -199,6 +188,7 @@ internal static void ParsePanelConfig(string TrainPath, System.Text.Encoding Enc
Program.AppendToLogFile("Loading train panel: " + File);
Panel2 = true;
Panel2CfgParser.ParsePanel2Config("panel2.cfg", TrainPath, Encoding, Train, Train.DriverCar);
Train.Cars[Train.DriverCar].CameraRestrictionMode = World.CameraRestrictionMode.On;
World.CameraRestriction = World.CameraRestrictionMode.On;
}
else
Expand All @@ -208,6 +198,7 @@ internal static void ParsePanelConfig(string TrainPath, System.Text.Encoding Enc
{
Program.AppendToLogFile("Loading train panel: " + File);
PanelCfgParser.ParsePanelConfig(TrainPath, Encoding, Train);
Train.Cars[Train.DriverCar].CameraRestrictionMode = World.CameraRestrictionMode.On;
World.CameraRestriction = World.CameraRestrictionMode.On;
}
else
Expand All @@ -228,37 +219,6 @@ internal static void ParsePanelConfig(string TrainPath, System.Text.Encoding Enc
}
}


// get acceleration output
internal static double GetAccelerationOutput(Train Train, int CarIndex, int CurveIndex, double Speed)
{
if (CurveIndex < Train.Cars[CarIndex].Specs.AccelerationCurves.Length)
{
double a0 = Train.Cars[CarIndex].Specs.AccelerationCurves[CurveIndex].StageZeroAcceleration;
double s1 = Train.Cars[CarIndex].Specs.AccelerationCurves[CurveIndex].StageOneSpeed;
double a1 = Train.Cars[CarIndex].Specs.AccelerationCurves[CurveIndex].StageOneAcceleration;
double s2 = Train.Cars[CarIndex].Specs.AccelerationCurves[CurveIndex].StageTwoSpeed;
double e2 = Train.Cars[CarIndex].Specs.AccelerationCurves[CurveIndex].StageTwoExponent;
double f = Train.Cars[CarIndex].Specs.AccelerationCurvesMultiplier;
if (Speed <= 0.0)
{
return f * a0;
}
if (Speed < s1)
{
double t = Speed / s1;
return f * (a0 * (1.0 - t) + a1 * t);
}
if (Speed < s2)
{
return f * s1 * a1 / Speed;
}
return f * s1 * a1 * Math.Pow(s2, e2 - 1.0) * Math.Pow(Speed, -e2);

}
return 0.0;
}

// get resistance
private static double GetResistance(Train Train, int CarIndex, ref Axle Axle, double Speed)
{
Expand Down
1 change: 1 addition & 0 deletions source/OpenBVE/OpenBve.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Simulation\TrainManager\Motor\AccelerationCurve.cs" />
<Compile Include="Simulation\TrainManager\Car\Axle.cs" />
<Compile Include="Simulation\TrainManager\Car\Car.Bogie.cs" />
<Compile Include="Simulation\TrainManager\Car\Car.CarSection.cs" />
Expand Down
18 changes: 12 additions & 6 deletions source/OpenBVE/Parsers/Train/TrainDatParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi
double CoefficientOfStaticFriction = 0.35;
double CoefficientOfRollingResistance = 0.0025;
double AerodynamicDragCoefficient = 1.1;
TrainManager.AccelerationCurve[] AccelerationCurves = new TrainManager.AccelerationCurve[] { };
TrainManager.BveAccelerationCurve[] AccelerationCurves = new TrainManager.BveAccelerationCurve[] { };
Vector3 Driver = new Vector3();
int DriverCar = 0;
double MotorCarMass = 1.0, TrailerCarMass = 1.0;
Expand Down Expand Up @@ -123,7 +123,8 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi
switch (Lines[i].ToLowerInvariant()) {
case "#acceleration":
i++; while (i < Lines.Length && !Lines[i].StartsWith("#", StringComparison.Ordinal)) {
Array.Resize<TrainManager.AccelerationCurve>(ref AccelerationCurves, n + 1);
Array.Resize<TrainManager.BveAccelerationCurve>(ref AccelerationCurves, n + 1);
AccelerationCurves[n] = new TrainManager.BveAccelerationCurve();
string t = Lines[i] + ",";
int m = 0;
while (true) {
Expand Down Expand Up @@ -611,7 +612,10 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi
Train.Cars[i].Specs.BrakeType = BrakeType;
Train.Cars[i].Specs.ElectropneumaticType = ElectropneumaticType;
Train.Cars[i].Specs.BrakeControlSpeed = BrakeControlSpeed;
Train.Cars[i].Specs.BrakeDecelerationAtServiceMaximumPressure = BrakeDeceleration;
Train.Cars[i].Specs.DecelerationCurves = new TrainManager.AccelerationCurve[]
{
new TrainManager.BveDecelerationCurve(BrakeDeceleration),
};
Train.Cars[i].Specs.MotorDeceleration = MotorDeceleration;
Train.Cars[i].Specs.AirBrake.AirCompressorEnabled = false;
Train.Cars[i].Specs.AirBrake.AirCompressorMinimumPressure = MainReservoirMinimumPressure;
Expand Down Expand Up @@ -834,8 +838,11 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi
Train.Cars[i].Specs.AirBrake.Type = TrainManager.AirBrakeType.Main;
Train.Cars[i].Specs.MassEmpty = MotorCarMass;
Train.Cars[i].Specs.MassCurrent = MotorCarMass;
Train.Cars[i].Specs.AccelerationCurves = AccelerationCurves;
Train.Cars[i].Specs.AccelerationCurvesMultiplier = 1.0 + TrailerCars * TrailerCarMass / (MotorCars * MotorCarMass);
Array.Resize(ref Train.Cars[i].Specs.AccelerationCurves, AccelerationCurves.Length);
for (int j = 0; j < AccelerationCurves.Length; j++)
{
Train.Cars[i].Specs.AccelerationCurves[j] = AccelerationCurves[j].Clone(1.0 + TrailerCars * TrailerCarMass / (MotorCars * MotorCarMass));
}
Train.Cars[i].Specs.AccelerationCurveMaximum = MaximumAcceleration;
switch (ReAdhesionDevice) {
case 0: // type a:
Expand Down Expand Up @@ -884,7 +891,6 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi
Train.Cars[i].Specs.MassEmpty = TrailerCarMass;
Train.Cars[i].Specs.MassCurrent = TrailerCarMass;
Train.Cars[i].Specs.AccelerationCurves = new TrainManager.AccelerationCurve[] { };
Train.Cars[i].Specs.AccelerationCurvesMultiplier = 0.0;
Train.Cars[i].Specs.AccelerationCurveMaximum = 0.0;
Train.Cars[i].Specs.ReAdhesionDevice.ApplicationFactor = 0.0;
Train.Cars[i].Sounds.Motor.SpeedConversionFactor = 18.0;
Expand Down
17 changes: 15 additions & 2 deletions source/OpenBVE/Simulation/TrainManager/Car/Car.Specs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,27 @@ internal struct CarSpecs
/// motor
internal bool IsMotorCar;
internal AccelerationCurve[] AccelerationCurves;
internal double AccelerationCurvesMultiplier;
internal AccelerationCurve[] DecelerationCurves;

internal double BrakeDecelerationAtServiceMaximumPressure(int Notch)
{
if (Notch == 0)
{
return this.DecelerationCurves[0].GetAccelerationOutput(this.CurrentSpeed, 1.0);
}
if (this.DecelerationCurves.Length >= Notch)
{
return this.DecelerationCurves[Notch - 1].GetAccelerationOutput(this.CurrentSpeed, 1.0);
}
return this.DecelerationCurves[this.DecelerationCurves.Length - 1].GetAccelerationOutput(this.CurrentSpeed, 1.0);
}

internal double AccelerationCurveMaximum;
internal double JerkPowerUp;
internal double JerkPowerDown;
internal double JerkBrakeUp;
internal double JerkBrakeDown;
/// brake
internal double BrakeDecelerationAtServiceMaximumPressure;
internal double BrakeControlSpeed;
internal double MotorDeceleration;
/// physical properties
Expand Down
2 changes: 1 addition & 1 deletion source/OpenBVE/Simulation/TrainManager/Car/Car.cs
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ internal void UpdateMotorSounds(double TimeElapsed)
else if (ndir == -1)
{
// brake
double max = Specs.BrakeDecelerationAtServiceMaximumPressure;
double max = Specs.BrakeDecelerationAtServiceMaximumPressure(this.baseTrain.Specs.CurrentBrakeNotch.Actual);
if (max != 0.0)
{
double cur = -Specs.CurrentAccelerationOutput;
Expand Down
74 changes: 74 additions & 0 deletions source/OpenBVE/Simulation/TrainManager/Motor/AccelerationCurve.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System;

namespace OpenBve
{
/// <summary>The TrainManager is the root class containing functions to load and manage trains within the simulation world.</summary>
public static partial class TrainManager
{
/// <summary>An abstract acceleration curve</summary>
internal abstract class AccelerationCurve
{
/// <summary>Gets the acceleration output for this curve</summary>
/// <param name="Speed">The current speed</param>
/// <param name="Loading">A double between 0 (Unloaded) and 1.0 (Loaded) representing the load factor</param>
/// <returns>The acceleration output</returns>
internal abstract double GetAccelerationOutput(double Speed, double Loading);
}

/// <summary>Represents a BVE2 / BVE4 format Acceleration Curve</summary>
internal class BveAccelerationCurve : AccelerationCurve
{
internal double StageZeroAcceleration;
internal double StageOneSpeed;
internal double StageOneAcceleration;
internal double StageTwoSpeed;
internal double StageTwoExponent;
internal double Multiplier;

internal override double GetAccelerationOutput(double Speed, double Loading)
{
if (Speed <= 0.0)
{
return Multiplier * this.StageZeroAcceleration;
}
if (Speed < this.StageOneSpeed)
{
double t = Speed / this.StageOneSpeed;
return Multiplier * (this.StageZeroAcceleration * (1.0 - t) + this.StageOneAcceleration * t);
}
if (Speed < this.StageTwoSpeed)
{
return Multiplier * this.StageOneSpeed * this.StageOneAcceleration / Speed;
}
return Multiplier * this.StageOneSpeed * this.StageOneAcceleration * Math.Pow(this.StageTwoSpeed, this.StageTwoExponent - 1.0) * Math.Pow(Speed, -this.StageTwoExponent);
}

internal BveAccelerationCurve Clone(double multiplier)
{
return new BveAccelerationCurve
{
StageZeroAcceleration = this.StageZeroAcceleration,
StageOneSpeed = this.StageOneSpeed,
StageOneAcceleration = this.StageOneAcceleration,
StageTwoSpeed = this.StageTwoSpeed,
StageTwoExponent = this.StageTwoExponent,
Multiplier = multiplier
};
}
}

internal class BveDecelerationCurve : AccelerationCurve
{
private double MaxDecelerationOutput;
internal override double GetAccelerationOutput(double Speed, double Loading)
{
return this.MaxDecelerationOutput;
}

internal BveDecelerationCurve(double Deceleration)
{
this.MaxDecelerationOutput = Deceleration;
}
}
}
}
10 changes: 5 additions & 5 deletions source/OpenBVE/Simulation/TrainManager/Train/BrakeSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -400,11 +400,11 @@ private static void UpdateBrakeSystem(Train Train, int CarIndex, double TimeElap
//double f = (double)Train.Specs.CurrentBrakeNotch.Actual / (double)Train.Specs.MaximumBrakeNotch;
double a = Train.Cars[CarIndex].Specs.MotorDeceleration;
double pr = p / Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderServiceMaximumPressure;
double b = pr * Train.Cars[CarIndex].Specs.BrakeDecelerationAtServiceMaximumPressure;
double b = pr * Train.Cars[CarIndex].Specs.BrakeDecelerationAtServiceMaximumPressure(Train.Specs.CurrentBrakeNotch.Actual);
double d = b - a;
if (d > 0.0)
{
p = d / Train.Cars[CarIndex].Specs.BrakeDecelerationAtServiceMaximumPressure;
p = d / Train.Cars[CarIndex].Specs.BrakeDecelerationAtServiceMaximumPressure(Train.Specs.CurrentBrakeNotch.Actual);
if (p > 1.0) p = 1.0;
p *= Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderServiceMaximumPressure;
}
Expand Down Expand Up @@ -507,11 +507,11 @@ private static void UpdateBrakeSystem(Train Train, int CarIndex, double TimeElap
//double f = (double)Train.Specs.CurrentBrakeNotch.Actual / (double)Train.Specs.MaximumBrakeNotch;
double a = Train.Cars[CarIndex].Specs.MotorDeceleration;
double pr = p / Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderServiceMaximumPressure;
double b = pr * Train.Cars[CarIndex].Specs.BrakeDecelerationAtServiceMaximumPressure;
double b = pr * Train.Cars[CarIndex].Specs.BrakeDecelerationAtServiceMaximumPressure(Train.Specs.CurrentBrakeNotch.Actual);
double d = b - a;
if (d > 0.0)
{
p = d / Train.Cars[CarIndex].Specs.BrakeDecelerationAtServiceMaximumPressure;
p = d / Train.Cars[CarIndex].Specs.BrakeDecelerationAtServiceMaximumPressure(Train.Specs.CurrentBrakeNotch.Actual);
if (p > 1.0) p = 1.0;
p *= Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderServiceMaximumPressure;
}
Expand Down Expand Up @@ -662,7 +662,7 @@ private static void UpdateBrakeSystem(Train Train, int CarIndex, double TimeElap
}
// deceleration provided by brake
double pressureratio = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure / Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderServiceMaximumPressure;
DecelerationDueToBrake = pressureratio * Train.Cars[CarIndex].Specs.BrakeDecelerationAtServiceMaximumPressure;
DecelerationDueToBrake = pressureratio * Train.Cars[CarIndex].Specs.BrakeDecelerationAtServiceMaximumPressure(Train.Specs.CurrentBrakeNotch.Actual);
// deceleration provided by motor
if (Train.Cars[CarIndex].Specs.BrakeType != CarBrakeType.AutomaticAirBrake && Math.Abs(Train.Cars[CarIndex].Specs.CurrentSpeed) >= Train.Cars[CarIndex].Specs.BrakeControlSpeed & Train.Specs.CurrentReverser.Actual != 0 & !Train.Specs.CurrentEmergencyBrake.Actual)
{
Expand Down
11 changes: 10 additions & 1 deletion source/OpenBVE/Simulation/TrainManager/Train/Train.cs
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,16 @@ private void UpdateSpeeds(double TimeElapsed)
if (Specs.CurrentReverser.Actual != 0 & Specs.CurrentPowerNotch.Actual > 0 & !Specs.CurrentHoldBrake.Actual & !Specs.CurrentEmergencyBrake.Actual)
{
// target acceleration
a = GetAccelerationOutput(this, i, Specs.CurrentPowerNotch.Actual - 1, (double)Specs.CurrentReverser.Actual * Cars[i].Specs.CurrentSpeed);
if (Specs.CurrentPowerNotch.Actual - 1 < Cars[i].Specs.AccelerationCurves.Length)
{
// Load factor is a constant 1.0 for anything prior to BVE5
// This will need to be changed when the relevant branch is merged in
a = Cars[i].Specs.AccelerationCurves[Specs.CurrentPowerNotch.Actual - 1].GetAccelerationOutput((double)Specs.CurrentReverser.Actual * Cars[i].Specs.CurrentSpeed, 1.0);
}
else
{
a = 0.0;
}
// readhesion device
if (a > Cars[i].Specs.ReAdhesionDevice.MaximumAccelerationOutput)
{
Expand Down

0 comments on commit 0b4200b

Please sign in to comment.