Skip to content

Commit fa57fcb

Browse files
committed
Automatic merge of T1.5.1-1689-g72674c98d and 14 pull requests
- Pull request #900 at 4629736: DMI in 3D cab + two more dials - Pull request #1030 at d3ae4a2: Refactor settings, in prep for settings exporter - Pull request #1045 at cc4d53c: Bugfix: Empty Start Time for Explore, and other issues loading from Menu Selection and Content Routes - Pull request #1052 at 17c8d18: Content Manager: Add axle count, and lowest derail force - Pull request #1062 at 3b18c48: Train Forces popup Window. - Pull request #1064 at 53dd604: Add Train Info tab to Help window (F1) - Pull request #1066 at 62c89c1: Log derailment, using TraceInformation. - Pull request #892 at 1f5ba4c: Signal Function OPP_SIG_ID_TRAINPATH - Pull request #1000 at d8d9709: Locomotive operation from control car - Pull request #1029 at 92c74ef: Superelevation Follow Up Fixes - Pull request #1065 at 409064d: Fix for PantographToggle sound event - Pull request #1068 at d6e1f83: Build for online-only documentation files - Pull request #896 at f1681df: First implementation of https://blueprints.launchpad.net/or/+spec/specific-sounds-for-ai-trains - Pull request #1067 at 777efaf: Traction and dynamic brake retardation
16 parents 8f1a7c1 + 72674c9 + 4629736 + d3ae4a2 + cc4d53c + 17c8d18 + 3b18c48 + 53dd604 + 62c89c1 + 1f5ba4c + d8d9709 + 92c74ef + 409064d + d6e1f83 + f1681df + 777efaf commit fa57fcb

37 files changed

+1146
-1265
lines changed

Source/Contrib/ContentManager/Models/Car.cs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public class Car
4343
public readonly float MassKG;
4444
public readonly float LengthM;
4545
public readonly int NumDriveAxles;
46+
public readonly int NumIdleAxles;
4647
public readonly int NumAllAxles;
4748
public readonly float MaxBrakeForceN;
4849
public readonly float MaxPowerW;
@@ -57,8 +58,6 @@ public Car(Content content)
5758

5859
const float GravitationalAccelerationMpS2 = 9.80665f;
5960

60-
int ortsEngAxles = -1; // not present
61-
6261
// .eng files also have a wagon block
6362
var wagFile = new WagonFile(content.PathName);
6463
Type = CarType.Wagon;
@@ -81,20 +80,27 @@ public Car(Content content)
8180
Description = engFile.Description;
8281

8382
// see MSTSLocomotive.Initialize()
84-
ortsEngAxles = engFile.NumDriveAxles;
85-
if (ortsEngAxles >= 0) { NumDriveAxles = ortsEngAxles; }
86-
else if (engFile.NumEngWheels >= 7f) { NumDriveAxles = (int)(engFile.NumEngWheels / 2f); }
87-
else if (engFile.NumEngWheels > 0f) { NumDriveAxles = (int)engFile.NumEngWheels; }
88-
else { NumDriveAxles = 4; }
83+
NumDriveAxles = engFile.NumDriveAxles;
84+
if (NumDriveAxles == 0)
85+
{
86+
if (engFile.NumEngWheels != 0 && engFile.NumEngWheels < 7) { NumDriveAxles = (int)engFile.NumEngWheels; }
87+
else { NumDriveAxles = 4; }
88+
}
8989
}
9090

9191
// see MSTSWagon.LoadFromWagFile()
92-
if (ortsEngAxles >= 0 && wagFile.NumWagAxles >= 0) { NumAllAxles = ortsEngAxles + wagFile.NumWagAxles; }
93-
else if (wagFile.NumWagAxles >= 0) { NumAllAxles = wagFile.NumWagAxles; }
94-
else if (wagFile.NumWagWheels >= 7f) { NumAllAxles = (int)(wagFile.NumWagWheels / 2f); }
95-
else if (wagFile.NumWagWheels > 0f) { NumAllAxles = (int)wagFile.NumWagWheels; }
96-
else { NumAllAxles = 4; }
97-
if (NumDriveAxles > NumAllAxles) { NumAllAxles = NumDriveAxles; }
92+
NumIdleAxles = wagFile.NumWagAxles;
93+
if ((NumIdleAxles == 0) && Type != CarType.Engine)
94+
{
95+
if (wagFile.NumWagWheels != 0 && wagFile.NumWagWheels < 6) { NumIdleAxles = (int)wagFile.NumWagWheels; }
96+
else { NumIdleAxles = 4; }
97+
}
98+
99+
// correction for steam engines; see TrainCar.Update()
100+
// this is not always correct as TrainCar uses the WheelAxles array for the count; that is too complex to do here
101+
if (SubType.Equals("Steam") && NumDriveAxles >= (NumDriveAxles + NumIdleAxles)) { NumDriveAxles /= 2; }
102+
103+
NumAllAxles = NumDriveAxles + NumIdleAxles;
98104

