]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/altimeter.cxx
Support helipad names in the --runway startup option
[flightgear.git] / src / Instrumentation / altimeter.cxx
1 // altimeter.cxx - an altimeter tied to the static port.
2 // Written by David Megginson, started 2002.
3 // Modified by John Denker in 2007 to use a two layer atmosphere
4 // model in src/Environment/atmosphere.?xx
5 // Last modified by Eric van den Berg, 25 Nov 2012
6 //
7 // This file is in the Public Domain and comes with no warranty.
8
9 // Example invocation, in the instrumentation.xml file:
10 //      <altimeter>
11 //        <name>encoder</name>
12 //        <number>0</number>
13 //        <static-pressure>/systems/static/pressure-inhg</static-pressure>
14 //        <quantum>10</quantum>
15 //        <tau>0</tau>
16 //      </altimeter>
17 // Note non-default name, quantum, and tau values.
18
19 #ifdef HAVE_CONFIG_H
20 #  include <config.h>
21 #endif
22
23 #include <simgear/constants.h>
24 #include <simgear/math/interpolater.hxx>
25 #include <simgear/math/SGMath.hxx>
26
27 #include <Main/fg_props.hxx>
28 #include <Main/util.hxx>
29 #include <Environment/atmosphere.hxx>
30
31 #include "altimeter.hxx"
32
33 Altimeter::Altimeter ( SGPropertyNode *node, const std::string& aDefaultName, double quantum ) :
34       _name(node->getStringValue("name", aDefaultName.c_str())),
35       _num(node->getIntValue("number", 0)),
36       _static_pressure(node->getStringValue("static-pressure", "/systems/static/pressure-inhg")),
37       _tau(node->getDoubleValue("tau", 0.1)),
38       _quantum(node->getDoubleValue("quantum", quantum)),
39       _settingInHg(29.921260)
40 {
41     // FIXME: change default to false once all aircraft which use
42     // altimiter as an encoder are converted to request this explicitly
43     _encodeModeC = node->getBoolValue("encode-mode-c", true);
44     _encodeModeS = node->getBoolValue("encode-mode-s", false);
45     
46     _tiedProperties.setRoot( _rootNode );
47 }
48
49 Altimeter::~Altimeter ()
50 {}
51
52 double
53 Altimeter::getSettingInHg() const
54 {
55     return _settingInHg;
56 }
57
58 void
59 Altimeter::setSettingInHg( double value )
60 {
61     _settingInHg = value;
62 }
63
64 double
65 Altimeter::getSettingHPa() const
66 {
67     return _settingInHg * SG_INHG_TO_PA / 100;
68 }
69
70 void
71 Altimeter::setSettingHPa( double value )
72 {
73     _settingInHg = value * SG_PA_TO_INHG * 100;
74 }
75
76
77 void
78 Altimeter::init ()
79 {
80     _pressure_node     = fgGetNode(_static_pressure.c_str(), true);
81     _serviceable_node  = _rootNode->getChild("serviceable", 0, true);
82     _press_alt_node    = _rootNode->getChild("pressure-alt-ft", 0, true);
83     if (_encodeModeC) {
84         _mode_c_node = _rootNode->getChild("mode-c-alt-ft", 0, true);
85     }
86     
87     if (_encodeModeS) {
88         _mode_s_node = _rootNode->getChild("mode-s-alt-ft", 0, true);
89     }
90     
91     _altitude_node     = _rootNode->getChild("indicated-altitude-ft", 0, true);
92
93     reinit();
94 }
95
96 void
97 Altimeter::reinit ()
98 {
99     _raw_PA = 0.0;
100     _kollsman = 0.0;
101 }
102
103 void
104 Altimeter::bind()
105 {
106     _rootNode = fgGetNode("/instrumentation/" + _name, _num, true );
107     _tiedProperties.setRoot(_rootNode);
108     
109     _tiedProperties.Tie("setting-inhg", this, &Altimeter::getSettingInHg, &Altimeter::setSettingInHg );
110     _tiedProperties.Tie("setting-hpa", this, &Altimeter::getSettingHPa, &Altimeter::setSettingHPa );
111 }
112
113 void
114 Altimeter::unbind()
115 {
116     _tiedProperties.Untie();
117 }
118
119 void
120 Altimeter::update (double dt)
121 {
122     if (_serviceable_node->getBoolValue()) {
123         double trat = _tau > 0 ? dt/_tau : 100;
124         double pressure = _pressure_node->getDoubleValue();
125         double press_alt = _press_alt_node->getDoubleValue();
126         // The mechanism settles slowly toward new pressure altitude:
127         _raw_PA = fgGetLowPass(_raw_PA, _altimeter.press_alt_ft(pressure), trat);
128         
129         if (_encodeModeC) {
130             _mode_c_node->setDoubleValue(100 * SGMiscd::round(_raw_PA/100));
131         }
132         
133         if (_encodeModeS) {
134             _mode_s_node->setDoubleValue(10 * SGMiscd::round(_raw_PA/10));
135         }
136
137         _kollsman = fgGetLowPass(_kollsman, _altimeter.kollsman_ft(_settingInHg), trat);
138         if (_quantum)
139             press_alt = _quantum * SGMiscd::round(_raw_PA/_quantum);
140         else
141             press_alt = _raw_PA;
142         _press_alt_node->setDoubleValue(press_alt);
143         _altitude_node->setDoubleValue(press_alt - _kollsman);
144     }
145 }
146
147 // end of altimeter.cxx