Skip to content

Commit cf3caa0

Browse files
committed
Fix the load stages save/restore
1 parent ccdc633 commit cf3caa0

File tree

5 files changed

+107
-59
lines changed

5 files changed

+107
-59
lines changed

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

Lines changed: 69 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -673,8 +673,9 @@ public virtual void LoadFromWagFile(string wagFilePath)
673673
CentreOfGravityM = InitialCentreOfGravityM;
674674

675675
// Initialize the switchable brake system
676-
if (BrakeModeNames?.Length > 0) // If the filter is set, enforce it
676+
if (BrakeModeNames?.Length > 0)
677677
{
678+
// If the filter is set, enforce it
678679
foreach (var key in BrakeSystems.Keys.ToArray())
679680
if (!BrakeModeNames.Contains(key.BrakeMode.ToString()))
680681
BrakeSystems.Remove(key);
@@ -1055,68 +1056,77 @@ public void SetBrakeSystemMode(BrakeModes mode, float massKg, bool forceSwitch =
10551056

10561057
if (BrakeSystems?.Count > 0)
10571058
{
1059+
// 1) First get the values from the zero load stage / base stage
1060+
if (mode != BrakeSystem.BrakeMode && BrakeSystems.TryGetValue((mode, 0), out var brakeSystem))
1061+
{
1062+
HandleIncompatibleBrakesystems(brakeSystem);
1063+
BrakeSystem.InitializeFromCopy(brakeSystem, true);
1064+
}
1065+
1066+
// 2) Then try to auto-switch to / get values from the appropriate load stage
10581067
var max = 0f;
10591068
foreach (var key in BrakeSystems.Keys)
10601069
if (key.BrakeMode == mode && key.MinMass <= massKg)
10611070
max = Math.Max(max, key.MinMass);
1062-
1063-
if (BrakeSystems.TryGetValue((mode, max), out var brakeSystem))
1071+
if ((BrakeSystem.BrakeMode, BrakeSystem.LoadStageMinMassKg) != (mode, max) && BrakeSystems.TryGetValue((mode, max), out brakeSystem))
10641072
{
1065-
if (brakeSystem is VacuumSinglePipe ^ BrakeSystem is VacuumSinglePipe)
1066-
{
1067-
if (BrakeSystemAlt == null)
1068-
{
1069-
BrakeSystemAlt = BrakeSystem.CreateNewLike(brakeSystem, this).InitializeDefault();
1070-
1071-
// Leave the car in a working state. However the train should reinitialize the car with correct values when all the switchings were finished.
1072-
(var maxPressurePSI, var fullServPressurePSI) = brakeSystem.GetDefaultPressures();
1073-
var handbrakeOn = BrakeSystem.GetHandbrakeStatus();
1074-
var immediateRelease = BrakeSystem.GetCylPressurePSI() == 0;
1075-
BrakeSystemAlt.Initialize(handbrakeOn, maxPressurePSI, fullServPressurePSI, immediateRelease);
1076-
}
1077-
BrakeSystemAlt.FrontBrakeHoseConnected = BrakeSystem.FrontBrakeHoseConnected;
1078-
BrakeSystemAlt.RearBrakeHoseConnected = BrakeSystem.RearBrakeHoseConnected;
1079-
BrakeSystemAlt.AngleCockAOpen = BrakeSystem.AngleCockAOpen;
1080-
BrakeSystemAlt.AngleCockAOpenAmount = BrakeSystem.AngleCockAOpenAmount;
1081-
BrakeSystemAlt.AngleCockAOpenTime = BrakeSystem.AngleCockAOpenTime;
1082-
BrakeSystemAlt.AngleCockBOpen = BrakeSystem.AngleCockBOpen;
1083-
BrakeSystemAlt.AngleCockBOpenAmount = BrakeSystem.AngleCockBOpenAmount;
1084-
BrakeSystemAlt.AngleCockBOpenTime = BrakeSystem.AngleCockBOpenTime;
1085-
BrakeSystemAlt.BleedOffValveOpen = BrakeSystem.BleedOffValveOpen;
1086-
BrakeSystemAlt.TwoPipes = BrakeSystem.TwoPipes;
1087-
1088-
(BrakeSystem, BrakeSystemAlt) = (BrakeSystemAlt, BrakeSystem);
1089-
}
1073+
HandleIncompatibleBrakesystems(brakeSystem);
10901074
BrakeSystem.InitializeFromCopy(brakeSystem, true);
1091-
}
1092-
else
1093-
{
1094-
brakeSystem = BrakeSystem;
1095-
}
10961075

1097-
LoadEmptyMaxHandbrakeForceN = brakeSystem.InitialMaxHandbrakeForceN;
1098-
LoadEmptyMaxBrakeForceN = brakeSystem.MaxBrakeShoeForceN != 0 && BrakeShoeType != BrakeShoeTypes.Unknown ? brakeSystem.MaxBrakeShoeForceN : brakeSystem.InitialMaxBrakeForceN;
1099-
LoadEmptyRelayValveRatio = (brakeSystem as AirSinglePipe)?.RelayValveRatio ?? 0;
1100-
LoadEmptyInshotPSI = (brakeSystem as AirSinglePipe)?.RelayValveInshotPSI ?? 0;
1101-
FrictionBrakeBlendingMaxForceN = brakeSystem.InitialMaxBrakeForceN; // set the value of braking when blended with dynamic brakes
1076+
LoadEmptyMaxHandbrakeForceN = brakeSystem.InitialMaxHandbrakeForceN;
1077+
LoadEmptyMaxBrakeForceN = brakeSystem.MaxBrakeShoeForceN != 0 && BrakeShoeType != BrakeShoeTypes.Unknown ? brakeSystem.MaxBrakeShoeForceN : brakeSystem.InitialMaxBrakeForceN;
1078+
LoadEmptyRelayValveRatio = (brakeSystem as AirSinglePipe)?.RelayValveRatio ?? 0;
1079+
LoadEmptyInshotPSI = (brakeSystem as AirSinglePipe)?.RelayValveInshotPSI ?? 0;
1080+
FrictionBrakeBlendingMaxForceN = brakeSystem.InitialMaxBrakeForceN; // set the value of braking when blended with dynamic brakes
1081+
1082+
// 3) Finally try to find the next load stage for being able to interpolate if necessary
1083+
var next = float.MaxValue;
1084+
foreach (var key in BrakeSystems.Keys)
1085+
if (key.BrakeMode == mode && massKg <= key.MinMass)
1086+
next = Math.Min(next, key.MinMass);
1087+
if (next == float.MaxValue)
1088+
next = max;
1089+
1090+
if (!BrakeSystems.TryGetValue((mode, next), out var brakeSystemNext))
1091+
brakeSystemNext = BrakeSystem;
1092+
1093+
LoadFullMaxHandbrakeForceN = brakeSystemNext.InitialMaxHandbrakeForceN;
1094+
LoadFullMaxBrakeForceN = brakeSystemNext.MaxBrakeShoeForceN != 0 && BrakeShoeType != BrakeShoeTypes.Unknown ? brakeSystemNext.MaxBrakeShoeForceN : brakeSystemNext.InitialMaxBrakeForceN;
1095+
LoadFullRelayValveRatio = (brakeSystemNext as AirSinglePipe)?.RelayValveRatio ?? 0;
1096+
LoadFullInshotPSI = (brakeSystemNext as AirSinglePipe)?.RelayValveInshotPSI ?? 0;
1097+
}
1098+
}
11021099

1103-
var next = float.MaxValue;
1104-
foreach (var key in BrakeSystems.Keys)
1105-
if (key.BrakeMode == mode && massKg <= key.MinMass)
1106-
next = Math.Min(next, key.MinMass);
1107-
if (next == float.MaxValue)
1108-
next = max;
1100+
UpdateBrakeLoadCompensation(TempMassDiffRatio);
1101+
}
11091102

