Skip to content

Commit 607889f

Browse files
committed
Automatic merge of T1.5.1-794-g4cad06780 and 14 pull requests
- Pull request #570 at 3539862: Experimental glTF 2.0 support with PBR lighting - Pull request #839 at d00beb9: First phase of https://blueprints.launchpad.net/or/+spec/additional-cruise-control-parameters - Pull request #876 at f92de76: docs: add source for documents previously on website to source Documentation folder - Pull request #882 at a055bca: Blueprint/train car operations UI window - Pull request #885 at d9ce84b: feat: Add notifications to Menu - Pull request #886 at 6c0785b: Scene viewer extension to TrackViewer - Pull request #892 at 1f5ba4c: Signal Function OPP_SIG_ID_TRAINPATH - Pull request #896 at 5866028: First implementation of https://blueprints.launchpad.net/or/+spec/specific-sounds-for-ai-trains - Pull request #897 at 0a9d939: feat: Improved system information collection - Pull request #899 at 0fb4d1c: Duplex steam engines - Booster Engine addition - Pull request #903 at 22edf27: Downloading route content (Github, zip) - Pull request #906 at 5850660: Bug fix for https://bugs.launchpad.net/or/+bug/2047299 Crash loading a 3Dcab-only loco - Pull request #907 at 9b0b04f: Bug fix for https://bugs.launchpad.net/or/+bug/2047300 Dynamic tracks disappear after long tunnel - Pull request #908 at 4b4afe3: feat: supports switching adhesion precisions
16 parents 8e14580 + 4cad067 + 3539862 + d00beb9 + f92de76 + a055bca + d9ce84b + 6c0785b + 1f5ba4c + 5866028 + 0a9d939 + 0fb4d1c + 22edf27 + 5850660 + 9b0b04f + 4b4afe3 commit 607889f

File tree

2 files changed

+91
-89
lines changed
  • Source
    • Orts.Simulation/Simulation/RollingStocks/SubSystems/PowerTransmissions
    • RunActivity/Viewer3D/Popups

2 files changed

+91
-89
lines changed

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

Lines changed: 90 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -283,23 +283,105 @@ public void Restore(BinaryReader inf)
283283
AxleList[i].Restore(inf);
284284
}
285285
}
286+
287+
/// <summary>
288+
/// switch between Polach and Pacha adhesion calculation
289+
/// </summary>
290+
public static bool UsePolachAdhesion = false; // "static" so there's only one value in the program.
291+
public bool PreviousUsePolachAdhesion = false; // Keep a note for each Axles so that we can tell if it changed.
292+
286293
/// <summary>
287294
/// Updates each axle on the list
288295
/// </summary>
289-
/// <param name="elapsedClockSeconds">Time span within the simulation cycle</param>
290-
public void Update(float elapsedClockSeconds)
296+
/// <param name="elapsedSeconds">Time span within the simulation cycle</param>
297+
public void Update(float elapsedSeconds)
291298
{
299+
UsePolachAdhesion = AdhesionPrecision.IsPrecisionHigh(this, elapsedSeconds, Car.Simulator.GameTime);
292300
foreach (var axle in AxleList)
293301
{
294-
axle.Update(elapsedClockSeconds);
302+
if (UsePolachAdhesion != PreviousUsePolachAdhesion) // There's been a transition
303+
{
304+
axle.AxleSpeedMpS = axle.TrainSpeedMpS; // So the transition doesn't cause a wheelslip
305+
}
306+
axle.Update(elapsedSeconds);
295307
}
308+
PreviousUsePolachAdhesion = UsePolachAdhesion;
296309
}
297310
public List<Axle>.Enumerator GetEnumerator()
298311
{
299312
return AxleList.GetEnumerator();
300313
}
314+
315+
static class AdhesionPrecision // "static" so all "Axles" share the same level of precision
316+
{
317+
enum AdhesionPrecisionLevel
318+
{
319+
/// <summary>
320+
/// Initial level uses Polach algorithm
321+
/// </summary>
322+
High = 0,
323+
/// <summary>
324+
/// Low-performance PCs use Pacha's algorithm
325+
/// </summary>
326+
Low = 1,
327+
/// <summary>
328+
/// After frequent transitions, low-performance PCs are locked to Pacha's algorithm
329+
/// </summary>
330+
LowLocked = 2
301331
}
302332

333+
// Adjustable limits
334+
const float LowerLimitS = 0.025f; // timespan 0.025 = 40 fps screen rate, low timeSpan and high FPS
335+
const float UpperLimitS = 0.033f; // timespan 0.033 = 30 fps screen rate, high timeSpan and low FPS
336+
const double IntervalBetweenDowngradesLimitS = 5 * 60; // Locks in low precision if < 5 mins between downgrades
337+
338+
static AdhesionPrecisionLevel PrecisionLevel = AdhesionPrecisionLevel.High;
339+
static double TimeOfLatestDowngrade = 0 - IntervalBetweenDowngradesLimitS; // Starts at -5 mins
340+
341+
// Tested by dropping the framerate below 30 fps interactively. Did this by opening and closing the HelpWindow after inserting
342+
// Threading.Thread.Sleep(40);
343+
// into HelpWindow.PrepareFrame() temporarily.
344+
public static bool IsPrecisionHigh(Axles axles, float elapsedSeconds, double gameTime)
345+
{
346+
// Switches between Polach (high precision) adhesion model and Pacha (low precision) adhesion model depending upon the PC performance
347+
switch (PrecisionLevel)
348+
{
349+
case AdhesionPrecisionLevel.High:
350+
if (elapsedSeconds > UpperLimitS)
351+
{
352+
var screenFrameRate = 1 / elapsedSeconds;
353+
var timeSincePreviousDowngradeS = gameTime - TimeOfLatestDowngrade;
354+
if (timeSincePreviousDowngradeS < IntervalBetweenDowngradesLimitS)
355+
{
356+
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})");
357+
PrecisionLevel = AdhesionPrecisionLevel.LowLocked;
358+
}
359+
else
360+
{
361+
TimeOfLatestDowngrade = gameTime;
362+
Trace.TraceInformation($"At {gameTime:F0} secs, advanced adhesion model switched to low precision after low frame rate {screenFrameRate:F1} below limit {1 / UpperLimitS:F0}");
363+
PrecisionLevel = AdhesionPrecisionLevel.Low;
364+
}
365+
}
366+
break;
367+
368+
case AdhesionPrecisionLevel.Low:
369+
if (elapsedSeconds > 0 // When debugging step by step, elapsedSeconds == 0, so test for that
370+
&& elapsedSeconds < LowerLimitS)
371+
{
372+
PrecisionLevel = AdhesionPrecisionLevel.High;
373+
var ScreenFrameRate = 1 / elapsedSeconds;
374+
Trace.TraceInformation($"At {gameTime:F0} secs, advanced adhesion model switched to high precision after high frame rate {ScreenFrameRate:F1} above limit {1 / LowerLimitS:F0}");
375+
}
376+
break;
377+
378+
case AdhesionPrecisionLevel.LowLocked:
379+
break;
380+
}
381+
return (PrecisionLevel == AdhesionPrecisionLevel.High);
382+
}
383+
}
384+
}
303385

