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
7 // This file is in the Public Domain and comes with no warranty.
9 // Example invocation, in the instrumentation.xml file:
11 // <name>encoder</name>
13 // <static-pressure>/systems/static/pressure-inhg</static-pressure>
14 // <quantum>10</quantum>
17 // Note non-default name, quantum, and tau values.
23 #include <simgear/constants.h>
24 #include <simgear/math/interpolater.hxx>
25 #include <simgear/math/SGMath.hxx>
27 #include <Main/fg_props.hxx>
28 #include <Main/util.hxx>
29 #include <Environment/atmosphere.hxx>
31 #include "altimeter.hxx"
33 Altimeter::Altimeter ( SGPropertyNode *node, double quantum )
35 fgGetNode("/instrumentation",true)->
36 getChild( node->getStringValue("name", "altimeter"),
37 node->getIntValue("number", 0),
39 _static_pressure(node->getStringValue("static-pressure", "/systems/static/pressure-inhg")),
40 _tau(node->getDoubleValue("tau", 0.1)),
41 _quantum(node->getDoubleValue("quantum", quantum)),
42 _settingInHg(29.921260)
44 // FIXME: change default to false once all aircraft which use
45 // altimiter as an encoder are converted to request this explicitly
46 _encodeModeC = node->getBoolValue("encode-mode-c", true);
47 _encodeModeS = node->getBoolValue("encode-mode-s", false);
49 _tiedProperties.setRoot( _rootNode );
52 Altimeter::~Altimeter ()
56 Altimeter::getSettingInHg() const
62 Altimeter::setSettingInHg( double value )
68 Altimeter::getSettingHPa() const
70 return _settingInHg * SG_INHG_TO_PA / 100;
74 Altimeter::setSettingHPa( double value )
76 _settingInHg = value * SG_PA_TO_INHG * 100;
83 _pressure_node = fgGetNode(_static_pressure.c_str(), true);
84 _serviceable_node = _rootNode->getChild("serviceable", 0, true);
85 _press_alt_node = _rootNode->getChild("pressure-alt-ft", 0, true);
87 _mode_c_node = _rootNode->getChild("mode-c-alt-ft", 0, true);
91 _mode_s_node = _rootNode->getChild("mode-s-alt-ft", 0, true);
94 _altitude_node = _rootNode->getChild("indicated-altitude-ft", 0, true);
109 _tiedProperties.Tie("setting-inhg", this, &Altimeter::getSettingInHg, &Altimeter::setSettingInHg );
110 _tiedProperties.Tie("setting-hpa", this, &Altimeter::getSettingHPa, &Altimeter::setSettingHPa );
116 _tiedProperties.Untie();
120 Altimeter::update (double dt)
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);
130 _mode_c_node->setDoubleValue(100 * SGMiscd::round(_raw_PA/100));
134 _mode_s_node->setDoubleValue(10 * SGMiscd::round(_raw_PA/10));
137 _kollsman = fgGetLowPass(_kollsman, _altimeter.kollsman_ft(_settingInHg), trat);
139 press_alt = _quantum * SGMiscd::round(_raw_PA/_quantum);
142 _press_alt_node->setDoubleValue(press_alt);
143 _altitude_node->setDoubleValue(press_alt - _kollsman);
147 // end of altimeter.cxx