@@ -261,6 +261,9 @@ public class MSTSSteamLocomotive : MSTSLocomotive
261
261
float MSTSBoilerLengthM;
262
262
float ORBoilerLengthM;
263
263
float BoilerLengthM;
264
+ float BoilerDiameterM;
265
+ float BoilerCrownCoverageHeightM;
266
+ float BoilerCrownHeightM;
264
267
public float GradientBoilerLevelPercent;
265
268
public int MSTSNumCylinders = 2; // Number of Cylinders
266
269
public float MSTSCylinderStrokeM; // High pressure cylinders
@@ -955,6 +958,9 @@ public override void Parse(string lowercasetoken, STFReader stf)
955
958
case "engine(boilervolume": BoilerVolumeFT3 = stf.ReadFloatBlock(STFReader.UNITS.VolumeDefaultFT3, null); break;
956
959
case "engine(boilerlength": MSTSBoilerLengthM = stf.ReadFloatBlock(STFReader.UNITS.Distance, null); break;
957
960
case "engine(ortsboilerlength": ORBoilerLengthM = stf.ReadFloatBlock(STFReader.UNITS.Distance, null); break;
961
+ case "engine(ortsboilerdiameter": BoilerDiameterM = stf.ReadFloatBlock(STFReader.UNITS.Distance, null); break;
962
+ case "engine(ortsboilercrownheight": BoilerCrownHeightM = stf.ReadFloatBlock(STFReader.UNITS.Distance, null); break;
963
+ case "engine(ortsboilercrowncoverageheight": BoilerCrownCoverageHeightM = stf.ReadFloatBlock(STFReader.UNITS.Distance, null); break;
958
964
case "engine(steamgaugeglassheight": MSTSSteamGaugeGlassHeightM = stf.ReadFloatBlock(STFReader.UNITS.Distance, null); break;
959
965
case "engine(ortswatergaugeglassheight": ORSteamGaugeGlassHeightM = stf.ReadFloatBlock(STFReader.UNITS.Distance, null); break;
960
966
case "engine(maxboilerpressure": MaxBoilerPressurePSI = stf.ReadFloatBlock(STFReader.UNITS.PressureDefaultPSI, null); break;
@@ -1105,6 +1111,8 @@ public override void Copy(MSTSWagon copy)
1105
1111
BoilerVolumeFT3 = locoCopy.BoilerVolumeFT3;
1106
1112
MSTSBoilerLengthM = locoCopy.MSTSBoilerLengthM;
1107
1113
ORBoilerLengthM = locoCopy.ORBoilerLengthM;
1114
+ BoilerCrownHeightM = locoCopy.BoilerCrownHeightM;
1115
+ BoilerCrownCoverageHeightM = locoCopy.BoilerCrownCoverageHeightM;
1108
1116
MSTSSteamGaugeGlassHeightM = locoCopy.MSTSSteamGaugeGlassHeightM;
1109
1117
ORSteamGaugeGlassHeightM = locoCopy.ORSteamGaugeGlassHeightM;
1110
1118
MaxBoilerPressurePSI = locoCopy.MaxBoilerPressurePSI;
@@ -1520,13 +1528,24 @@ public override void Initialize()
1520
1528
}
1521
1529
*/
1522
1530
1531
+ if (ORBoilerLengthM > 0 && ORSteamGaugeGlassHeightM > 0 && BoilerDiameterM == 0)
1532
+ {
1533
+ BoilerDiameterM = 2.0f;
1523
1534
1524
- if (WaterGlassLengthM > 0 && BoilerLengthM > 0 )
1535
+ if (Simulator.Settings.VerboseConfigurationMessages)
1536
+ {
1537
+ Trace.TraceInformation("Boiler diameter set to default = {0}", FormatStrings.FormatDistance(BoilerCrownCoverageHeightM, IsMetric));
1538
+ }
1539
+ }
1540
+
1541
+ if (WaterGlassLengthM > 0 && BoilerLengthM > 0 && ORBoilerLengthM > 0 && BoilerCrownHeightM > 0 && BoilerCrownCoverageHeightM >0)
1525
1542
{
1526
1543
WaterGlassLevelGradientEnabled = true;
1527
1544
}
1528
1545
1529
- // Trace.TraceInformation("Boiler Water Level - MSTSLength {0} ORLength {1} MSTSGlass {2} OR Glass {3} Enabled {4}, WaterGlass {5} BoilerLength {6}", MSTSBoilerLengthM, ORBoilerLengthM, MSTSSteamGaugeGlassHeightM, ORSteamGaugeGlassHeightM, WaterGlassLevelGradientEnabled, WaterGlassLengthM, BoilerLengthM);
1546
+ Trace.TraceInformation("Boiler - CrownHeight {0} CrownCoverage {1}", BoilerCrownHeightM, BoilerCrownCoverageHeightM);
1547
+
1548
+ // Trace.TraceInformation("Boiler Water Level - MSTSLength {0} ORLength {1} MSTSGlass {2} OR Glass {3} Enabled {4}, WaterGlass {5} BoilerLength {6}", MSTSBoilerLengthM, ORBoilerLengthM, MSTSSteamGaugeGlassHeightM, ORSteamGaugeGlassHeightM, WaterGlassLevelGradientEnabled, WaterGlassLengthM, BoilerLengthM);
1530
1549
1531
1550
float BoilerVolumeCheck = Me2.ToFt2(EvaporationAreaM2) / BoilerVolumeFT3; //Calculate the Boiler Volume Check value.
1532
1551
if (BoilerVolumeCheck > 15) // If boiler volume is not in ENG file or less then a viable figure (ie high ratio figure), then set to a default value
@@ -7098,6 +7117,56 @@ private void UpdateAuxiliaries(float elapsedClockSeconds, float absSpeedMpS)
7098
7117
7099
7118
private void UpdateWaterGauge()
7100
7119
{
7120
+ // Calculate water glass level when on gradient
7121
+ if (WaterGlassLevelGradientEnabled)
7122
+ {
7123
+ var boilerangleRad = Math.Atan(CurrentElevationPercent / 100);
7124
+ var waterVariationLevelM = (float)Math.Sin(boilerangleRad) * BoilerLengthM / 2.0f;
7125
+
7126
+ float glassLevelGradientM = 0;
7127
+
7128
+ // Downslope - CurrentElevationPercent = +ve, level variation will be -ve
7129
+ // Uphill - CurrentElevationPercent = -ve, level variation will be +ve
7130
+ // gradient variation due to slope needs to be reversed
7131
+
7132
+ glassLevelGradientM = waterVariationLevelM * -1.0f;
7133
+
7134
+ // Assume that reference glass height is 50% of glass
7135
+ var maxWaterVariationIN = Me.ToIn(WaterGlassLengthM) / 2.0f;
7136
+
7137
+ float glasslevelfraction = 0;
7138
+ float glasslevelM = 0;
7139
+
7140
+ // Calculate water level on level gradient
7141
+ var referenceLevelFraction = (BoilerCrownCoverageHeightM + BoilerCrownHeightM + BoilerDiameterM / 2.0f)/BoilerDiameterM;
7142
+
7143
+ // Convert reference point to reading on glass
7144
+ if (WaterFraction > referenceLevelFraction)
7145
+ {
7146
+ glasslevelfraction = WaterFraction - referenceLevelFraction;
7147
+
7148
+ }
7149
+ else if (WaterFraction < referenceLevelFraction)
7150
+ {
7151
+ glasslevelfraction = -1.0f * referenceLevelFraction - WaterFraction;
7152
+ }
7153
+
7154
+ glasslevelM = glasslevelfraction * BoilerDiameterM;
7155
+
7156
+
7157
+ var totalglassLevelM = glasslevelM + glassLevelGradientM;
7158
+
7159
+ GradientBoilerLevelPercent = totalglassLevelM * 100;
7160
+
7161
+ // Trace.TraceInformation("Gradient - Current {0} BoilAng {1} GlassIN {2} Glass% {3}", CurrentElevationPercent, boilerangleRad, glasslevelIN, GradientBoilerLevelPercent);
7162
+
7163
+ // Trace.TraceInformation("Boiler - refLevel {0} GlassLevel {1} GlassLevelM {2} GradientLevel {3} TotalLevel {4} % {5}", referenceLevelFraction, glasslevelfraction, glasslevelM, glassLevelGradientM, totalglassLevelM, GradientBoilerLevelPercent);
7164
+
7165
+ }
7166
+
7167
+
7168
+
7169
+
7101
7170
WaterGlassLevelIN = ((WaterFraction - WaterGlassMinLevel) / (WaterGlassMaxLevel - WaterGlassMinLevel)) * WaterGlassLengthIN;
7102
7171
WaterGlassLevelIN = MathHelper.Clamp(WaterGlassLevelIN, 0, WaterGlassLengthIN);
7103
7172
@@ -7124,33 +7193,7 @@ private void UpdateWaterGauge()
7124
7193
BoilerIsPriming = false;
7125
7194
}
7126
7195
7127
- // Calculate water glass level when on gradient
7128
- if (WaterGlassLevelGradientEnabled)
7129
- {
7130
- var boilerangleRad = Math.Atan(CurrentElevationPercent / 100);
7131
- var waterVariationLevelM = (float)Math.Sin(boilerangleRad) * BoilerLengthM / 2.0f;
7132
-
7133
- // Assume that reference glass height is 50% of glass
7134
- var maxWaterVariationIN = Me.ToIn(WaterGlassLengthM) / 2.0f;
7135
7196
7136
- float glasslevelIN = 0;
7137
- float glassLevelFraction = 0;
7138
-
7139
- if (CurrentElevationPercent > 0) // Downslope - -ve water slope
7140
- {
7141
- glasslevelIN -= Me.ToIn(waterVariationLevelM) * -1.0f;
7142
- }
7143
- else // up slope - +ve water level
7144
- {
7145
- glasslevelIN += Me.ToIn(waterVariationLevelM) * -1.0f;
7146
- }
7147
-
7148
- glassLevelFraction = glasslevelIN / maxWaterVariationIN;
7149
-
7150
- GradientBoilerLevelPercent = glassLevelFraction * 100;
7151
-
7152
- // Trace.TraceInformation("Gradient - Current {0} BoilAng {1} GlassIN {2} Glass% {3}", CurrentElevationPercent, boilerangleRad, glasslevelIN, GradientBoilerLevelPercent);
7153
- }
7154
7197
7155
7198
7156
7199
}
0 commit comments