Skip to content

Commit d331d9d

Browse files
committed
Correct Maximum Indicated HP per engine
1 parent 549ca09 commit d331d9d

File tree

2 files changed

+97
-45
lines changed

2 files changed

+97
-45
lines changed

Source/Orts.Simulation/Simulation/RollingStocks/MSTSSteamLocomotive.cs

Lines changed: 88 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,7 +1499,6 @@ public override void Initialize()
14991499
MaxTractiveEffortLbf += SteamEngines[i].MaxTractiveEffortLbf;
15001500
}
15011501

1502-
15031502
DisplayMaxTractiveEffortLbf = MaxTractiveEffortLbf;
15041503

15051504
// ****************** Test Boiler Type *********************
@@ -1892,23 +1891,33 @@ public override void Initialize()
18921891
RetainedGearedMaxMaxIndicatedHorsePowerHP = MaxIndicatedHorsePowerHP;
18931892
}
18941893

1895-
if (MaxIndicatedHorsePowerHP == 0) // if MaxIHP is not set in ENG file, then set a default
1894+
for (int i = 0; i < SteamEngines.Count; i++)
18961895
{
1897-
// Max IHP = (Max TE x Speed) / 375.0, use a factor of 0.85 to calculate max TE
1898-
MaxIndicatedHorsePowerHP = MaxSpeedFactor * (MaxTractiveEffortLbf * MaxLocoSpeedMpH) / 375.0f; // To be checked what MaxTractive Effort is for the purposes of this formula.
1899-
1900-
// Check to see if MaxIHP is in fact limited by the boiler
1901-
if (MaxIndicatedHorsePowerHP > MaxBoilerOutputHP)
1896+
if (SteamEngines[i].MaxIndicatedHorsePowerHP == 0 && SteamEngines.Count == 0 && MaxIndicatedHorsePowerHP != 0) // if MaxIHP is not set in ENG file, then set a default
19021897
{
1903-
MaxIndicatedHorsePowerHP = MaxBoilerOutputHP; // Set maxIHp to limit set by boiler
1904-
ISBoilerLimited = true;
1898+
SteamEngines[i].MaxIndicatedHorsePowerHP = MaxIndicatedHorsePowerHP;
19051899
}
19061900
else
1907-
{
1908-
ISBoilerLimited = false;
1901+
{
1902+
// Max IHP = (Max TE x Speed) / 375.0, use a factor of 0.85 to calculate max TE
1903+
SteamEngines[i].MaxIndicatedHorsePowerHP = MaxSpeedFactor * (SteamEngines[i].MaxTractiveEffortLbf * MaxLocoSpeedMpH) / 375.0f; // To be checked what MaxTractive Effort is for the purposes of this formula.
1904+
1905+
MaxIndicatedHorsePowerHP += SteamEngines[i].MaxIndicatedHorsePowerHP;
19091906
}
19101907
}
19111908

1909+
1910+
// Check to see if MaxIHP is in fact limited by the boiler
1911+
if (MaxIndicatedHorsePowerHP > MaxBoilerOutputHP)
1912+
{
1913+
MaxIndicatedHorsePowerHP = MaxBoilerOutputHP; // Set maxIHp to limit set by boiler
1914+
ISBoilerLimited = true;
1915+
}
1916+
else
1917+
{
1918+
ISBoilerLimited = false;
1919+
}
1920+
19121921
DisplayMaxIndicatedHorsePowerHP = MaxIndicatedHorsePowerHP;
19131922

19141923
// If DrvWheelWeight is not in ENG file, then calculate from Factor of Adhesion(FoA) = DrvWheelWeight / Start (Max) Tractive Effort, assume FoA = 4.2
@@ -2793,7 +2802,7 @@ private void UpdateFX(float elapsedClockSeconds)
27932802
{
27942803
variable[i] = Math.Abs((float)SteamEngines[i].AttachedAxle.AxleSpeedMpS / SteamEngines[i].AttachedAxle.WheelRadiusM / MathHelper.Pi * 5);
27952804
}
2796-
Variable1 = ThrottlePercent == 0 ? 0 : variable[i];
2805+
variable[i] = ThrottlePercent == 0 ? 0 : variable[i];
27972806
}
27982807

27992808
// Set variables for each engine
@@ -2802,6 +2811,8 @@ private void UpdateFX(float elapsedClockSeconds)
28022811
Variable3_1 = variable[2];
28032812
Variable4_1 = variable[3];
28042813