1110-
if (!BrakeSystems.TryGetValue((mode, next), out var brakeSystemNext))
1111-
brakeSystemNext = BrakeSystem;
1103+
void HandleIncompatibleBrakesystems(BrakeSystem newBrakeSystem)
1104+
{
1105+
if (newBrakeSystem is VacuumSinglePipe ^ BrakeSystem is VacuumSinglePipe)
1106+
{
1107+
if (BrakeSystemAlt == null)
1108+
{
1109+
BrakeSystemAlt = BrakeSystem.CreateNewLike(newBrakeSystem, this).InitializeDefault();
11121110

1113-
LoadFullMaxHandbrakeForceN = brakeSystemNext.InitialMaxHandbrakeForceN;
1114-
LoadFullMaxBrakeForceN = brakeSystemNext.MaxBrakeShoeForceN != 0 && BrakeShoeType != BrakeShoeTypes.Unknown ? brakeSystemNext.MaxBrakeShoeForceN : brakeSystemNext.InitialMaxBrakeForceN;
1115-
LoadFullRelayValveRatio = (brakeSystemNext as AirSinglePipe)?.RelayValveRatio ?? 0;
1116-
LoadFullInshotPSI = (brakeSystemNext as AirSinglePipe)?.RelayValveInshotPSI ?? 0;
1111+
// Leave the car in a working state. However the train should reinitialize the car with correct values when all the switchings were finished.
1112+
(var maxPressurePSI, var fullServPressurePSI) = newBrakeSystem.GetDefaultPressures();
1113+
var handbrakeOn = BrakeSystem.GetHandbrakeStatus();
1114+
var immediateRelease = BrakeSystem.GetCylPressurePSI() == 0;
1115+
BrakeSystemAlt.Initialize(handbrakeOn, maxPressurePSI, fullServPressurePSI, immediateRelease);
1116+
}
1117+
BrakeSystemAlt.FrontBrakeHoseConnected = BrakeSystem.FrontBrakeHoseConnected;
1118+
BrakeSystemAlt.RearBrakeHoseConnected = BrakeSystem.RearBrakeHoseConnected;
1119+
BrakeSystemAlt.AngleCockAOpen = BrakeSystem.AngleCockAOpen;
1120+
BrakeSystemAlt.AngleCockAOpenAmount = BrakeSystem.AngleCockAOpenAmount;
1121+
BrakeSystemAlt.AngleCockAOpenTime = BrakeSystem.AngleCockAOpenTime;
1122+
BrakeSystemAlt.AngleCockBOpen = BrakeSystem.AngleCockBOpen;
1123+
BrakeSystemAlt.AngleCockBOpenAmount = BrakeSystem.AngleCockBOpenAmount;
1124+
BrakeSystemAlt.AngleCockBOpenTime = BrakeSystem.AngleCockBOpenTime;
1125+
BrakeSystemAlt.BleedOffValveOpen = BrakeSystem.BleedOffValveOpen;
1126+
BrakeSystemAlt.TwoPipes = BrakeSystem.TwoPipes;
1127+
1128+
(BrakeSystem, BrakeSystemAlt) = (BrakeSystemAlt, BrakeSystem);
11171129
}
1118-
1119-
UpdateBrakeLoadCompensation(TempMassDiffRatio);
11201130
}
11211131

