Skip to content

Commit bf4e3ff

Browse files
committed
Automatic merge of T1.6-rc2-41-gacd714487 and 12 pull requests
- Pull request #1104 at f15bb6b: Handle simple adhesion within the axle module - Pull request #1057 at 1c2bcb4: Switchable brake system - Pull request #1086 at e10390b: Add Settings Exporter tool (copy settings to INI, etc) - Pull request #1091 at 2391bc0: Automatic speed control - Pull request #1110 at 387388e: Fix Activity Runner persists after loading exception - Pull request #1114 at 9a4a873: Fix color of DB in DrivingInfo when in setup with DPU fenced. (r1.6) - Pull request #1115 at 270f22f: Do not activate ETS switch if no suitable cars are attached - Pull request #1116 at 721d118: Fix Potential Hang in AnimatedPart.SetFrameWrap - Pull request #1118 at f1e0f35: Fix DPMode when last remote is moved to front. (r1.6) - Pull request #1119 at 57243f0: Re-add missing PR #1103 - Pull request #1082 at 5845a1a: Allow variable water level in glass gauge - Pull request #1081 at 689494b: Brake cuts power unification
14 parents 0400e6d + acd7144 + f15bb6b + 1c2bcb4 + e10390b + 2391bc0 + 387388e + 9a4a873 + 270f22f + 721d118 + f1e0f35 + 57243f0 + 5845a1a + 689494b commit bf4e3ff

24 files changed

+1023
-819
lines changed

Source/Documentation/Manual/physics.rst

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2743,6 +2743,46 @@ For EP brakes, two variants are available:
27432743
actuating the cylinders. This system is sometimes called "UIC EP brake". It is typically the system
27442744
used in high speed trains.
27452745

2746+
Defining Multiple Brake Systems
2747+
-------------------------------
2748+
2749+
It is possible to define multiple systems within ``OrtsBrakeMode`` sections::
2750+
2751+
ORTSBrakeMode (
2752+
ORTSBrakeModeName ( AG )
2753+
BrakeSystemType( Air_single_pipe )
2754+
Comment ( All brake parameters are available in such a section )
2755+
)
2756+
ORTSBrakeMode (
2757+
ORTSBrakeModeName ( VB )
2758+
BrakeSystemType( Vacuum_single_pipe )
2759+
Comment ( All brake parameters are available in such a section )
2760+
)
2761+
2762+
These sections can be used to either define dual vacuum/air rolling stock, or
2763+
can be used to define the brake modes of the UIC stock in the following form::
2764+
2765+
BrakeSystemType( Air_twin_pipe )
2766+
ORTSBrakeMode (
2767+
ORTSBrakeModeName ( G )
2768+
ORTSBrakeMass ( 67t )
2769+
Comment ( All brake parameters are available in such a section )
2770+
)
2771+
ORTSBrakeMode (
2772+
ORTSBrakeModeName ( P )
2773+
ORTSBrakeMass ( 83t )
2774+
BrakeSystemType( Vacuum_single_pipe )
2775+
Comment ( All brake parameters are available in such a section )
2776+
)
2777+
2778+
Available brake mode names to be used are: GG, G, PP, P, RR, R, R_MG, AG, AP, AU, VB, VP, VU.
2779+
With the ``ORTSBrakeModeNames`` keyword the used brake modes can be filtered,
2780+
for being able to define them in an include file, and using only the needed
2781+
ones. It can be used e.g. in the following form::
2782+
2783+
ORTSBrakeModeNames ( "P, R" )
2784+
2785+
27462786
.. _physics-brake-controller:
27472787

