Skip to content

Commit 5c0bb4f

Browse files
committed
Wag file axle configuration
1 parent 1a709aa commit 5c0bb4f

File tree

3 files changed

+102
-64
lines changed

3 files changed

+102
-64
lines changed

Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs

+14-51
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,6 @@ public enum TractionMotorTypes
451451
public ILocomotivePowerSupply LocomotivePowerSupply => PowerSupply as ILocomotivePowerSupply;
452452
public ScriptedTrainControlSystem TrainControlSystem;
453453

454-
public Axles LocomotiveAxles;
455454
public IIRFilter CurrentFilter;
456455
public IIRFilter AdhesionFilter;
457456
public float SaveAdhesionFilter;
@@ -478,7 +477,6 @@ public MSTSLocomotive(Simulator simulator, string wagPath)
478477
MilepostUnitsMetric = Simulator.TRK.Tr_RouteFile.MilepostUnitsMetric;
479478
BrakeCutsPowerAtBrakeCylinderPressurePSI = 4.0f;
480479

481-
LocomotiveAxles = new Axles(this);
482480
LocomotiveAxles.Add(new Axle());
483481
CurrentFilter = new IIRFilter(IIRFilter.FilterTypes.Butterworth, 1, IIRFilter.HzToRad(0.5f), 0.001f);
484482
AdhesionFilter = new IIRFilter(IIRFilter.FilterTypes.Butterworth, 1, IIRFilter.HzToRad(1f), 0.001f);
@@ -1223,23 +1221,10 @@ public override void Copy(MSTSWagon copy)
12231221
WaterScoopFillElevationM = locoCopy.WaterScoopFillElevationM;
12241222
WaterScoopDepthM = locoCopy.WaterScoopDepthM;
12251223
WaterScoopWidthM = locoCopy.WaterScoopWidthM;
1226-
MoveParamsToAxle();
12271224
CruiseControl = locoCopy.CruiseControl?.Clone(this);
12281225
MultiPositionControllers = locoCopy.CloneMPC(this);
12291226
}
12301227

1231-
/// <summary>
1232-
/// We are moving parameters from locomotive to axle.
1233-
/// </summary>
1234-
public void MoveParamsToAxle()
1235-
{
1236-
foreach (var axle in LocomotiveAxles)
1237-
{
1238-
axle.SlipWarningTresholdPercent = SlipWarningThresholdPercent;
1239-
axle.AdhesionK = AdhesionK;
1240-
}
1241-
}
1242-
12431228
/// <summary>
12441229
/// We are saving the game. Save anything that we'll need to restore the
12451230
/// status later.
@@ -1288,7 +1273,6 @@ public override void Save(BinaryWriter outf)
12881273
LocomotivePowerSupply?.Save(outf);
12891274
TrainControlSystem.Save(outf);
12901275

1291-
LocomotiveAxles.Save(outf);
12921276
CruiseControl?.Save(outf);
12931277
}
12941278

@@ -1342,9 +1326,7 @@ public override void Restore(BinaryReader inf)
13421326

13431327
LocomotivePowerSupply?.Restore(inf);
13441328
TrainControlSystem.Restore(inf);
1345-
1346-
MoveParamsToAxle();
1347-
LocomotiveAxles.Restore(inf);
1329+
13481330
CruiseControl?.Restore(inf);
13491331
}
13501332

@@ -1426,7 +1408,6 @@ public override void Initialize()
14261408
BrakemanBrakeController.Initialize();
14271409
LocomotivePowerSupply?.Initialize();
14281410
TrainControlSystem.Initialize();
1429-
LocomotiveAxles.Initialize();
14301411
CruiseControl?.Initialize();
14311412
foreach (MultiPositionController mpc in MultiPositionControllers)
14321413
{
@@ -1485,6 +1466,18 @@ public override void Initialize()
14851466
Trace.TraceInformation("Number of Locomotive Drive Axles set to default value of {0}", LocoNumDrvAxles);
14861467
}
14871468
}
1469+
//Compute axle inertia from parameters if possible
1470+
if (AxleInertiaKgm2 <= 0) // if no axleinertia value supplied in ENG file, calculate axleinertia value.
1471+
{
1472+
if (LocoNumDrvAxles > 0 && DriverWheelRadiusM > 0)
1473+
{
1474+
float radiusSquared = DriverWheelRadiusM * DriverWheelRadiusM;
1475+
float wheelMass = 500 * radiusSquared / (0.5f * 0.5f);
1476+
AxleInertiaKgm2 = Math.Min(LocoNumDrvAxles * wheelMass * radiusSquared + 500, 40000);
1477+
}
1478+
else
1479+
AxleInertiaKgm2 = 2000.0f;
1480+
}
14881481
if (TractionMotorType == TractionMotorTypes.AC)
14891482
{
14901483
foreach (var axle in LocomotiveAxles)
@@ -1494,7 +1487,6 @@ public override void Initialize()
14941487
}
14951488
}
14961489

