Skip to content

Commit 0fb4d1c

Browse files
committed
Add operating logic and steam effects to Booster engine.
1 parent 234b167 commit 0fb4d1c

File tree

2 files changed

+117
-21
lines changed

2 files changed

+117
-21
lines changed

Source/Orts.Simulation/Simulation/RollingStocks/MSTSSteamLocomotive.cs

Lines changed: 106 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,14 @@ public class MSTSSteamLocomotive : MSTSLocomotive
132132
public bool SteamBoosterAirOpen = false;
133133
public bool SteamBoosterRunMode = false;
134134
public bool SteamBoosterIdleMode = false;
135+
public bool BoosterGearsEngaged = false;
135136
public bool SteamBoosterLatchedLocked = false;
136137
float BoosterGearEngageTimeS;
137-
float BoosterIdleTimeS;
138-
float BoosterGearEngageTimeStartS;
138+
float BoosterIdleHeatingTimerS;
139+
float BoosterIdleHeatingTimePeriodS = 120; // This is the time period that the Booster needs to be idled to heat it up
140+
bool BoosterIdleHeatingTimerReset = false;
141+
float BoosterGearEngageTimePeriodS;
142+
float BoosterGearSyncTimePeriodS = 6; // This is the time period that the gears take to mesh, once the throttle is opened.
139143
public float HuDBoosterSteamConsumptionLbpS;
140144
public float BoosterSteamConsumptionLbpS;
141145
float BoosterIdleChokeSizeIn;
@@ -664,6 +668,17 @@ public float TenderCoalMassKG // Decreased by firing and increased
664668
bool CylinderSteamExhaust3On = false;
665669
bool CylinderSteamExhaust4On = false;
666670