27482788
Train Brake Controller Positions
@@ -3152,6 +3192,13 @@ using the ORTSBrakeShoeFriction parameter, 1D (ie, speed only, see above section
31523192

31533193
``ORTSNumberCarBrakeShoes`` - to facilitate the operation of the default 2D curves above it is necessary to configure the number of brake shoes for each car.
31543194

3195+
``ORTSBrakeMass`` - Railways part of the UIC organisation instead of NBR
3196+
provide brake masses, measured in tonnes, which is a virtual value to define
3197+
the brake efficiency. Openrails uses this value as an alternative to setting
3198+
the max brake shoe force directly, and recalculates this to that force using
3199+
approximating formulas to the published UIC brake curves. This parameter is
3200+
ignored if the ``ORTSMaxBrakeShoeForce`` also set.
3201+
31553202
Whilst OR will attempt to set some defaults if parameters are left out, the most realistic operation will be achieved by using all the relevant parameters.
31563203

31573204
The following two legacy arrangements can be used as an alternative to the above method,
@@ -3160,6 +3207,26 @@ The following two legacy arrangements can be used as an alternative to the above
31603207

31613208
- Legacy #2 - where MaxBrakeForce and ORTSBrakeShoeFriction have been set, legacy operation will remain unchanged.
31623209

3210+
Load Compensation
3211+
-----------------
3212+
3213+
Load compensation stages can be defined in the following way::
3214+
3215+
OrtsLoadStage (
3216+
OrtsBrakeMass ( 28t )
3217+
Comment ( All brake parameters are available in such a section )
3218+
)
3219+
OrtsLoadStage (
3220+
OrtsBrakeMass ( 37t )
3221+
OrtsLoadStageMinMass ( 34t )
3222+
Comment ( All brake parameters are available in such a section )
3223+
)
3224+
3225+
The ``OrtsLoadStageMinMass`` parameter defines the minimum car mass (together
3226+
with the load) where the stage can be activated without risking the brake lock.
3227+
For the lowest stage this keyword should be omitted. In OpenRails the switching
3228+
between stages is automatic.
3229+
31633230

31643231
Train Brake Pipe Losses
31653232
-----------------------
@@ -3671,10 +3738,11 @@ The retainers of a car will only be available if either the General Option
36713738
:ref:`Retainer valve on all cars <options-retainers>` is checked, or the car's
36723739
.wag file contains a retainer valve declaration. To declare a retainer the line
36733740
``BrakeEquipmentType ( )`` in the .wag file must include either the item
3674-
``Retainer_4_Position`` or the item ``Retainer_3_Position``. A 4 position
3741+
``Retainer_4_Position``, ``Retainer_3_Position`` or ``UIC_mountain``. A 4 position
36753742
retainer includes four states: exhaust, low pressure (10 psi), high pressure
36763743
(20 psi), and slow direct (gradual drop to zero). A 3 position retainer does
3677-
not include the low pressure position. The use and display of the retainers is
3744+
not include the low pressure position. The UIC plain-mountain switch has only
3745+
2 positions. The use and display of the retainers is
36783746
described in :ref:`Extended HUD for Brake Information <physics-hud-brake>`.
36793747

36803748
The setting of the retained pressure and the number of retainers is

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 * (1.0f / 1000.0f); }
192+
public static float ToTonne(float kg) { return kg / 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.Parsers.Msts/STFReader.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -609,11 +609,10 @@ 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);
614612
if (item.Length == 0) return 0.0f;
615613
if (item[item.Length - 1] == ',') item = item.TrimEnd(',');
616-
if (float.TryParse(item, parseNum, parseNFI, out val)) return (scale == 1) ? val : (float)(scale * val);
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);
617616
STFException.TraceWarning(this, "Cannot parse the constant number " + item);
618617
if (item == ")") StepBackOneItem();
619618
return defaultValue.GetValueOrDefault(0);

Source/Orts.Simulation/Simulation/AIs/AITrain.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3990,6 +3990,7 @@ public override void InitializeBrakes()
39903990
base.InitializeBrakes();
39913991
return;
39923992
}
3993+
SetInitialBrakeModes();
39933994
float maxPressurePSI = 90;
39943995
float fullServPressurePSI = 64;
39953996
float maxPressurePSIVacuum = 21;

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

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4059,33 +4059,14 @@ public void UnconditionalInitializeBrakes()
40594059
MSTSLocomotive lead = (MSTSLocomotive)Cars[LeadLocomotiveIndex];
40604060
if (lead.TrainBrakeController != null)
40614061
{
4062-
foreach (MSTSWagon car in Cars)
4062+
foreach (var car in Cars)
40634063
{
4064-
if (lead.CarBrakeSystemType != car.CarBrakeSystemType) // Test to see if car brake system is the same as the locomotive
4064+
if (lead.BrakeSystem.GetType() != car.BrakeSystem.GetType())
40654065
{
4066-
// If not, change so that they are compatible
4067-
car.CarBrakeSystemType = lead.CarBrakeSystemType;
4068-
if (lead.BrakeSystem is VacuumSinglePipe)
4069-
car.MSTSBrakeSystem = new VacuumSinglePipe(car);
4070-
else if (lead.BrakeSystem is AirTwinPipe)
4071-
car.MSTSBrakeSystem = new AirTwinPipe(car);
4072-
else if (lead.BrakeSystem is AirSinglePipe leadAir)
4073-
{
4074-
car.MSTSBrakeSystem = new AirSinglePipe(car);
4075-
// if emergency reservoir has been set on lead locomotive then also set on trailing cars
4076-
if (leadAir.EmergencyReservoirPresent)
4077-
{
4078-
(car.BrakeSystem as AirSinglePipe).EmergencyReservoirPresent = leadAir.EmergencyReservoirPresent;
4079-
}
4080-
}
4081-
else if (lead.BrakeSystem is EPBrakeSystem ep)
4082-
car.MSTSBrakeSystem = new EPBrakeSystem(car, ep.TwoPipes);
4083-
else if (lead.BrakeSystem is SingleTransferPipe)
4084-
car.MSTSBrakeSystem = new SingleTransferPipe(car);
4085-
else
4086-
throw new Exception("Unknown brake type");
4087-
4088-
car.MSTSBrakeSystem.InitializeFromCopy(lead.BrakeSystem);
4066+
car.BrakeSystem = BrakeSystem.CreateNewLike(lead.BrakeSystem, car);
4067+
car.BrakeSystem.InitializeFromCopy(lead.BrakeSystem, false);
4068+
if (car.BrakeSystem is AirSinglePipe carAir && lead.BrakeSystem is AirSinglePipe leadAir)
4069+
carAir.EmergencyReservoirPresent = leadAir.EmergencyReservoirPresent;
40894070
Trace.TraceInformation("Car and Locomotive Brake System Types Incompatible on Car {0} - Car brakesystem type changed to {1}", car.CarID, car.CarBrakeSystemType);
40904071
}
40914072
}
@@ -4095,6 +4076,8 @@ public void UnconditionalInitializeBrakes()
40954076
if (Simulator.Confirmer != null && IsActualPlayerTrain) // As Confirmer may not be created until after a restore.
40964077
Simulator.Confirmer.Confirm(CabControl.InitializeBrakes, CabSetting.Off);
40974078

4079+
SetInitialBrakeModes();
4080+
40984081
float maxPressurePSI = 90;
40994082
float fullServPressurePSI = 64;
41004083
if (FirstCar != null && FirstCar.BrakeSystem is VacuumSinglePipe)
@@ -4578,6 +4561,38 @@ public void CheckFreight()
45784561
if (TrainType == TRAINTYPE.AI_INCORPORATED && IncorporatingTrainNo > -1) IsPlayable = true;
45794562
} // CheckFreight
45804563