1497-
14981490
// Calculate minimum speed to pickup water
14991491
const float Aconst = 2;
15001492
WaterScoopMinSpeedMpS = Me.FromFt((float)Math.Sqrt(Aconst * GravitationalAccelerationFtpSpS * Me.ToFt(WaterScoopFillElevationM)));
@@ -1742,9 +1734,8 @@ public List<MultiPositionController> CloneMPC(MSTSLocomotive locomotive)
17421734

17431735
public override void InitializeMoving()
17441736
{
1745-
base.InitializeMoving();
17461737
AdhesionFilter.Reset(0.5f);
1747-
LocomotiveAxles.InitializeMoving();
1738+
base.InitializeMoving();
17481739
AverageForceN = MaxForceN * Train.MUThrottlePercent / 100;
17491740
float maxPowerW = MaxPowerW * Train.MUThrottlePercent * Train.MUThrottlePercent / 10000;
17501741
if (AverageForceN * SpeedMpS > maxPowerW) AverageForceN = maxPowerW / SpeedMpS;
@@ -2761,34 +2752,6 @@ public virtual void AdvancedAdhesion(float elapsedClockSeconds)
27612752
return;
27622753
}
27632754

2764-
if (EngineType == EngineTypes.Steam && SteamEngineType != MSTSSteamLocomotive.SteamEngineTypes.Geared)
2765-
{
2766-
// Managed in MSTSSteamLocomotive implementation of AdvancedAdhesion
2767-
}
2768-
else
2769-
{
2770-
2771-
//Compute axle inertia from parameters if possible
2772-
if (AxleInertiaKgm2 <= 0) // if no axleinertia value supplied in ENG file, calculate axleinertia value.
2773-
{
2774-
if (LocoNumDrvAxles > 0 && DriverWheelRadiusM > 0)
2775-
{
2776-
float radiusSquared = DriverWheelRadiusM * DriverWheelRadiusM;
2777-
float wheelMass = 500 * radiusSquared / (0.5f * 0.5f);
2778-
AxleInertiaKgm2 = LocoNumDrvAxles * wheelMass * radiusSquared + 500;
2779-
}
2780-
else
2781-
AxleInertiaKgm2 = 2000.0f;
2782-
}
2783-
foreach (var axle in LocomotiveAxles)
2784-
{
2785-
//Limit the inertia to 40000 kgm2
2786-
axle.InertiaKgm2 = Math.Min(AxleInertiaKgm2, 40000);
2787-
axle.DampingNs = MassKG / 1000.0f;
2788-
axle.FrictionN = MassKG / 1000.0f;
2789-
axle.AxleWeightN = 9.81f * DrvWheelWeightKg/LocomotiveAxles.Count;; //remains fixed for diesel/electric locomotives, but varies for steam locomotives
2790-
}
2791-
}
27922755
foreach (var axle in LocomotiveAxles)
27932756
{
27942757
axle.BrakeRetardForceN = BrakeRetardForceN/LocomotiveAxles.Count;

Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs

+27-11
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
using Orts.Simulation.RollingStocks.SubSystems.Brakes.MSTS;
4444
using Orts.Simulation.RollingStocks.SubSystems.Controllers;
4545
using Orts.Simulation.RollingStocks.SubSystems.PowerSupplies;
46+
using Orts.Simulation.RollingStocks.SubSystems.PowerTransmissions;
4647
using ORTS.Common;
4748
using ORTS.Scripting.Api;
4849
using System;
@@ -148,13 +149,14 @@ public class MSTSWagon : TrainCar
148149
public float Curtius_KnifflerC = 0.161f; // speedMpS * 3.6 + B
149150
public float AdhesionK = 0.7f; //slip characteristics slope
150151
public float AxleInertiaKgm2; //axle inertia
151-
public float AdhesionDriveWheelRadiusM;
152152
public float WheelSpeedMpS;
153153
public float WheelSpeedSlipMpS; // speed of wheel if locomotive is slipping
154154
public float SlipWarningThresholdPercent = 70;
155155
public MSTSNotchController WeightLoadController; // Used to control freight loading in freight cars
156156
public float AbsWheelSpeedMpS; // Math.Abs(WheelSpeedMpS) is used frequently in the subclasses, maybe it's more efficient to compute it once
157157

158+
public Axles LocomotiveAxles; // Only used at locomotives for efficiency
159+
158160
// Colours for smoke and steam effects
159161
public Color ExhaustTransientColor = Color.Black;
160162
public Color ExhaustDecelColor = Color.WhiteSmoke;
@@ -347,6 +349,7 @@ public MSTSWagon(Simulator simulator, string wagFilePath)
347349
{
348350
Pantographs = new Pantographs(this);
349351
Doors = new Doors(this);
352+
LocomotiveAxles = new Axles(this);
350353
}
351354

352355
public void Load()
@@ -980,6 +983,7 @@ public override void Initialize()
980983
Pantographs.Initialize();
981984
Doors.Initialize();
982985
PassengerCarPowerSupply?.Initialize();
986+
LocomotiveAxles.Initialize();
983987

984988
base.Initialize();
985989

@@ -1011,6 +1015,7 @@ public override void Initialize()
10111015
public override void InitializeMoving()
10121016
{
10131017
PassengerCarPowerSupply?.InitializeMoving();
1018+
LocomotiveAxles.InitializeMoving();
10141019

10151020
base.InitializeMoving();
10161021
}
@@ -1382,15 +1387,8 @@ public virtual void Parse(string lowercasetoken, STFReader stf)
13821387
SlipWarningThresholdPercent = stf.ReadFloat(STFReader.UNITS.None, 70.0f); if (SlipWarningThresholdPercent <= 0) SlipWarningThresholdPercent = 70.0f;
13831388
stf.SkipRestOfBlock();
13841389
break;
1385-
case "wagon(ortsadhesion(wheelset(axle(ortsinertia":
1386-
stf.MustMatch("(");
1387-
AxleInertiaKgm2 = stf.ReadFloat(STFReader.UNITS.RotationalInertia, null);
1388-
stf.SkipRestOfBlock();
1389-
break;
1390-
case "wagon(ortsadhesion(wheelset(axle(ortsradius":
1391-
stf.MustMatch("(");
1392-
AdhesionDriveWheelRadiusM = stf.ReadFloat(STFReader.UNITS.Distance, null);
1393-
stf.SkipRestOfBlock();
1390+
case "wagon(ortsadhesion(wheelset":
1391+
LocomotiveAxles.Parse(lowercasetoken, stf);
13941392
break;
13951393
case "wagon(lights":
13961394
Lights = new LightCollection(stf);
@@ -1555,7 +1553,6 @@ public virtual void Copy(MSTSWagon copy)
15551553
Curtius_KnifflerC = copy.Curtius_KnifflerC;
15561554
AdhesionK = copy.AdhesionK;
15571555
AxleInertiaKgm2 = copy.AxleInertiaKgm2;
1558-
AdhesionDriveWheelRadiusM = copy.AdhesionDriveWheelRadiusM;
15591556
SlipWarningThresholdPercent = copy.SlipWarningThresholdPercent;
15601557
Lights = copy.Lights;
15611558
ExternalSoundPassThruPercent = copy.ExternalSoundPassThruPercent;
@@ -1618,6 +1615,20 @@ public virtual void Copy(MSTSWagon copy)
16181615
PowerSupply = new ScriptedPassengerCarPowerSupply(this);
16191616
PassengerCarPowerSupply.Copy(copy.PassengerCarPowerSupply);
16201617
}
1618+
LocomotiveAxles.Copy(copy.LocomotiveAxles);
1619+
MoveParamsToAxle();
1620+
}
1621+
1622+
/// <summary>
1623+
/// We are moving parameters from locomotive to axle.
1624+
/// </summary>
1625+
public void MoveParamsToAxle()
1626+
{
1627+
foreach (var axle in LocomotiveAxles)
1628+
{
1629+
axle.SlipWarningTresholdPercent = SlipWarningThresholdPercent;
1630+
axle.AdhesionK = AdhesionK;
1631+
}
16211632
}
16221633