2814+
// Trace.TraceInformation("Variable1 {0} Variable2_1 {1} Variable3_1 {2} Variable4_1 {3}", Variable1, Variable2_1, Variable3_1, Variable4_1);
2815+
28052816
Variable2 = MathHelper.Clamp((CylinderCocksPressureAtmPSI - OneAtmospherePSI) / BoilerPressurePSI * 100f, 0, 100);
28062817
Variable3 = FuelRateSmoothed * 100;
28072818

@@ -5124,10 +5135,10 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float loc
51245135
// Pass force and power information to MSTSLocomotive file by overriding corresponding method there
51255136

51265137
// Set Max Power equal to max IHP
5127-
MaxPowerW = W.FromHp(MaxIndicatedHorsePowerHP);
5138+
MaxPowerW = W.FromHp(SteamEngines[numberofengine].MaxIndicatedHorsePowerHP);
51285139

51295140
// Set maximum force for the locomotive
5130-
MaxForceN = N.FromLbf(MaxTractiveEffortLbf * CylinderEfficiencyRate);
5141+
MaxForceN = N.FromLbf(SteamEngines[numberofengine].MaxTractiveEffortLbf * CylinderEfficiencyRate);
51315142

51325143
// Set Max Velocity of locomotive
51335144
MaxSpeedMpS = Me.FromMi(pS.FrompH(MaxLocoSpeedMpH)); // Note this is not the true max velocity of the locomotive, but the speed at which max HP is reached
@@ -5378,6 +5389,11 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float loc
53785389

53795390
SteamEngines[numberofengine].TractiveForceN += N.FromLbf(Math.Max(tangentialWheelTreadForceLbf, -1000));
53805391

