@@ -146,7 +146,8 @@ public class MSTSSteamLocomotive : MSTSLocomotive
146146 float BoosterIdleChokeSizeIn;
147147 float BoosterPressureFactor = 0;
148148 float BoosterMaxIdleChokeSizeIn = 0.625f;
149- float SteamBoosterChestPressurePSI;
149+ float CabSteamBoosterPressurePSI;
150+ float PrevCabSteamBoosterPressurePSI;
150151
151152 /// <summary>
152153 /// Grate limit of locomotive exceedeed?
@@ -477,6 +478,7 @@ public float TenderCoalMassKG // Decreased by firing and increased
477478 float CylinderCocksPressureAtmPSI; // Pressure in cylinder (impacted by cylinder cocks).
478479 float CylinderCocksPressurePSI;
479480 float SteamChestPressurePSI; // Pressure in steam chest - input to cylinder
481+ float CabSteamChestPressurePSI;
480482
481483 float CylinderWork_ab_InLbs; // Work done during steam admission into cylinder
482484 float CylinderExhaustOpenFactor; // Point on cylinder stroke when exhaust valve opens.
@@ -574,10 +576,15 @@ public float TenderCoalMassKG // Decreased by firing and increased
574576 0.0f, MathHelper.Pi/2, 0.0f, 0.0f // default 2 cylinder locomotive
575577 };
576578
579+ static float[] WheelCrankAngleDiffEng2Rad = new float[]
580+ {
581+ 0.0f, MathHelper.Pi/2, 0.0f, 0.0f // default 2 cylinder locomotive
582+ };
583+
577584 static float[] BoosterWheelCrankAngleDiffRad = new float[]
578- {
585+ {
579586 0.0f, MathHelper.Pi/2, 0.0f, 0.0f // default 2 cylinder locomotive
580- };
587+ };
581588
582589 public float IndicatedHorsePowerHP; // Indicated Horse Power (IHP), theoretical power of the locomotive, it doesn't take into account the losses due to friction, etc. Typically output HP will be 70 - 90% of the IHP
583590 public float DrawbarHorsePowerHP; // Drawbar Horse Power (DHP), maximum power available at the wheels.
@@ -665,6 +672,22 @@ public float TenderCoalMassKG // Decreased by firing and increased
665672 public float Cylinders41SteamVolumeM3pS;
666673 public float Cylinders42SteamVolumeM3pS;
667674
675+ public float Cylinders2_11SteamVolumeM3pS;
676+ public float Cylinders2_12SteamVolumeM3pS;
677+ public float Cylinders2_21SteamVolumeM3pS;
678+ public float Cylinders2_22SteamVolumeM3pS;
679+
680+ public float CylinderSteamExhaust2_1SteamVolumeM3pS;
681+ public float CylinderSteamExhaust2_2SteamVolumeM3pS;
682+
683+ bool CylinderSteamExhaust2_1On = false;
684+ bool CylinderSteamExhaust2_2On = false;
685+
686+ bool CylinderCock2_11On = true;
687+ bool CylinderCock2_12On = false;
688+ bool CylinderCock2_21On = true;
689+ bool CylinderCock2_22On = false;
690+
668691 public float CylinderSteamExhaustSteamVelocityMpS;
669692 public float CylinderSteamExhaust1SteamVolumeM3pS;
670693 public float CylinderSteamExhaust2SteamVolumeM3pS;
@@ -2255,7 +2278,8 @@ public override void Update(float elapsedClockSeconds)
22552278 CylCockSteamUsageLBpS = 0;
22562279 MeanEffectivePressurePSI = 0;
22572280 CylinderCocksPressureAtmPSI = 0;
2258- SteamChestPressurePSI = 0;
2281+ CabSteamChestPressurePSI = 0;
2282+ CabSteamBoosterPressurePSI = 0;
22592283
22602284 for (int i = 0; i < SteamEngines.Count; i++)
22612285 {
@@ -2396,14 +2420,46 @@ public override void Update(float elapsedClockSeconds)
23962420 CylinderCocksPressureAtmPSI = SteamEngines[i].CylinderCocksPressureAtmPSI;
23972421 }
23982422
2399- if (SteamEngines[i].LogSteamChestPressurePSI > SteamChestPressurePSI && SteamEngines[i].AuxiliarySteamEngineType != SteamEngine.AuxiliarySteamEngineTypes.Booster)
2423+ if (SteamEngines[i].LogSteamChestPressurePSI > CabSteamChestPressurePSI && SteamEngines[i].AuxiliarySteamEngineType != SteamEngine.AuxiliarySteamEngineTypes.Booster)
2424+ {
2425+ CabSteamChestPressurePSI = SteamEngines[i].LogSteamChestPressurePSI;
2426+ }
2427+
2428+ // Calculate steam pressure for booster steam gauge
2429+ if (SteamEngines[i].AuxiliarySteamEngineType == SteamEngine.AuxiliarySteamEngineTypes.Booster)
24002430 {
2401- SteamChestPressurePSI = SteamEngines[i].LogSteamChestPressurePSI;
2431+ if (SteamEngines[i].LogSteamChestPressurePSI > CabSteamChestPressurePSI && SteamBoosterRunMode && SteamBoosterAirOpen)
2432+ {
2433+ CabSteamBoosterPressurePSI = SteamEngines[i].LogSteamChestPressurePSI;
2434+ PrevCabSteamBoosterPressurePSI = CabSteamBoosterPressurePSI;
2435+ }
2436+ else if (SteamBoosterIdleMode)
2437+ {
2438+ var DesiredBoosterPressure = (BoosterIdleChokeSizeIn / BoosterMaxIdleChokeSizeIn) * BoilerPressurePSI;
2439+
2440+ if (DesiredBoosterPressure > PrevCabSteamBoosterPressurePSI)
2441+ {
2442+ CabSteamBoosterPressurePSI = PrevCabSteamBoosterPressurePSI + 1;
2443+ CabSteamBoosterPressurePSI = MathHelper.Clamp(CabSteamBoosterPressurePSI, 0, MaxBoilerPressurePSI);
2444+ PrevCabSteamBoosterPressurePSI = CabSteamBoosterPressurePSI;
2445+ }
2446+ }
2447+ else
2448+ {
2449+ var DesiredBoosterPressure = 0;
2450+
2451+ if (DesiredBoosterPressure < PrevCabSteamBoosterPressurePSI)
2452+ {
2453+ CabSteamBoosterPressurePSI = PrevCabSteamBoosterPressurePSI - 1;
2454+ CabSteamBoosterPressurePSI = MathHelper.Clamp(CabSteamBoosterPressurePSI, 0, MaxBoilerPressurePSI);
2455+ PrevCabSteamBoosterPressurePSI = CabSteamBoosterPressurePSI;
2456+ }
2457+ }
24022458 }
24032459
2404- if (SteamEngines[i].LogSteamChestPressurePSI > SteamChestPressurePSI && SteamEngines[i].AuxiliarySteamEngineType == SteamEngine.AuxiliarySteamEngineTypes.Booster)
2460+ if (SteamEngines[i].LogSteamChestPressurePSI > CabSteamChestPressurePSI && SteamEngines[i].AuxiliarySteamEngineType == SteamEngine.AuxiliarySteamEngineTypes.Booster)
24052461 {
2406- SteamBoosterChestPressurePSI = SteamEngines[i].LogSteamChestPressurePSI;
2462+ CabSteamBoosterPressurePSI = SteamEngines[i].LogSteamChestPressurePSI;
24072463 }
24082464
24092465
@@ -2465,8 +2521,11 @@ private void UpdateFX(float elapsedClockSeconds)
24652521 if (CylinderAdvancedSteamEffects) // For advanced steam effects process each cylinder individually -
24662522 // - all ENG files will need to be changed.
24672523 {
2524+ var TotalNumberCyindersEng1 = SteamEngines[0].NumberCylinders + SteamEngines[0].LPNumberCylinders;
2525+
2526+ // Engine #1
24682527 // Find
2469- for (int i = 0; i < MSTSNumCylinders ; i++)
2528+ for (int i = 0; i < TotalNumberCyindersEng1 ; i++)
24702529 {
24712530 var crankAngleDiffRad = WheelCrankAngleDiffRad[i];
24722531 float normalisedCrankAngleRad = NormalisedCrankAngle(i, crankAngleDiffRad);
@@ -2532,7 +2591,7 @@ private void UpdateFX(float elapsedClockSeconds)
25322591 }
25332592 }
25342593
2535- if (MSTSNumCylinders == 4)
2594+ if (TotalNumberCyindersEng1 == 4)
25362595 {
25372596 // Cylinder Cocks
25382597 if (i == 0)
@@ -2600,7 +2659,7 @@ private void UpdateFX(float elapsedClockSeconds)
26002659 }
26012660 }
26022661 }
2603- else if (MSTSNumCylinders == 3)
2662+ else if (TotalNumberCyindersEng1 == 3)
26042663 {
26052664 if (i == 0)
26062665 {
@@ -2687,6 +2746,97 @@ private void UpdateFX(float elapsedClockSeconds)
26872746 }
26882747 }
26892748 }
2749+
2750+
2751+ if (SteamEngines.Count > 1)
2752+ {
2753+ var TotalNumberCyindersEng2 = SteamEngines[1].NumberCylinders + SteamEngines[1].LPNumberCylinders;
2754+
2755+ // Engine #2
2756+ // Find
2757+ for (int i = 0; i < TotalNumberCyindersEng2; i++)
2758+ {
2759+ var crankAngleDiffRad = WheelCrankAngleDiffEng2Rad[i];
2760+ float normalisedCrankAngleRad = NormalisedCrankAngle(i, crankAngleDiffRad);
2761+
2762+ // Exhaust crank angle
2763+ float exhaustCrankAngleRad = 0;
2764+ if (normalisedCrankAngleRad <= MathHelper.Pi)
2765+ {
2766+ exhaustCrankAngleRad = CylinderExhaustOpenFactor * (float)Math.PI;
2767+ }
2768+ else
2769+ {
2770+ exhaustCrankAngleRad = CylinderExhaustOpenFactor * (float)Math.PI + (float)Math.PI;
2771+ }
2772+
2773+ // Trace.TraceInformation("Cylinder {0} ExhaustCrank {1} RealCrank {2} NormalCrank {3}", i + 1, MathHelper.ToDegrees(exhaustCrankAngleRad), MathHelper.ToDegrees(realCrankAngleRad), MathHelper.ToDegrees(normalisedCrankAngleRad));
2774+
2775+ if (absSpeedMpS > 0.001)
2776+ {
2777+ if (i == 0 && ((normalisedCrankAngleRad <= MathHelper.Pi && normalisedCrankAngleRad >= exhaustCrankAngleRad) || (normalisedCrankAngleRad < 2 * MathHelper.Pi && normalisedCrankAngleRad >= exhaustCrankAngleRad)))
2778+ {
2779+ CylinderSteamExhaust2_1On = true;
2780+
2781+ // Trace.TraceInformation("Exhaust - Factor {0} ExhaustCrank {1} RealCrank {2} NormalCrank {3} Exhaust1On {4} Cylinder {5} i {6}", CylinderExhaustOpenFactor, MathHelper.ToDegrees(exhaustCrankAngleRad), MathHelper.ToDegrees(realCrankAngleRad), MathHelper.ToDegrees(normalisedCrankAngleRad), CylinderSteamExhaust1On, i + 1, i);
2782+ }
2783+ else if (i == 0)
2784+ {
2785+ CylinderSteamExhaust2_1On = false;
2786+ // Trace.TraceInformation("Test #1 {0}", CylinderSteamExhaust1On);
2787+ }
2788+
2789+ else if (i == 1 && ((normalisedCrankAngleRad <= MathHelper.Pi && normalisedCrankAngleRad >= exhaustCrankAngleRad) || (normalisedCrankAngleRad < 2 * MathHelper.Pi && normalisedCrankAngleRad >= exhaustCrankAngleRad)))
2790+ {
2791+ CylinderSteamExhaust2_2On = true;
2792+ // Trace.TraceInformation("Exhaust - Factor {0} ExhaustCrank {1} RealCrank {2} NormalCrank {3} Exhaust2On {4} Cylinder {5} i {6}", CylinderExhaustOpenFactor, MathHelper.ToDegrees(exhaustCrankAngleRad), MathHelper.ToDegrees(realCrankAngleRad), MathHelper.ToDegrees(normalisedCrankAngleRad), CylinderSteamExhaust2On, i + 1, i);
2793+ }
2794+ else if (i == 1)
2795+ {
2796+ CylinderSteamExhaust2_2On = false;
2797+ }
2798+
2799+ // Trace.TraceInformation("Exhaust - Factor {0} ExhaustCrank {1} RealCrank {2} NormalCrank {3} ExhaustOn {4} Cylinder {5}", CylinderExhaustOpenFactor, MathHelper.ToDegrees(exhaustCrankAngleRad), MathHelper.ToDegrees(realCrankAngleRad), MathHelper.ToDegrees(normalisedCrankAngleRad), SteamExhaust1On, i+1);
2800+
2801+ }
2802+
2803+ if (TotalNumberCyindersEng2 == 2)
2804+ {
2805+ if (i == 0)
2806+ {
2807+ if (normalisedCrankAngleRad <= MathHelper.Pi)
2808+ {
2809+ CylinderCock2_11On = true;
2810+ CylinderCock2_12On = false;
2811+ }
2812+ }
2813+ else
2814+ {
2815+ if (normalisedCrankAngleRad > MathHelper.Pi)
2816+ {
2817+ CylinderCock2_11On = false;
2818+ CylinderCock2_12On = true;
2819+ }
2820+ }
2821+ if (i == 1)
2822+ {
2823+ if (normalisedCrankAngleRad <= MathHelper.Pi)
2824+ {
2825+ CylinderCock2_21On = true;
2826+ CylinderCock2_22On = false;
2827+ }
2828+ }
2829+ else
2830+ {
2831+ if (normalisedCrankAngleRad > MathHelper.Pi)
2832+ {
2833+ CylinderCock2_21On = false;
2834+ CylinderCock2_22On = true;
2835+ }
2836+ }
2837+ }
2838+ }
2839+ }
26902840 }
26912841 else if (Cylinder2SteamEffects) // For MSTS locomotives with one cylinder cock ignore calculation of cock opening times.
26922842 // Currently retained as a legacy issue, and eventually both this and the MSTS version should be removed
@@ -2828,6 +2978,14 @@ private void UpdateFX(float elapsedClockSeconds)
28282978 CylinderSteamExhaustSteamVelocityMpS = 100.0f;
28292979 CylinderSteamExhaustParticleDurationS = 1.0f;
28302980
2981+ CylinderSteamExhaust2_1SteamVolumeM3pS = throttle > 0.0 && CylinderSteamExhaust2_1On ? (cutoff * 10.0f * SteamEffectsFactor) : 0.0f;
2982+ CylinderSteamExhaust2_2SteamVolumeM3pS = throttle > 0.0 && CylinderSteamExhaust2_2On ? (cutoff * 10.0f * SteamEffectsFactor) : 0.0f;
2983+
2984+ Cylinders2_11SteamVolumeM3pS = CylinderCock2_11On && CylinderCocksAreOpen && throttle > 0.0 && CylCockSteamUsageDisplayLBpS > 0.0 ? (10.0f * SteamEffectsFactor) : 0.0f;
2985+ Cylinders2_12SteamVolumeM3pS = CylinderCock2_12On && CylinderCocksAreOpen && throttle > 0.0 && CylCockSteamUsageDisplayLBpS > 0.0 ? (10.0f * SteamEffectsFactor) : 0.0f;
2986+ Cylinders2_21SteamVolumeM3pS = CylinderCock2_21On && CylinderCocksAreOpen && throttle > 0.0 && CylCockSteamUsageDisplayLBpS > 0.0 ? (10.0f * SteamEffectsFactor) : 0.0f;
2987+ Cylinders2_22SteamVolumeM3pS = CylinderCock2_22On && CylinderCocksAreOpen && throttle > 0.0 && CylCockSteamUsageDisplayLBpS > 0.0 ? (10.0f * SteamEffectsFactor) : 0.0f;
2988+
28312989 // Booster Engine steam pressure
28322990 float BoosterSteamFraction = 0;
28332991
@@ -6776,13 +6934,13 @@ public override float GetDataOf(CabViewControl cvc)
67766934 data = ConvertFromPSI(cvc, BoilerPressurePSI);
67776935 break;
67786936 case CABViewControlTypes.STEAMCHEST_PR:
6779- data = ConvertFromPSI(cvc, SteamChestPressurePSI );
6937+ data = ConvertFromPSI(cvc, CabSteamChestPressurePSI );
67806938 break;
67816939 case CABViewControlTypes.STEAMHEAT_PRESSURE:
67826940 data = ConvertFromPSI(cvc, CurrentSteamHeatPressurePSI);
67836941 break;
67846942 case CABViewControlTypes.STEAM_BOOSTER_PRESSURE:
6785- data = ConvertFromPSI(cvc, SteamBoosterChestPressurePSI );
6943+ data = ConvertFromPSI(cvc, CabSteamBoosterPressurePSI );
67866944 break;
67876945 case CABViewControlTypes.CUTOFF:
67886946 case CABViewControlTypes.REVERSER_PLATE:
0 commit comments