Skip to content

Commit 0d2de70

Browse files
authored
Merge pull request #1120 from SteelFill/auto_friction
Automatically Calculate Friction Values if Missing
2 parents 9e88e3a + 47e9955 commit 0d2de70

File tree

5 files changed

+409
-244
lines changed

5 files changed

+409
-244
lines changed

Source/Documentation/Manual/features-rollingstock.rst

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -762,9 +762,9 @@ and the state of these parameters when the wagon or locomotive is full.
762762
single: FullBrakeRelayValveInshot
763763

764764
To configure the stock correctly the following empty and full parameters need to be
765-
included in the ORTSFreightAnims file. Empty values are included in the first block,
766-
and full values are included in the second code block. A sample code block is shown
767-
below::
765+
included in the ``ORTSFreightAnims`` block. Empty values are included in the first block,
766+
and full values are included in the ``FreightAnimContinuous`` or ``FreightAnimStatic``
767+
sub-block. A sample code block is shown below::
768768

769769
ORTSFreightAnims
770770
(
@@ -800,6 +800,12 @@ below::
800800
)
801801
)
802802

803+
Any parameters not included will use the equivalent value specified outside
804+
the ORTSFreightAnims block. If the Davis A, B, and C values are not given
805+
they will be determined automatically using other properties of the rolling
806+
stock and either the 1926 Davis formula or 1992 CN formula, depending on the
807+
ORTSBearingType specified in the Wagon section.
808+
803809
For some rolling stock, it may be more realistic to handle variations in load/empty
804810
brake force by changing the brake cylinder pressure developed, rather than changing
805811
the brake force directly. In such cases, the empty/load relay valve parameters work

Source/Documentation/Manual/physics.rst

Lines changed: 66 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -39,50 +39,75 @@ the WAG / ENG file is discussed.
3939
Resistive Forces
4040
----------------
4141

42-
Open Rails physics calculates resistance based on real world physics:
43-
gravity, mass, rolling resistance and optionally curve resistance. This is
44-
calculated individually for each car in the train. The program calculates
45-
rolling resistance, or friction, based on the Friction parameters in the
46-
Wagon section of .wag/.eng file. Open Rails identifies whether the .wag
47-
file uses the *FCalc* utility or other friction data. If *FCalc* was used to
48-
determine the Friction variables within the .wag file, Open Rails compares
49-
that data to the Open Rails Davis equations to identify the closest match
50-
with the Open Rails Davis equation. If no-FCalc Friction parameters are
51-
used in the .wag file, Open Rails ignores those values, substituting its
52-
actual Davis equation values for the train car.
42+
Open Rails physics calculates resistance based on real world principles:
43+
gravity, mass, wind, rolling resistance, and curve resistance. This is
44+
calculated individually for each car in the train.
45+
46+
The program supports a few methods for determining rolling resistance.
47+
The oldest method, intended only to support legacy content, uses the
48+
``Friction`` parameters in the Wagon section of .wag/.eng file.
49+
Open Rails identifies whether the .wag file used the *FCalc* utility or
50+
other friction data. If *FCalc* was used to determine the Friction variables
51+
within the .wag file, Open Rails attempts to determine the Davis coefficients
52+
originally used to derive the Friction parameters. If no FCalc Friction
53+
parameters are used in the .wag file, Open Rails ignores those values,
54+
substituting resistance calculated by the original 1923 Davis equation.
5355

5456
.. index::
5557
single: ORTSDavis_A
5658
single: ORTSDavis_B
5759
single: ORTSDavis_C
60+
single: ORTSBearingType
5861

59-
A basic (simplified) Davis formula is used in the following form:
62+
For new content, it is preferred to not use the ``Friction`` parameters,
63+
and instead enter the Davis coefficients directly as this is more
64+
prototypical. In the Wagon section, the parameters ``ORTSDavis_A``,
65+
``ORTSDavis_B``, and ``ORTSDavis_C`` can be used to provide these values.
66+
When using this method, the wagon section should also specify the type of
67+
wheel bearings used with the ``ORTSBearingType`` parameter.
68+
These values are then used in a generic form of the Davis formula:
6069

6170
F\ :sub:`res` = ORTSDavis_A + speedMpS * (ORTSDavis_B + ORTSDavis_C * speedMpS\ :sup:`2`\ )
6271

