Skip to content

Commit

Permalink
Automatic merge of T1.4-72-gebdff935d and 8 pull requests
Browse files Browse the repository at this point in the history
- Pull request #510 at ded7bd3: Add performance monitoring for diesel mechanic locomotives and new parameters
- Pull request #525 at b5ac1d2: Add SignalTypeName and DrawStateName to SignalFeatures
- Pull request #527 at 27f05a1: Brake cuts power refactor and new parameters
- Pull request #531 at b2affac: Bug fix for https://bugs.launchpad.net/or/+bug/1950578 Dyn Brake setup state not disappearing in cab
- Pull request #533 at 62a1c27: fix for shapes hidden by animations( 0 )
- Pull request #537 at e753905: C# signal script extensions
- Pull request #538 at c457f11: Delete binary paths if the ascii version or the tdb was modified. Blueprint: https://blueprints.launchpad.net/or/+spec/binary-timetable-paths
- Pull request #539 at fd04274: Correct starting tractive force of steam locomotive
  • Loading branch information
openrails-bot committed Dec 5, 2021
10 parents 0471824 + ebdff93 + ded7bd3 + b5ac1d2 + 27f05a1 + b2affac + 62a1c27 + e753905 + c457f11 + fd04274 commit d604151
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 33 deletions.
Expand Up @@ -1203,7 +1203,7 @@ public void Update(float elapsedClockSeconds)
CurrentDieselOutputPowerW = CurrentDieselOutputPowerW < 0f ? 0f : CurrentDieselOutputPowerW;
}

