Skip to content

Commit 780b0e8

Browse files
committed
Adjustments to derail algorithim
1 parent 8a7c2af commit 780b0e8

File tree

1 file changed

+23
-15
lines changed
  • Source/Orts.Simulation/Simulation/RollingStocks

1 file changed

+23
-15
lines changed

Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,6 +1420,7 @@ public void UpdateTrainDerailmentRisk(float elapsedClockSeconds)
14201420

14211421
// Calculate the vertical force on the wheel of the car, to determine whether wagon derails or not
14221422
// To calculate vertical force on outer wheel = (WagMass / NumWheels) * gravity + WagMass / NumAxles * ( (Speed^2 / CurveRadius) - (gravity * superelevation angle)) * (height * track width)
1423+
// Equation 5
14231424

14241425
if (IsPlayerTrain)
14251426
{
@@ -1435,7 +1436,7 @@ public void UpdateTrainDerailmentRisk(float elapsedClockSeconds)
14351436
// Prevent NaN if numWheels = 0
14361437
if (numWheels != 0)
14371438
{
1438-
A = MassKG * GravitationalAccelerationMpS2 / numWheels;
1439+
A = (MassKG / numWheels) * GravitationalAccelerationMpS2;
14391440
}
14401441
else
14411442
{
@@ -1445,16 +1446,17 @@ public void UpdateTrainDerailmentRisk(float elapsedClockSeconds)
14451446
// Prevent NaN if numAxles = 0
14461447
if (numAxles != 0)
14471448
{
1448-
B1 = (MassKG / numAxles) * (float)Math.Pow(Math.Abs(SpeedMpS), 2) / CurrentCurveRadius;
1449+
B1 = (MassKG / numAxles);
14491450
}
14501451
else
14511452
{
1452-
B1 = MassKG * (float)Math.Pow(Math.Abs(SpeedMpS), 2) / CurrentCurveRadius;
1453+
B1 = MassKG;
14531454
}
1454-
var B2 = GravitationalAccelerationMpS2 * (float)Math.Cos(SuperElevationAngleRad);
1455-
var B3 = CentreOfGravityM.Y / TrackGaugeM;
1455+
var B2 = GravitationalAccelerationMpS2 * (float)Math.Sin(SuperElevationAngleRad);
1456+
var B3 = (float)Math.Pow(Math.Abs(SpeedMpS), 2) / CurrentCurveRadius;
1457+
var B4 = CentreOfGravityM.Y / TrackGaugeM;
14561458

1457-
TotalWagonVerticalDerailForceN = A + (B1 - B2) * B3;
1459+
TotalWagonVerticalDerailForceN = A + B1 * (B3 - B2) * B4;
14581460

14591461
// Calculate lateral force per wheelset on the first bogie
14601462
// Lateral Force = (Coupler force x Sin (Coupler Angle) / NumBogies) + WagMass / NumAxles * ( (Speed^2 / CurveRadius) - (gravity * superelevation angle))
@@ -1467,11 +1469,13 @@ public void UpdateTrainDerailmentRisk(float elapsedClockSeconds)
14671469
// Prevent NaN if WagonNumBogies = 0
14681470
if ( WagonNumBogies != 0)
14691471
{
1470-
AA1 = CarAhead.CouplerForceU * (float)Math.Sin(WagonCouplerAngleDerailRad) / WagonNumBogies;
1472+
// AA1 = CarAhead.CouplerForceU * (float)Math.Sin(WagonCouplerAngleDerailRad) / WagonNumBogies;
1473+
AA1 = Math.Abs(CarAhead.CouplerForceUSmoothed.SmoothedValue) * (float)Math.Sin(WagonCouplerAngleDerailRad) / WagonNumBogies;
14711474
}
14721475
else
14731476
{
1474-
AA1 = CarAhead.CouplerForceU * (float)Math.Sin(WagonCouplerAngleDerailRad);
1477+
// AA1 = CarAhead.CouplerForceU * (float)Math.Sin(WagonCouplerAngleDerailRad);
1478+
AA1 = Math.Abs(CarAhead.CouplerForceUSmoothed.SmoothedValue) * (float)Math.Sin(WagonCouplerAngleDerailRad);
14751479
}
14761480

14771481
// Prevent NaN if numAxles = 0
@@ -1486,19 +1490,21 @@ public void UpdateTrainDerailmentRisk(float elapsedClockSeconds)
14861490
var BB2 = (float)Math.Pow(Math.Abs(SpeedMpS), 2) / CurrentCurveRadius;
14871491
var BB3 = GravitationalAccelerationMpS2 * (float)Math.Sin(SuperElevationAngleRad);
14881492

1489-
TotalWagonLateralDerailForceN = AA1 + BB1 * (BB2 - BB3);
1493+
TotalWagonLateralDerailForceN = Math.Abs(AA1 + BB1 * (BB2 - BB3));
14901494
}
14911495

1492-
DerailmentCoefficient = Math.Abs(TotalWagonLateralDerailForceN / TotalWagonVerticalDerailForceN);
1496+
DerailmentCoefficient = TotalWagonLateralDerailForceN / TotalWagonVerticalDerailForceN;
14931497

1494-
// use the dynamic multiplication coefficient to calculate final derailment coefficient
1498+
// use the dynamic multiplication coefficient to calculate final derailment coefficient, the above method calculated using quasi-static factors.
1499+
// The quasi-static do not include allowance for wheel unloading due to static carbody pitch. Hence the following factors have been used to adjust to dynamic effects.
1500+
// They have been adjusted slightly based upon derailment accident reports. Original figures quoted were 2 x for standard curves, and 3.1 x for turnouts.
14951501
if (IsOverJunction())
14961502
{
1497-
DerailmentCoefficient *= 3.1f;
1503+
DerailmentCoefficient *= 2.17f;
14981504
}
14991505
else
15001506
{
1501-
DerailmentCoefficient *= 2.0f;
1507+
DerailmentCoefficient *= 1.4f;
15021508
}
15031509

15041510
var wagonAdhesion = Train.WagonCoefficientFriction;
@@ -1543,11 +1549,13 @@ public void UpdateTrainDerailmentRisk(float elapsedClockSeconds)
15431549
{
15441550
DerailExpected = true;
15451551
Simulator.Confirmer.Message(ConfirmLevel.Warning, Simulator.Catalog.GetStringFmt("Car {0} has derailed on the curve.", CarID));
1546-
1552+
// Trace.TraceInformation("Car Derail - CarID: {0}, Coupler: {1}, CouplerSmoothed {2}, Lateral {3}, Vertical {4}, Angle {5} Nadal {6} Coeff {7}", CarID, CouplerForceU, CouplerForceUSmoothed.SmoothedValue, TotalWagonLateralDerailForceN, TotalWagonVerticalDerailForceN, WagonCouplerAngleDerailRad, NadalDerailmentCoefficient, DerailmentCoefficient);
1553+
// Trace.TraceInformation("Car Ahead Derail - CarID: {0}, Coupler: {1}, CouplerSmoothed {2}, Lateral {3}, Vertical {4}, Angle {5}", CarAhead.CarID, CarAhead.CouplerForceU, CarAhead.CouplerForceUSmoothed.SmoothedValue, CarAhead.TotalWagonLateralDerailForceN, CarAhead.TotalWagonVerticalDerailForceN, CarAhead.WagonCouplerAngleDerailRad);
15471554
}
15481555
else if (DerailPossible)
15491556
{
15501557
DerailElapsedTimeS += elapsedClockSeconds;
1558+
// Trace.TraceInformation("Car Derail Time - CarID: {0}, Coupler: {1}, CouplerSmoothed {2}, Lateral {3}, Vertical {4}, Angle {5}, Elapsed {6}, DeratilTime {7}, Distance {8} Nadal {9} Coeff {10}", CarID, CouplerForceU, CouplerForceUSmoothed.SmoothedValue, TotalWagonLateralDerailForceN, TotalWagonVerticalDerailForceN, WagonCouplerAngleDerailRad, DerailElapsedTimeS, derailTimeS, DerailClimbDistanceM, NadalDerailmentCoefficient, DerailmentCoefficient);
15511559
}
15521560
else
15531561
{
@@ -1767,7 +1775,7 @@ public virtual void UpdateCurveSpeedLimit()
17671775

17681776
SuperelevationM = MathHelper.Clamp(SuperelevationM, 0.0001f, 0.150f); // If superelevation is greater then 6" (150mm) then limit to this value, having a value of zero causes problems with calculations
17691777

1770-
SuperElevationAngleRad = (float)Math.Sinh(SuperelevationM); // Total superelevation includes both balanced and unbalanced superelevation
1778+
SuperElevationAngleRad = (float)Math.Sinh(SuperelevationM); // Balanced superelevation only angle
17711779

17721780
MaxCurveEqualLoadSpeedMps = (float)Math.Sqrt((SuperelevationM * GravitationalAccelerationMpS2 * CurrentCurveRadius) / TrackGaugeM); // Used for calculating curve resistance
17731781

0 commit comments

Comments
 (0)