Skip to content

Commit b90893b

Browse files
authored
Merge pull request #904 from cjakeman/fix-advanced-adhesion-downgrade-once-only
fix: adds downgrade to low precision
2 parents 362e836 + 71beb33 commit b90893b

File tree

3 files changed

+79
-37
lines changed

3 files changed

+79
-37
lines changed

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

Lines changed: 73 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
using Orts.Simulation.RollingStocks.SubSystems.PowerTransmissions;
3030
using SharpDX.Direct2D1;
3131
using SharpDX.Direct3D9;
32+
using Orts.Formats.OR;
33+
using static Orts.Simulation.RollingStocks.SubSystems.PowerTransmissions.Axle;
3234

3335
namespace Orts.Simulation.RollingStocks.SubSystems.PowerTransmissions
3436
{
@@ -429,7 +431,7 @@ public float InertiaKgm2
429431
/// <summary>
430432
/// switch between Polach and Pacha adhesion calculation
431433
/// </summary>
432-
bool UsePolachAdhesion = false;
434+
public static bool UsePolachAdhesion = false; // "static" so it's shared by all axles of the Player's loco
433435

434436
/// <summary>
435437
/// Pre-calculation of slip characteristics at 0 slip speed
@@ -996,37 +998,13 @@ void Integrate(float elapsedClockSeconds)
996998
/// - computes axle dynamic model according to its driveType
997999
/// - computes wheelslip indicators
9981000
/// </summary>
999-
/// <param name="timeSpan"></param>
1000-
public virtual void Update(float timeSpan)
1001+
/// <param name="elapsedSeconds"></param>
1002+
public virtual void Update(float elapsedSeconds)
10011003
{
1002-
// Test to determine whether to use Polach or Pacha adhesion
1003-
1004-
// Switches between Polach (high performance) adhesion model and Pacha (low performance) adhesion model depending upon the PC performance
1005-
if(timeSpan < 0.025) // timespan 0.025 = 40 fps screen rate, low timeSpan and high FPS
1006-
{
1007-
UsePolachAdhesion = true;
1008-
}
1009-
else if(timeSpan > 0.033) // timespan 0.033 = 30 fps screen rate, high timeSpan and low FPS
1010-
{
1011-
UsePolachAdhesion = false;
1012-
if (TrainSpeedMpS > 0 )
1013-
{
1014-
var ScreenFrameRate = 1 / timeSpan;
1015-
Trace.TraceInformation("Advanced adhesion model switched to low performance option due to low frame rate {0} at ElapsedClockSeconds of {1}", ScreenFrameRate, timeSpan);
1016-
1017-
}
1018-
1019-
// Set values for Pacha adhesion
1020-
WheelSlipThresholdMpS = MpS.FromKpH(AdhesionK / AdhesionLimit);
1021-
WheelAdhesion = 0.99f;
1022-
MaximumPolachWheelAdhesion = 0.99f;
1023-
1024-
}
1025-
1026-
forceToAccelerationFactor = WheelRadiusM * WheelRadiusM / totalInertiaKgm2;
1027-
1004+
UsePolachAdhesion = AdhesionPrecision.IsPrecisionHigh(elapsedSeconds);
10281005
if (UsePolachAdhesion)
10291006
{
1007+
forceToAccelerationFactor = WheelRadiusM * WheelRadiusM / totalInertiaKgm2;
10301008

10311009
Polach.Update();
10321010
axleStaticForceN = AxleWeightN * SlipCharacteristicsPolach(0);
@@ -1039,6 +1017,15 @@ public virtual void Update(float timeSpan)
10391017
axleStaticForceN = AxleWeightN * SlipCharacteristicsPolach(0);
10401018
}
10411019
}
1020+
else
1021+
{
1022+
// Set values for Pacha adhesion
1023+
WheelSlipThresholdMpS = MpS.FromKpH(AdhesionK / AdhesionLimit);
1024+
WheelAdhesion = 0.99f;
1025+
MaximumPolachWheelAdhesion = 0.99f;
1026+
1027+
forceToAccelerationFactor = WheelRadiusM * WheelRadiusM / totalInertiaKgm2;
1028+
}
10421029

10431030
#if DEBUG_ADHESION
10441031
double[] spd = new double[50];
@@ -1063,9 +1050,9 @@ public virtual void Update(float timeSpan)
10631050
Console.WriteLine("");
10641051
#endif
10651052

1066-
motor?.Update(timeSpan);
1053+
motor?.Update(elapsedSeconds);
10671054

1068-
Integrate(timeSpan);
1055+
Integrate(elapsedSeconds);
10691056
// TODO: We should calculate brake force here
10701057
// Adding and substracting the brake force is correct for normal operation,
10711058
// but during wheelslip this will produce wrong results.
@@ -1084,14 +1071,14 @@ public virtual void Update(float timeSpan)
10841071
{
10851072
IsWheelSlip = IsWheelSlipWarning = true;
10861073
}
1087-
WheelSlipTimeS += timeSpan;
1074+
WheelSlipTimeS += elapsedSeconds;
10881075
}
10891076
else if (Math.Abs(SlipSpeedPercent) > SlipWarningTresholdPercent)
10901077
{
10911078
// Wait some time before indicating wheelslip to avoid false triggers
10921079
if (WheelSlipWarningTimeS > 1) IsWheelSlipWarning = true;
10931080
IsWheelSlip = false;
1094-
WheelSlipWarningTimeS += timeSpan;
1081+
WheelSlipWarningTimeS += elapsedSeconds;
10951082
}
10961083
else
10971084
{
@@ -1100,16 +1087,65 @@ public virtual void Update(float timeSpan)
11001087
WheelSlipWarningTimeS = WheelSlipTimeS = 0;
11011088
}
11021089

