@@ -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
0 commit comments