Skip to content

Commit 2ef7f37

Browse files
committed
Add counter pressure braking
1 parent 1ccdf71 commit 2ef7f37

File tree

5 files changed

+84
-9
lines changed

5 files changed

+84
-9
lines changed

Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ public enum LocomotiveRailDriveTypes
115115
public LocomotiveRailDriveTypes LocomotiveRailDriveType;
116116

117117
public bool RackGogWheelEngaged = false;
118+
public float CogWheelDiameterM;
118119

119120
// simulation parameters
120121
public bool ManualHorn = false;
@@ -3019,6 +3020,7 @@ public virtual void AdvancedAdhesion(float elapsedClockSeconds)
30193020
axle.BrakeRetardForceN = BrakeRetardForceN / LocomotiveAxles.Count;
30203021
axle.TrainSpeedMpS = SpeedMpS; //Set the train speed of the axle mod
30213022
axle.WheelRadiusM = DriverWheelRadiusM;
3023+
axle.CogWheelRadiusM = CogWheelRadiusM;
30223024
axle.WheelDistanceGaugeM = TrackGaugeM;
30233025
axle.CurrentCurveRadiusM = CurrentCurveRadiusM;
30243026
axle.BogieRigidWheelBaseM = RigidWheelBaseM;

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

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
using SharpDX.Direct3D9;
8787
using Orts.Simulation.RollingStocks;
8888
using static Orts.Simulation.RollingStocks.MSTSSteamLocomotive;
89+
using SharpDX.MediaFoundation;
8990

9091
namespace 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

Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,6 +1296,7 @@ public virtual void Parse(string lowercasetoken, STFReader stf)
12961296
case "wagon(ortsheatingboilerfuelusage": TrainHeatBoilerFuelUsageGalukpH = new Interpolator(stf); break;
12971297
case "wagon(wheelradius": WheelRadiusM = stf.ReadFloatBlock(STFReader.UNITS.Distance, null); break;
12981298
case "engine(wheelradius": DriverWheelRadiusM = stf.ReadFloatBlock(STFReader.UNITS.Distance, null); break;
1299+
case "engine(ortscogwheelradius": CogWheelRadiusM = stf.ReadFloatBlock(STFReader.UNITS.Distance, null); break;
12991300
case "wagon(sound": MainSoundFileName = stf.ReadStringBlock(null); break;
13001301
case "wagon(ortsbrakeshoefriction": BrakeShoeFrictionFactor = new Interpolator(stf); break;
13011302
case "wagon(maxhandbrakeforce": InitialMaxHandbrakeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, null); break;
@@ -1548,11 +1549,6 @@ public virtual void Parse(string lowercasetoken, STFReader stf)
15481549
Couplers[CouplerCountLocation].Rigid = false;
15491550
Couplers[CouplerCountLocation].Rigid = stf.ReadBoolBlock(true);
15501551
break;
1551-
1552-
case "wagon(ortscogwheel":
1553-
CogWheelFitted = stf.ReadBoolBlock(false);
1554-
break;
1555-
15561552
case "wagon(adheasion":
15571553
stf.MustMatch("(");
15581554
Adhesion1 = stf.ReadFloat(STFReader.UNITS.None, null);
@@ -1694,6 +1690,7 @@ public virtual void Copy(MSTSWagon copy)
16941690
InitialMassKG = copy.InitialMassKG;
16951691
WheelRadiusM = copy.WheelRadiusM;
16961692
DriverWheelRadiusM = copy.DriverWheelRadiusM;
1693+
CogWheelRadiusM = copy.CogWheelRadiusM;
16971694
MainSoundFileName = copy.MainSoundFileName;
16981695
BrakeShoeFrictionFactor = copy.BrakeShoeFrictionFactor;
16991696
WheelBrakeSlideProtectionFitted = copy.WheelBrakeSlideProtectionFitted;
@@ -1757,7 +1754,6 @@ public virtual void Copy(MSTSWagon copy)
17571754
Curtius_KnifflerB = copy.Curtius_KnifflerB;
17581755
Curtius_KnifflerC = copy.Curtius_KnifflerC;
17591756
AdhesionK = copy.AdhesionK;
1760-
CogWheelFitted = copy.CogWheelFitted;
17611757
AxleInertiaKgm2 = copy.AxleInertiaKgm2;
17621758
SlipWarningThresholdPercent = copy.SlipWarningThresholdPercent;
17631759
Lights = copy.Lights;

Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/PowerTransmissions/Axle.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,8 @@ public void Initialize()
258258
if (axle.AxleWeightN <= 0) axle.AxleWeightN = 9.81f * axle.WheelWeightKg; //remains fixed for diesel/electric locomotives, but varies for steam locomotives
259259
if (axle.NumWheelsetAxles <= 0) axle.NumWheelsetAxles = locomotive.LocoNumDrvAxles;
260260
if (axle.WheelRadiusM <= 0) axle.WheelRadiusM = locomotive.DriverWheelRadiusM;
261+
if (axle.CogWheelRadiusM <= 0) axle.CogWheelRadiusM = locomotive.CogWheelRadiusM;
262+
if (!axle.CogWheelFitted) axle.CogWheelFitted = locomotive.CogWheelFitted;
261263
if (axle.WheelFlangeAngleRad <= 0) axle.WheelFlangeAngleRad = locomotive.MaximumWheelFlangeAngleRad;
262264
if (axle.DampingNs <= 0) axle.DampingNs = locomotive.MassKG / 1000.0f / AxleList.Count;
263265
if (axle.FrictionN <= 0) axle.FrictionN = locomotive.MassKG / 1000.0f / AxleList.Count;
@@ -607,6 +609,11 @@ public float TransmissionEfficiency
607609
/// </summary>
608610
public float WheelRadiusM;
609611