304386

305387
/// <summary>
@@ -433,12 +515,6 @@ public float InertiaKgm2
433515
/// </summary>
434516
float forceToAccelerationFactor;
435517

436-
/// <summary>
437-
/// switch between Polach and Pacha adhesion calculation
438-
/// </summary>
439-
public static bool UsePolachAdhesion = false; // "static" so it's shared by all axles of the Player's loco
440-
public double GameTime; // Set by MSTSLocomotive and used by AdhesionPrecision.IsPrecisionHigh
441-
442518
/// <summary>
443519
/// Pre-calculation of slip characteristics at 0 slip speed
444520
/// </summary>
@@ -561,7 +637,7 @@ public float TransmissionEfficiency
561637
/// <summary>
562638
/// Axle speed value, in metric meters per second
563639
/// </summary>
564-
public double AxleSpeedMpS { get; private set; }
640+
public double AxleSpeedMpS { get; set; }
565641

566642
/// <summary>
567643
/// Axle angular position in radians
@@ -845,7 +921,7 @@ public void Save(BinaryWriter outf)
845921
double slipSpeedMpS = axleSpeedMpS - TrainSpeedMpS;
846922
double axleOutForceN = 0;
847923

848-
if (UsePolachAdhesion)
924+
if (Axles.UsePolachAdhesion)
849925
{
850926
axleOutForceN = Math.Sign(slipSpeedMpS) * AxleWeightN * SlipCharacteristicsPolach(slipSpeedMpS);
851927
}
@@ -891,7 +967,7 @@ void Integrate(float elapsedClockSeconds)
891967
if (elapsedClockSeconds <= 0) return;
892968
double prevSpeedMpS = AxleSpeedMpS;
893969