671+
bool BoosterCylinderSteamExhaustOn = false;
672+
public float BoosterCylinderSteamExhaust01SteamVelocityMpS;
673+
public float BoosterCylinderSteamExhaust01SteamVolumeM3pS;
674+
public float BoosterCylinderSteamExhaust02SteamVelocityMpS;
675+
public float BoosterCylinderSteamExhaust02SteamVolumeM3pS;
676+
677+
float BoosterCylinderCockTimerS = 0.0f;
678+
float BoosterCylinderCockOpenTimePeriodS = 0.0f;
679+
bool BoosterCylinderCock01On = false;
680+
bool BoosterCylinderCock02On = false;
681+
667682
public float BlowdownSteamVolumeM3pS;
668683
public float BlowdownSteamVelocityMpS;
669684
public float BlowdownParticleDurationS = 3.0f;
@@ -2217,52 +2232,92 @@ public override void Update(float elapsedClockSeconds)
22172232
}
22182233
else if (SteamEngines[i].AuxiliarySteamEngineType == SteamEngine.AuxiliarySteamEngineTypes.Booster) // Booster Engine
22192234
{
2220-
2235+
bool BoosterAirisLow = false;
2236+
if (MainResPressurePSI < 70)
2237+
{
2238+
BoosterAirisLow = true;
2239+
}
2240+
22212241
var boostercutoff = SteamEngines[i].BoosterCutoff;
22222242

22232243
// Confirm that Latch is on
22242244
if (SteamBoosterLatchOn && cutoff > SteamEngines[i].BoosterThrottleCutoff)
22252245
{
2226-
SteamBoosterLatchedLocked = true;
2246+
if (SteamBoosterLatchedLocked == false)
2247+
{
2248+
SteamBoosterLatchedLocked = true;
2249+
}
22272250
}
22282251
else
22292252
{
2230-
SteamBoosterLatchedLocked = false;
2253+
if (SteamBoosterLatchedLocked == true)
2254+
{
2255+
SteamBoosterLatchedLocked = false;
2256+
}
22312257
}
22322258

22332259
// Identify operating mode for the Booster
22342260
// Idle mode
2235-
if (SteamBoosterAirOpen && !SteamBoosterIdle)
2261+
if (SteamBoosterAirOpen && !SteamBoosterIdle && !BoosterAirisLow)
22362262
{
22372263
SteamBoosterRunMode = false;
22382264
SteamBoosterIdleMode = true;
2265+
BoosterGearsEngaged = false;
2266+
BoosterCylinderSteamExhaustOn = true;
22392267
enginethrottle = 0.0f;
22402268
BoosterGearEngageTimeS = 0;
2269+
2270+
// Allow time for cylinders to heat up
2271+
if (!BoosterIdleHeatingTimerReset)
2272+
{
2273+
if (BoosterIdleHeatingTimerS > BoosterIdleHeatingTimePeriodS)
2274+
{
2275+
BoosterIdleHeatingTimerReset = true; // Stop Idle heating timer
2276+
}
2277+
BoosterIdleHeatingTimerS += elapsedClockSeconds;
2278+
2279+
// Booster needs to be idled (heated) for approx this period of time before engaging the gears in Run mode
2280+
BoosterGearEngageTimePeriodS = BoosterIdleHeatingTimePeriodS + BoosterGearSyncTimePeriodS - BoosterIdleHeatingTimerS;
2281+
}
2282+
2283+
// Trace.TraceInformation("Idle Mode - Timer {0} GearPeriod {1} Reset {2} BoosterHeating {3} Sync {4}", BoosterIdleHeatingTimerS, BoosterGearEngageTimePeriodS, BoosterIdleHeatingTimerReset, BoosterIdleHeatingTimePeriodS, BoosterGearSyncTimePeriodS);
22412284
}
22422285
// Run mode
2243-
else if (SteamBoosterAirOpen && SteamBoosterIdle && SteamBoosterLatchedLocked)
2286+
else if (SteamBoosterAirOpen && SteamBoosterIdle && SteamBoosterLatchedLocked && !BoosterAirisLow && throttle > 0.01)
22442287
{
2245-
if (BoosterGearEngageTimeS > 6)
2288+
SteamBoosterIdleMode = false;
2289+
SteamBoosterRunMode = true;
2290+
2291+
// Trace.TraceInformation("Run Mode - Timer {0} GearPeriod {1}", BoosterGearEngageTimeS, BoosterGearEngageTimePeriodS);
2292+
2293+
if (BoosterGearEngageTimeS > BoosterGearEngageTimePeriodS)
22462294
{
2247-
SteamBoosterIdleMode = false;
2248-
SteamBoosterRunMode = true;
22492295
enginethrottle = throttle;
2296+
BoosterCylinderSteamExhaustOn = false;
2297+
BoosterGearsEngaged = true;
2298+
BoosterIdleHeatingTimerReset = false;
2299+
BoosterIdleHeatingTimerS = 0;
2300+
// Trace.TraceInformation("Run Mode - " );
22502301
}
2251-
BoosterGearEngageTimeS += elapsedClockSeconds;
2302+
BoosterGearEngageTimeS += elapsedClockSeconds;
22522303
}
22532304
else if (!SteamBoosterAirOpen || !SteamBoosterLatchedLocked) // Turn Booster off completely
22542305
{
22552306
SteamBoosterRunMode = false;
22562307
SteamBoosterIdleMode = false;
2308+
BoosterCylinderSteamExhaustOn = false;
22572309
enginethrottle = 0;
22582310
BoosterGearEngageTimeS = 0;
2259-
BoosterIdleTimeS = 0;
2311+
BoosterIdleHeatingTimerReset = false;
2312+
BoosterCylinderSteamExhaustOn = false;
2313+
BoosterGearsEngaged = false;
2314+
BoosterIdleHeatingTimerS = 0;
22602315
}
22612316

2262-
UpdateCylinders(elapsedClockSeconds, enginethrottle, boostercutoff, absSpeedMpS, i);
2317+
UpdateCylinders(elapsedClockSeconds, enginethrottle, boostercutoff, absSpeedMpS, i);
22632318

2264-
// Update Booster steam consumption
2265-
if (SteamBoosterIdleMode)
2319+
// Update Booster steam consumption
2320+
if (SteamBoosterIdleMode)
22662321
{
22672322
// In Idle mode steam consumption will be calculated by steam through an orifice.
22682323
// Steam Flow (lb/hr) = 24.24 x Press(BoilerPressure + Atmosphere(psi)) x ChokeDia^2 (in) - this needs to be multiplied by Num Cyls
@@ -2276,7 +2331,7 @@ public override void Update(float elapsedClockSeconds)
22762331
// In run mode steam consumption calculated by cylinder model
22772332
HuDBoosterSteamConsumptionLbpS = SteamEngines[i].CylinderSteamUsageLBpS;
22782333
}
2279-
2334+
22802335

22812336
}
22822337
BoilerMassLB -= elapsedClockSeconds * SteamEngines[i].CylinderSteamUsageLBpS; // Boiler mass will be reduced by cylinder steam usage
@@ -2302,7 +2357,7 @@ public override void Update(float elapsedClockSeconds)
23022357
{
23032358
tractiveforcethrottle = enginethrottle;
23042359
}
2305-
else if (SteamBoosterIdleMode || !SteamBoosterAirOpen)
2360+
else if ((SteamBoosterIdleMode || !SteamBoosterAirOpen) && !BoosterGearsEngaged)
23062361
{
23072362
// Booster produces no output force
23082363
tractiveforcethrottle = 0;
@@ -2600,6 +2655,29 @@ private void UpdateFX(float elapsedClockSeconds)
26002655
}
26012656
}
26022657

