Skip to content

Commit 7c2247f

Browse files
committed
Automatic merge of T1.5.1-372-g5db5c7824 and 11 pull requests
- Pull request #570 at de7a14f: Experimental glTF 2.0 support with PBR lighting - Pull request #732 at 22f66dc: Improvements for air brakes - Pull request #751 at 00981a2: Web interface to control cab controls with external hardware - Pull request #799 at dc03850: Consolidated wind simulation - Pull request #802 at 4d198e4: Added support for activity location events to the TrackViewer - Pull request #803 at 7157e08: Various adjustments to steam adhesion - Pull request #813 at 001e285: Refactored garbage generators - Pull request #815 at a5cc165: chore: Add GitHub automatic release notes configuration - Pull request #816 at eae646d: Bug fix for https://bugs.launchpad.net/or/+bug/2014992 EOT can't be dismounted after train reversal - Pull request #818 at 5c0bb4f: Allow independent drive axles for locomotives - Pull request #819 at 51b98b2: Headlight switch makes sound when not appropriate
13 parents 862e809 + 5db5c78 + de7a14f + 22f66dc + 00981a2 + dc03850 + 4d198e4 + 7157e08 + 001e285 + a5cc165 + eae646d + 5c0bb4f + 51b98b2 commit 7c2247f

File tree

3 files changed

+103
-65
lines changed

3 files changed

+103
-65
lines changed

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

+15-52
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

@@ -1349,8 +1333,6 @@ public override void Restore(BinaryReader inf)
13491333
LocomotivePowerSupply?.Restore(inf);
13501334
TrainControlSystem.Restore(inf);
13511335

1352-
MoveParamsToAxle();
1353-
LocomotiveAxles.Restore(inf);
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;
@@ -2792,40 +2783,12 @@ public virtual void AdvancedAdhesion(float elapsedClockSeconds)
27922783
return;
27932784
}
27942785

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

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;
@@ -143,13 +144,14 @@ public class MSTSWagon : TrainCar
143144
public float Curtius_KnifflerC = 0.161f; // speedMpS * 3.6 + B
144145
public float AdhesionK = 0.7f; //slip characteristics slope
145146
public float AxleInertiaKgm2; //axle inertia
146-
public float AdhesionDriveWheelRadiusM;
147147
public float WheelSpeedMpS;
148148
public float WheelSpeedSlipMpS; // speed of wheel if locomotive is slipping
149149
public float SlipWarningThresholdPercent = 70;
150150
public MSTSNotchController WeightLoadController; // Used to control freight loading in freight cars
151151
public float AbsWheelSpeedMpS; // Math.Abs(WheelSpeedMpS) is used frequently in the subclasses, maybe it's more efficient to compute it once
152152

153+
public Axles LocomotiveAxles; // Only used at locomotives for efficiency
154+
153155
// Colours for smoke and steam effects
154156
public Color ExhaustTransientColor = Color.Black;
155157
public Color ExhaustDecelColor = Color.WhiteSmoke;
@@ -343,6 +345,7 @@ public MSTSWagon(Simulator simulator, string wagFilePath)
343345
{
344346
Pantographs = new Pantographs(this);
345347
Doors = new Doors(this);
348+
LocomotiveAxles = new Axles(this);
346349
}
347350

348351
public void Load()
@@ -978,6 +981,7 @@ public override void Initialize()
978981
Pantographs.Initialize();
979982
Doors.Initialize();
980983
PassengerCarPowerSupply?.Initialize();
984+
LocomotiveAxles.Initialize();
981985

982986
base.Initialize();
983987

@@ -1009,6 +1013,7 @@ public override void Initialize()
10091013
public override void InitializeMoving()
10101014
{
10111015
PassengerCarPowerSupply?.InitializeMoving();
1016+
LocomotiveAxles.InitializeMoving();
10121017

10131018
base.InitializeMoving();
10141019
}
@@ -1381,15 +1386,8 @@ public virtual void Parse(string lowercasetoken, STFReader stf)
13811386
SlipWarningThresholdPercent = stf.ReadFloat(STFReader.UNITS.None, 70.0f); if (SlipWarningThresholdPercent <= 0) SlipWarningThresholdPercent = 70.0f;
13821387
stf.SkipRestOfBlock();
13831388
break;
1384-
case "wagon(ortsadhesion(wheelset(axle(ortsinertia":
1385-
stf.MustMatch("(");
1386-
AxleInertiaKgm2 = stf.ReadFloat(STFReader.UNITS.RotationalInertia, null);
1387-
stf.SkipRestOfBlock();
1388-
break;
1389-
case "wagon(ortsadhesion(wheelset(axle(ortsradius":
1390-
stf.MustMatch("(");
1391-
AdhesionDriveWheelRadiusM = stf.ReadFloat(STFReader.UNITS.Distance, null);
1392-
stf.SkipRestOfBlock();
1389+
case "wagon(ortsadhesion(wheelset":
1390+
LocomotiveAxles.Parse(lowercasetoken, stf);
13931391
break;
13941392
case "wagon(lights":
13951393
Lights = new LightCollection(stf);
@@ -1554,7 +1552,6 @@ public virtual void Copy(MSTSWagon copy)
15541552
Curtius_KnifflerC = copy.Curtius_KnifflerC;
15551553
AdhesionK = copy.AdhesionK;
15561554
AxleInertiaKgm2 = copy.AxleInertiaKgm2;
1557-
AdhesionDriveWheelRadiusM = copy.AdhesionDriveWheelRadiusM;
15581555
SlipWarningThresholdPercent = copy.SlipWarningThresholdPercent;
15591556
Lights = copy.Lights;
15601557
ExternalSoundPassThruPercent = copy.ExternalSoundPassThruPercent;
@@ -1617,6 +1614,20 @@ public virtual void Copy(MSTSWagon copy)
16171614
PowerSupply = new ScriptedPassengerCarPowerSupply(this);
16181615
PassengerCarPowerSupply.Copy(copy.PassengerCarPowerSupply);
16191616
}
1617+
LocomotiveAxles.Copy(copy.LocomotiveAxles);
1618+
MoveParamsToAxle();
1619+
}
1620+
1621+
/// <summary>
1622+
/// We are moving parameters from locomotive to axle.
1623+
/// </summary>
1624+
public void MoveParamsToAxle()
1625+
{
1626+
foreach (var axle in LocomotiveAxles)
1627+
{
1628+
axle.SlipWarningTresholdPercent = SlipWarningThresholdPercent;
1629+
axle.AdhesionK = AdhesionK;
1630+
}
16201631
}
16211632

16221633
protected void ParseWagonInside(STFReader stf)
@@ -1730,6 +1741,8 @@ public override void Save(BinaryWriter outf)
17301741
outf.Write(DerailExpected);
17311742
outf.Write(DerailElapsedTimeS);
17321743

1744+
LocomotiveAxles.Save(outf);
1745+
17331746
base.Save(outf);
17341747
}
17351748

@@ -1783,6 +1796,9 @@ public override void Restore(BinaryReader inf)
17831796
DerailExpected = inf.ReadBoolean();
17841797
DerailElapsedTimeS = inf.ReadSingle();
17851798

1799+
MoveParamsToAxle();
1800+
LocomotiveAxles.Restore(inf);
1801+
17861802
base.Restore(inf);
17871803
}
17881804

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)