// If it is a geared locomotive, and rpm is greater then Max RpM, then output power should be reduced.
// If it is a geared locomotive, and rpm is greater then Max RpM, then output power display should be reduced.
if (GovenorEnabled && HasGearBox)
{
if (DemandedRPM > MaxRPM)
Expand Down
Expand Up @@ -196,6 +196,9 @@ public class GearBox : ISubSystem<GearBox>
public bool GearBoxScoopCouplingFitted;
public bool GearBoxFreeWheelFitted;

public float previousThrottleSetting;
public float previousRpM;

public float ManualGearTimerResetS = 2; // Allow gear change to take 2 seconds
public float ManualGearTimerS; // Time for gears to change
public bool ManualGearBoxChangeOn = false;
Expand Down Expand Up @@ -469,6 +472,7 @@ public bool IsOverspeedWarning
public GearBoxOperation GearBoxOperation = GearBoxOperation.Manual;
public GearBoxOperation OriginalGearBoxOperation = GearBoxOperation.Manual;

public float tractiveForceN;
public float TractiveForceN
{
get
Expand All @@ -480,7 +484,7 @@ public float TractiveForceN
{
if (ClutchPercent >= -20)
{
float tractiveForceN = DieselEngine.DieselTorqueTab[DieselEngine.RealRPM] * DieselEngine.DemandedThrottlePercent / DieselEngine.DieselTorqueTab.MaxY() * 0.01f * CurrentGear.MaxTractiveForceN;
tractiveForceN = DieselEngine.DieselTorqueTab[DieselEngine.RealRPM] * DieselEngine.DemandedThrottlePercent / DieselEngine.DieselTorqueTab.MaxY() * 0.01f * CurrentGear.MaxTractiveForceN;
if (CurrentSpeedMpS > 0)
{
if (tractiveForceN > (DieselEngine.CurrentDieselOutputPowerW / CurrentSpeedMpS))
Expand All @@ -507,41 +511,127 @@ public float TractiveForceN
dieselRpM = DieselEngine.RealRPM;
}

// For diesel mechanic locomotives hold torque (TE) at the value requested by throttle
if (Locomotive.DieselTransmissionType != TrainCar.DieselTransmissionTypes.Mechanic && dieselRpM > DieselEngine.ThrottleRPMTab[DieselEngine.DemandedThrottlePercent])
float throttleFraction = 0;

if (ShaftRPM != dieselRpM && !IsClutchOn && DieselEngine.ApparentThrottleSetting < DieselEngine.DemandedThrottlePercent)
{
dieselRpM = DieselEngine.ThrottleRPMTab[DieselEngine.DemandedThrottlePercent];
// Use apparent throttle when accelerating, but use demenaded throttle at other times????
throttleFraction = DieselEngine.ApparentThrottleSetting * 0.01f; // Convert from percentage to fraction, use the apparent throttle as this includes some delay for rpm increase
}
else
{
throttleFraction = DieselEngine.DemandedThrottlePercent * 0.01f;
}

float tractiveForceN = DieselEngine.DieselTorqueTab[dieselRpM] / DieselEngine.DieselTorqueTab.MaxY() * CurrentGear.MaxTractiveForceN;

Locomotive.HuDGearMaximumTractiveForce = CurrentGear.MaxTractiveForceN;

// Limit tractive force if engine is governed, ie speed cannot exceed the governed speed or the throttled speed
// Diesel mechanical transmission are not "governed" at all engine speed settings, rather only at Idle and Max RpM.
// (See above where DM units TE held at constant value, unless overwritten by the following)
if ((DieselEngine.RealRPM >= DieselEngine.GovenorRPM && ShaftRPM > DieselEngine.GovenorRPM) || (Locomotive.DieselTransmissionType != TrainCar.DieselTransmissionTypes.Mechanic && DieselEngine.RealRPM < DieselEngine.GovenorRPM && DieselEngine.RealRPM > DieselEngine.ThrottleRPMTab[DieselEngine.DemandedThrottlePercent]))
if (Locomotive.DieselTransmissionType == TrainCar.DieselTransmissionTypes.Mechanic)
{
// use decay function to decrease tractive effort if RpM exceeds governed RpM value.
// y = original amount ( 1 - decay rate)^length of prediction
float decayRpM = 0;

if (DieselEngine.RealRPM < DieselEngine.GovenorRPM && DieselEngine.RealRPM > DieselEngine.ThrottleRPMTab[DieselEngine.DemandedThrottlePercent])
if (DieselEngine.DemandedThrottlePercent > 0 && DieselEngine.RealRPM > DieselEngine.IdleRPM * 1.5)
{
decayRpM = ShaftRPM - DieselEngine.ThrottleRPMTab[DieselEngine.DemandedThrottlePercent];

// Governor at maxRpM
if (DieselEngine.RealRPM >= DieselEngine.GovenorRPM && ShaftRPM > DieselEngine.GovenorRPM && ShaftRPM > previousRpM && tractiveForceN > 0)
{
throttleFraction = previousThrottleSetting - 0.1f; // reduce fuel admission by reducing throttle (calculation only, not displayed)
throttleFraction = MathHelper.Clamp(throttleFraction, 0.0f, 1.0f); // Clamp throttle setting within bounds, so it doesn't go negative
previousThrottleSetting = throttleFraction; // Set for next iteration
previousRpM = ShaftRPM;
// Trace.TraceInformation("Decrease - RealRpm {0} GovernorRpM {1} previousRpM {2} Shaft {3} PrevThottle {4} ", DieselEngine.RealRPM, DieselEngine.GovenorRPM, previousRpM, ShaftRPM, previousThrottleSetting);
}
else if (DieselEngine.RealRPM >= DieselEngine.GovenorRPM && ShaftRPM > DieselEngine.GovenorRPM && ShaftRPM + 5.0f < previousRpM)
{
throttleFraction = previousThrottleSetting + 0.1f; // increase fuel admission by increasing the throttle (calculation only, not displayed)
throttleFraction = MathHelper.Clamp(throttleFraction, 0.0f, 1.0f); // Clamp throttle setting within bounds
previousThrottleSetting = throttleFraction; // Set for next iteration
previousRpM = ShaftRPM;
// Trace.TraceInformation("Increase - RealRpm {0} GovernorRpM {1} previousRpM {2} Shaft {3} PrevThottle {4} ", DieselEngine.RealRPM, DieselEngine.GovenorRPM, previousRpM, ShaftRPM, previousThrottleSetting);
}
else if (DieselEngine.RealRPM < DieselEngine.GovenorRPM && ShaftRPM < DieselEngine.GovenorRPM) // Reset
{
previousThrottleSetting = throttleFraction; // Set for next iteration
previousRpM = DieselEngine.RealRPM;
// Trace.TraceInformation("Loop - RealRpm {0} Shaft {1} PrevThrottle {2}", DieselEngine.RealRPM, ShaftRPM, previousThrottleSetting);
}
else if (DieselEngine.RealRPM >= DieselEngine.GovenorRPM && ShaftRPM > DieselEngine.GovenorRPM && tractiveForceN < 0)
{
throttleFraction = previousThrottleSetting + 0.1f; // increase fuel admission by increasing the throttle (calculation only, not displayed)
throttleFraction = MathHelper.Clamp(throttleFraction, 0.0f, 1.0f); // Clamp throttle setting within bounds
previousThrottleSetting = throttleFraction; // Set for next iteration
previousRpM = ShaftRPM;
// Trace.TraceInformation("Negative - RealRpm {0} GovernorRpM {1} previousRpM {2} Shaft {3} PrevThottle {4} ", DieselEngine.RealRPM, DieselEngine.GovenorRPM, previousRpM, ShaftRPM, previousThrottleSetting);
}
else // No Change
{

throttleFraction = previousThrottleSetting;
previousThrottleSetting = throttleFraction; // Set for next iteration
// previousRpM = DieselEngine.RealRPM;
// Trace.TraceInformation("Loop#2 - RealRpm {0} Shaft {1} PrevThrottle {2}", DieselEngine.RealRPM, ShaftRPM, previousThrottleSetting);

}

}
else

if (DieselEngine.DemandedThrottlePercent > 0 && DieselEngine.RealRPM < DieselEngine.IdleRPM * 1.5)
{
decayRpM = ShaftRPM - DieselEngine.GovenorRPM;
// Governor at IdleRpM

if (DieselEngine.RealRPM <= DieselEngine.IdleRPM && ShaftRPM < DieselEngine.IdleRPM && ShaftRPM < previousRpM && tractiveForceN > 0)
{
throttleFraction = previousThrottleSetting + 0.1f; // reduce fuel admission by reducing throttle (calculation only, not displayed)
throttleFraction = MathHelper.Clamp(throttleFraction, 0.0f, 1.0f); // Clamp throttle setting within bounds, so it doesn't go negative
previousThrottleSetting = throttleFraction; // Set for next iteration
previousRpM = ShaftRPM;
// Trace.TraceInformation("Increase - RealRpm {0} GovernorRpM {1} previousRpM {2} Shaft {3} PrevThottle {4} TE {5}", DieselEngine.RealRPM, DieselEngine.GovenorRPM, previousRpM, ShaftRPM, previousThrottleSetting, tractiveForceN);
}
else if (DieselEngine.RealRPM <= DieselEngine.IdleRPM && ShaftRPM < DieselEngine.IdleRPM && ShaftRPM - 5.0f > previousRpM)
{
throttleFraction = previousThrottleSetting - 0.1f; // increase fuel admission by increasing the throttle (calculation only, not displayed)
throttleFraction = MathHelper.Clamp(throttleFraction, 0.0f, 1.0f); // Clamp throttle setting within bounds
previousThrottleSetting = throttleFraction; // Set for next iteration
previousRpM = ShaftRPM;
// Trace.TraceInformation("Decrease - RealRpm {0} GovernorRpM {1} previousRpM {2} Shaft {3} PrevThottle {4} ", DieselEngine.RealRPM, DieselEngine.GovenorRPM, previousRpM, ShaftRPM, previousThrottleSetting);
}
else if (DieselEngine.RealRPM > DieselEngine.IdleRPM && ShaftRPM > DieselEngine.IdleRPM) // Reset
{
previousThrottleSetting = throttleFraction; // Set for next iteration
previousRpM = DieselEngine.RealRPM;
// Trace.TraceInformation("Loop - RealRpm {0} Shaft {1} PrevThrottle {2}", DieselEngine.RealRPM, ShaftRPM, previousThrottleSetting);
}
else // No Change
{

throttleFraction = previousThrottleSetting;
previousThrottleSetting = throttleFraction; // Set for next iteration
// previousRpM = DieselEngine.RealRPM;
// Trace.TraceInformation("Loop#2 - RealRpm {0} Shaft {1} PrevThrottle {2}", DieselEngine.RealRPM, ShaftRPM, previousThrottleSetting);

}


}

var teDecline = Math.Pow((1.0f - 0.05f), decayRpM);

tractiveForceN = (float)Math.Abs(CurrentGear.MaxTractiveForceN * teDecline);
tractiveForceN = MathHelper.Clamp(tractiveForceN, 0.0f, CurrentGear.MaxTractiveForceN); // Clamp tractive effort so that it doesn't go below zero
}

// Trace.TraceInformation("Geared Tractive Effort #1 - Driving - TE: {0} lbf, RpM: {1}, Torque: {2} lb-ft, Throttle%: {3}, MaxTorque: {4} lb-ft, MaxTE {5} lbf, Speed: {6} mph, Clutch {7}, Gear: {8} IsClutchOn {9} Shaft RpM {10} DemandedRpM {11}", tractiveForceN * 0.224809f, DieselEngine.RealRPM, DieselEngine.DieselTorqueTab[DieselEngine.RealRPM] * 0.737562f, DieselEngine.DemandedThrottlePercent, DieselEngine.DieselTorqueTab.MaxY(), CurrentGear.MaxTractiveForceN * 0.224809f, CurrentSpeedMpS * 2.23694f, ClutchPercent, Locomotive.GearBoxController.CurrentNotch, IsClutchOn, ShaftRPM, DieselEngine.DemandedRPM);


// A torque vs rpm family of curves has been built based on the information on this page
// https://www.cm-labs.com/vortexstudiodocumentation/Vortex_User_Documentation/Content/Editor/editor_vs_configure_engine.html
//
// Calculate torque curve for throttle position and RpM
var rpmRatio = (dieselRpM - DieselEngine.IdleRPM) / (DieselEngine.MaxRPM - DieselEngine.IdleRPM);
var torqueCurveMultiplier = (0.824f * throttleFraction + 0.176f) + (0.785f * throttleFraction - 0.785f) * rpmRatio;

// During normal operation fuel admission is fixed, and therefore TE follows curve as RpM varies
tractiveForceN = torqueCurveMultiplier * CurrentGear.MaxTractiveForceN;

// Trace.TraceInformation("Tractive Force {0}, Throttle {1} TCM {2} RpM {3} Throttle% {4}", tractiveForceN, throttleFraction, torqueCurveMultiplier, dieselRpM, DieselEngine.DemandedThrottlePercent);

Locomotive.HuDGearMaximumTractiveForce = CurrentGear.MaxTractiveForceN;

// Trace.TraceInformation("Geared Tractive Effort #1 - Driving - TE: {0} lbf, RpM: {1}, Torque: {2} lb-ft, Throttle%: {3}, MaxTorque: {4} lb-ft, MaxTE {5} lbf, Speed: {6} mph, Clutch {7}, Gear: {8} IsClutchOn {9} Shaft RpM {10} DemandedRpM {11} rpmRatio {12} TCM {13}", tractiveForceN * 0.224809f, DieselEngine.RealRPM, DieselEngine.DieselTorqueTab[DieselEngine.RealRPM] * 0.737562f, DieselEngine.DemandedThrottlePercent, DieselEngine.DieselTorqueTab.MaxY(), CurrentGear.MaxTractiveForceN * 0.224809f, CurrentSpeedMpS * 2.23694f, ClutchPercent, Locomotive.GearBoxController.CurrentNotch, IsClutchOn, ShaftRPM, DieselEngine.DemandedRPM, rpmRatio, torqueCurveMultiplier);

if (CurrentSpeedMpS > 0)
{
Expand All @@ -557,20 +647,12 @@ public float TractiveForceN
{
tractiveForceN = 0;
}

// If throttle closed and in gear then coasting, the gear box and engine will apply a small force to retard the movement of the locomotive
if (CurrentGear != null && CurrentSpeedMpS > 0.01 && DieselEngine.demandedThrottlePercent == 0)
tractiveForceN = - CurrentGear.CoastingForceN;
// tractiveForceN = -CurrentGear.CoastingForceN * (100f + ClutchPercent) / 100f;
else if (CurrentGear != null && CurrentSpeedMpS < 0.01 && DieselEngine.demandedThrottlePercent == 0)
tractiveForceN = CurrentGear.CoastingForceN;
// tractiveForceN = CurrentGear.CoastingForceN * (100f + ClutchPercent) / 100f;


return tractiveForceN;
}
else
{
return 0;
return 0;
}
}
else
Expand Down

0 comments on commit d604151

Please sign in to comment.