@@ -5023,7 +5023,6 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float t,
50235023 LPslipBackPressureAtmPSI = LPCompPressure_m_AtmPSI ;
50245024 LPslipCompressionPressureAtmPSI = LPCompPressure_n_AtmPSI ;
50255025 LPslipAdmissionPressureAtmPSI = LPCompPressure_q_AtmPSI ;
5026-
50275026 }
50285027 else // Simple mode
50295028 {
@@ -5042,7 +5041,6 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float t,
50425041 LPslipBackPressureAtmPSI = LPPressure_d_AtmPSI ;
50435042 LPslipCompressionPressureAtmPSI = LPPressure_e_AtmPSI ;
50445043 LPslipAdmissionPressureAtmPSI = LPPressure_f_AtmPSI ;
5045-
50465044 }
50475045 }
50485046 else // simple locomotive
@@ -5053,29 +5051,26 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float t,
50535051 slipBackPressureAtmPSI = Pressure_d_AtmPSI ;
50545052 slipCompressionPressureAtmPSI = Pressure_e_AtmPSI ;
50555053 slipAdmissionPressureAtmPSI = Pressure_f_AtmPSI ;
5056-
5057- // Trace.TraceInformation("Initialise IntialPressure {0} Pressure A {1}", slipInitialPressureAtmPSI, Pressure_a_AtmPSI);
5058-
50595054 }
50605055
50615056 TractiveForceN = 0 ;
50625057 float totalDrvWeightN = 0 ;
50635058 DisplayTangentialWheelTreadForceLbf = 0 ;
5064- float testCrankAngle = 0 ;
5065-
5059+
50665060 for ( int i = 0 ; i < NumCylinders ; i ++ )
50675061 {
5068- float crankAngleRad = ( float ) ( LocomotiveAxles [ 0 ] . AxlePositionRad + WheelCrankAngleDiffRad [ i ] ) ;
5069-
5070- testCrankAngle = crankAngleRad ;
5071-
5072- crankAngleRad = ( float ) ( MathHelper . WrapAngle ( crankAngleRad ) ) ;
5062+ // This feature sues some different reference angles as follows:
5063+ // AxlePositionRad - comes from the axle module and is -180 - 0 - 180
5064+ // Crank Angle - converts the above range to 0 - 180 - 0 - this is the principle reference used so that it lines up with reference
5065+ // tables used to buold this function
5066+ // Normalised Crank Angle - converts the above to a 0 - 360 range, this is used for triggering special steam effects, etc.
5067+ float axlePostionRad = LocomotiveAxles [ 0 ] . AxlePositionRad ;
5068+ float crankAngleRad = ( float ) ( axlePostionRad + WheelCrankAngleDiffRad [ i ] ) ;
50735069
5074- // Trace.TraceInformation("Cyl {0} crankAng {1} Position {2} Diff {3}", NumCylinders, MathHelper.ToDegrees(crankAngleRad), MathHelper.ToDegrees(LocomotiveAxle.AxlePositionRad), MathHelper.ToDegrees(WheelCrankAngleDiffRad));
5070+ crankAngleRad = ( float ) ( MathHelper . WrapAngle ( crankAngleRad ) ) ; // Ensures that crank angle is in the range 0 - 180 - 0
50755071
50765072 float crankCylinderPressure = ( MeanEffectivePressurePSI * CylinderEfficiencyRate ) ; // fallback default value
50775073
5078-
50795074 // Calculate cylinder position in relation to crank (and hence wheel) position.
50805075 // For each full wheel revolution, the cylinder will do two storkes (forward and backwards).
50815076 // Each stroke in turn will have a forward component with a corresponding pressure producing a "+ve" force and reverse component producing a "-ve" force.
@@ -5102,10 +5097,6 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float t,
51025097 backwardCylinderPosition = crankCylinderPosition ;
51035098 }
51045099
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-
51095100 float normalisedCrankAngleRad = NormalisedCrankAngle ( i ) ;
51105101
51115102 // Crank angles
@@ -5165,7 +5156,6 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float t,
51655156 Trace . TraceInformation ( "Cylinder {0} CrankAngle {1} FwdCylPosition {2} FwdCylPressure {3} BwdCylPosition {4} BwdCylPressure {5} CrankPressure {6} ForwardStroke {7} Speed {8}" , i , MathHelper . ToDegrees ( crankAngleRad ) , forwardCylinderPosition , forwardCylinderPressure , backwardCylinderPosition , backwardCylinderPressure , crankCylinderPressure , forwardStroke , MpS . ToMpH ( absSpeedMpS ) ) ;
51665157 }
51675158#endif
5168-
51695159 // Calculate wheel tangential forces = Force applied to wheels
51705160
51715161 float pistonForceLbf = Me2 . ToIn2 ( Me2 . FromFt2 ( CylinderPistonAreaFt2 ) ) * crankCylinderPressure ;
@@ -5174,7 +5164,6 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float t,
51745164
51755165 float tangentialForcelbf = tangentialCrankForceFactor * pistonForceLbf ;
51765166
5177-
51785167 float reciprocatingInertiaAngleFactor = 0 ;
51795168 float connectRodInertiaAngleFactor = 0 ;
51805169
@@ -5194,7 +5183,7 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float t,
51945183 float connectRodInertiaForcelbf = inertiaSpeedCorrectionFactor * connectRodInertiaAngleFactor * ConnectingRodWeightLb ;
51955184
51965185 // 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.
5197- if ( crankAngleRad > 0 && crankAngleRad < Math . PI && normalisedCrankAngleRad < Math . PI )
5186+ if ( axlePostionRad < 0 )
51985187 {
51995188 reciprocatingInertiaForcelbf *= - 1 ;
52005189 connectRodInertiaForcelbf *= - 1 ;
@@ -5219,18 +5208,6 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float t,
52195208 // should be deducted from this as well.
52205209 float tangentialWheelTreadForceLbf = tangentialCrankWheelForceLbf * Me . ToIn ( CylinderStrokeM ) / Me . ToIn ( DrvWheelDiaM ) ;
52215210
5222- // Debug Adhesion problem
5223- /* if (SpeedMpS > 17.88 && SpeedMpS < 18.2 )
5224- {
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-
5229- }
5230-
5231- */
5232-
5233-
52345211 DisplayTangentialWheelTreadForceLbf += tangentialWheelTreadForceLbf ;
52355212 TractiveForceN += N . FromLbf ( tangentialWheelTreadForceLbf ) ;
52365213
@@ -5250,7 +5227,7 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float t,
52505227 float excessBalanceForcelbf = inertiaSpeedCorrectionFactor * excessBalanceWeightLb * sin ;
52515228
52525229 // Account for the position of the crosshead position. In other words it depends upon whether the ExcessBalance is above or below the axle.
5253- if ( crankAngleRad > 0 && crankAngleRad < Math . PI )
5230+ if ( axlePostionRad < 0 )
52545231 {
52555232 excessBalanceForcelbf *= - 1 ;
52565233 }
@@ -5274,23 +5251,6 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float t,
52745251 totalDrvWeightN += N . FromLbf ( excessBalanceForcelbf - verticalThrustForcelbf ) ;
52755252 }
52765253
5277- /* if (DisplayTangentialWheelTreadForceLbf > SteamStaticWheelForce || WheelSlip)
5278- {
5279- // Trace.TraceInformation("MaxSpeed {0}", MaxLocoSpeedMpH);
5280-
5281- Trace.TraceInformation("Cylinder Pressures - Cylinder {0} CylinderPressure {1} forwardPressure {2} backwardPressure {3} InitialPressure {4} CutoffPressure {5} forwardPosition {6} backwardPosition {7}", i+1, crankCylinderPressure, forwardCylinderPressure, backwardCylinderPressure, slipInitialPressureAtmPSI, slipCutoffPressureAtmPSI, forwardCylinderPosition, backwardCylinderPosition);
5282-
5283- Trace.TraceInformation("Crank Angle {0} Cylinder Position {1} AxlePosition {2} Cylinder {3} CylArea {4} CylPress {5}", MathHelper.ToDegrees(crankAngleRad), crankCylinderPosition, MathHelper.ToDegrees(LocomotiveAxle.AxlePositionRad), i, Me2.ToIn2(Me2.FromFt2(CylinderPistonAreaFt2)), crankCylinderPressure);
5284-
5285- Trace.TraceInformation("Tang.CrankFactor {0} RecInertiaFactor {1}, ConInertiaFactor {2} VerticalForceFactor {3} InertiaSpeedFactor {4}", tangentialCrankForceFactor, reciprocatingInertiaAngleFactor, connectRodInertiaAngleFactor, verticalThrustFactor, inertiaSpeedCorrectionFactor);
5286-
5287- Trace.TraceInformation("PistonForce {0}lbf RodForce {1}lbf RecForce {2}lbf", pistonForceLbf, connectRodInertiaForcelbf, reciprocatingInertiaForcelbf);
5288-
5289- Trace.TraceInformation("VerticalThrustForce {0}lbf ExcessBalanceForce {1}lbf", verticalThrustForcelbf, excessBalanceForcelbf);
5290-
5291- }
5292- */
5293-
52945254#if DEBUG_STEAM_SLIP
52955255 if ( throttle > 0.01 && ( absSpeedMpS < 0.2 || absSpeedMpS > 17.7 && absSpeedMpS < 18.2 ) )
52965256 {
@@ -5310,30 +5270,14 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float t,
53105270
53115271 LocomotiveAxles [ 0 ] . AxleWeightN = totalDrvWeightN + 9.81f * DrvWheelWeightKg ;
53125272 SteamStaticWheelForce = N . ToLbf ( totalDrvWeightN + 9.81f * DrvWheelWeightKg ) * LocomotiveCoefficientFrictionHUD ;
5313- /*
5314- if (DisplayTangentialWheelTreadForceLbf > SteamStaticWheelForce)
5315- {
5316- Trace.TraceInformation("Static Wheel Slip (initiated by static comparison) - TangForce {0}lbf: AdhesiveForce {1}lbf: Speed {2}mph, WheelSpeed {3}mph, CrankAngle {4}deg, AdvSlip {5}, AdvSlipWarn {6}, AxleInput - DriveForceCorrect {7}lbf, TotalDriveW {8}lbf, AxleWeightForce {9}lbf, Friction {10}, throttle {11}, Reverser {12} SlipThresholdSpeed {13}mph, WheelSlipSpeed {14}mph, AxleDriveForce {15}lbf", DisplayTangentialWheelTreadForceLbf, SteamStaticWheelForce, MpS.ToMpH(absSpeedMpS), MpS.ToMpH(WheelSpeedMpS), MathHelper.ToDegrees(testCrankAngle), WheelSlip, WheelSlipWarning, N.ToLbf(totalDrvWeightN), N.ToLbf(9.81f * DrvWheelWeightKg), N.ToLbf(LocomotiveAxle.AxleWeightN), LocomotiveCoefficientFrictionHUD, throttle, cutoff, MpS.ToMpH(LocomotiveAxle.WheelSlipThresholdMpS), MpS.ToMpH(LocomotiveAxle.SlipSpeedMpS), N.ToLbf(LocomotiveAxle.DriveForceN));
5317-
5318- }
5319-
5320- if (WheelSlip && DisplayTangentialWheelTreadForceLbf < SteamStaticWheelForce)
5321- {
5322- Trace.TraceInformation("Static Wheel Slip (initiated by axle model) - TangForce {0}lbf: AdhesiveForce {1}lbf: Speed {2}mph, WheelSpeed {3}mph, CrankAngle {4}deg, AdvSlip {5}, AdvSlipWarn {6}, AxleInput - DriveForceCorrect {7}lbf, TotalDriveW {8}lbf, AxleWeightForce {9}lbf, Friction {10}, throttle {11}, Reverser {12} SlipThresholdSpeed {13}mph, WheelSlipSpeed {14}mph, AxleDriveForce {15}lbf", DisplayTangentialWheelTreadForceLbf, SteamStaticWheelForce, MpS.ToMpH(absSpeedMpS), MpS.ToMpH(WheelSpeedMpS), MathHelper.ToDegrees(testCrankAngle), WheelSlip, WheelSlipWarning, N.ToLbf(totalDrvWeightN), N.ToLbf(9.81f * DrvWheelWeightKg), N.ToLbf(LocomotiveAxle.AxleWeightN), LocomotiveCoefficientFrictionHUD, throttle, cutoff, MpS.ToMpH(LocomotiveAxle.WheelSlipThresholdMpS), MpS.ToMpH(LocomotiveAxle.SlipSpeedMpS), N.ToLbf(LocomotiveAxle.DriveForceN));
5323-
5324- }
5325-
5326- */
53275273
53285274#if DEBUG_STEAM_SLIP
5329-
53305275 if ( throttle > 0.01 && ( absSpeedMpS < 0.2 || absSpeedMpS > 17.7 && absSpeedMpS < 18.2 ) )
53315276 {
53325277 Trace . TraceInformation ( "RotationalForce {0} AdhesiveForce {1}" , N . ToLbf ( TractiveForceN ) , SteamStaticWheelForce ) ;
53335278
53345279
53355280 }
5336-
53375281#endif
53385282
53395283
@@ -5385,44 +5329,18 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float t,
53855329 LocomotiveAxles [ 0 ] . DriveForceN = TractiveForceN ;
53865330 }
53875331
5388-
53895332 /// <summary>
53905333 /// Normalise crank angle so that it is a value between 0 and 360 starting at the real crank angle difference
53915334 /// </summary>
5392- private float NormalisedCrankAngle ( int cylinderNumber )
5335+ private float NormalisedCrankAngle ( int cylinderNumber )
53935336 {
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-
5337+ float normalisedCrankAngleRad = ( float ) MathHelper . WrapAngle ( LocomotiveAxles [ 0 ] . AxlePositionRad + WheelCrankAngleDiffRad [ cylinderNumber ] ) ;
54045338
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 )
5339+ if ( normalisedCrankAngleRad < 0 )
54165340 {
5417- normalisedCrankAngleRad -= ( float ) ( 2.0f * Math . PI ) ;
5418-
5341+ normalisedCrankAngleRad += ( float ) ( 2 * Math . PI ) ;
54195342 }
54205343 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-
54265344 }
54275345
54285346
0 commit comments