99105
// see TrainCar.UpdateTrainDerailmentRisk()
100106
var numWheels = NumAllAxles * 2;

Source/Contrib/ContentManager/Models/Consist.cs

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public Consist(Content content)
6060
var CarList = new List<Car>();
6161
foreach (Wagon wag in file.Train.TrainCfg.WagonList)
6262
{
63-
float wagonMassKG = 0; int ortsEngAxles = -1; int numDriveAxles = 0; int numAllAxles = 0;
63+
float wagonMassKG = 0; int numDriveAxles = 0; int numIdleAxles = 0; int numAllAxles = 0;
6464
try
6565
{
6666
var fileType = wag.IsEngine ? ".eng" : ".wag";
@@ -73,16 +73,20 @@ public Consist(Content content)
7373
wagonMassKG = wagonFile.MassKG;
7474
MaxBrakeForce += wagonFile.MaxBrakeForceN;
7575
MinCouplerStrengthN = Math.Min(MinCouplerStrengthN, wagonFile.MinCouplerStrengthN);
76+
var subType = wagonFile.WagonType;
7677
if (wagonFile.MaxBrakeForceN > 0) { NumOperativeBrakes++; }
7778

78-
if (wag.IsEngine)
79+
if (engFile != null)
7980
{
81+
subType = engFile.EngineType;
82+
8083
// see MSTSLocomotive.Initialize()
81-
ortsEngAxles = engFile.NumDriveAxles;
82-
if (ortsEngAxles >= 0) { numDriveAxles = ortsEngAxles; }
83-
else if (engFile.NumEngWheels > 7f) { numDriveAxles = (int)(engFile.NumEngWheels / 2f); }
84-
else if (engFile.NumEngWheels > 0) { numDriveAxles = (int)engFile.NumEngWheels; }
85-
else { numDriveAxles = 4; }
84+
numDriveAxles = engFile.NumDriveAxles;
85+
if (numDriveAxles == 0)
86+
{
87+
if (engFile.NumEngWheels != 0 && engFile.NumEngWheels < 7) { numDriveAxles = (int)engFile.NumEngWheels; }
88+
else { numDriveAxles = 4; }
89+
}
8690

8791
if (engFile.MaxForceN > 25000) // exclude legacy driving trailers / cab-cars
8892
{
@@ -99,12 +103,18 @@ public Consist(Content content)
99103
}
100104

101105
// see MSTSWagon.LoadFromWagFile()
102-
if (ortsEngAxles >= 0 && wagonFile.NumWagAxles >= 0) { numAllAxles = ortsEngAxles + wagonFile.NumWagAxles; }
103-
else if (wagonFile.NumWagAxles >= 0) { numAllAxles = wagonFile.NumWagAxles; }
104-
else if (wagonFile.NumWagWheels >= 7f) { numAllAxles = (int)(wagonFile.NumWagWheels / 2f); }
105-
else if (wagonFile.NumWagWheels >= 0f) { numAllAxles = (int)wagonFile.NumWagWheels; }
106-
else { numAllAxles = 4; }
107-
if (numDriveAxles > numAllAxles) { numAllAxles = numDriveAxles; }
106+
numIdleAxles = wagonFile.NumWagAxles;
107+
if (numIdleAxles == 0 && !wag.IsEngine)
108+
{
109+
if (wagonFile.NumWagWheels != 0 && wagonFile.NumWagWheels < 6) { numIdleAxles = (int)wagonFile.NumWagWheels; }
110+
else { numIdleAxles = 4; }
111+
}
112+
113+
// correction for steam engines; see TrainCar.Update()
114+
// this is not always correct as TrainCar uses the WheelAxles array for the count; that is too complex to do here
115+
if (subType.Equals("Steam") && numDriveAxles >= (numDriveAxles + numIdleAxles)) { numDriveAxles /= 2; }
116+
117+
numAllAxles = numDriveAxles + numIdleAxles;
108118

109119
// exclude legacy EOT from total axle count
110120
if (!wag.IsEOT && wagonFile.WagonSize.LengthM > 1.1)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"profiles": {
3+
"SettingsExporter": {
4+
"commandName": "Project",
5+
"commandLineArgs": "REG INI"
6+
}
7+
}
8+
}

Source/Documentation/Manual/physics.rst

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,6 +1141,58 @@ with the ``ORTSTractionMotorType ( AC ) `` parameter, to be inserted in the Engi
11411141
section of the ENG file. The use of this motor will have an impact on wheel slip,
11421142
because the wheel speed never exceeds the frequency of the rotating magnetic field.
11431143
1144+
Traction force retardation
1145+
''''''''''''''''''''''''''
1146+
1147+
.. index::
1148+
single: ORTSTractiveForceRampUpRate
1149+
single: ORTSTractiveForceRampDownRate
1150+
single: ORTSTractiveForceRampDownToZeroRate
1151+
single: ORTSDynamicBrakeForceRampUpRate
1152+
single: ORTSDynamicBrakeForceRampDownRate
1153+
single: ORTSDynamicBrakeForceRampDownToZeroRate
1154+
single: ORTSDelayTimeBeforeUpdating
1155+
1156+
When the driver sets full throttle, the control electronics may not apply the full
1157+
tractive force instantly, but it will instead linearly apply force until reaching
1158+
the target demand. This can be tuned both for traction and dynamic braking by inserting
1159+
``ORTSTractiveForceRampUpRate``, ``ORTSTractiveForceRampDownRate``,
1160+
``ORTSTractiveForceRampDownToZeroRate``, ``ORTSDynamicBrakeForceRampUpRate``,
1161+
``ORTSDynamicBrakeForceRampDownRate`` and ``ORTSDynamicBrakeForceRampDownToZeroRate``
1162+
in the .eng file. The value of each parameter determines the force increase/decrease
1163+
rate in one second.
1164+
1165+
Example::
1166+
1167+
Engine (
1168+
ORTSTractiveForceRampUpRate ( 50kN )
1169+
ORTSTractiveForceRampDownRate ( 50kN )
1170+
ORTSTractiveForceRampDownToZeroRate ( 100kN )
1171+
ORTSDynamicBrakeForceRampUpRate ( 70kN )
1172+
ORTSDynamicBrakeForceRampDownRate ( 50kN )
1173+
ORTSDynamicBrakeForceRampDownToZeroRate ( 50kN )
1174+
)
1175+
1176+
Another possibility to avoid sudden variations in tractive force while the driver
1177+
is moving the throttle, is to only update the throttle/brake demand when the lever
1178+
has not been moved for a defined amount of time. This can be implemented using the
1179+
``ORTSDelayTimeBeforeUpdating``, which has to be inserted for the desired
1180+
controller in the ``EngineControllers`` block.
1181+
1182+
Example::
1183+
1184+
Engine (
1185+
EngineControllers (
1186+
Throttle ( 0 1 0.1 0
1187+
NumNotches ( 0 )
1188+
ORTSDelayTimeBeforeUpdating ( 0.5s )
1189+
)
1190+
Brake_Dynamic ( 0 1 0.1 0
1191+
NumNotches ( 0 )
1192+
ORTSDelayTimeBeforeUpdating ( 1s )
1193+
)
1194+
)
1195+
)
11441196

11451197
Steam Locomotives
11461198
-----------------

Source/Orts.Common/Conversions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ public static class Kg
189189
/// <summary>Convert from kilograms to UK Tons</summary>
190190
public static float ToTUK(float kg) { return kg * (1.0f / 1016.047f); }
191191
/// <summary>Convert from kilogram to metric tonnes</summary>
192-
public static float ToTonne(float kg) { return kg / 1000.0f; }
192+
public static float ToTonne(float kg) { return kg * (1.0f / 1000.0f); }
193193
/// <summary>Convert from metrix tonnes to kilogram</summary>
194194
public static float FromTonne(float tonne) { return tonne * 1000.0f; }
195195
}

Source/Orts.Formats.Msts/EngineFile.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public class EngineFile
3333
public float MaxForceN;
3434
public float MaxDynamicBrakeForceN;
3535
public float MaxSpeedMps;
36-
public int NumDriveAxles = -1; // ORTS; -1 indicates absent
36+
public int NumDriveAxles; // ORTS
3737
public float NumEngWheels; // MSTS
3838
public string Description;
3939
public string CabViewFile;

Source/Orts.Formats.Msts/WagonFile.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public class WagonFile
3232
public string WagonType;
3333
public float MassKG;
3434
public CarSize WagonSize;
35-
public int NumWagAxles = -1; // ORTS; -1 indicates absent
35+
public int NumWagAxles; // ORTS
3636
public float NumWagWheels; // MSTS
3737
public float MaxBrakeForceN;
3838
public float MinCouplerStrengthN = ImpossiblyHighForceN;

Source/Orts.Parsers.Msts/STFReader.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -609,10 +609,11 @@ public float ReadFloat(UNITS validUnits, float? defaultValue)
609609
// However, some values (mostly "time" ones) may be followed by text. Therefore that approach cannot be used consistently
610610
// and has been abandoned. </CJComment>
611611

612+
float val;
613+
double scale = ParseUnitSuffix(ref item, validUnits);
612614
if (item.Length == 0) return 0.0f;
613615
if (item[item.Length - 1] == ',') item = item.TrimEnd(',');
614-
double scale = ParseUnitSuffix(ref item, validUnits); // must be after TrimEnd(','), otherwise the unit parsed becomes invalid
615-
if (float.TryParse(item, parseNum, parseNFI, out float val)) return (scale == 1) ? val : (float)(scale * val);
616+
if (float.TryParse(item, parseNum, parseNFI, out val)) return (scale == 1) ? val : (float)(scale * val);
616617
STFException.TraceWarning(this, "Cannot parse the constant number " + item);
617618
if (item == ")") StepBackOneItem();
618619
return defaultValue.GetValueOrDefault(0);

Source/Orts.Simulation/Simulation/Physics/Train.cs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4061,14 +4061,33 @@ public void UnconditionalInitializeBrakes()
40614061
MSTSLocomotive lead = (MSTSLocomotive)Cars[LeadLocomotiveIndex];
40624062
if (lead.TrainBrakeController != null)
40634063
{
4064-
foreach (var car in Cars)
4064+
foreach (MSTSWagon car in Cars)
40654065
{
4066-
if (lead.BrakeSystem.GetType() != car.BrakeSystem.GetType())
4066+
if (lead.CarBrakeSystemType != car.CarBrakeSystemType) // Test to see if car brake system is the same as the locomotive
40674067
{
4068-
car.BrakeSystem = BrakeSystem.CreateNewLike(lead.BrakeSystem, car);
4069-
car.BrakeSystem.InitializeFromCopy(lead.BrakeSystem, false);
4070-
if (car.BrakeSystem is AirSinglePipe carAir && lead.BrakeSystem is AirSinglePipe leadAir)
4071-
carAir.EmergencyReservoirPresent = leadAir.EmergencyReservoirPresent;
4068+
// If not, change so that they are compatible
4069+
car.CarBrakeSystemType = lead.CarBrakeSystemType;
4070+
if (lead.BrakeSystem is VacuumSinglePipe)
4071+
car.MSTSBrakeSystem = new VacuumSinglePipe(car);
4072+
else if (lead.BrakeSystem is AirTwinPipe)
4073+
car.MSTSBrakeSystem = new AirTwinPipe(car);
4074+
else if (lead.BrakeSystem is AirSinglePipe leadAir)
4075+
{
4076+
car.MSTSBrakeSystem = new AirSinglePipe(car);
4077+
// if emergency reservoir has been set on lead locomotive then also set on trailing cars
4078+
if (leadAir.EmergencyReservoirPresent)
4079+
{
4080+
(car.BrakeSystem as AirSinglePipe).EmergencyReservoirPresent = leadAir.EmergencyReservoirPresent;
4081+
}
4082+
}
4083+
else if (lead.BrakeSystem is EPBrakeSystem ep)
4084+
car.MSTSBrakeSystem = new EPBrakeSystem(car, ep.TwoPipes);
4085+
else if (lead.BrakeSystem is SingleTransferPipe)
4086+
car.MSTSBrakeSystem = new SingleTransferPipe(car);
4087+
else
4088+
throw new Exception("Unknown brake type");
4089+
4090+
car.MSTSBrakeSystem.InitializeFromCopy(lead.BrakeSystem);
40724091
Trace.TraceInformation("Car and Locomotive Brake System Types Incompatible on Car {0} - Car brakesystem type changed to {1}", car.CarID, car.CarBrakeSystemType);
40734092
}
40744093
}

Source/Orts.Simulation/Simulation/RollingStocks/MSTSControlTrailerCar.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ public override string GetStatus()
263263
/// <summary>
264264
/// This function updates periodically the locomotive's motive force.
265265
/// </summary>
266-
protected override void UpdateTractiveForce(float elapsedClockSeconds, float t, float AbsSpeedMpS, float AbsWheelSpeedMpS)
266+
protected override void UpdateTractiveForce(float elapsedClockSeconds)
267267
{
268268
}
269269

0 commit comments

Comments
 (0)