1103-
if (timeSpan > 0.0f)
1090+
if (elapsedSeconds > 0.0f)
11041091
{
1105-
slipDerivationMpSS = (SlipSpeedMpS - previousSlipSpeedMpS) / timeSpan;
1092+
slipDerivationMpSS = (SlipSpeedMpS - previousSlipSpeedMpS) / elapsedSeconds;
11061093
previousSlipSpeedMpS = SlipSpeedMpS;
11071094

1108-
slipDerivationPercentpS = (SlipSpeedPercent - previousSlipPercent) / timeSpan;
1095+
slipDerivationPercentpS = (SlipSpeedPercent - previousSlipPercent) / elapsedSeconds;
11091096
previousSlipPercent = SlipSpeedPercent;
11101097
}
11111098
}
11121099

1100+
static class AdhesionPrecision // "static" so all "Axle"s share the same level of precision
1101+
{
1102+
enum AdhesionPrecisionLevel
1103+
{
1104+
/// <summary>
1105+
/// Initial level uses Polach algorithm
1106+
/// </summary>
1107+
High,
1108+
/// <summary>
1109+
/// Low-performance PCs use Pacha's algorithm
1110+
/// </summary>
1111+
Low
1112+
}
1113+
1114+
static AdhesionPrecisionLevel PrecisionLevel = AdhesionPrecisionLevel.High;
1115+
static double TimeOfLatestDowngrade = 0;
1116+
1117+
// Adjustable limits
1118+
const float UpperLimitS = 0.033f; // timespan 0.033 = 30 fps screen rate, high timeSpan and low FPS
1119+
1120+
// Tested by varying the framerate interactively. Did this by opening and closing the HelpWindow after inserting
1121+
// Threading.Thread.Sleep(40);
1122+
// into HelpWindow.PrepareFrame() temporarily.
1123+
public static bool IsPrecisionHigh(float elapsedSeconds)
1124+
{
1125+
if (elapsedSeconds > 0) // Ignore period with elapsedSeconds == 0 until user starts game.
1126+
{
1127+
// Switches between Polach (high precision) adhesion model and Pacha (low precision) adhesion model depending upon the PC performance
1128+
switch (PrecisionLevel)
1129+
{
1130+
case AdhesionPrecisionLevel.High:
1131+
if (elapsedSeconds > UpperLimitS)
1132+
{
1133+
var screenFrameRate = 1 / elapsedSeconds;
1134+
{
1135+
Trace.TraceInformation($"Advanced adhesion model switched to low precision permanently after low frame rate {screenFrameRate:F1} below limit {1 / UpperLimitS:F0}");
1136+
PrecisionLevel = AdhesionPrecisionLevel.Low;
1137+
}
1138+
}
1139+
break;
1140+
1141+
case AdhesionPrecisionLevel.Low:
1142+
break;
1143+
}
1144+
}
1145+
return (PrecisionLevel == AdhesionPrecisionLevel.High);
1146+
}
1147+
}
1148+
11131149
class PolachCalculator
11141150
{
11151151
Axle Axle;
@@ -1200,6 +1236,7 @@ public void Update()
12001236
polach_Ks = (1.2 * zeroSpeedAdhesion) - 0.26;
12011237
if (polach_Ks < 0.1) polach_Ks = 0.1f;
12021238
}
1239+
12031240
public double SlipCharacteristics(double slipSpeedMpS)
12041241
{
12051242
var polach_uadhesion = zeroSpeedAdhesion * (((1 - polach_A) * Math.Exp(-polach_B * slipSpeedMpS)) + polach_A);

Source/RunActivity/Viewer3D/Popups/HUDWindow.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
using Orts.Simulation.RollingStocks.SubSystems.Brakes;
2828
using Orts.Simulation.RollingStocks.SubSystems.Brakes.MSTS;
2929
using Orts.Simulation.RollingStocks.SubSystems.PowerSupplies;
30+
using Orts.Simulation.RollingStocks.SubSystems.PowerTransmissions;
3031
using Orts.Viewer3D.Processes;
3132
using ORTS.Common;
3233
using ORTS.Scripting.Api;
@@ -1078,7 +1079,9 @@ void TextPageForceInfo(TableData table)
10781079
{
10791080
if (mstsLocomotive.AdvancedAdhesionModel)
10801081
{
1081-
TableAddLine(table, Viewer.Catalog.GetString("(Advanced adhesion model)"));
1082+
var text = Viewer.Catalog.GetString("(Advanced adhesion model)");
1083+
if (Axle.UsePolachAdhesion == false) text += "???";
1084+
TableAddLine(table, text);
10821085
int row0 = table.CurrentRow;
10831086
TableSetCell(table, table.CurrentRow++, table.CurrentLabelColumn, Viewer.Catalog.GetString("Wheel slip (Thres)"));
10841087
TableSetCell(table, table.CurrentRow++, table.CurrentLabelColumn, Viewer.Catalog.GetString("Conditions"));

Source/RunActivity/Viewer3D/Popups/HelpWindow.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,6 +1216,8 @@ public TabData(Tab tab, string tabLabel, Action<ControlLayout> layout)
12161216

12171217
public override void PrepareFrame(ElapsedTime elapsedTime, bool updateFull)
12181218
{
1219+
// Uncomment this statement to reduce framerate during play for testing
1220+
//System.Threading.Thread.Sleep(40); // Press F1 to force framerate below 25 fps
12191221

12201222
base.PrepareFrame(elapsedTime, updateFull);
12211223

0 commit comments

Comments
 (0)