5392+
if (SteamEngines[numberofengine].AuxiliarySteamEngineType == SteamEngine.AuxiliarySteamEngineTypes.Booster)
5393+
{
5394+
SteamEngines[numberofengine].TractiveForceN *= SteamEngines[numberofengine].BoosterGearRatio;
5395+
}
5396+
53815397
#if DEBUG_STEAM_SLIP
53825398
if (SpeedMpS > 17.88 && SpeedMpS < 18.5 || SpeedMpS > 34.0 && throttle == 0)
53835399
{
@@ -5525,10 +5541,10 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float loc
55255541

55265542
#endregion
55275543

5528-
if (IndicatedHorsePowerHP >= MaxIndicatedHorsePowerHP)
5544+
if (SteamEngines[numberofengine].IndicatedHorsePowerHP >= SteamEngines[numberofengine].MaxIndicatedHorsePowerHP)
55295545
{
55305546
SteamEngines[numberofengine].TractiveForceN = N.FromLbf((MaxIndicatedHorsePowerHP * 375.0f) / pS.TopH(Me.ToMi(SpeedMpS)));
5531-
IndicatedHorsePowerHP = MaxIndicatedHorsePowerHP; // Set IHP to maximum value
5547+
SteamEngines[numberofengine].IndicatedHorsePowerHP = SteamEngines[numberofengine].MaxIndicatedHorsePowerHP; // Set IHP to maximum value
55325548
IsCritTELimit = true; // Flag if limiting TE
55335549
}
55345550
else
@@ -5546,15 +5562,12 @@ protected override void UpdateTractiveForce(float elapsedClockSeconds, float loc
55465562
SteamEngines[numberofengine].TractiveForceN = 0.5f;
55475563
}
55485564

5549-
5550-
5551-
55525565
// Based upon max IHP, limit motive force.
55535566

5554-
if (IndicatedHorsePowerHP >= MaxIndicatedHorsePowerHP)
5567+
if (SteamEngines[numberofengine].IndicatedHorsePowerHP >= SteamEngines[numberofengine].MaxIndicatedHorsePowerHP)
55555568
{
5556-
TractiveForceN = N.FromLbf((MaxIndicatedHorsePowerHP * 375.0f) / pS.TopH(Me.ToMi(SpeedMpS)));
5557-
IndicatedHorsePowerHP = MaxIndicatedHorsePowerHP; // Set IHP to maximum value
5569+
SteamEngines[numberofengine].TractiveForceN = N.FromLbf((SteamEngines[numberofengine].MaxIndicatedHorsePowerHP * 375.0f) / pS.TopH(Me.ToMi(SpeedMpS)));
5570+
SteamEngines[numberofengine].IndicatedHorsePowerHP = SteamEngines[numberofengine].MaxIndicatedHorsePowerHP; // Set IHP to maximum value
55585571
IsCritTELimit = true; // Flag if limiting TE
55595572
}
55605573
else
@@ -7005,31 +7018,63 @@ public override string GetDebugStatus()
70057018
else
70067019
{
70077020
status.AppendFormat("\n\t\t === {0} === \n", Simulator.Catalog.GetString("Performance"));
7008-
status.AppendFormat("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\n",
7009-
Simulator.Catalog.GetString("Power:"),
7010-
Simulator.Catalog.GetString("MaxInd"),
7011-
FormatStrings.FormatPower(W.FromHp(MaxIndicatedHorsePowerHP), IsMetric, false, false),
7012-
Simulator.Catalog.GetString("Ind"),
7013-
FormatStrings.FormatPower(W.FromHp(IndicatedHorsePowerHP), IsMetric, false, false),
7014-
Simulator.Catalog.GetString("Drawbar"),
7015-
FormatStrings.FormatPower(W.FromHp(DrawbarHorsePowerHP), IsMetric, false, false),
7016-
Simulator.Catalog.GetString("BlrLmt"),
7017-
ISBoilerLimited ? Simulator.Catalog.GetString("Yes") : Simulator.Catalog.GetString("No"));
70187021

7019-
status.AppendFormat("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}\t{11}\t{12}\n",
7022+
if (SteamEngines.Count > 1)
7023+
{
7024+
for (int i = 0; i < SteamEngines.Count; i++)
7025+
{
7026+
status.AppendFormat("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\n",
7027+
Simulator.Catalog.GetString("Power:"),
7028+
Simulator.Catalog.GetString("Eng#"),
7029+
i + 1,
7030+
Simulator.Catalog.GetString("MaxInd"),
7031+
FormatStrings.FormatPower(W.FromHp(SteamEngines[i].MaxIndicatedHorsePowerHP), IsMetric, false, false),
7032+
Simulator.Catalog.GetString("Ind"),
7033+
FormatStrings.FormatPower(W.FromHp(SteamEngines[i].IndicatedHorsePowerHP), IsMetric, false, false)
7034+
);
7035+
}
7036+
}
7037+
7038+
status.AppendFormat("{0}\t\t\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\n",
7039+
Simulator.Catalog.GetString("PowerTot:"),
7040+
Simulator.Catalog.GetString("MaxInd"),
7041+
FormatStrings.FormatPower(W.FromHp(MaxIndicatedHorsePowerHP), IsMetric, false, false),
7042+
Simulator.Catalog.GetString("Ind"),
7043+
FormatStrings.FormatPower(W.FromHp(IndicatedHorsePowerHP), IsMetric, false, false),
7044+
Simulator.Catalog.GetString("Drawbar"),
7045+
FormatStrings.FormatPower(W.FromHp(DrawbarHorsePowerHP), IsMetric, false, false),
7046+
Simulator.Catalog.GetString("BlrLmt"),
7047+
ISBoilerLimited ? Simulator.Catalog.GetString("Yes") : Simulator.Catalog.GetString("No"));
7048+
7049+
if (SteamEngines.Count > 1)
7050+
{
7051+
for (int i = 0; i < SteamEngines.Count; i++)
7052+
{
7053+
status.AppendFormat("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\n",
70207054
Simulator.Catalog.GetString("Force:"),
7055+
Simulator.Catalog.GetString("Eng#"),
7056+
i + 1,
70217057
Simulator.Catalog.GetString("TheorTE"),
7022-
FormatStrings.FormatForce(N.FromLbf(MaxTractiveEffortLbf), IsMetric),
7023-
Simulator.Catalog.GetString("StartTE"),
7024-
FormatStrings.FormatForce(absStartTractiveEffortN, IsMetric),
7058+
FormatStrings.FormatForce(N.FromLbf(SteamEngines[i].MaxTractiveEffortLbf), IsMetric),
70257059
Simulator.Catalog.GetString("TE"),
7026-
FormatStrings.FormatForce(MotiveForceN, IsMetric),
7027-
Simulator.Catalog.GetString("Draw"),
7028-
FormatStrings.FormatForce(N.FromLbf(DrawBarPullLbsF), IsMetric),
7029-
Simulator.Catalog.GetString("CritSpeed"),
7030-
FormatStrings.FormatSpeedDisplay(MpS.FromMpH(MaxLocoSpeedMpH), IsMetric),
7031-
Simulator.Catalog.GetString("SpdLmt"),
7032-
IsCritTELimit ? Simulator.Catalog.GetString("Yes") : Simulator.Catalog.GetString("No"));
7060+
FormatStrings.FormatForce(SteamEngines[i].TractiveForceN, IsMetric));
7061+
}
7062+
}
7063+
7064+
status.AppendFormat("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}\t{11}\t{12}\n",
7065+
Simulator.Catalog.GetString("ForceTot:"),
7066+
Simulator.Catalog.GetString("TheorTE"),
7067+
FormatStrings.FormatForce(N.FromLbf(MaxTractiveEffortLbf), IsMetric),
7068+
Simulator.Catalog.GetString("StartTE"),
7069+
FormatStrings.FormatForce(absStartTractiveEffortN, IsMetric),
7070+
Simulator.Catalog.GetString("TE"),
7071+
FormatStrings.FormatForce(MotiveForceN, IsMetric),
7072+
Simulator.Catalog.GetString("Draw"),
7073+
FormatStrings.FormatForce(N.FromLbf(DrawBarPullLbsF), IsMetric),
7074+
Simulator.Catalog.GetString("CritSpeed"),
7075+
FormatStrings.FormatSpeedDisplay(MpS.FromMpH(MaxLocoSpeedMpH), IsMetric),
7076+
Simulator.Catalog.GetString("SpdLmt"),
7077+
IsCritTELimit ? Simulator.Catalog.GetString("Yes") : Simulator.Catalog.GetString("No"));
70337078

70347079
status.AppendFormat("{0}\t{1}\t{2:N0} {7}/{8}\t\t{3}\t{4:N0} {9}\t{5} {6:N2}\t\t{10}\t{11}\n",
70357080
Simulator.Catalog.GetString("Move:"),

Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/PowerSupplies/SteamEngine.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ public void Parse(string lowercasetoken, STFReader stf)
108108
}
109109
}
110110
break;
111-
112111
}
113112
}
114113