63-
Where F\ :sub:`res` is the friction force of the car. The rolling resistance
64-
can be defined either by *FCalc* or ORTSDavis_A, _B and _C components. If
65-
one of the *ORTSDavis* components is zero, *FCalc* is used. Therefore, e.g.
66-
if the data doesn't contain the B part of the Davis formula, a very small
67-
number should be used instead of zero.
72+
Where F\ :sub:`res` is the friction force of the car when travelling at a
73+
speed of *speedMpS*. Note that in this formula, unlike the empirical Davis
74+
formula, the weight of the rolling stock and the number of axles are not
75+
considered by this equation; the ORTSDavis values must be set already
76+
accounting for the weight and number of axles. Accepted units of measure
77+
for ORTSDavis parameters and the list of bearing types can be found in the
78+
:ref:`required parameters table <required-params>`.
79+
80+
In the case that ORTSDavis coefficients are not known or prove awkward to calculate,
81+
Open Rails can automatically calculate rolling resistance using other data
82+
in combination with the 1926 Davis equation (for grease and friction bearings)
83+
or the 1992 CN equation (for roller and low bearings). If given a supported
84+
``ORTSBearingType``, missing A and B coefficients will be found from the rail
85+
vehicle weight and number of axles. Likewise, if the C coefficient is missing it
86+
is automatically calculated from the ``ORTSWagonFrontalArea`` and
87+
``ORTSDavisDragConstant`` values (or defaults, if those are missing).
88+
While the auto-calculated results will be reasonable for standard rolling stock,
89+
manual entry of ORTSDavis coefficients is still preferred for more complicated
90+
rolling stock such as steam locomotives, multiple units, high speed trains,
91+
articulated units, and anything studied in experiments other than Davis.
6892

6993
.. index::
7094
single: ORTSMergeSpeed
7195
single: ORTSStandstillFriction
7296

73-
When a train is initially started, additional force is needed to overcome
74-
the initial higher bearing torque (forces) and track resistance. Starting resistance is calculated
75-
automatically by Open Rails based upon empirical prototypical data at low speeds.
76-
By selecting different values for ``ORTSBearingType`` different values of starting
77-
resistance will be applied. The Open Rails calculation for starting resistance takes
78-
into account different conditions, such as weather (for example, snowing or clear),
79-
wagon (axle) load, wheel bearing temperature and wheel diameter. Hence when using the OR calculation
80-
the correct values should be inserted in ``ORTSNumberAxles`` parameter in the wagon section, and
81-
``ORTSNumberDriveAxles`` in the engine section. The ``WheelRadius`` value should also be
82-
inserted in both sections as appropriate.
83-
84-
Alternatively the low-speed friction force can be manually specified by the user by setting
85-
``ORTSStandstillFriction`` and ``ORTSMergeSpeed``.
97+
The various forms of Davis equation are only accurate above 5 mph or so. They
98+
prove inaccurate at low speeds as additional force is needed to overcome
99+
the initial higher bearing torque (forces) and track resistance. Starting resistance
100+
is calculated automatically by Open Rails based upon environmental conditions
101+
and the setting of ``ORTSBearingType``. Each bearing type has a different starting
102+
resistance profile based on empirical prototypical data, including consideration
103+
for the temperature of the bearing, wagon (axle) load, and wheel diameter. Hence
104+
when using the OR calculation the correct values should be inserted in ``ORTSNumberAxles``
105+
parameter in the wagon section, and ``ORTSNumberDriveAxles`` in the engine section. The
106+
``WheelRadius`` value should also be inserted in both sections as appropriate.
107+
108+
Alternatively the low-speed friction force can be manually specified by the user by
109+
setting the zero-speed force in ``ORTSStandstillFriction`` and the speed at which the
110+
regular Davis equation takes over with ``ORTSMergeSpeed``.
86111

87112
.. index::
88113
single: ORTSTrackGauge
@@ -2161,6 +2186,8 @@ iii. `Testing Resources for Open Rails Steam Locomotives
21612186
.. |-| unicode:: U+00AD .. soft hyphen
21622187
:trim:
21632188

2189+
.. _required-params:
2190+
21642191
+-----------------------------------------------------------+-------------------+-------------------+-------------------+
21652192
|Parameter |Description |Recommended Units |Typical Examples |
21662193
+===========================================================+===================+===================+===================+
@@ -2273,9 +2300,10 @@ iii. `Testing Resources for Open Rails Steam Locomotives
22732300
| |friction |lbf/mph^2 |(1.43lbf/mph^2) |
22742301
| | |Use FCalc | |
22752302
+-----------------------------------------------------------+-------------------+-------------------+-------------------+
2276-
|ORTS |-| Bearing |-| Type ( x ) |Bearing type, || Roller, |( Roller ) |
2277-
| |defaults to || Friction, | |
2278-
| |Friction || Low | |
2303+
|ORTS |-| Bearing |-| Type ( x ) |Bearing type used || Grease, |( Roller ) |
2304+
| |to determine || Friction, | |
2305+
| |rolling resistance || Roller | |
2306+
| | || Low | |
22792307
| | | | |
22802308
+-----------------------------------------------------------+-------------------+-------------------+-------------------+
22812309
|**Friction (Engine section)** |
@@ -4769,10 +4797,7 @@ impact due to the wind will be zero.
47694797