11221132
// Compute total mass of wagon including freight animations and variable loads like containers
@@ -1422,7 +1432,6 @@ public virtual void Parse(string lowercasetoken, STFReader stf)
14221432
}
14231433
break;
14241434
case "wagon(ortsbrakemode(ortsloadstage":
1425-
var minMass = 0f;
14261435
var stage = BrakeSystem.CreateNewLike(newSystem, this).InitializeDefault();
14271436
stage.BrakeMode = newSystem.BrakeMode;
14281437
stf.VerifyStartOfBlock();
@@ -1432,7 +1441,7 @@ public virtual void Parse(string lowercasetoken, STFReader stf)
14321441
lowercasetoken = stf.Tree.ToLower();
14331442
switch (lowercasetoken)
14341443
{
1435-
case "wagon(ortsbrakemode(ortsloadstage(ortsloadstageminmass": minMass = stf.ReadFloatBlock(STFReader.UNITS.Mass, null); break;
1444+
case "wagon(ortsbrakemode(ortsloadstage(ortsloadstageminmass": stage.LoadStageMinMassKg = stf.ReadFloatBlock(STFReader.UNITS.Mass, null); break;
14361445
default:
14371446
if (lowercasetoken.EndsWith("("))
14381447
{
@@ -1446,10 +1455,10 @@ public virtual void Parse(string lowercasetoken, STFReader stf)
14461455
break;
14471456
}
14481457
}
1449-
if (!BrakeSystems.ContainsKey((newSystem.BrakeMode, minMass)))
1450-
BrakeSystems.Add((newSystem.BrakeMode, minMass), stage);
1458+
if (!BrakeSystems.ContainsKey((newSystem.BrakeMode, stage.LoadStageMinMassKg)))
1459+
BrakeSystems.Add((newSystem.BrakeMode, stage.LoadStageMinMassKg), stage);
14511460
else
1452-
BrakeSystems[(newSystem.BrakeMode, minMass)].InitializeFromCopy(stage, true);
1461+
BrakeSystems[(newSystem.BrakeMode, stage.LoadStageMinMassKg)].InitializeFromCopy(stage, true);
14531462
break;
14541463
default:
14551464
if (lowercasetoken.EndsWith("("))
@@ -1886,6 +1895,7 @@ public virtual void Copy(MSTSWagon copy)
18861895
BrakeSystems.Add(key, copySystem);
18871896
}
18881897
BrakeModeNames = copy.BrakeModeNames.Clone() as string[];
1898+
TempMassDiffRatio = copy.TempMassDiffRatio;
18891899

