@@ -172,7 +172,7 @@ public class MSTSSteamLocomotive : MSTSLocomotive
172172 bool BoosterAirisLow = false;
173173 int BoosterEngineNumber;
174174
175- float SteamLocomotiveRetardingDynamicBrakeForceN = 0 ;
175+ bool CounterPressureBrakingFitted = false ;
176176
177177 /// <summary>
178178 /// Grate limit of locomotive exceedeed?
@@ -1059,6 +1059,10 @@ public override void Parse(string lowercasetoken, STFReader stf)
10591059 IsSelectGeared = String.Compare(typeString2, "Select") == 0;
10601060 break;
10611061
1062+ case "engine(ortscounterpressurebraking":
1063+ CounterPressureBrakingFitted = stf.ReadBoolBlock(false);
1064+ break;
1065+
10621066 case "engine(ortsbattery(mode":
10631067 case "engine(ortsbattery(delay":
10641068 case "engine(ortsbattery(defaulton":
@@ -1107,6 +1111,7 @@ public override void Copy(MSTSWagon copy)
11071111 EjectorLargeSteamConsumptionLbpS = locoCopy.EjectorLargeSteamConsumptionLbpS;
11081112 ShovelMassKG = locoCopy.ShovelMassKG;
11091113 GearedTractiveEffortFactor = locoCopy.GearedTractiveEffortFactor;
1114+ CounterPressureBrakingFitted = locoCopy.CounterPressureBrakingFitted;
11101115 TractiveEffortFactor = locoCopy.TractiveEffortFactor;
11111116 MaxTenderFuelMassKG = locoCopy.MaxTenderFuelMassKG;
11121117 MaxLocoTenderWaterMassKG = locoCopy.MaxLocoTenderWaterMassKG;
@@ -2523,7 +2528,6 @@ public override void Update(float elapsedClockSeconds)
25232528
25242529 if (SteamEngines[i].AuxiliarySteamEngineType != SteamEngine.AuxiliarySteamEngineTypes.Booster)
25252530 {
2526- UpdateCounterPressure(elapsedClockSeconds, cutoff, i);
25272531 UpdateCylinders(elapsedClockSeconds, throttle, cutoff, absSpeedMpS, i);
25282532 }
25292533 else if (SteamEngines[i].AuxiliarySteamEngineType == SteamEngine.AuxiliarySteamEngineTypes.Booster) // Booster Engine
@@ -4876,55 +4880,6 @@ private void UpdateSuperHeat()
48764880 }
48774881
48784882 SuperheaterSteamUsageFactor = MathHelper.Clamp(SuperheaterSteamUsageFactor, 0.60f, SuperheaterSteamUsageFactor); // ensure factor does not go below 0.6, as this represents base steam consumption by the cylinders.
4879-
4880- }
4881-
4882- /// <summary>
4883- /// Calculate the counter pressure to be used by a locomotive as a braking effect
4884- /// To do this we first calculate the MEP air pressure of compressed air with each stroke, then we calculate the resulting "resisting" tractive force
4885- /// </summary>
4886- private void UpdateCounterPressure(float elapsedClockSeconds, float cutoff, int numberofengine)
4887- {
4888- SteamLocomotiveRetardingDynamicBrakeForceN = 0;
4889-
4890- float currentDynamicBrakeFraction = DynamicBrakePercent / 100;
4891-
4892- if (currentDynamicBrakeFraction > 0 && absSpeedMpS >0)
4893- {
4894- float CylinderVolumePoint_compression = (currentDynamicBrakeFraction * Me.ToIn(SteamEngines[numberofengine].CylindersStrokeM)) + CylinderClearancePC;
4895- float CylinderVolumePoint_release = (Me.ToIn(SteamEngines[numberofengine].CylindersStrokeM) + 2 * CylinderClearancePC) - CylinderVolumePoint_compression;
4896-
4897- // Trace.TraceInformation("Vol-release {0} Vol-compression {1} Stroke {2}", CylinderVolumePoint_release, CylinderVolumePoint_compression, Me.ToIn(SteamEngines[numberofengine].CylindersStrokeM));
4898-
4899- // Ratio of compression = stroke during compression = stroke @ start of compression / stroke and end of compression
4900- float CylinderRatio_compression = CylinderVolumePoint_compression / CylinderClearancePC;
4901- float CylinderRatio_release = CylinderVolumePoint_compression / (Me.ToIn(SteamEngines[numberofengine].CylindersStrokeM) + 2 * CylinderClearancePC);
4902-
4903- float CompMeanPressure_compressionAtmPSI = OneAtmospherePSI * CylinderRatio_compression * ((float)Math.Log(CylinderRatio_compression, 10) / (CylinderRatio_compression - 1.0f));
4904- float CompMeanPressure_releaseAtmPSI = CompMeanPressure_compressionAtmPSI * CylinderRatio_release * ((float)Math.Log(CylinderRatio_release) / (CylinderRatio_release - 1.0f));
4905-
4906- // Trace.TraceInformation("MEPcomp {0} Log {1} CompRatio {2}", CompMeanPressure_compressionAtmPSI, (float)Math.Log(CylinderRatio_compression), CylinderRatio_compression);
4907-
4908- float CylinderWork_compression_InLbs = CompMeanPressure_compressionAtmPSI * CylinderVolumePoint_compression;
4909- float CylinderWork_release_InLbs = CompMeanPressure_releaseAtmPSI * CylinderVolumePoint_release;
4910-
4911- // Trace.TraceInformation("Workc {0} Workr {1} Pc {2} Pr {3}", CylinderWork_compression_InLbs, CylinderWork_release_InLbs, CompMeanPressure_compressionAtmPSI, CompMeanPressure_releaseAtmPSI);
4912-
4913- float TotalWorkCounterPressure = CylinderWork_compression_InLbs + CylinderWork_release_InLbs;
4914-
4915- float CounterPressureMEP = TotalWorkCounterPressure / Me.ToIn(SteamEngines[numberofengine].CylindersStrokeM);
4916-
4917- // Calculate tractive retarding force
4918- SteamLocomotiveRetardingDynamicBrakeForceN = N.FromLbf(CounterPressureMEP * Me.ToIn(SteamEngines[numberofengine].CylindersDiameterM) * Me.ToIn(SteamEngines[numberofengine].CylindersDiameterM) * Me.ToIn(SteamEngines[numberofengine].CylindersStrokeM) / Me.ToIn(SteamEngines[numberofengine].AttachedAxle.CogWheelRadiusM));
4919-
4920- // Trace.TraceInformation("CogRetardForce {0} throttle {1} MEP {2} Ratio-Comp {3} Ratio-Rel {4}", N.ToLbf(SteamLocomotiveRetardingDynamicBrakeForceN), throttle, CounterPressureMEP, CylinderRatio_compression, CylinderRatio_release);
4921- }
4922- else
4923- {
4924- SteamLocomotiveRetardingDynamicBrakeForceN = 0;
4925- }
4926-
4927-
49284883 }
49294884
49304885 private void UpdateCylinders(float elapsedClockSeconds, float throttle, float cutoff, float absSpeedMpS, int numberofengine)
@@ -6043,6 +5998,51 @@ private void UpdateCylinders(float elapsedClockSeconds, float throttle, float cu
60435998
60445999 SteamReleasePressure_AtmPSI = SteamEngines[numberofengine].Pressure_c_AtmPSI; // for steam and smoke effects
60456000
6001+
6002+ // Calculate the counter pressure to be used by a locomotive as a braking effect
6003+ // To do this we first calculate the MEP air pressure of compressed air with each stroke, then we calculate the resulting "resisting" tractive force
6004+
6005+ SteamEngines[numberofengine].CylinderCounterPressureBrakeForceN = 0;
6006+
6007+ float currentDynamicBrakeFraction = DynamicBrakePercent / 100;
6008+
6009+ if (currentDynamicBrakeFraction > 0 && absSpeedMpS > 0 && cutoff != 0)
6010+ {
6011+ float absCutoff = Math.Abs(cutoff);
6012+ float CylinderVolumePoint_compression = (currentDynamicBrakeFraction * absCutoff * Me.ToIn(SteamEngines[numberofengine].CylindersStrokeM)) + CylinderClearancePC;
6013+ float CylinderVolumePoint_release = (Me.ToIn(SteamEngines[numberofengine].CylindersStrokeM) + 2 * CylinderClearancePC) - CylinderVolumePoint_compression;
6014+
6015+ // Trace.TraceInformation("Vol-release {0} Vol-compression {1} Stroke {2}", CylinderVolumePoint_release, CylinderVolumePoint_compression, Me.ToIn(SteamEngines[numberofengine].CylindersStrokeM));
6016+
6017+ // Ratio of compression = stroke during compression = stroke @ start of compression / stroke and end of compression
6018+ float CylinderRatio_compression = CylinderVolumePoint_compression / CylinderClearancePC;
6019+ float CylinderRatio_release = CylinderVolumePoint_compression / (Me.ToIn(SteamEngines[numberofengine].CylindersStrokeM) + 2 * CylinderClearancePC);
6020+
6021+ float CompMeanPressure_compressionAtmPSI = OneAtmospherePSI * CylinderRatio_compression * ((float)Math.Log(CylinderRatio_compression, 10) / (CylinderRatio_compression - 1.0f));
6022+ float CompMeanPressure_releaseAtmPSI = CompMeanPressure_compressionAtmPSI * CylinderRatio_release * ((float)Math.Log(CylinderRatio_release) / (CylinderRatio_release - 1.0f));
6023+
6024+ // Trace.TraceInformation("MEPcomp {0} Log {1} CompRatio {2}", CompMeanPressure_compressionAtmPSI, (float)Math.Log(CylinderRatio_compression), CylinderRatio_compression);
6025+
6026+ float CylinderWork_compression_InLbs = CompMeanPressure_compressionAtmPSI * CylinderVolumePoint_compression;
6027+ float CylinderWork_release_InLbs = CompMeanPressure_releaseAtmPSI * CylinderVolumePoint_release;
6028+
6029+ // Trace.TraceInformation("Workc {0} Workr {1} Pc {2} Pr {3}", CylinderWork_compression_InLbs, CylinderWork_release_InLbs, CompMeanPressure_compressionAtmPSI, CompMeanPressure_releaseAtmPSI);
6030+
6031+ float TotalWorkCounterPressure = CylinderWork_compression_InLbs + CylinderWork_release_InLbs;
6032+
6033+ float CounterPressureMEP = TotalWorkCounterPressure / Me.ToIn(SteamEngines[numberofengine].CylindersStrokeM);
6034+
6035+ // Assume no impact of "return" stroke as air is being drawn into cylinder
6036+
6037+ // Calculate tractive retarding force
6038+ SteamEngines[numberofengine].CylinderCounterPressureBrakeForceN = N.FromLbf(CounterPressureMEP * Me.ToIn(SteamEngines[numberofengine].CylindersDiameterM) * Me.ToIn(SteamEngines[numberofengine].CylindersDiameterM) * Me.ToIn(SteamEngines[numberofengine].CylindersStrokeM) / Me.ToIn(SteamEngines[numberofengine].AttachedAxle.CogWheelRadiusM));
6039+
6040+ // Trace.TraceInformation("CogRetardForce {0} throttle {1} MEP {2} Ratio-Comp {3} Ratio-Rel {4}", N.ToLbf(SteamLocomotiveRetardingDynamicBrakeForceN), throttle, CounterPressureMEP, CylinderRatio_compression, CylinderRatio_release);
6041+ }
6042+ else
6043+ {
6044+ SteamEngines[numberofengine].CylinderCounterPressureBrakeForceN = 0;
6045+ }
60466046 }
60476047
60486048
@@ -6562,6 +6562,7 @@ private void UpdateSteamTractiveForce(float elapsedClockSeconds, float locomotiv
65626562 protected override void UpdateTractiveForce(float elapsedClockSeconds, float locomotivethrottle, float AbsSpeedMpS, float AbsWheelSpeedMpS)
65636563 {
65646564 TractiveForceN = 0; // reset tractiveforceN in preparation to calculating a new value
6565+ DynamicBrakeForceN = 0;
65656566 if (!Simulator.UseAdvancedAdhesion && Simulator.Settings.SimpleControlPhysics)
65666567 {
65676568 // Simple adhesion
@@ -6587,11 +6588,31 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float loc
65876588 {
65886589 ApplyDirectionToTractiveForce(ref SteamEngines[i].RealTractiveForceN, i);
65896590
6590- TractiveForceN += SteamEngines[i].RealTractiveForceN;
6591+ TractiveForceN += SteamEngines[i].RealTractiveForceN + DynamicBrakeForceN ;
65916592
65926593 if (Simulator.UseAdvancedAdhesion && !Simulator.Settings.SimpleControlPhysics)
65936594 {
65946595 SteamEngines[i].AttachedAxle.DriveForceN = SteamEngines[i].RealTractiveForceN;
6596+
6597+ // Counter Pressure braking system
6598+
6599+ if (DynamicBrakePercent > 0 && CounterPressureBrakingFitted && absSpeedMpS > 0.1)
6600+ {
6601+ DynamicBrakeForceN += SteamEngines[i].CylinderCounterPressureBrakeForceN;
6602+ TractiveForceN -= (SpeedMpS > 0 ? 1 : SpeedMpS < 0 ? -1 : Direction == Direction.Reverse ? -1 : 1) * DynamicBrakeForceN;
6603+ SteamEngines[i].AttachedAxle.DriveForceN = SteamEngines[i].RealTractiveForceN;
6604+ }
6605+ else
6606+ {
6607+ DynamicBrakeForceN = 0;
6608+ }
6609+
6610+ if (DynamicBrakeForceN > 0)
6611+ {
6612+
6613+ SteamEngines[i].AttachedAxle.DriveForceN = DynamicBrakeForceN;
6614+ }
6615+
65956616 UpdateAxleDriveForce();
65966617
65976618 SteamEngines[i].DisplayTractiveForceN = SteamEngines[i].AverageTractiveForceN;
@@ -6641,25 +6662,12 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float loc
66416662 MaxSpeedMpS = Me.FromMi(pS.FrompH(MaxLocoSpeedMpH)); // Note this is not the true max velocity of the locomotive, but the speed at which max HP is reached
66426663
66436664 // Set tractive force to zero if throttle is closed
6644- if (locomotivethrottle < 0.001)
6665+ if (locomotivethrottle < 0.001 && !CounterPressureBrakingFitted )
66456666 {
66466667 TractiveForceN = 0;
66476668 }
6648-
6649- // if (DynamicBrakePercent > 0 && DynamicBrake)
6650-
6651- if (DynamicBrakePercent > 0)
6652- {
6653- DynamicBrakeForceN = SteamLocomotiveRetardingDynamicBrakeForceN;
6654- }
6655- else
6656- {
6657- DynamicBrakeForceN = 0;
6658- }
6659-
66606669 }
66616670
6662-
66636671 /// <summary>
66646672 /// This function applies a sign to the motive force as a function of the direction of the train.
66656673 /// </summary>
@@ -8443,7 +8451,6 @@ public override string GetDebugStatus()
84438451 FormatStrings.mm);
84448452 }
84458453
8446-
84478454 if (SteamIsAuxTenderCoupled)
84488455 {
84498456 status.AppendFormat("{0}\t{1}\t{2}\t{3:N0}%\t{4}\t{5}\t\t{6:N0}%\t{7}\t{8}\t\t{9}\t{10}\t\t{11}\t{12:N0}\t{13}\t{14:N0}\n",
0 commit comments