155 lines
4.2 KiB
C++
155 lines
4.2 KiB
C++
// 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:
|
|
// <altimeter>
|
|
// <name>encoder</name>
|
|
// <number>0</number>
|
|
// <static-pressure>/systems/static/pressure-inhg</static-pressure>
|
|
// <quantum>10</quantum>
|
|
// <tau>0</tau>
|
|
// </altimeter>
|
|
// Note non-default name, quantum, and tau values.
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include <config.h>
|
|
#endif
|
|
|
|
#include <simgear/constants.h>
|
|
#include <simgear/math/interpolater.hxx>
|
|
#include <simgear/math/SGMath.hxx>
|
|
|
|
#include <Main/fg_props.hxx>
|
|
#include <Main/util.hxx>
|
|
#include <Environment/atmosphere.hxx>
|
|
|
|
#include "altimeter.hxx"
|
|
|
|
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)
|
|
{
|
|
// 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;
|
|
}
|
|
|
|
void
|
|
Altimeter::setSettingInHg( double value )
|
|
{
|
|
_settingInHg = value;
|
|
}
|
|
|
|
double
|
|
Altimeter::getSettingHPa() const
|
|
{
|
|
return _settingInHg * SG_INHG_TO_PA / 100;
|
|
}
|
|
|
|
void
|
|
Altimeter::setSettingHPa( double value )
|
|
{
|
|
_settingInHg = value * SG_PA_TO_INHG * 100;
|
|
}
|
|
|
|
|
|
void
|
|
Altimeter::init ()
|
|
{
|
|
_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();
|
|
}
|
|
|
|
void
|
|
Altimeter::reinit ()
|
|
{
|
|
_raw_PA = 0.0;
|
|
_kollsman = 0.0;
|
|
}
|
|
|
|
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 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);
|
|
}
|
|
}
|
|
|
|
|
|
// Register the subsystem.
|
|
#if 0
|
|
SGSubsystemMgr::InstancedRegistrant<Altimeter> registrantAltimeter(
|
|
SGSubsystemMgr::FDM,
|
|
{{"instrumentation", SGSubsystemMgr::Dependency::HARD}});
|
|
#endif
|
|
|
|
// end of altimeter.cxx
|