Skip to content

Commit 2319f7f

Browse files
authored
Merge pull request #939 from SteelFill/cabview_units
Add KM/HOUR/MIN to Cabview Units + Custom Units
2 parents c44c911 + 15ba46b commit 2319f7f

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

Source/Documentation/Manual/cabs.rst

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,33 @@ can be customized with following line, to be added within the control block in t
785785
.cvf file::
786786

787787
ORTSLabel ( "string" )
788+
789+
Custom Display Units
790+
--------------------
791+
792+
Due to the wide variety of railroad equipment across the world, Open Rails may not
793+
provide the units of measure needed for a cabview control. In this case, the tokens
794+
`ORTSUnitsExponent`, `ORTSUnitsScaleFactor`, and `ORTSUnitsOffset` can be added
795+
to the control block in the .cvf file to create the units of measure required for
796+
the cab view.
797+
798+
- ORTSUnitsExponent ( x ): Raises the value shown by the cab view control to the
799+
power of x, which may be used to calibrate nonlinear gauges or complete nonlinear
800+
conversions. Fractional and negative values are allowed. For example, an accelerometer
801+
gauge with ORTSUnitsExponent ( 0.5 ) would change the accelerometer to be more sensitive
802+
to small accelerations, but less sensitive to large acceleration. (However, the values
803+
shown would not be in any meaningful units.)
804+
- ORTSUnitsScaleFactor ( y ): After accounting for any exponent, multiplies the value
805+
shown by the cab view control by a factor of y, allowing for arbitrary conversion of
806+
units of measure. For example, a cab view control displaying MILES_PER_HOUR with
807+
ORTSUnitsScaleFactor ( 1.467 ) would instead display a value equivalent to feet per second.
808+
- ORTSUnitsOffset ( z ): After applying the scale factor, adds z to the value shown
809+
by the cab view control. To subtract from the shown value, set z to a negative number.
810+
For example, a cab view control with units of BAR and ORTSUnitsOffset ( 0.987 ) would show
811+
pressure as absolute pressure, rather than gauge pressure.
812+
813+
Note that while these tokens can be used to convert between many units, it is recommended
814+
to use built in Open Rails units wherever suitable.
788815

789816
Multiple screen pages on displays
790817
---------------------------------

Source/Orts.Formats.Msts/CabViewFile.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,8 @@ public enum CABViewControlUnits
322322
METRES_SEC_SEC,
323323
KMµHOURµHOUR,
324324
KM_HOUR_HOUR,
325+
KMµHOURµMIN,
326+
KM_HOUR_MIN,
325327
KMµHOURµSEC,
326328
KM_HOUR_SEC,
327329
METRESµSECµHOUR,
@@ -468,6 +470,10 @@ public class CabViewControl
468470
public CABViewControlStyles ControlStyle = CABViewControlStyles.NONE;
469471
public CABViewControlUnits Units = CABViewControlUnits.NONE;
470472

