Skip to content

Commit df4e92a

Browse files
authored
Merge pull request #431 from peternewell/motive-force-separation
Correct issue with motive force being reduced by braking force https://bugs.launchpad.net/or/+bug/1931520
2 parents 9249e6c + 057dc64 commit df4e92a

File tree

3 files changed

+70
-23
lines changed

3 files changed

+70
-23
lines changed

Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2374,15 +2374,16 @@ public void AdvancedAdhesion(float elapsedClockSeconds)
23742374

23752375
//Set axle model parameters
23762376

2377-
//LocomotiveAxle.BrakeForceN = FrictionForceN;
2378-
// LocomotiveAxle.BrakeRetardForceN = BrakeForceN;
2379-
2377+
// Inputs
23802378
LocomotiveAxle.BrakeRetardForceN = BrakeRetardForceN;
2381-
LocomotiveAxle.AxleWeightN = 9.81f * DrvWheelWeightKg; //will be computed each time considering the tilting
2382-
LocomotiveAxle.DriveForceN = MotiveForceN; //Total force applied to wheels
2383-
LocomotiveAxle.TrainSpeedMpS = SpeedMpS; //Set the train speed of the axle model
2384-
LocomotiveAxle.Update(elapsedClockSeconds); //Main updater of the axle model
2385-
MotiveForceN = LocomotiveAxle.AxleForceN; //Get the Axle force and use it for the motion
2379+
LocomotiveAxle.AxleWeightN = 9.81f * DrvWheelWeightKg; //will be computed each time considering the tilting
2380+
LocomotiveAxle.DriveForceN = MotiveForceN; //Total force applied to wheels
2381+
LocomotiveAxle.TrainSpeedMpS = SpeedMpS; //Set the train speed of the axle model
2382+
LocomotiveAxle.Update(elapsedClockSeconds); //Main updater of the axle model
2383+
2384+
// Output
2385+
MotiveForceN = LocomotiveAxle.CompensatedAxleForceN; //Get the Axle force and use it for the motion (use compensated value as it is independent of brake force)
2386+
23862387
if (elapsedClockSeconds > 0)
23872388
{
23882389
WheelSlip = LocomotiveAxle.IsWheelSlip; //Get the wheelslip indicator
@@ -4279,7 +4280,7 @@ public virtual float GetDataOf(CabViewControl cvc)
42794280
if (FilteredMotiveForceN != 0)
42804281
data = this.FilteredMotiveForceN / MaxForceN * rangeFactor;
42814282
else
4282-
data = this.LocomotiveAxle.AxleForceN / MaxForceN * rangeFactor;
4283+
data = this.LocomotiveAxle.DriveForceN / MaxForceN * rangeFactor;
42834284
data = Math.Abs(data);
42844285
}
42854286
if (DynamicBrakePercent > 0 && MaxDynamicBrakeForceN > 0)
@@ -4325,7 +4326,7 @@ public virtual float GetDataOf(CabViewControl cvc)
43254326
if (FilteredMotiveForceN != 0)
43264327
data = this.FilteredMotiveForceN / MaxForceN * MaxCurrentA;
43274328
else
4328-
data = this.LocomotiveAxle.AxleForceN / MaxForceN * MaxCurrentA;
4329+
data = this.LocomotiveAxle.DriveForceN / MaxForceN * MaxCurrentA;
43294330
data = Math.Abs(data);
43304331
}
43314332
if (DynamicBrakePercent > 0 && MaxDynamicBrakeForceN > 0)
@@ -4346,7 +4347,7 @@ public virtual float GetDataOf(CabViewControl cvc)
43464347
if (FilteredMotiveForceN != 0)
43474348
data = this.FilteredMotiveForceN;
43484349
else
4349-
data = this.LocomotiveAxle.AxleForceN;
4350+
data = this.LocomotiveAxle.DriveForceN;
43504351
if (DynamicBrakePercent > 0)
43514352
{
43524353
data = DynamicBrakeForceN;
@@ -4394,7 +4395,7 @@ public virtual float GetDataOf(CabViewControl cvc)
43944395
if (FilteredMotiveForceN != 0)
43954396
data = Math.Abs(this.FilteredMotiveForceN);
43964397
else
4397-
data = Math.Abs(this.LocomotiveAxle.AxleForceN);
4398+
data = Math.Abs(this.LocomotiveAxle.DriveForceN);
43984399
if (DynamicBrakePercent > 0)
43994400
{
44004401
data = -Math.Abs(DynamicBrakeForceN);

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

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public class Axle
6060
public Integrator AxleRevolutionsInt = new Integrator(0.0f, IntegratorMethods.RungeKutta4);
6161

6262
public MovingAverage FilterMovingAverage = new MovingAverage(10);
63+
public MovingAverage CompensatedFilterMovingAverage = new MovingAverage(10);
6364

6465
/// <summary>
6566
/// Brake force covered by BrakeForceN interface
@@ -344,6 +345,21 @@ public float AxleForceN
344345
}
345346
}
346347

348+
/// <summary>
349+
/// Compensated Axle force value, this provided the motive force equivalent excluding brake force, in Newtons
350+
/// </summary>
351+
float compensatedaxleForceN;
352+
/// <summary>
353+
/// Read only axle force value, in Newtons
354+
/// </summary>
355+
public float CompensatedAxleForceN
356+
{
357+
get
358+
{
359+
return compensatedaxleForceN;
360+
}
361+
}
362+
347363
/// <summary>
348364
/// Read/Write axle weight parameter in Newtons
349365
/// </summary>
@@ -617,6 +633,12 @@ public virtual void Update(float timeSpan)
617633
//Update axle force ( = k * loadTorqueNm)
618634
axleForceN = AxleWeightN * SlipCharacteristics(AxleSpeedMpS - TrainSpeedMpS, TrainSpeedMpS, AdhesionK, AdhesionConditions, Adhesion2);
619635