4564+
4565+
public void SetInitialBrakeModes()
4566+
{
4567+
var lead = LeadLocomotive ?? Cars?.FirstOrDefault();
4568+
if (lead == null) return;
4569+
4570+
// Check if lead is vacuum-braked
4571+
if (lead.BrakeSystem is VacuumSinglePipe || (lead.BrakeSystems?.Any(b => b.Value is VacuumSinglePipe) ?? false) &&
4572+
Cars.Count(c => c.BrakeSystem is VacuumSinglePipe || c.BrakeSystem is ManualBraking ||
4573+
(c.BrakeSystems?.Any(b => b.Value is VacuumSinglePipe || b.Value is ManualBraking) ?? false)) > Cars.Count / 3)
4574+
{
4575+
foreach (var car in Cars.Cast<MSTSWagon>())
4576+
{
4577+
if (car.BrakeSystems?.ContainsKey((BrakeModes.VP, 0)) ?? false) car.SetBrakeSystemMode(BrakeModes.VP, car.MassKG);
4578+
else if (car.BrakeSystems?.ContainsKey((BrakeModes.VB, 0)) ?? false) car.SetBrakeSystemMode(BrakeModes.VB, car.MassKG);
4579+
else if (car.BrakeSystems?.ContainsKey((BrakeModes.VU, 0)) ?? false) car.SetBrakeSystemMode(BrakeModes.VU, car.MassKG);
4580+
}
4581+
}
4582+
else
4583+
{
4584+
foreach (var car in Cars.Cast<MSTSWagon>())
4585+
{
4586+
if (car.BrakeSystems?.ContainsKey((BrakeModes.R_MG, 0)) ?? false) car.SetBrakeSystemMode(BrakeModes.R_MG, car.MassKG);
4587+
else if (car.BrakeSystems?.ContainsKey((BrakeModes.R, 0)) ?? false) car.SetBrakeSystemMode(BrakeModes.R, car.MassKG);
4588+
else if (car.BrakeSystems?.ContainsKey((BrakeModes.P, 0)) ?? false) car.SetBrakeSystemMode(BrakeModes.P, car.MassKG);
4589+
else if (car.BrakeSystems?.ContainsKey((BrakeModes.AP, 0)) ?? false) car.SetBrakeSystemMode(BrakeModes.AP, car.MassKG);
4590+
else if (car.BrakeSystems?.ContainsKey((BrakeModes.G, 0)) ?? false) car.SetBrakeSystemMode(BrakeModes.G, car.MassKG);
4591+
else if (car.BrakeSystems?.ContainsKey((BrakeModes.AG, 0)) ?? false) car.SetBrakeSystemMode(BrakeModes.AG, car.MassKG);
4592+
}
4593+
}
4594+
}
4595+
45814596
public void CalculatePositionOfCars()
45824597
{
45834598
CalculatePositionOfCars(0, 0);

0 commit comments

Comments
 (0)