473+
public double UnitsExponent = 1.0f;
474+
public float UnitsScale = 1.0f;
475+
public float UnitsOffset;
476+
471477
public bool DisabledIfLowVoltagePowerSupplyOff { get; private set; } = false;
472478
public bool DisabledIfCabPowerSupplyOff { get; private set; } = false;
473479
public bool HideIfDisabled { get; private set; } = true;
@@ -685,6 +691,9 @@ public CVCDial(STFReader stf, string basepath)
685691
new STFReader.TokenProcessor("ortsdisplay", ()=>{ParseDisplay(stf); }),
686692
new STFReader.TokenProcessor("ortsscreenpage", () => {ParseScreen(stf); }),
687693
new STFReader.TokenProcessor("ortscabviewpoint", ()=>{ParseCabViewpoint(stf); }),
694+
new STFReader.TokenProcessor("ortsunitsexponent", ()=>{ UnitsExponent = stf.ReadFloatBlock(STFReader.UNITS.None, null); }),
695+
new STFReader.TokenProcessor("ortsunitsscalefactor", ()=>{ UnitsScale = stf.ReadFloatBlock(STFReader.UNITS.None, null); }),
696+
new STFReader.TokenProcessor("ortsunitsoffset", ()=>{ UnitsOffset = stf.ReadFloatBlock(STFReader.UNITS.None, null); }),
688697
});
689698
}
690699
}
@@ -781,6 +790,9 @@ public CVCGauge(STFReader stf, string basepath)
781790
new STFReader.TokenProcessor("ortsdisplay", ()=>{ParseDisplay(stf); }),
782791
new STFReader.TokenProcessor("ortsscreenpage", () => {ParseScreen(stf); }),
783792
new STFReader.TokenProcessor("ortscabviewpoint", ()=>{ParseCabViewpoint(stf); }),
793+
new STFReader.TokenProcessor("ortsunitsexponent", ()=>{ UnitsExponent = stf.ReadFloatBlock(STFReader.UNITS.None, null); }),
794+
new STFReader.TokenProcessor("ortsunitsscalefactor", ()=>{ UnitsScale = stf.ReadFloatBlock(STFReader.UNITS.None, null); }),
795+
new STFReader.TokenProcessor("ortsunitsoffset", ()=>{ UnitsOffset = stf.ReadFloatBlock(STFReader.UNITS.None, null); }),
784796
});
785797
}
786798
}
@@ -923,6 +935,9 @@ public CVCDigital(STFReader stf, string basepath)
923935
new STFReader.TokenProcessor("ortsdisplay", ()=>{ParseDisplay(stf); }),
924936
new STFReader.TokenProcessor("ortsscreenpage", () => {ParseScreen(stf); }),
925937
new STFReader.TokenProcessor("ortscabviewpoint", ()=>{ParseCabViewpoint(stf); }),
938+
new STFReader.TokenProcessor("ortsunitsexponent", ()=>{ UnitsExponent = stf.ReadFloatBlock(STFReader.UNITS.None, null); }),
939+
new STFReader.TokenProcessor("ortsunitsscalefactor", ()=>{ UnitsScale = stf.ReadFloatBlock(STFReader.UNITS.None, null); }),
940+
new STFReader.TokenProcessor("ortsunitsoffset", ()=>{ UnitsOffset = stf.ReadFloatBlock(STFReader.UNITS.None, null); }),
926941
});
927942
}
928943

@@ -1179,6 +1194,9 @@ public CVCDiscrete(STFReader stf, string basepath, DiscreteStates discreteState)
11791194
new STFReader.TokenProcessor("ortsnewscreenpage", () => {ParseNewScreen(stf); }),
11801195
new STFReader.TokenProcessor("ortscabviewpoint", ()=>{ParseCabViewpoint(stf); }),
11811196
new STFReader.TokenProcessor("ortsparameter1", ()=>{ Parameter1 = stf.ReadFloatBlock(STFReader.UNITS.Any, 0); }),
1197+
new STFReader.TokenProcessor("ortsunitsexponent", ()=>{ UnitsExponent = stf.ReadFloatBlock(STFReader.UNITS.None, null); }),
1198+
new STFReader.TokenProcessor("ortsunitsscalefactor", ()=>{ UnitsScale = stf.ReadFloatBlock(STFReader.UNITS.None, null); }),
1199+
new STFReader.TokenProcessor("ortsunitsoffset", ()=>{ UnitsOffset = stf.ReadFloatBlock(STFReader.UNITS.None, null); }),
11821200
});
11831201