2658+
2659+
if (BoosterCylinderSteamExhaustOn) // For Booster engine
2660+
{
2661+
BoosterCylinderCockOpenTimePeriodS = 0.5f * 1.0f / DrvWheelRevRpS; // Calculate how long cylinder cocks open @ speed = Time (sec) / (Drv Wheel RpS ) - assume two cylinder strokes per rev, ie each cock will only be open for 1/2 rev
2662+
CylinderCockTimerS += elapsedClockSeconds;
2663+
if (BoosterCylinderCockTimerS > BoosterCylinderCockOpenTimePeriodS)
2664+
{
2665+
if (BoosterCylinderCock01On)
2666+
{
2667+
BoosterCylinderCock01On = false;
2668+
BoosterCylinderCock02On = true;
2669+
BoosterCylinderCockTimerS = 0.0f; // Reset timer
2670+
}
2671+
else if (BoosterCylinderCock02On)
2672+
{
2673+
BoosterCylinderCock01On = true;
2674+
BoosterCylinderCock02On = false;
2675+
BoosterCylinderCockTimerS = 0.0f; // Reset timer
2676+
2677+
}
2678+
}
2679+
}
2680+
26032681
float SteamEffectsFactor = MathHelper.Clamp(BoilerPressurePSI / MaxBoilerPressurePSI, 0.1f, 1.0f); // Factor to allow for drops in boiler pressure reducing steam effects
26042682

26052683
// Bernoulli formula for future reference - steam velocity = SQRT ( 2 * dynamic pressure (pascals) / fluid density)
@@ -2628,6 +2706,13 @@ private void UpdateFX(float elapsedClockSeconds)
26282706
CylinderSteamExhaustSteamVelocityMpS = 100.0f;
26292707
CylinderSteamExhaustParticleDurationS = 1.0f;
26302708

2709+
// Booster Cylinder Cocks (automatic)
2710+
BoosterCylinderSteamExhaust01SteamVolumeM3pS = throttle > 0.0 && BoosterCylinderCock01On ? (cutoff * 10.0f * SteamEffectsFactor) : 0.0f;
2711+
BoosterCylinderSteamExhaust01SteamVelocityMpS = 100.0f;
2712+
2713+
BoosterCylinderSteamExhaust02SteamVolumeM3pS = throttle > 0.0 && BoosterCylinderCock02On ? (cutoff * 10.0f * SteamEffectsFactor) : 0.0f;
2714+
BoosterCylinderSteamExhaust02SteamVelocityMpS = 100.0f;
2715+
26312716
// Blowdown Steam Effects
26322717
BlowdownSteamVolumeM3pS = (BlowdownValveOpen && BlowdownSteamUsageLBpS > 0.0 ? (10.0f * SteamEffectsFactor) : 0.0f);
26332718
BlowdownSteamVelocityMpS = 350.0f;
@@ -6840,7 +6925,7 @@ public override string GetDebugStatus()
68406925
}
68416926
}
68426927