@@ -352,7 +351,10 @@ public enum AuxiliarySteamEngineTypes
352351
/// </summary>
353352
public float TractiveForceN;
354353

355-
354+
/// <summary>
355+
/// Steam Engine maximum indicated horsepower
356+
/// </summary>
357+
public float MaxIndicatedHorsePowerHP;
356358

357359

358360
/// <summary>
@@ -659,6 +661,10 @@ public virtual void Parse(STFReader stf)
659661
case "boosterthrottlecutoff": BoosterThrottleCutoff = stf.ReadFloatBlock(STFReader.UNITS.None, null); initLevel |= SettingsFlags.BoosterThrottleCutoffF; break;
660662
case "boostergearratio": BoosterGearRatio = stf.ReadFloatBlock(STFReader.UNITS.None, null); initLevel |= SettingsFlags.BoosterGearRatioF; break;
661663
case "attachedaxle": AttachedAxleId = stf.ReadIntBlock(null); initLevel |= SettingsFlags.AttachedAxleIdF; break;
664+
case "maxindicatedhorsepower":
665+
MaxIndicatedHorsePowerHP = stf.ReadFloatBlock(STFReader.UNITS.Power, null);
666+
MaxIndicatedHorsePowerHP = W.ToHp(MaxIndicatedHorsePowerHP); // Convert input to HP for use internally in this module
667+
break;
662668

663669
case "auxiliarysteamenginetype":
664670
stf.MustMatch("(");
@@ -690,6 +696,7 @@ public void Copy(SteamEngine other)
690696
LPCylindersStrokeM = other.LPCylindersStrokeM;
691697
LPCylindersDiameterM = other.LPCylindersDiameterM;
692698
BoosterCutoff = other.BoosterCutoff;
699+
MaxIndicatedHorsePowerHP = other.MaxIndicatedHorsePowerHP;
693700
BoosterThrottleCutoff = other.BoosterThrottleCutoff;
694701
BoosterGearRatio = other.BoosterGearRatio;
695702
AttachedAxleId = other.AttachedAxleId;

0 commit comments

Comments
 (0)