47704798
**Wind Lateral Force Resistance** - When the wind blows from the side of the
47714799
train, the train will be pushed against the outside track rail, thus increasing
4772-
the amount of resistance experienced by the train.
4773-
4774-
To activate calculation of wind resistance, select the tickbox for "Wind dependent
4775-
resistance" in the Simulation TAB of the options menu. As wind only becomes
4800+
the amount of resistance experienced by the train. As wind only becomes
47764801
significant at higher train speeds, the wind resistance calculation only commences
47774802
once the train speed exceeds 5 mph.
47784803

@@ -4808,9 +4833,9 @@ parameters can be inputted via the WAG file or section.
48084833
``ORTSWagonFrontalArea`` -- The frontal cross sectional area of the wagon. The default units
48094834
are in ft^2, so if entering metres, include the Units of Measure.
48104835

4811-
``ORTSDavisDragConstant`` -- OR by default uses the standard Davis Drag constants. If alternate
4812-
drag constants are used in calculating the still air resistance, then it might be worthwhile
4813-
inputting these values.
4836+
``ORTSDavisDragConstant`` -- OR assigns a default drag constant based on the type of
4837+
rolling stock. For more specifity or for less typical types of rolling stock, the drag
4838+
coefficient can be entered manually. Typical values are unitless in the range of 0.0002 - 0.0024.
48144839

48154840

48164841
.. _physics-track-sanding:
@@ -4905,7 +4930,7 @@ However for those who like to customise, the following parameter can be inputted
49054930
single: ORTSTrailLocomotiveResistanceFactor
49064931

49074932
``ORTSTrailLocomotiveResistanceFactor`` -- The constant value by which the leading locomotive resistance
4908-
needs to be decreased for trailing operation.
4933+
needs to be multiplied for trailing operation (eg: 0.5 halves resistance, default 0.2083).
49094934

49104935
For steam locomotive tenders it may be necessary to enter this value depending upon the Drag constant used
49114936
to calculate the tender resistance.

Source/Orts.Common/Conversions.cs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,23 @@ public static class NpM
260260
/// <summary>
261261
/// Resistance conversions from and to Newtons/metre/sec
262262
/// </summary>
263-
public static class NpMpS
263+
public static class NSpM
264264
{
265+
/// <summary>Convert from pounds per mph to newtons per meter per second</summary>
266+
public static float FromLbfpMpH(float lbfPerMpH) { return lbfPerMpH * 9.9503884f; }
267+
/// <summary>Convert from newtons per meter per second to pounds per mph</summary>
268+
public static float ToLbfpMpH(float nPerMpS) { return nPerMpS / 9.9503884f; }
269+
}
270+
271+
/// <summary>
272+
/// Resistance conversions from and to Newtons/metre^2/sec^2
273+
/// </summary>
274+
public static class NSSpMM
275+
{
276+
/// <summary>Convert from pounds per mph^2 to newtons per mps^2</summary>
277+
public static float FromLbfpMpH2(float lbfPerMpH2) { return lbfPerMpH2 * 22.2583849f; }
278+
/// <summary>Convert from newtons per mps^2 to pounds per mph^2</summary>
279+
public static float ToLbfpMpH2(float nPerMpS2) { return nPerMpS2 / 22.2583849f; }
265280
}
266281

267282
/// <summary>
@@ -576,8 +591,12 @@ public static class FormatStrings
576591
public static string f = Catalog.GetString("°F");
577592
public static string n = Catalog.GetString("N");
578593
public static string kN = Catalog.GetString("kN");
594+
public static string nspm = Catalog.GetString("N/m/s");
595+
public static string nsspmm = Catalog.GetString("N/(m/s)²");
579596
public static string lbf = Catalog.GetString("lbf");
580597
public static string klbf = Catalog.GetString("klbf");
598+
public static string lbfpmph = Catalog.GetString("lbf/mph");
599+
public static string lbfpmph2 = Catalog.GetString("lbf/mph²");
581600
public static string deg = Catalog.GetString("°");
582601

583602
/// <summary>
@@ -789,6 +808,18 @@ public static string FormatLargeForce(float forceN, bool isMetric)
789808
return String.Format(CultureInfo.CurrentCulture, "{0:F1} {1}", force * 1e-3f, unit);
790809
}
791810

