Skip to content

Commit f9e03fb

Browse files
committed

File tree

5 files changed

+88
-19
lines changed

5 files changed

+88
-19
lines changed

source/CarXMLConvertor/Convert.ExtensionsCfg.cs

+1
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,7 @@ internal static void GenerateCarXML(ref TabbedList newLines, int i)
572572
newLines.Add("<EmergencyRate>" + ConvertTrainDat.BrakeCylinderEmergencyRate + "</EmergencyRate>");
573573
newLines.Add("<ReleaseRate>" + ConvertTrainDat.BrakeCylinderReleaseRate + "</ReleaseRate>");
574574
newLines.Add("</BrakeCylinder>");
575+
newLines.Add("<LegacyPressureDistribution>true</LegacyPressureDistribution>");
575576
newLines.Add("</Brake>");
576577
newLines.Add("<Doors>");
577578
newLines.Add("<Width>" + ConvertTrainDat.DoorWidth / 1000.0 + "</Width>");

source/Plugins/Train.OpenBve/Train/BVE/TrainDatParser.cs

+1
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ internal void Parse(string FileName, Encoding Encoding, TrainBase Train) {
231231
ReadhesionDeviceType ReAdhesionDevice = ReadhesionDeviceType.TypeA;
232232
PassAlarmType passAlarm = PassAlarmType.None;
233233
Train.Handles.HasLocoBrake = false;
234+
Train.Specs.AveragesPressureDistribution = true;
234235
double[] powerDelayUp = { }, powerDelayDown = { }, brakeDelayUp = { }, brakeDelayDown = { }, locoBrakeDelayUp = { }, locoBrakeDelayDown = { };
235236
double electricBrakeDelayUp = 0, electricBrakeDelayDown = 0;
236237
int powerNotches = 0, brakeNotches = 0, locoBrakeNotches = 0, powerReduceSteps = -1, locoBrakeType = 0, driverPowerNotches = 0, driverBrakeNotches = 0;

source/Plugins/Train.OpenBve/Train/XML/TrainXmlParser.BrakeNode.cs

+10
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,16 @@ private void ParseBrakeNode(XmlNode Node, string fileName, int Car, ref TrainBas
230230
case "handle":
231231
ParseHandleNode(c, ref Train.Handles.Brake, Car, Train, fileName);
232232
break;
233+
case "legacypressuredistribution":
234+
if (c.InnerText == "1" || c.InnerText.ToLowerInvariant() == "true")
235+
{
236+
Train.Specs.AveragesPressureDistribution = true;
237+
}
238+
else
239+
{
240+
Train.Specs.AveragesPressureDistribution = false;
241+
}
242+
break;
233243

234244
}
235245
}

source/TrainManager/Train/BrakeSystem.cs

