X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FInstrumentation%2Faltimeter.cxx;h=a691f1e90814d7f77180eb7845a4c2087edcb5af;hb=ef1ec369dbd422e17efb3959821069867f58dba4;hp=ceea78ddc450107b06121bca97ce6f8010f7082f;hpb=28fe28ec4f1d3bd3994984c2ced836f42488ba55;p=flightgear.git diff --git a/src/Instrumentation/altimeter.cxx b/src/Instrumentation/altimeter.cxx index ceea78ddc..a691f1e90 100644 --- a/src/Instrumentation/altimeter.cxx +++ b/src/Instrumentation/altimeter.cxx @@ -1,121 +1,146 @@ // altimeter.cxx - an altimeter tied to the static port. // Written by David Megginson, started 2002. +// Modified by John Denker in 2007 to use a two layer atmosphere +// model in src/Environment/atmosphere.?xx +// Last modified by Eric van den Berg, 25 Nov 2012 // // This file is in the Public Domain and comes with no warranty. +// Example invocation, in the instrumentation.xml file: +// +// encoder +// 0 +// /systems/static/pressure-inhg +// 10 +// 0 +// +// Note non-default name, quantum, and tau values. + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include #include +#include -#include "altimeter.hxx" #include
#include
+#include +#include "altimeter.hxx" -// A higher number means more responsive -#define RESPONSIVENESS 10.0 - - -// Altitude based on pressure difference from sea level. -// pressure difference inHG, altitude ft -static double altitude_data[][2] = { - { -8.41, -8858.27 }, - { 0.00, 0.00 }, - { 3.05, 2952.76 }, - { 5.86, 5905.51 }, - { 8.41, 8858.27 }, - { 10.74, 11811.02 }, - { 12.87, 14763.78 }, - { 14.78, 17716.54 }, - { 16.55, 20669.29 }, - { 18.13, 23622.05 }, - { 19.62, 26574.80 }, - { 20.82, 29527.56 }, - { 21.96, 32480.31 }, - { 23.01, 35433.07 }, - { 23.91, 38385.83 }, - { 24.71, 41338.58 }, - { 25.40, 44291.34 }, - { 26.00, 47244.09 }, - { 26.51, 50196.85 }, - { 26.96, 53149.61 }, - { 27.35, 56102.36 }, - { 27.68, 59055.12 }, - { 27.98, 62007.87 }, - { 29.62, 100000.00 }, // just to fill it in - { -1, -1 } -}; - - -Altimeter::Altimeter ( SGPropertyNode *node ) - : name("altimeter"), - num(0), - static_port("/systems/static"), - _altitude_table(new SGInterpTable) +Altimeter::Altimeter ( SGPropertyNode *node, const std::string& aDefaultName, double quantum ) : + _name(node->getStringValue("name", aDefaultName.c_str())), + _num(node->getIntValue("number", 0)), + _static_pressure(node->getStringValue("static-pressure", "/systems/static/pressure-inhg")), + _tau(node->getDoubleValue("tau", 0.1)), + _quantum(node->getDoubleValue("quantum", quantum)), + _settingInHg(29.921260) { - int i; - for (i = 0; altitude_data[i][0] != -1; i++) - _altitude_table->addEntry(altitude_data[i][0], altitude_data[i][1]); - - for ( i = 0; i < node->nChildren(); ++i ) { - SGPropertyNode *child = node->getChild(i); - string cname = child->getName(); - string cval = child->getStringValue(); - if ( cname == "name" ) { - name = cval; - } else if ( cname == "number" ) { - num = child->getIntValue(); - } else if ( cname == "static-port" ) { - static_port = cval; - } else { - SG_LOG( SG_INSTR, SG_WARN, "Error in altimeter config logic" ); - if ( name.length() ) { - SG_LOG( SG_INSTR, SG_WARN, "Section = " << name ); - } - } - } + // FIXME: change default to false once all aircraft which use + // altimiter as an encoder are converted to request this explicitly + _encodeModeC = node->getBoolValue("encode-mode-c", true); + _encodeModeS = node->getBoolValue("encode-mode-s", false); + + _tiedProperties.setRoot( _rootNode ); +} + +Altimeter::~Altimeter () +{} + +double +Altimeter::getSettingInHg() const +{ + return _settingInHg; } -Altimeter::Altimeter () - : _altitude_table(new SGInterpTable) +void +Altimeter::setSettingInHg( double value ) { + _settingInHg = value; +} - for (int i = 0; altitude_data[i][0] != -1; i++) - _altitude_table->addEntry(altitude_data[i][0], altitude_data[i][1]); +double +Altimeter::getSettingHPa() const +{ + return _settingInHg * SG_INHG_TO_PA / 100; } -Altimeter::~Altimeter () +void +Altimeter::setSettingHPa( double value ) { - delete _altitude_table; + _settingInHg = value * SG_PA_TO_INHG * 100; } + void Altimeter::init () { - string branch; - branch = "/instrumentation/" + name; - static_port += "/pressure-inhg"; + _pressure_node = fgGetNode(_static_pressure.c_str(), true); + _serviceable_node = _rootNode->getChild("serviceable", 0, true); + _press_alt_node = _rootNode->getChild("pressure-alt-ft", 0, true); + if (_encodeModeC) { + _mode_c_node = _rootNode->getChild("mode-c-alt-ft", 0, true); + } + + if (_encodeModeS) { + _mode_s_node = _rootNode->getChild("mode-s-alt-ft", 0, true); + } + + _altitude_node = _rootNode->getChild("indicated-altitude-ft", 0, true); + + reinit(); +} - SGPropertyNode *node = fgGetNode(branch.c_str(), num, true ); +void +Altimeter::reinit () +{ + _raw_PA = 0.0; + _kollsman = 0.0; +} - _serviceable_node = node->getChild("serviceable", 0, true); - _setting_node = node->getChild("setting-inhg", 0, true); - _pressure_node = fgGetNode(static_port.c_str(), true); - _altitude_node = node->getChild("indicated-altitude-ft", 0, true); +void +Altimeter::bind() +{ + _rootNode = fgGetNode("/instrumentation/" + _name, _num, true ); + _tiedProperties.setRoot(_rootNode); + + _tiedProperties.Tie("setting-inhg", this, &Altimeter::getSettingInHg, &Altimeter::setSettingInHg ); + _tiedProperties.Tie("setting-hpa", this, &Altimeter::getSettingHPa, &Altimeter::setSettingHPa ); +} + +void +Altimeter::unbind() +{ + _tiedProperties.Untie(); } void Altimeter::update (double dt) { if (_serviceable_node->getBoolValue()) { + double trat = _tau > 0 ? dt/_tau : 100; double pressure = _pressure_node->getDoubleValue(); - double setting = _setting_node->getDoubleValue(); - - // Move towards the current setting - double last_altitude = _altitude_node->getDoubleValue(); - double current_altitude = - _altitude_table->interpolate(setting - pressure); - _altitude_node->setDoubleValue(fgGetLowPass(last_altitude, - current_altitude, - dt * RESPONSIVENESS)); + double press_alt = _press_alt_node->getDoubleValue(); + // The mechanism settles slowly toward new pressure altitude: + _raw_PA = fgGetLowPass(_raw_PA, _altimeter.press_alt_ft(pressure), trat); + + if (_encodeModeC) { + _mode_c_node->setDoubleValue(100 * SGMiscd::round(_raw_PA/100)); + } + + if (_encodeModeS) { + _mode_s_node->setDoubleValue(10 * SGMiscd::round(_raw_PA/10)); + } + + _kollsman = fgGetLowPass(_kollsman, _altimeter.kollsman_ft(_settingInHg), trat); + if (_quantum) + press_alt = _quantum * SGMiscd::round(_raw_PA/_quantum); + else + press_alt = _raw_PA; + _press_alt_node->setDoubleValue(press_alt); + _altitude_node->setDoubleValue(press_alt - _kollsman); } }