612+
/// <summary>
613+
/// Radius of wheels connected to rack track
614+
/// </summary>
615+
public float CogWheelRadiusM;
616+
610617
/// <summary>
611618
/// Wheel number
612619
/// </summary>
@@ -903,10 +910,13 @@ public void Parse(STFReader stf)
903910
WheelWeightKg = stf.ReadFloatBlock(STFReader.UNITS.Mass, null);
904911
AxleWeightN = 9.81f * WheelWeightKg;
905912
break;
906-
case "cogwheel":
913+
case "cogwheelfitted":
907914
CogWheelFitted = stf.ReadBoolBlock(false);
908915
Trace.TraceInformation("CogWheel - {0}", CogWheelFitted);
909916
break;
917+
case "cogwheelradius":
918+
CogWheelRadiusM = stf.ReadFloatBlock(STFReader.UNITS.Distance, null);
919+
break;
910920
case "animatedparts":
911921
foreach (var part in stf.ReadStringBlock("").ToUpper().Replace(" ", "").Split(','))
912922
{
@@ -922,6 +932,7 @@ public void Parse(STFReader stf)
922932
public void Copy(Axle other)
923933
{
924934
WheelRadiusM = other.WheelRadiusM;
935+
CogWheelRadiusM = other.CogWheelRadiusM;
925936
WheelFlangeAngleRad = other.WheelFlangeAngleRad;
926937
NumWheelsetAxles = other.NumWheelsetAxles;
927938
InertiaKgm2 = other.InertiaKgm2;

Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,8 @@ public Direction Direction
658658
public int LocoNumDrvAxles; // Number of drive axles on locomotive
659659
protected float MSTSLocoNumDrvWheels; // Number of drive axles on locomotive - used to read MSTS value as default
660660
public float DriverWheelRadiusM = Me.FromIn(30.0f); // Drive wheel radius of locomotive wheels - Wheel radius of loco drive wheels can be anywhere from about 10" to 40".
661-
public enum SteamEngineTypes
661+
public float CogWheelRadiusM = Me.FromIn(22.0f);
662+
public enum SteamEngineTypes
662663
{
663664
Unknown,
664665
Simple,

0 commit comments

Comments
 (0)