+74-19
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ namespace TrainManager.Trains
66
{
77
public partial class TrainBase
88
{
9+
10+
911
/// <summary>Updates the brake system for the entire train</summary>
1012
/// <param name="TimeElapsed">The frame time elapsed</param>
1113
/// <param name="DecelerationDueToBrake">An array containing the deceleration figures generated by the brake system of each car in the train</param>
@@ -20,41 +22,94 @@ public void UpdateBrakeSystem(double TimeElapsed, out double[] DecelerationDueTo
2022
UpdateBrakeSystem(i, TimeElapsed, out DecelerationDueToBrake[i], out DecelerationDueToMotor[i]);
2123
}
2224

23-
// brake pipe pressure distribution dummy (just averages)
24-
double TotalPressure = 0.0;
25-
for (int i = 0; i < Cars.Length; i++)
25+
if (Specs.AveragesPressureDistribution)
2626
{
27-
if (i > 0)
27+
// brake pipe pressure distribution dummy (just averages)
28+
double TotalPressure = 0.0;
29+
for (int i = 0; i < Cars.Length; i++)
2830
{
29-
if (Cars[i - 1].Derailed | Cars[i].Derailed)
31+
if (i > 0)
3032
{
31-
Cars[i].CarBrake.brakePipe.CurrentPressure -= Cars[i].CarBrake.brakePipe.LeakRate * TimeElapsed;
32-
if (Cars[i].CarBrake.brakePipe.CurrentPressure < 0.0) Cars[i].CarBrake.brakePipe.CurrentPressure = 0.0;
33+
if (Cars[i - 1].Derailed | Cars[i].Derailed)
34+
{
35+
Cars[i].CarBrake.brakePipe.CurrentPressure -= Cars[i].CarBrake.brakePipe.LeakRate * TimeElapsed;
36+
if (Cars[i].CarBrake.brakePipe.CurrentPressure < 0.0) Cars[i].CarBrake.brakePipe.CurrentPressure = 0.0;
37+
}
3338
}
34-
}
3539

36-
if (i < Cars.Length - 1)
37-
{
38-
if (Cars[i].Derailed | Cars[i + 1].Derailed)
40+
if (i < Cars.Length - 1)
3941
{
40-
Cars[i].CarBrake.brakePipe.CurrentPressure -= Cars[i].CarBrake.brakePipe.LeakRate * TimeElapsed;
41-
if (Cars[i].CarBrake.brakePipe.CurrentPressure < 0.0) Cars[i].CarBrake.brakePipe.CurrentPressure = 0.0;
42+
if (Cars[i].Derailed | Cars[i + 1].Derailed)
43+
{
44+
Cars[i].CarBrake.brakePipe.CurrentPressure -= Cars[i].CarBrake.brakePipe.LeakRate * TimeElapsed;
45+
if (Cars[i].CarBrake.brakePipe.CurrentPressure < 0.0) Cars[i].CarBrake.brakePipe.CurrentPressure = 0.0;
46+
}
4247
}
48+
49+
TotalPressure += Cars[i].CarBrake.brakePipe.CurrentPressure;
4350
}
4451

45-
TotalPressure += Cars[i].CarBrake.brakePipe.CurrentPressure;
52+
double averagePressure = TotalPressure / Cars.Length;
53+
for (int i = 0; i < Cars.Length; i++)
54+
{
55+
Cars[i].CarBrake.brakePipe.CurrentPressure = averagePressure;
56+
}
4657
}
47-
48-
double AveragePressure = TotalPressure / Cars.Length;
49-
for (int i = 0; i < Cars.Length; i++)
58+
else
5059
{
51-
Cars[i].CarBrake.brakePipe.CurrentPressure = AveragePressure;
60+
61+
/*
62+
* Notes:
63+
* This algorithm will have a 1 frame (~10ms at 100fps) delay
64+
* in pressure changes rippling down the pipe
65+
*
66+
* For the minute (subject to change), assuming that the charge rate is
67+
* the total from *both* ends of the pipe, so divide by 2
68+
*
69+
*/
70+
71+
int lastMainBrake = 0;
72+
for (int i = 0; i < Cars.Length; i++)
73+
{
74+
Cars[i].CarBrake.brakePipe.CurrentPressure -= Cars[i].CarBrake.brakePipe.LeakRate * TimeElapsed;
75+
if (Cars[i].CarBrake.brakePipe.CurrentPressure < 0.0) Cars[i].CarBrake.brakePipe.CurrentPressure = 0.0;
76+
if (Cars[i].CarBrake.brakeType == BrakeType.Main)
77+
{
78+
// If at the end of the train or a compressor we don't need to flow into it
79+
bool nextCarIsMainBrake = i == Cars.Length || Cars[i + 1].CarBrake.brakeType == BrakeType.Main;
80+
81+
if (i > 0)
82+
{
83+
// Back flow
84+
for (int j = i; j > lastMainBrake; j--)
85+
{
86+
double pressureChange = Math.Min(Cars[j].CarBrake.brakePipe.NormalPressure - Cars[j].CarBrake.brakePipe.CurrentPressure, Cars[j].CarBrake.brakePipe.ChargeRate / 2) * TimeElapsed;
87+
double pressureDiff = Math.Min(pressureChange, Cars[j].CarBrake.brakePipe.CurrentPressure) * TimeElapsed;
88+
Cars[i].CarBrake.brakePipe.CurrentPressure -= pressureDiff;
89+
Cars[j].CarBrake.brakePipe.CurrentPressure += pressureDiff;
90+
}
91+
}
92+
// Forwards flow
93+
for (int j = i; j < Cars.Length; j++)
94+
{
95+
double pressureChange = Math.Min(Cars[j].CarBrake.brakePipe.NormalPressure - Cars[j].CarBrake.brakePipe.CurrentPressure, Cars[j].CarBrake.brakePipe.ChargeRate / 2) * TimeElapsed;
96+
double pressureDiff = Math.Min(pressureChange, Cars[j].CarBrake.brakePipe.CurrentPressure) * TimeElapsed;
97+
Cars[i].CarBrake.brakePipe.CurrentPressure -= pressureDiff;
98+
Cars[j].CarBrake.brakePipe.CurrentPressure += pressureDiff;
99+
if (nextCarIsMainBrake)
100+
{
101+
break;
102+
}
103+
}
104+
lastMainBrake = i;
105+
}
106+
}
52107
}
53108
}
54109

55110
/// <summary>Updates the brake system for a car within this train</summary>
56111
/// <remarks>This must remain a property of the train, for easy access to various base properties</remarks>
57-
/// <param name="CarIndex">The induvidual car</param>
112+
/// <param name="CarIndex">The individual car</param>
58113
/// <param name="TimeElapsed">The frame time elapsed</param>
59114
/// <param name="DecelerationDueToBrake">The total brake deceleration this car provides</param>
60115
/// <param name="DecelerationDueToMotor">The total motor deceleration this car provides</param>

source/TrainManager/Train/TrainSpecs.cs

+2
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,7 @@ public struct TrainSpecs
2020
public DoorMode DoorCloseMode;
2121
/// <summary>Whether door closure has been attempted</summary>
2222
public bool DoorClosureAttempted;
23+
/// <summary>Whether the pressure distribution uses the legacy averages algorithm</summary>
24+
public bool AveragesPressureDistribution;
2325
}
2426
}

0 commit comments

Comments
 (0)