18901900
if (copy.WeightLoadController != null) WeightLoadController = new MSTSNotchController(copy.WeightLoadController);
18911901

@@ -2033,6 +2043,7 @@ public override void Save(BinaryWriter outf)
20332043
}
20342044

20352045
LocomotiveAxles.Save(outf);
2046+
outf.Write(TempMassDiffRatio);
20362047

20372048
base.Save(outf);
20382049
}
@@ -2091,6 +2102,7 @@ public override void Restore(BinaryReader inf)
20912102

20922103
MoveParamsToAxle();
20932104
LocomotiveAxles.Restore(inf);
2105+
TempMassDiffRatio = inf.ReadSingle();
20942106

20952107
base.Restore(inf);
20962108
}

Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/BrakeSystem.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ public abstract class BrakeSystem
8080
public float InitialMaxBrakeForceN; // Initial force when the wagon initialised, this is the force on the wheel, ie after the brake shoe.
8181

8282
public BrakeModes BrakeMode;
83+
public float LoadStageMinMassKg;
8384

8485
protected TrainCar Car;
8586

Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/AirSinglePipe.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,9 @@ public override void InitializeFromCopy(BrakeSystem copy, bool diff)
268268
BrakeMode = diff && thiscopy.BrakeMode == default ? BrakeMode : thiscopy.BrakeMode;
269269
BrakeMass = diff && thiscopy.BrakeMass == default ? BrakeMass : thiscopy.BrakeMass;
270270
MaxBrakeShoeForceN = diff && thiscopy.MaxBrakeShoeForceN == default ? MaxBrakeShoeForceN : thiscopy.MaxBrakeShoeForceN;
271+
InitialMaxHandbrakeForceN = diff && thiscopy.InitialMaxHandbrakeForceN == default ? InitialMaxHandbrakeForceN : thiscopy.InitialMaxHandbrakeForceN;
272+
InitialMaxBrakeForceN = diff && thiscopy.InitialMaxBrakeForceN == default ? InitialMaxBrakeForceN : thiscopy.InitialMaxBrakeForceN;
273+
LoadStageMinMassKg = diff && thiscopy.LoadStageMinMassKg == default ? LoadStageMinMassKg : thiscopy.LoadStageMinMassKg;
271274

272275
}
273276

@@ -301,7 +304,12 @@ public override BrakeSystem InitializeDefault()
301304
UniformReleaseThresholdPSI = default;
302305
AcceleratedApplicationLimitPSIpS = default;
303306
AcceleratedEmergencyReleaseThresholdPSI = default;
307+
BrakeMode = default;
304308
BrakeMass = default;
309+
MaxBrakeShoeForceN = default;
310+
InitialMaxHandbrakeForceN = default;
311+
InitialMaxBrakeForceN = default;
312+
LoadStageMinMassKg = default;
305313

306314
return base.InitializeDefault();
307315
}
@@ -529,6 +537,12 @@ public override void Save(BinaryWriter outf)
529537
outf.Write(EmergResQuickReleaseActive);
530538
outf.Write(TwoStageLowSpeedActive);
531539
outf.Write(LegacyEmergencyValve);
540+
outf.Write((int)BrakeMode);
541+
outf.Write(BrakeMass);
542+
outf.Write(MaxBrakeShoeForceN);
543+
outf.Write(InitialMaxHandbrakeForceN);
544+
outf.Write(InitialMaxBrakeForceN);
545+
outf.Write(LoadStageMinMassKg);
532546
}
533547

534548
public override void Restore(BinaryReader inf)
@@ -568,6 +582,12 @@ public override void Restore(BinaryReader inf)
568582
EmergResQuickReleaseActive = inf.ReadBoolean();
569583
TwoStageLowSpeedActive = inf.ReadBoolean();
570584
LegacyEmergencyValve = inf.ReadBoolean();
585+
BrakeMode = (BrakeModes)inf.ReadInt32();
586+
BrakeMass = inf.ReadSingle();
587+
MaxBrakeShoeForceN = inf.ReadSingle();
588+
InitialMaxHandbrakeForceN = inf.ReadSingle();
589+
InitialMaxBrakeForceN = inf.ReadSingle();
590+
LoadStageMinMassKg = inf.ReadSingle();
571591
}
572592