11841202
// If no ACE, just don't need any fixup
@@ -1425,6 +1443,9 @@ public CVCMultiStateDisplay(STFReader stf, string basepath)
14251443
new STFReader.TokenProcessor("ortsdisplay", ()=>{ParseDisplay(stf); }),
14261444
new STFReader.TokenProcessor("ortsscreenpage", () => {ParseScreen(stf); }),
14271445
new STFReader.TokenProcessor("ortscabviewpoint", ()=>{ParseCabViewpoint(stf); }),
1446+
new STFReader.TokenProcessor("ortsunitsexponent", ()=>{ UnitsExponent = stf.ReadFloatBlock(STFReader.UNITS.None, null); }),
1447+
new STFReader.TokenProcessor("ortsunitsscalefactor", ()=>{ UnitsScale = stf.ReadFloatBlock(STFReader.UNITS.None, null); }),
1448+
new STFReader.TokenProcessor("ortsunitsoffset", ()=>{ UnitsOffset = stf.ReadFloatBlock(STFReader.UNITS.None, null); }),
14281449
});
14291450
}
14301451
protected int ParseNumStyle(STFReader stf)
@@ -1475,6 +1496,9 @@ public CVCAnimatedDisplay(STFReader stf, string basepath)
14751496
new STFReader.TokenProcessor("ortsdisplay", ()=>{ParseDisplay(stf); }),
14761497
new STFReader.TokenProcessor("ortsscreenpage", () => {ParseScreen(stf); }),
14771498
new STFReader.TokenProcessor("ortscabviewpoint", ()=>{ParseCabViewpoint(stf); }),
1499+
new STFReader.TokenProcessor("ortsunitsexponent", ()=>{ UnitsExponent = stf.ReadFloatBlock(STFReader.UNITS.None, null); }),
1500+
new STFReader.TokenProcessor("ortsunitsscalefactor", ()=>{ UnitsScale = stf.ReadFloatBlock(STFReader.UNITS.None, null); }),
1501+
new STFReader.TokenProcessor("ortsunitsoffset", ()=>{ UnitsOffset = stf.ReadFloatBlock(STFReader.UNITS.None, null); }),
14781502
});
14791503
}
14801504
protected int ParseNumStyle(STFReader stf)
@@ -1516,6 +1540,9 @@ public CVCScreen(STFReader stf, string basepath)
15161540
new STFReader.TokenProcessor("ortsdisplay", ()=>{ParseDisplay(stf); }),
15171541
new STFReader.TokenProcessor("ortsscreenpage", () => {ParseScreen(stf); }),
15181542
new STFReader.TokenProcessor("ortscabviewpoint", ()=>{ParseCabViewpoint(stf); }),
1543+
new STFReader.TokenProcessor("ortsunitsexponent", ()=>{ UnitsExponent = stf.ReadFloatBlock(STFReader.UNITS.None, null); }),
1544+
new STFReader.TokenProcessor("ortsunitsscalefactor", ()=>{ UnitsScale = stf.ReadFloatBlock(STFReader.UNITS.None, null); }),
1545+
new STFReader.TokenProcessor("ortsunitsoffset", ()=>{ UnitsOffset = stf.ReadFloatBlock(STFReader.UNITS.None, null); }),
15191546
});
15201547
}
15211548
protected void ParseCustomParameters(STFReader stf)

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5195,6 +5195,10 @@ public virtual float GetDataOf(CabViewControl cvc)
51955195
data = this.AccelerationMpSS * 3.6f;
51965196
break;
51975197

5198+
case CABViewControlUnits.KM_HOUR_MIN:
5199+
data = this.AccelerationMpSS * 3.6f * 60.0f;
5200+
break;
5201+
51985202
case CABViewControlUnits.KM_HOUR_HOUR:
51995203
data = this.AccelerationMpSS * 3.6f * 3600.0f;
52005204
break;
@@ -5216,7 +5220,7 @@ public virtual float GetDataOf(CabViewControl cvc)
52165220
break;
52175221
}
52185222

5219-
case CABViewControlTypes.ORTS_WATER_SCOOP:
5223+
case CABViewControlTypes.ORTS_WATER_SCOOP:
52205224
data = WaterScoopDown ? 1 : 0;
52215225
break;
52225226

@@ -6129,6 +6133,12 @@ public virtual float GetDataOf(CabViewControl cvc)
61296133
data = Train.EOT.GetDataOf(cvc);
61306134
break;
61316135
}
6136+
// Don't waste time calculating exponents if one isn't set
6137+
// To avoid potential imaginary numbers, use data's absolute value
6138+
if (cvc.UnitsExponent != 1.0f)
6139+
data = Math.Sign(data)*(float)Math.Pow(Math.Abs(data), cvc.UnitsExponent);
6140+
data = cvc.UnitsOffset + (data * cvc.UnitsScale);
6141+
61326142
return data;
61336143
}
61346144

0 commit comments

Comments
 (0)