636+
// The Axle module subtracts brake force from the motive force for calculation purposes. However brake force is already taken into account in the braking module.
637+
// And thus there is a duplication of the braking effect in OR. To compensate for this, after the slip characteristics have been calculated, the output of the axle module
638+
// has the brake force "added" back in to give the appropriate motive force output for the locomotive. Braking force is handled separately.
639+
// Hence CompensatedAxleForce is the actual output force on the axle.
640+
var compensateAxleForceN = axleForceN;
641+
620642
switch (driveType)
621643
{
622644
case AxleDriveType.NotDriven:
@@ -656,42 +678,60 @@ public virtual void Update(float timeSpan)
656678
/ totalInertiaKgm2
657679
);
658680

681+
compensateAxleForceN = axleForceN + brakeRetardForceN;
682+
683+
if (Math.Abs(compensateAxleForceN) > Math.Abs(driveForceN))
684+
{
685+
compensateAxleForceN = driveForceN;
686+
}
687+
659688
if (brakeRetardForceN > driveForceN && AxleSpeedMpS < 0.1f)
660689
{
661690
axleSpeedMpS = 0.0f;
662691
axleForceN = -brakeRetardForceN + driveForceN;
692+
compensateAxleForceN = driveForceN;
663693
}
664694
}
665695
else if (TrainSpeedMpS < -0.01f)
666696
{
667-
axleSpeedMpS = AxleRevolutionsInt.Integrate(timeSpan,
668-
(
669-
driveForceN * transmissionEfficiency
670-
+ brakeRetardForceN
671-
- slipDerivationMpSS * dampingNs
672-
+ Math.Abs(SlipSpeedMpS) * frictionN
673-
- AxleForceN
674-
)
675-
/ totalInertiaKgm2
676-
);
697+
698+
axleSpeedMpS = AxleRevolutionsInt.Integrate(timeSpan,
699+
(
700+
driveForceN * transmissionEfficiency
701+
+ brakeRetardForceN
702+
- slipDerivationMpSS * dampingNs
703+
+ Math.Abs(SlipSpeedMpS) * frictionN
704+
- AxleForceN
705+
)
706+
/ totalInertiaKgm2
707+
);
708+
709+
compensateAxleForceN = axleForceN - brakeRetardForceN;
710+
711+
if (Math.Abs(compensateAxleForceN) > Math.Abs(driveForceN))
712+
{
713+
compensateAxleForceN = driveForceN;
714+
}
677715

678716
if (brakeRetardForceN > Math.Abs(driveForceN) && AxleSpeedMpS > -0.1f)
679717
{
680718
axleSpeedMpS = 0.0f;
681719
axleForceN = brakeRetardForceN - driveForceN;
720+
compensateAxleForceN = driveForceN;
682721
}
683722
}
684723
else
685724
{
686725
if (Math.Abs(driveForceN) < 1f)
687726
{
688727
Reset();
689-
axleSpeedMpS = 0.0f;
728+
axleSpeedMpS = 0.0f;
690729
//axleForceN = 0.0f;
691730
}
692731
else
693732
{
694733
axleForceN = driveForceN - brakeRetardForceN;
734+
compensateAxleForceN = driveForceN;
695735
if (Math.Abs(axleSpeedMpS) < 0.01f)
696736
Reset();
697737
}
@@ -722,6 +762,9 @@ public virtual void Update(float timeSpan)
722762
adhesionK = (adhesionK <= 0.7f) ? 0.7f : (adhesionK - 0.005f);
723763
}
724764

765+
// Set output MotiveForce to actual value exclusive of brake force.
766+
compensatedaxleForceN = CompensatedFilterMovingAverage.Update(Math.Abs(compensatedaxleForceN) > Math.Abs(driveForceN) ? driveForceN : compensateAxleForceN);
767+
725768
axleForceN = FilterMovingAverage.Update(Math.Abs(axleForceN) > Math.Abs(driveForceN) ? driveForceN : axleForceN);
726769
}
727770

Source/RunActivity/Viewer3D/Popups/HUDWindow.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,9 @@ void TextPageForceInfo(TableData table)
872872
TableAddLabelValue(table, Viewer.Catalog.GetString("Axle out force"), "{0} ({1})",
873873
FormatStrings.FormatForce(mstsLocomotive.LocomotiveAxle.AxleForceN, mstsLocomotive.IsMetric),
874874
FormatStrings.FormatPower(mstsLocomotive.LocomotiveAxle.AxleForceN * mstsLocomotive.AbsTractionSpeedMpS, mstsLocomotive.IsMetric, false, false));
875+
TableAddLabelValue(table, Viewer.Catalog.GetString("Comp Axle out force"), "{0} ({1})",
876+
FormatStrings.FormatForce(mstsLocomotive.LocomotiveAxle.CompensatedAxleForceN, mstsLocomotive.IsMetric),
877+
FormatStrings.FormatPower(mstsLocomotive.LocomotiveAxle.CompensatedAxleForceN * mstsLocomotive.AbsTractionSpeedMpS, mstsLocomotive.IsMetric, false, false));
875878
TableAddLabelValue(table, Viewer.Catalog.GetString("Wheel Speed"), "{0} ({1})",
876879
FormatStrings.FormatSpeedDisplay(mstsLocomotive.AbsWheelSpeedMpS, mstsLocomotive.IsMetric),
877880
FormatStrings.FormatSpeedDisplay(mstsLocomotive.LocomotiveAxle.SlipSpeedMpS, mstsLocomotive.IsMetric)

0 commit comments

Comments
 (0)