Skip to content

Commit a325039

Browse files
committed
feat: supports switching adhesion precisions
1 parent ffaeec0 commit a325039

File tree

1 file changed

+47
-22
lines changed
  • Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/PowerTransmissions

1 file changed

+47
-22
lines changed

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

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ public float InertiaKgm2
432432
/// switch between Polach and Pacha adhesion calculation
433433
/// </summary>
434434
public static bool UsePolachAdhesion = false; // "static" so it's shared by all axles of the Player's loco
435+
public double GameTime; // Set by MSTSLocomotive and used by AdhesionPrecision.IsPrecisionHigh
435436

436437
/// <summary>
437438
/// Pre-calculation of slip characteristics at 0 slip speed
@@ -1001,7 +1002,7 @@ void Integrate(float elapsedClockSeconds)
10011002
/// <param name="elapsedSeconds"></param>
10021003
public virtual void Update(float elapsedSeconds)
10031004
{
1004-
UsePolachAdhesion = AdhesionPrecision.IsPrecisionHigh(elapsedSeconds);
1005+
UsePolachAdhesion = AdhesionPrecision.IsPrecisionHigh(elapsedSeconds, GameTime);
10051006
if (UsePolachAdhesion)
10061007
{
10071008
forceToAccelerationFactor = WheelRadiusM * WheelRadiusM / totalInertiaKgm2;
@@ -1104,43 +1105,67 @@ enum AdhesionPrecisionLevel
11041105
/// <summary>
11051106
/// Initial level uses Polach algorithm
11061107
/// </summary>
1107-
High,
1108+
High = 0,
11081109
/// <summary>
11091110
/// Low-performance PCs use Pacha's algorithm
11101111
/// </summary>
1111-
Low
1112+
Low = 1,
1113+
/// <summary>
1114+
/// After frequent transitions, low-performance PCs are locked to Pacha's algorithm
1115+
/// </summary>
1116+
LowLocked = 2
11121117
}
11131118

1114-
static AdhesionPrecisionLevel PrecisionLevel = AdhesionPrecisionLevel.High;
1115-
static double TimeOfLatestDowngrade = 0;
1116-
11171119
// Adjustable limits
1120+
const float LowerLimitS = 0.025f; // timespan 0.025 = 40 fps screen rate, low timeSpan and high FPS
11181121
const float UpperLimitS = 0.033f; // timespan 0.033 = 30 fps screen rate, high timeSpan and low FPS
1122+
const double IntervalBetweenDowngradesLimitS = 5 * 60; // Locks in low precision if < 5 mins between downgrades
1123+
1124+
static AdhesionPrecisionLevel PrecisionLevel = AdhesionPrecisionLevel.High;
1125+
static double TimeOfLatestDowngrade = 0 - IntervalBetweenDowngradesLimitS; // Starts at -5 mins
11191126

11201127
// Tested by varying the framerate interactively. Did this by opening and closing the HelpWindow after inserting
11211128
// Threading.Thread.Sleep(40);
11221129
// into HelpWindow.PrepareFrame() temporarily.
1123-
public static bool IsPrecisionHigh(float elapsedSeconds)
1130+
public static bool IsPrecisionHigh(float elapsedSeconds, double gameTime)
11241131
{
1125-
if (elapsedSeconds > 0) // Ignore period with elapsedSeconds == 0 until user starts game.
1132+
// Switches between Polach (high precision) adhesion model and Pacha (low precision) adhesion model depending upon the PC performance
1133+
switch (PrecisionLevel)
11261134
{
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)
1135+
case AdhesionPrecisionLevel.High:
1136+
if (elapsedSeconds > UpperLimitS)
1137+
{
1138+
var screenFrameRate = 1 / elapsedSeconds;
1139+
var timeSincePreviousDowngradeS = gameTime - TimeOfLatestDowngrade;
1140+
if (timeSincePreviousDowngradeS < IntervalBetweenDowngradesLimitS)
11321141
{
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-
}
1142+
Trace.TraceInformation($"At {gameTime:F0} secs, advanced adhesion model switched to low precision permanently after {timeSincePreviousDowngradeS:F0} secs since previous switch (less than limit of {IntervalBetweenDowngradesLimitS})");
1143+
PrecisionLevel = AdhesionPrecisionLevel.LowLocked;
11381144
}
1139-
break;
1145+
else
1146+
{
1147+
TimeOfLatestDowngrade = gameTime;
1148+
1149+
Trace.TraceInformation($"At {gameTime:F0} secs, advanced adhesion model switched to low precision after low frame rate {screenFrameRate:F1} below limit {1 / UpperLimitS:F0}");
1150+
PrecisionLevel = AdhesionPrecisionLevel.Low;
1151+
1152+
}
1153+
}
1154+
break;
1155+
1156+
case AdhesionPrecisionLevel.Low:
1157+
if (elapsedSeconds > 0 // When debugging step by step, elapsedSeconds == 0, so test for that
1158+
&& elapsedSeconds < LowerLimitS)
1159+
{
1160+
PrecisionLevel = AdhesionPrecisionLevel.High;
1161+
var ScreenFrameRate = 1 / elapsedSeconds;
1162+
Trace.TraceInformation($"At {gameTime:F0} secs, advanced adhesion model switched to high precision after high frame rate {ScreenFrameRate:F1} above limit {1 / LowerLimitS:F0}");
1163+
}
1164+
break;
1165+
1166+
case AdhesionPrecisionLevel.LowLocked:
1167+
break;
11401168

1141-
case AdhesionPrecisionLevel.Low:
1142-
break;
1143-
}
11441169
}
11451170
return (PrecisionLevel == AdhesionPrecisionLevel.High);
11461171
}

0 commit comments

Comments
 (0)