8686using SharpDX.Direct3D9;
8787using Orts.Simulation.RollingStocks;
8888using static Orts.Simulation.RollingStocks.MSTSSteamLocomotive;
89+ using SharpDX.MediaFoundation;
8990
9091namespace Orts.Simulation.RollingStocks
9192{
@@ -171,6 +172,8 @@ public class MSTSSteamLocomotive : MSTSLocomotive
171172 bool BoosterAirisLow = false;
172173 int BoosterEngineNumber;
173174
175+ float SteamLocomotiveRetardingDynamicBrakeForceN = 0;
176+
174177 /// <summary>
175178 /// Grate limit of locomotive exceedeed?
176179 /// </summary>
@@ -2498,6 +2501,7 @@ public override void Update(float elapsedClockSeconds)
24982501 LocoTenderFrictionForceN = CombFrictionN;
24992502
25002503 #region transfer energy
2504+
25012505 UpdateFX(elapsedClockSeconds);
25022506 UpdateTender(elapsedClockSeconds);
25032507 UpdateFirebox(elapsedClockSeconds, absSpeedMpS);
@@ -2519,6 +2523,7 @@ public override void Update(float elapsedClockSeconds)
25192523
25202524 if (SteamEngines[i].AuxiliarySteamEngineType != SteamEngine.AuxiliarySteamEngineTypes.Booster)
25212525 {
2526+ UpdateCounterPressure(elapsedClockSeconds, cutoff, i);
25222527 UpdateCylinders(elapsedClockSeconds, throttle, cutoff, absSpeedMpS, i);
25232528 }
25242529 else if (SteamEngines[i].AuxiliarySteamEngineType == SteamEngine.AuxiliarySteamEngineTypes.Booster) // Booster Engine
@@ -4874,7 +4879,55 @@ private void UpdateSuperHeat()
48744879
48754880 }
48764881
4877- private void UpdateCylinders(float elapsedClockSeconds, float throttle, float cutoff, float absSpeedMpS, int numberofengine)
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+
4928+ }
4929+
4930+ private void UpdateCylinders(float elapsedClockSeconds, float throttle, float cutoff, float absSpeedMpS, int numberofengine)
48784931 {
48794932 // Calculate speed of locomotive in wheel rpm - used to determine changes in performance based upon speed.
48804933 SteamEngines[numberofengine].DriveWheelRevRpS = absSpeedMpS / (2.0f * MathHelper.Pi * SteamEngines[numberofengine].AttachedAxle.WheelRadiusM);
@@ -6592,6 +6645,18 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float loc
65926645 {
65936646 TractiveForceN = 0;
65946647 }
6648+
6649+ // if (DynamicBrakePercent > 0 && DynamicBrake)
6650+
6651+ if (DynamicBrakePercent > 0)
6652+ {
6653+ DynamicBrakeForceN = SteamLocomotiveRetardingDynamicBrakeForceN;
6654+ }
6655+ else
6656+ {
6657+ DynamicBrakeForceN = 0;
6658+ }
6659+
65956660 }
65966661
65976662
0 commit comments