6843-
status.AppendFormat("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}\t{11}\t{12}\n",
6928+
status.AppendFormat("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}\t{11}\t{12}\t{13}\t{14}\n",
68446929
Simulator.Catalog.GetString("Status:"),
68456930
Simulator.Catalog.GetString("Safety"),
68466931
SafetyIsOn ? Simulator.Catalog.GetString("Open") : Simulator.Catalog.GetString("Closed"),
@@ -6853,7 +6938,9 @@ public override string GetDebugStatus()
68536938
Simulator.Catalog.GetString("BoostIdle"),
68546939
SteamBoosterIdleMode ? Simulator.Catalog.GetString("On") : Simulator.Catalog.GetString("Off"),
68556940
Simulator.Catalog.GetString("BoostRun"),
6856-
SteamBoosterRunMode ? Simulator.Catalog.GetString("On") : Simulator.Catalog.GetString("Off")
6941+
SteamBoosterRunMode ? Simulator.Catalog.GetString("On") : Simulator.Catalog.GetString("Off"),
6942+
Simulator.Catalog.GetString("BoostGear"),
6943+
BoosterGearsEngaged ? Simulator.Catalog.GetString("On") : Simulator.Catalog.GetString("Off")
68576944
);
68586945

68596946
#if DEBUG_LOCO_STEAM_USAGE

Source/RunActivity/Viewer3D/RollingStock/MSTSSteamLocomotiveViewer.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ public class MSTSSteamLocomotiveViewer : MSTSLocomotiveViewer
4848
List<ParticleEmitterViewer> CylinderSteamExhaust2 = new List<ParticleEmitterViewer>();
4949
List<ParticleEmitterViewer> CylinderSteamExhaust3 = new List<ParticleEmitterViewer>();
5050
List<ParticleEmitterViewer> CylinderSteamExhaust4 = new List<ParticleEmitterViewer>();
51+
List<ParticleEmitterViewer> BoosterCylinderSteamExhaust01 = new List<ParticleEmitterViewer>();
52+
List<ParticleEmitterViewer> BoosterCylinderSteamExhaust02 = new List<ParticleEmitterViewer>();
5153
List<ParticleEmitterViewer> Blowdown = new List<ParticleEmitterViewer>();
5254
List<ParticleEmitterViewer> Drainpipe = new List<ParticleEmitterViewer>();
5355
List<ParticleEmitterViewer> Injectors1 = new List<ParticleEmitterViewer>();
@@ -106,6 +108,10 @@ public MSTSSteamLocomotiveViewer(Viewer viewer, MSTSSteamLocomotive car)
106108
CylinderSteamExhaust3.AddRange(emitter.Value);
107109
else if (emitter.Key.ToLowerInvariant() == "cylindersteamexhaust4fx")
108110
CylinderSteamExhaust4.AddRange(emitter.Value);
111+
else if (emitter.Key.ToLowerInvariant() == "boostercylindersteamexhaust01fx")
112+
BoosterCylinderSteamExhaust01.AddRange(emitter.Value);
113+
else if (emitter.Key.ToLowerInvariant() == "boostercylindersteamexhaust02fx")
114+
BoosterCylinderSteamExhaust02.AddRange(emitter.Value);
109115
else if (emitter.Key.ToLowerInvariant() == "blowdownfx")
110116
Blowdown.AddRange(emitter.Value);
111117
else if (emitter.Key.ToLowerInvariant() == "drainpipefx") // Drainpipe was not used in MSTS, and has no control set up for it
@@ -307,8 +313,11 @@ public override void PrepareFrame(RenderFrame frame, ElapsedTime elapsedTime)
307313
foreach (var drawer in CylinderSteamExhaust3)
308314
drawer.SetOutput(car.CylinderSteamExhaustSteamVelocityMpS, car.CylinderSteamExhaust3SteamVolumeM3pS, car.CylinderSteamExhaustParticleDurationS);
309315

310-
foreach (var drawer in CylinderSteamExhaust4)
311-
drawer.SetOutput(car.CylinderSteamExhaustSteamVelocityMpS, car.CylinderSteamExhaust4SteamVolumeM3pS, car.CylinderSteamExhaustParticleDurationS);
316+
foreach (var drawer in BoosterCylinderSteamExhaust01)
317+
drawer.SetOutput(car.BoosterCylinderSteamExhaust01SteamVelocityMpS, car.BoosterCylinderSteamExhaust01SteamVolumeM3pS, car.CylinderSteamExhaustParticleDurationS);
318+
319+
foreach (var drawer in BoosterCylinderSteamExhaust02)
320+
drawer.SetOutput(car.BoosterCylinderSteamExhaust02SteamVelocityMpS, car.BoosterCylinderSteamExhaust02SteamVolumeM3pS, car.CylinderSteamExhaustParticleDurationS);
312321

313322
foreach (var drawer in Blowdown)
314323
drawer.SetOutput(car.BlowdownSteamVelocityMpS, car.BlowdownSteamVolumeM3pS, car.BlowdownParticleDurationS);

0 commit comments

Comments
 (0)