894-
if (UsePolachAdhesion)
970+
if (Axles.UsePolachAdhesion)
895971
{
896972

897973
float upperSubStepLimit = 100;
@@ -980,7 +1056,7 @@ void Integrate(float elapsedClockSeconds)
9801056
{
9811057
var k1 = GetAxleMotionVariation(AxleSpeedMpS, dt);
9821058

983-
if (i == 0 && !UsePolachAdhesion)
1059+
if (i == 0 && !Axles.UsePolachAdhesion)
9841060
{
9851061
if (k1.Item1 * dt > Math.Max((Math.Abs(SlipSpeedMpS) - 1) * 10, 1) / 100)
9861062
{
@@ -1023,8 +1099,7 @@ void Integrate(float elapsedClockSeconds)
10231099
/// <param name="elapsedSeconds"></param>
10241100
public virtual void Update(float elapsedSeconds)
10251101
{
1026-
UsePolachAdhesion = AdhesionPrecision.IsPrecisionHigh(elapsedSeconds, GameTime);
1027-
if (UsePolachAdhesion)
1102+
if (Axles.UsePolachAdhesion)
10281103
{
10291104
forceToAccelerationFactor = WheelRadiusM * WheelRadiusM / totalInertiaKgm2;
10301105

@@ -1128,79 +1203,6 @@ public virtual void Update(float elapsedSeconds)
11281203
}
11291204
}
11301205

1131-
static class AdhesionPrecision // "static" so all "Axle"s share the same level of precision
1132-
{
1133-
enum AdhesionPrecisionLevel
1134-
{
1135-
/// <summary>
1136-
/// Initial level uses Polach algorithm
1137-
/// </summary>
1138-
High = 0,
1139-
/// <summary>
1140-
/// Low-performance PCs use Pacha's algorithm
1141-
/// </summary>
1142-
Low = 1,
1143-
/// <summary>
1144-
/// After frequent transitions, low-performance PCs are locked to Pacha's algorithm
1145-
/// </summary>
1146-
LowLocked = 2
1147-
}
1148-
1149-
// Adjustable limits
1150-
const float LowerLimitS = 0.025f; // timespan 0.025 = 40 fps screen rate, low timeSpan and high FPS
1151-
const float UpperLimitS = 0.033f; // timespan 0.033 = 30 fps screen rate, high timeSpan and low FPS
1152-
const double IntervalBetweenDowngradesLimitS = 5 * 60; // Locks in low precision if < 5 mins between downgrades
1153-
1154-
static AdhesionPrecisionLevel PrecisionLevel = AdhesionPrecisionLevel.High;
1155-
static double TimeOfLatestDowngrade = 0 - IntervalBetweenDowngradesLimitS; // Starts at -5 mins
1156-
1157-
// Tested by varying the framerate interactively. Did this by opening and closing the HelpWindow after inserting
1158-
// Threading.Thread.Sleep(40);
1159-
// into HelpWindow.PrepareFrame() temporarily.
1160-
public static bool IsPrecisionHigh(float elapsedSeconds, double gameTime)
1161-
{
1162-
// Switches between Polach (high precision) adhesion model and Pacha (low precision) adhesion model depending upon the PC performance
1163-
switch (PrecisionLevel)
1164-
{
1165-
case AdhesionPrecisionLevel.High:
1166-
if (elapsedSeconds > UpperLimitS)
1167-
{
1168-
var screenFrameRate = 1 / elapsedSeconds;
1169-
var timeSincePreviousDowngradeS = gameTime - TimeOfLatestDowngrade;
1170-
if (timeSincePreviousDowngradeS < IntervalBetweenDowngradesLimitS)
1171-
{
1172-
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})");
1173-
PrecisionLevel = AdhesionPrecisionLevel.LowLocked;
1174-
}
1175-
else
1176-
{
1177-
TimeOfLatestDowngrade = gameTime;
1178-
1179-
Trace.TraceInformation($"At {gameTime:F0} secs, advanced adhesion model switched to low precision after low frame rate {screenFrameRate:F1} below limit {1 / UpperLimitS:F0}");
1180-
PrecisionLevel = AdhesionPrecisionLevel.Low;
1181-
1182-
}
1183-
}
1184-
break;
1185-
1186-
case AdhesionPrecisionLevel.Low:
1187-
if (elapsedSeconds > 0 // When debugging step by step, elapsedSeconds == 0, so test for that
1188-
&& elapsedSeconds < LowerLimitS)
1189-
{
1190-
PrecisionLevel = AdhesionPrecisionLevel.High;
1191-
var ScreenFrameRate = 1 / elapsedSeconds;
1192-
Trace.TraceInformation($"At {gameTime:F0} secs, advanced adhesion model switched to high precision after high frame rate {ScreenFrameRate:F1} above limit {1 / LowerLimitS:F0}");
1193-
}
1194-
break;
1195-
1196-
case AdhesionPrecisionLevel.LowLocked:
1197-
break;
1198-
1199-
}
1200-
return (PrecisionLevel == AdhesionPrecisionLevel.High);
1201-
}
1202-
}
1203-
12041206
class PolachCalculator
12051207
{
12061208
Axle Axle;

Source/RunActivity/Viewer3D/Popups/HUDWindow.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1080,7 +1080,7 @@ void TextPageForceInfo(TableData table)
10801080
if (mstsLocomotive.AdvancedAdhesionModel)
10811081
{
10821082
var text = Viewer.Catalog.GetString("(Advanced adhesion model)");
1083-
if (Axle.UsePolachAdhesion == false) text += "???";
1083+
if (Axles.UsePolachAdhesion == false) text += "???";
10841084
TableAddLine(table, text);
10851085
int row0 = table.CurrentRow;
10861086
TableSetCell(table, table.CurrentRow++, table.CurrentLabelColumn, Viewer.Catalog.GetString("Wheel slip (Thres)"));

0 commit comments

Comments
 (0)