Skip to content

Commit cebe7ac

Browse files
committed
Wag file axle configuration
1 parent 76f2801 commit cebe7ac

File tree

3 files changed

+102
-64
lines changed

3 files changed

+102
-64
lines changed

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

Lines changed: 14 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,6 @@ public enum TractionMotorTypes
453453
public ILocomotivePowerSupply LocomotivePowerSupply => PowerSupply as ILocomotivePowerSupply;
454454
public ScriptedTrainControlSystem TrainControlSystem;
455455

456-
public Axles LocomotiveAxles;
457456
public IIRFilter CurrentFilter;
458457
public IIRFilter AdhesionFilter;
459458
public float SaveAdhesionFilter;
@@ -480,7 +479,6 @@ public MSTSLocomotive(Simulator simulator, string wagPath)
480479
MilepostUnitsMetric = Simulator.TRK.Tr_RouteFile.MilepostUnitsMetric;
481480
BrakeCutsPowerAtBrakeCylinderPressurePSI = 4.0f;
482481

483-
LocomotiveAxles = new Axles(this);
484482
LocomotiveAxles.Add(new Axle());
485483
CurrentFilter = new IIRFilter(IIRFilter.FilterTypes.Butterworth, 1, IIRFilter.HzToRad(0.5f), 0.001f);
486484
AdhesionFilter = new IIRFilter(IIRFilter.FilterTypes.Butterworth, 1, IIRFilter.HzToRad(1f), 0.001f);
@@ -1229,23 +1227,10 @@ public override void Copy(MSTSWagon copy)
12291227
WaterScoopFillElevationM = locoCopy.WaterScoopFillElevationM;
12301228
WaterScoopDepthM = locoCopy.WaterScoopDepthM;
12311229
WaterScoopWidthM = locoCopy.WaterScoopWidthM;
1232-
MoveParamsToAxle();
12331230
CruiseControl = locoCopy.CruiseControl?.Clone(this);
12341231
MultiPositionControllers = locoCopy.CloneMPC(this);
12351232
}
12361233

1237-
/// <summary>
1238-
/// We are moving parameters from locomotive to axle.
1239-
/// </summary>
1240-
public void MoveParamsToAxle()
1241-
{
1242-
foreach (var axle in LocomotiveAxles)
1243-
{
1244-
axle.SlipWarningTresholdPercent = SlipWarningThresholdPercent;
1245-
axle.AdhesionK = AdhesionK;
1246-
}
1247-
}
1248-
12491234
/// <summary>
12501235
/// We are saving the game. Save anything that we'll need to restore the
12511236
/// status later.
@@ -1294,7 +1279,6 @@ public override void Save(BinaryWriter outf)
12941279
LocomotivePowerSupply?.Save(outf);
12951280
TrainControlSystem.Save(outf);
12961281

1297-
LocomotiveAxles.Save(outf);
12981282
CruiseControl?.Save(outf);
12991283
}
13001284

@@ -1348,9 +1332,7 @@ public override void Restore(BinaryReader inf)
13481332

13491333
LocomotivePowerSupply?.Restore(inf);
13501334
TrainControlSystem.Restore(inf);
1351-
1352-
MoveParamsToAxle();
1353-
LocomotiveAxles.Restore(inf);
1335+
13541336
CruiseControl?.Restore(inf);
13551337
}
13561338

@@ -1432,7 +1414,6 @@ public override void Initialize()
14321414
BrakemanBrakeController.Initialize();
14331415
LocomotivePowerSupply?.Initialize();
14341416
TrainControlSystem.Initialize();
1435-
LocomotiveAxles.Initialize();
14361417
CruiseControl?.Initialize();
14371418
foreach (MultiPositionController mpc in MultiPositionControllers)
14381419
{
@@ -1491,6 +1472,18 @@ public override void Initialize()
14911472
Trace.TraceInformation("Number of Locomotive Drive Axles set to default value of {0}", LocoNumDrvAxles);
14921473
}
14931474
}
1475+
//Compute axle inertia from parameters if possible
1476+
if (AxleInertiaKgm2 <= 0) // if no axleinertia value supplied in ENG file, calculate axleinertia value.
1477+
{
1478+
if (LocoNumDrvAxles > 0 && DriverWheelRadiusM > 0)
1479+
{
1480+
float radiusSquared = DriverWheelRadiusM * DriverWheelRadiusM;
1481+
float wheelMass = 500 * radiusSquared / (0.5f * 0.5f);
1482+
AxleInertiaKgm2 = Math.Min(LocoNumDrvAxles * wheelMass * radiusSquared + 500, 40000);
1483+
}
1484+
else
1485+
AxleInertiaKgm2 = 2000.0f;
1486+
}
14941487
if (TractionMotorType == TractionMotorTypes.AC)
14951488
{
14961489
foreach (var axle in LocomotiveAxles)
@@ -1500,7 +1493,6 @@ public override void Initialize()
15001493
}
15011494
}
15021495