573593
public override void Initialize(bool handbrakeOn, float maxPressurePSI, float fullServPressurePSI, bool immediateRelease)

Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/VacuumSinglePipe.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ public override void InitializeFromCopy(BrakeSystem copy, bool diff)
9696
VacResVolM3 = diff && thiscopy.VacResVolM3 == default ? VacResVolM3 : thiscopy.VacResVolM3;
9797
HasDirectAdmissionValue = diff && thiscopy.HasDirectAdmissionValue == default ? HasDirectAdmissionValue : thiscopy.HasDirectAdmissionValue;
9898
BrakeMode = diff && thiscopy.BrakeMode == default ? BrakeMode : thiscopy.BrakeMode;
99+
MaxBrakeShoeForceN = diff && thiscopy.MaxBrakeShoeForceN == default ? MaxBrakeShoeForceN : thiscopy.MaxBrakeShoeForceN;
100+
InitialMaxHandbrakeForceN = diff && thiscopy.InitialMaxHandbrakeForceN == default ? InitialMaxHandbrakeForceN : thiscopy.InitialMaxHandbrakeForceN;
101+
InitialMaxBrakeForceN = diff && thiscopy.InitialMaxBrakeForceN == default ? InitialMaxBrakeForceN : thiscopy.InitialMaxBrakeForceN;
99102
}
100103

101104
public override BrakeSystem InitializeDefault()
@@ -125,6 +128,10 @@ public override BrakeSystem InitializeDefault()
125128
SteamBrakeCylinderPressurePSI = default;
126129
SteamBrakeCompensation = default;
127130
SteamBrakingCurrentFraction = default;
131+
BrakeMode = default;
132+
MaxBrakeShoeForceN = default;
133+
InitialMaxHandbrakeForceN = default;
134+
InitialMaxBrakeForceN = default;
128135

129136
return base.InitializeDefault();
130137
}
@@ -315,6 +322,10 @@ public override void Save(BinaryWriter outf)
315322
outf.Write(AngleCockAOpen);
316323
outf.Write(AngleCockBOpen);
317324
outf.Write(BleedOffValveOpen);
325+
outf.Write((int)BrakeMode);
326+
outf.Write(MaxBrakeShoeForceN);
327+
outf.Write(InitialMaxHandbrakeForceN);
328+
outf.Write(InitialMaxBrakeForceN);
318329
}
319330

320331
public override void Restore(BinaryReader inf)
@@ -329,6 +340,10 @@ public override void Restore(BinaryReader inf)
329340
AngleCockAOpen = inf.ReadBoolean();
330341
AngleCockBOpen = inf.ReadBoolean();
331342
BleedOffValveOpen = inf.ReadBoolean();
343+
BrakeMode = (BrakeModes)inf.ReadInt32();
344+
MaxBrakeShoeForceN = inf.ReadSingle();
345+
InitialMaxHandbrakeForceN = inf.ReadSingle();
346+
InitialMaxBrakeForceN = inf.ReadSingle();
332347
}
333348

334349
public override void Initialize(bool handbrakeOn, float maxVacuumInHg, float fullServVacuumInHg, bool immediateRelease)

Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2185,7 +2185,7 @@ public virtual void Save(BinaryWriter outf)
21852185
{
21862186
foreach (var key in BrakeSystems.Keys)
21872187
{
2188-
outf.Write(key.BrakeMode.ToString());
2188+
outf.Write((int)key.BrakeMode);
21892189
outf.Write(key.MinMass);
21902190
BrakeSystems[key].Save(outf);
21912191
}
@@ -2220,7 +2220,7 @@ public virtual void Restore(BinaryReader inf)
22202220
CarHeatCompartmentHeaterOn = inf.ReadBoolean();
22212221
for (var i = 0; i < inf.ReadInt32(); i++)
22222222
{
2223-
Enum.TryParse(inf.ReadString(), out BrakeModes mode);
2223+
var mode = (BrakeModes)inf.ReadInt32();
22242224
var minMass = inf.ReadSingle();
22252225
BrakeSystem bs = null;
22262226
bs.Restore(inf);

0 commit comments

Comments
 (0)