Skip to content

Commit 8a7df84

Browse files
committed
Correct crank angle for adhesion calculation
1 parent 30d7b53 commit 8a7df84

File tree

1 file changed

+60
-32
lines changed

1 file changed

+60
-32
lines changed

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

Lines changed: 60 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ public class MSTSSteamLocomotive : MSTSLocomotive
142142
bool AIFireOverride = false; // Flag to show ai fire has has been overriden
143143
bool InjectorLockedOut = false; // Flag to lock injectors from changing within a fixed period of time
144144

145+
float DebugTimerS;
146+
145147
// Aux Tender Parameters
146148
public bool AuxTenderMoveFlag = false; // Flag to indicate whether train has moved
147149
bool SteamIsAuxTenderCoupled = false;
@@ -2105,29 +2107,7 @@ private void UpdateFX(float elapsedClockSeconds)
21052107
for (int i = 0; i < NumCylinders; i++)
21062108
{
21072109

2108-
// Trace.TraceInformation("NumCyl - {0} i {1}", NumCylinders, i);
2109-
2110-
// float realCrankAngleRad = (float)(LocomotiveAxle.AxlePositionRad + i * WheelCrankAngleDiffRad[i]);
2111-
float realCrankAngleRad = (float)(LocomotiveAxles[0].AxlePositionRad);
2112-
float normalisedCrankAngleRad = 0;
2113-
2114-
realCrankAngleRad = (float)(MathHelper.WrapAngle(realCrankAngleRad));
2115-
2116-
if (realCrankAngleRad < 0)
2117-
{
2118-
realCrankAngleRad = (float)(2.0f * Math.PI + realCrankAngleRad); // angle must be maintained in a +ve range, ie 0 - 360
2119-
}
2120-
2121-
// Normalise crank angle so that it is a value between 0 and 360 starting at the real crank angle difference
2122-
if (realCrankAngleRad >= WheelCrankAngleDiffRad[i])
2123-
{
2124-
normalisedCrankAngleRad = realCrankAngleRad - WheelCrankAngleDiffRad[i];
2125-
}
2126-
else
2127-
{
2128-
float diff = WheelCrankAngleDiffRad[i] - realCrankAngleRad;
2129-
normalisedCrankAngleRad = (float)(2.0f * Math.PI - diff);
2130-
}
2110+
float normalisedCrankAngleRad = NormalisedCrankAngle(i);
21312111

21322112
// Exhaust crank angle
21332113
float exhaustCrankAngleRad = 0;
@@ -5085,7 +5065,7 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float t,
50855065

50865066
for (int i = 0; i < NumCylinders; i++)
50875067
{
5088-
float crankAngleRad = (float)(LocomotiveAxles[0].AxlePositionRad + i * WheelCrankAngleDiffRad[i]);
5068+
float crankAngleRad = (float)(LocomotiveAxles[0].AxlePositionRad + WheelCrankAngleDiffRad[i]);
50895069

50905070
testCrankAngle = crankAngleRad;
50915071

@@ -5122,9 +5102,11 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float t,
51225102
backwardCylinderPosition = crankCylinderPosition;
51235103
}
51245104

5125-
/*
5126-
Trace.TraceInformation("Cyl {0} Position {1} testcrankAng {2} crankAngle {3} CrankPosition {4} forwardCrankPosition {5} backwardCrankPosition {6}", i+1, LocomotiveAxle.AxlePositionRad, MathHelper.ToDegrees(testCrankAngle), MathHelper.ToDegrees(crankAngleRad), crankCylinderPosition, forwardCylinderPosition, backwardCylinderPosition);
5127-
*/
5105+
/*
5106+
Trace.TraceInformation("Cyl {0} Position {1} testcrankAng {2} crankAngle {3} CrankPosition {4} forwardCrankPosition {5} backwardCrankPosition {6}", i+1, LocomotiveAxle.AxlePositionRad, MathHelper.ToDegrees(testCrankAngle), MathHelper.ToDegrees(crankAngleRad), crankCylinderPosition, forwardCylinderPosition, backwardCylinderPosition);
5107+
*/
5108+
5109+
float normalisedCrankAngleRad = NormalisedCrankAngle( i );
51285110

51295111
// Crank angles
51305112
float sin = (float)Math.Sin(crankAngleRad);
@@ -5212,7 +5194,7 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float t,
52125194
float connectRodInertiaForcelbf = inertiaSpeedCorrectionFactor * connectRodInertiaAngleFactor * ConnectingRodWeightLb;
52135195

52145196
// Account for the position of the crosshead position. In other words it depends upon whether the Rods and Reciporating gear is above or below the axle.
5215-
if (crankAngleRad > 0 && crankAngleRad < Math.PI)
5197+
if (crankAngleRad > 0 && crankAngleRad < Math.PI && normalisedCrankAngleRad < Math.PI)
52165198
{
52175199
reciprocatingInertiaForcelbf *= -1;
52185200
connectRodInertiaForcelbf *= -1;
@@ -5237,14 +5219,20 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float t,
52375219
// should be deducted from this as well.
52385220
float tangentialWheelTreadForceLbf = tangentialCrankWheelForceLbf * Me.ToIn(CylinderStrokeM) / Me.ToIn(DrvWheelDiaM);
52395221

5240-
if (throttle <= 0)
5222+
// Debug Adhesion problem
5223+
/* if (SpeedMpS > 17.88 && SpeedMpS < 18.2 )
52415224
{
5242-
tangentialWheelTreadForceLbf = 0; // force wheel force to zero if throttle - problem seems to only happen at higher speeds,
5243-
// so could be a decrease in sampling points as the wheels rotate faster.
5225+
Trace.TraceInformation("Adhesion Debug - Cyl {0} Time {1} Speed {2} WheelRpM {3} CrankAngle {4} TotalTangForce {5} TangForce {6} TotalInertiaForce {7} TotalTangInertiaForce {8} RecipForce {9} RecipANgleFactor {10} RecipWeight {11} SpeedFactor {12} RodForce {13} RodAngleFactor {14} ForwardCyLPos {15} BackCylPos {16} CrankCylPos {17} NormCrankAngle {18}", i + 1, DebugTimerS, MpS.ToMpH(SpeedMpS), DrvWheelRevRpS * 60.0f, MathHelper.ToDegrees(crankAngleRad), tangentialWheelTreadForceLbf, tangentialForcelbf, totalInertiaForcelbf, totalTangentialInertiaForcelbf, reciprocatingInertiaForcelbf, reciprocatingInertiaAngleFactor, ReciprocatingWeightLb, inertiaSpeedCorrectionFactor, connectRodInertiaForcelbf, connectRodInertiaAngleFactor, forwardCylinderPosition, backwardCylinderPosition, crankCylinderPosition, normalisedCrankAngleRad);
5226+
5227+
DebugTimerS += elapsedClockSeconds;
5228+
52445229
}
52455230
5231+
*/
5232+
5233+
52465234
DisplayTangentialWheelTreadForceLbf += tangentialWheelTreadForceLbf;
5247-
TractiveForceN += N.FromLbf(Math.Max(tangentialWheelTreadForceLbf, -1000));
5235+
TractiveForceN += N.FromLbf(tangentialWheelTreadForceLbf);
52485236

52495237
// ++++ Adhesive Force Calculation ++++++
52505238
// Calculation of components for use in wheel adhesive force calculation
@@ -5398,6 +5386,46 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float t,
53985386
}
53995387

54005388

5389+
/// <summary>
5390+
/// Normalise crank angle so that it is a value between 0 and 360 starting at the real crank angle difference
5391+
/// </summary>
5392+
private float NormalisedCrankAngle( int cylinderNumber)
5393+
{
5394+
float realCrankAngleRad = (float)(LocomotiveAxles[0].AxlePositionRad);
5395+
float normalisedCrankAngleRad = 0;
5396+
5397+
realCrankAngleRad = (float)(MathHelper.WrapAngle(realCrankAngleRad));
5398+
5399+
if (realCrankAngleRad < 0)
5400+
{
5401+
realCrankAngleRad = (float)(2.0f * Math.PI + realCrankAngleRad); // angle must be maintained in a +ve range, ie 0 - 360
5402+
}
5403+
5404+
5405+
if (cylinderNumber == 0) // initial cylinder
5406+
{
5407+
normalisedCrankAngleRad = realCrankAngleRad;
5408+
}
5409+
else
5410+
{
5411+
normalisedCrankAngleRad = realCrankAngleRad + WheelCrankAngleDiffRad[cylinderNumber];
5412+
}
5413+
5414+
5415+
if (normalisedCrankAngleRad > 2.0f * Math.PI)
5416+
{
5417+
normalisedCrankAngleRad -= (float)(2.0f * Math.PI);
5418+
5419+
}
5420+
return normalisedCrankAngleRad;
5421+
5422+
5423+
// if (SpeedMpS > 0)
5424+
// Trace.TraceInformation("Cylinder {0} CrankAngle {1} CrankDiff {2} RealCrank {3} NormalCrank {4}", i + 1, MathHelper.ToDegrees(crankAngleRad), MathHelper.ToDegrees(WheelCrankAngleDiffRad[i]), MathHelper.ToDegrees(realCrankAngleRad), MathHelper.ToDegrees(normalisedCrankAngleRad));
5425+
5426+
}
5427+
5428+
54015429
public override void AdvancedAdhesion(float elapsedClockSeconds)
54025430
{
54035431
if (SteamEngineType != SteamEngineTypes.Geared)

0 commit comments

Comments
 (0)