1503-
15041496
// Calculate minimum speed to pickup water
15051497
const float Aconst = 2;
15061498
WaterScoopMinSpeedMpS = Me.FromFt((float)Math.Sqrt(Aconst * GravitationalAccelerationFtpSpS * Me.ToFt(WaterScoopFillElevationM)));
@@ -1748,9 +1740,8 @@ public List<MultiPositionController> CloneMPC(MSTSLocomotive locomotive)
17481740

17491741
public override void InitializeMoving()
17501742
{
1751-
base.InitializeMoving();
17521743
AdhesionFilter.Reset(0.5f);
1753-
LocomotiveAxles.InitializeMoving();
1744+
base.InitializeMoving();
17541745
AverageForceN = MaxForceN * Train.MUThrottlePercent / 100;
17551746
float maxPowerW = MaxPowerW * Train.MUThrottlePercent * Train.MUThrottlePercent / 10000;
17561747
if (AverageForceN * SpeedMpS > maxPowerW) AverageForceN = maxPowerW / SpeedMpS;
@@ -2796,34 +2787,6 @@ public virtual void AdvancedAdhesion(float elapsedClockSeconds)
27962787
return;
27972788
}
27982789

2799-
if (EngineType == EngineTypes.Steam && SteamEngineType != MSTSSteamLocomotive.SteamEngineTypes.Geared)
2800-
{
2801-
// Managed in MSTSSteamLocomotive implementation of AdvancedAdhesion
2802-
}
2803-
else
2804-
{
2805-
2806-
//Compute axle inertia from parameters if possible
2807-
if (AxleInertiaKgm2 <= 0) // if no axleinertia value supplied in ENG file, calculate axleinertia value.
2808-
{
2809-
if (LocoNumDrvAxles > 0 && DriverWheelRadiusM > 0)
2810-
{
2811-
float radiusSquared = DriverWheelRadiusM * DriverWheelRadiusM;
2812-
float wheelMass = 500 * radiusSquared / (0.5f * 0.5f);
2813-
AxleInertiaKgm2 = LocoNumDrvAxles * wheelMass * radiusSquared + 500;
2814-
}
2815-
else
2816-
AxleInertiaKgm2 = 2000.0f;
2817-
}
2818-
foreach (var axle in LocomotiveAxles)
2819-
{
2820-
//Limit the inertia to 40000 kgm2
2821-
axle.InertiaKgm2 = Math.Min(AxleInertiaKgm2, 40000);
2822-
axle.DampingNs = MassKG / 1000.0f;
2823-
axle.FrictionN = MassKG / 1000.0f;
2824-
axle.AxleWeightN = 9.81f * DrvWheelWeightKg/LocomotiveAxles.Count;; //remains fixed for diesel/electric locomotives, but varies for steam locomotives
2825-
}
2826-
}
28272790
foreach (var axle in LocomotiveAxles)
28282791
{
28292792
axle.BrakeRetardForceN = BrakeRetardForceN/LocomotiveAxles.Count;

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

Lines changed: 27 additions & 11 deletions
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;
@@ -348,6 +350,7 @@ public MSTSWagon(Simulator simulator, string wagFilePath)
348350
{
349351
Pantographs = new Pantographs(this);
350352
Doors = new Doors(this);
353+
LocomotiveAxles = new Axles(this);
351354
}
352355

353356
public void Load()
@@ -981,6 +984,7 @@ public override void Initialize()
981984
Pantographs.Initialize();
982985
Doors.Initialize();
983986
PassengerCarPowerSupply?.Initialize();
987+
LocomotiveAxles.Initialize();
984988

985989
base.Initialize();
986990

@@ -1012,6 +1016,7 @@ public override void Initialize()
10121016
public override void InitializeMoving()
10131017
{
10141018
PassengerCarPowerSupply?.InitializeMoving();
1019+
LocomotiveAxles.InitializeMoving();
10151020

10161021
base.InitializeMoving();
10171022
}
@@ -1384,15 +1389,8 @@ public virtual void Parse(string lowercasetoken, STFReader stf)
13841389
SlipWarningThresholdPercent = stf.ReadFloat(STFReader.UNITS.None, 70.0f); if (SlipWarningThresholdPercent <= 0) SlipWarningThresholdPercent = 70.0f;
13851390
stf.SkipRestOfBlock();
13861391
break;
1387-
case "wagon(ortsadhesion(wheelset(axle(ortsinertia":
1388-
stf.MustMatch("(");
1389-
AxleInertiaKgm2 = stf.ReadFloat(STFReader.UNITS.RotationalInertia, null);
1390-
stf.SkipRestOfBlock();
1391-
break;
1392-
case "wagon(ortsadhesion(wheelset(axle(ortsradius":
1393-
stf.MustMatch("(");
1394-
AdhesionDriveWheelRadiusM = stf.ReadFloat(STFReader.UNITS.Distance, null);
1395-
stf.SkipRestOfBlock();
1392+
case "wagon(ortsadhesion(wheelset":
1393+
LocomotiveAxles.Parse(lowercasetoken, stf);
13961394
break;
13971395
case "wagon(lights":
13981396
Lights = new LightCollection(stf);
@@ -1557,7 +1555,6 @@ public virtual void Copy(MSTSWagon copy)
15571555
Curtius_KnifflerC = copy.Curtius_KnifflerC;
15581556
AdhesionK = copy.AdhesionK;
15591557
AxleInertiaKgm2 = copy.AxleInertiaKgm2;
1560-
AdhesionDriveWheelRadiusM = copy.AdhesionDriveWheelRadiusM;
15611558
SlipWarningThresholdPercent = copy.SlipWarningThresholdPercent;
15621559
Lights = copy.Lights;
15631560
ExternalSoundPassThruPercent = copy.ExternalSoundPassThruPercent;
@@ -1620,6 +1617,20 @@ public virtual void Copy(MSTSWagon copy)
16201617
PowerSupply = new ScriptedPassengerCarPowerSupply(this);
16211618
PassengerCarPowerSupply.Copy(copy.PassengerCarPowerSupply);
16221619
}
1620+
LocomotiveAxles.Copy(copy.LocomotiveAxles);
1621+
MoveParamsToAxle();
1622+
}
1623+
1624+
/// <summary>
1625+
/// We are moving parameters from locomotive to axle.
1626+
/// </summary>
1627+
public void MoveParamsToAxle()
1628+
{
1629+
foreach (var axle in LocomotiveAxles)
1630+
{
1631+
axle.SlipWarningTresholdPercent = SlipWarningThresholdPercent;
1632+
axle.AdhesionK = AdhesionK;
1633+
}
16231634
}
16241635

16251636
protected void ParseWagonInside(STFReader stf)
@@ -1733,6 +1744,8 @@ public override void Save(BinaryWriter outf)
17331744
outf.Write(DerailExpected);
17341745
outf.Write(DerailElapsedTimeS);
17351746

1747+
LocomotiveAxles.Save(outf);
1748+
17361749
base.Save(outf);
17371750
}
17381751

@@ -1786,6 +1799,9 @@ public override void Restore(BinaryReader inf)
17861799
DerailExpected = inf.ReadBoolean();
17871800
DerailElapsedTimeS = inf.ReadSingle();
17881801

1802+
MoveParamsToAxle();
1803+
LocomotiveAxles.Restore(inf);
1804+
17891805
base.Restore(inf);
17901806
}
17911807

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

Lines changed: 61 additions & 2 deletions
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)