16231634
protected void ParseWagonInside(STFReader stf)
@@ -1731,6 +1742,8 @@ public override void Save(BinaryWriter outf)
17311742
outf.Write(DerailExpected);
17321743
outf.Write(DerailElapsedTimeS);
17331744

1745+
LocomotiveAxles.Save(outf);
1746+
17341747
base.Save(outf);
17351748
}
17361749

@@ -1784,6 +1797,9 @@ public override void Restore(BinaryReader inf)
17841797
DerailExpected = inf.ReadBoolean();
17851798
DerailElapsedTimeS = inf.ReadSingle();
17861799

1800+
MoveParamsToAxle();
1801+
LocomotiveAxles.Restore(inf);
1802+
17871803
base.Restore(inf);
17881804
}
17891805

Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/PowerTransmissions/Axle.cs

+61-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
using System.Diagnostics;
2323
using Microsoft.Xna.Framework;
2424
using ORTS.Common;
25+
using Orts.Parsers.Msts;
2526
using Orts.Simulation.RollingStocks.SubSystems.PowerTransmissions;
2627
using SharpDX.Direct2D1;
2728

@@ -179,6 +180,34 @@ public void Add(Axle axle)
179180
{
180181
AxleList.Add(axle);
181182
}
183+
184+
/// <summary>
185+
/// Parses all the parameters within the ENG file
186+
/// </summary>
187+
/// <param name="stf">reference to the ENG file reader</param>
188+
public void Parse(string lowercasetoken, STFReader stf)
189+
{
190+
switch (lowercasetoken)
191+
{
192+
case "wagon(ortsadhesion(wheelset":
193+
AxleList.Clear();
194+
stf.MustMatch("(");
195+
stf.ParseBlock(
196+
new[] {
197+
new STFReader.TokenProcessor(
198+
"axle",
199+
() => {
200+
var axle = new Axle();
201+
AxleList.Add(axle);
202+
axle.Parse(stf);
203+
}
204+
)
205+
});
206+
if (AxleList.Count == 0)
207+
throw new InvalidDataException("Wheelset block with no axles");
208+
break;
209+
}
210+
}
182211
public void Copy(Axles other)
183212
{
184213
AxleList = new List<Axle>();
@@ -195,6 +224,13 @@ public void Initialize()
195224
ResetTime = Car.Simulator.GameTime;
196225
foreach (var axle in AxleList)
197226
{
227+
if (Car is MSTSLocomotive locomotive)
228+
{
229+
if (axle.InertiaKgm2 <= 0) axle.InertiaKgm2 = locomotive.AxleInertiaKgm2 / AxleList.Count;
230+
if (axle.AxleWeightN <= 0) axle.AxleWeightN = 9.81f * locomotive.DrvWheelWeightKg / AxleList.Count; //remains fixed for diesel/electric locomotives, but varies for steam locomotives
231+
if (axle.DampingNs <= 0) axle.DampingNs = locomotive.MassKG / 1000.0f / AxleList.Count;
232+
if (axle.FrictionN <= 0) axle.FrictionN = locomotive.MassKG / 1000.0f / AxleList.Count;
233+
}
198234
axle.Initialize();
199235
}
200236
}
@@ -604,10 +640,33 @@ public void InitializeMoving()
604640
AxleSpeedMpS = TrainSpeedMpS;
605641
motor?.InitializeMoving();
606642
}
643+
public void Parse(STFReader stf)
644+
{
645+
stf.MustMatch("(");
646+
while (!stf.EndOfBlock())
647+
{
648+
switch (stf.ReadItem().ToLower())
649+
{
650+
case "ortsradius":
651+
WheelRadiusM = stf.ReadFloatBlock(STFReader.UNITS.Distance, null);
652+
break;
653+
case "ortsinertia":
654+
InertiaKgm2 = stf.ReadFloatBlock(STFReader.UNITS.RotationalInertia, null);
655+
break;
656+
case "weight":
657+
AxleWeightN = 9.81f * stf.ReadFloatBlock(STFReader.UNITS.Mass, null);
658+
break;
659+
case "(":
660+
stf.SkipRestOfBlock();
661+
break;
662+
}
663+
}
664+
}
607665
public void Copy(Axle other)
608666
{
609-
// TODO
610-
motor?.Copy(other.motor);
667+
WheelRadiusM = other.WheelRadiusM;
668+
InertiaKgm2 = other.InertiaKgm2;
669+
AxleWeightN = other.AxleWeightN;
611670
}
612671

613672
/// <summary>

0 commit comments

Comments
 (0)