811+
public static string FormatLinearResistance(float resistanceNSpM, bool isMetric)
812+
{
813+
var resistance = isMetric ? resistanceNSpM : NSpM.ToLbfpMpH(resistanceNSpM);
814+
return String.Format(CultureInfo.CurrentCulture, isMetric ? "{0:F1} {1}" : "{0:F2} {2}", resistance, nspm, lbfpmph);
815+
}
816+
817+
public static string FormatQuadraticResistance(float resistanceNSSpMM, bool isMetric)
818+
{
819+
var resistance = isMetric ? resistanceNSSpMM : NSSpMM.ToLbfpMpH2(resistanceNSSpMM);
820+
return String.Format(CultureInfo.CurrentCulture, isMetric ? "{0:F3} {1}" : "{0:F4} {2}", resistance, nsspmm, lbfpmph2);
821+
}
822+
792823
public static string FormatTemperature(float temperatureC, bool isMetric, bool isDelta)
793824
{
794825
var temperature = isMetric ? temperatureC : isDelta ? C.ToDeltaF(temperatureC) : C.ToF(temperatureC);

Source/Orts.Parsers.Msts/STFReader.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,7 +1076,7 @@ internal double ParseUnitSuffix(ref string constant, UNITS validUnits)
10761076
case "": return 1.0;
10771077
case "n/m/s": return 1;
10781078
case "ns/m": return 1;
1079-
case "lbf/mph": return 10.0264321; // 1 lbf = 4.4822162, 1 mph = 0.44704 mps => 4.4822162 / 0.44704 = 10.0264321
1079+
case "lbf/mph": return 9.9503884; // 1 lbf = 4.4482216, 1 mph = 0.44704 mps => 4.4482216 / 0.44704 = 9.9503884
10801080
}
10811081
if ((validUnits & UNITS.PressureDefaultPSI) > 0)
10821082
switch (suffix)
@@ -1146,7 +1146,7 @@ internal double ParseUnitSuffix(ref string constant, UNITS validUnits)
11461146
{
11471147
case "": return 1.0;
11481148
case "Nm/s^2": return 1;
1149-
case "lbf/mph^2": return 22.42849; // 1 lbf = 4.4822162, 1 mph = 0.44704 mps +> 4.4822162 / (0.44704 * 0.44704) = 22.42849
1149+
case "lbf/mph^2": return 22.2583849; // 1 lbf = 4.4482216, 1 mph = 0.44704 mps +> 4.4482216 / (0.44704 * 0.44704) = 22.2583849
11501150
}
11511151
if ((validUnits & UNITS.Temperature) > 0)
11521152
{
@@ -3391,10 +3391,10 @@ static float ParseUnitSuffix(ref string constant, UNITS validUnits, StfToken tok
33913391
if ((validUnits & UNITS.Resistance) > 0)
33923392
switch (suffix)
33933393
{
3394-
case "": return 1.0f;
3394+
case "": return 1.0;
33953395
case "n/m/s": return 1;
33963396
case "ns/m": return 1;
3397-
case "lbf/mph": return 10.0264321f; // 1 lbf = 4.4822162, 1 mph = 0.44704 mps => 4.4822162 / 0.44704 = 10.0264321
3397+
case "lbf/mph": return 9.9503884; // 1 lbf = 4.4482216, 1 mph = 0.44704 mps => 4.4482216 / 0.44704 = 9.9503884
33983398
}
33993399
if ((validUnits & UNITS.PressureDefaultPSI) > 0)
34003400
switch (suffix)
@@ -3459,9 +3459,9 @@ static float ParseUnitSuffix(ref string constant, UNITS validUnits, StfToken tok
34593459
if ((validUnits & UNITS.ResistanceDavisC) > 0)
34603460
switch (suffix)
34613461
{
3462-
case "": return 1.0f;
3462+
case "": return 1.0;
34633463
case "Nm/s^2": return 1;
3464-
case "lbf/mph^2": return 22.42849f; // 1 lbf = 4.4822162, 1 mph = 0.44704 mps +> 4.4822162 / (0.44704 * 0.44704) = 22.42849
3464+
case "lbf/mph^2": return 22.2583849; // 1 lbf = 4.4482216, 1 mph = 0.44704 mps +> 4.4482216 / (0.44704 * 0.44704) = 22.2583849
34653465
}
34663466

34673467
STFException.TraceWarning(tokenForWarnings, "Found a suffix '" + suffix + "' which could not be parsed as a " + validUnits.ToString() + " unit");

0 commit comments

Comments
 (0)