2002-09-27 18:27:58 +00:00
|
|
|
// altimeter.cxx - an altimeter tied to the static port.
|
|
|
|
// Written by David Megginson, started 2002.
|
|
|
|
//
|
|
|
|
// This file is in the Public Domain and comes with no warranty.
|
|
|
|
|
|
|
|
#include <simgear/math/interpolater.hxx>
|
|
|
|
|
|
|
|
#include "altimeter.hxx"
|
|
|
|
#include <Main/fg_props.hxx>
|
2002-09-27 22:04:21 +00:00
|
|
|
#include <Main/util.hxx>
|
2002-09-27 18:27:58 +00:00
|
|
|
|
|
|
|
|
2003-02-12 18:35:04 +00:00
|
|
|
// A higher number means more responsive
|
|
|
|
#define RESPONSIVENESS 10.0
|
|
|
|
|
|
|
|
|
2002-09-27 18:27:58 +00:00
|
|
|
// Altitude based on pressure difference from sea level.
|
|
|
|
// pressure difference inHG, altitude ft
|
|
|
|
static double altitude_data[][2] = {
|
2002-12-30 22:21:31 +00:00
|
|
|
{ -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 }
|
2002-09-27 18:27:58 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2004-10-16 12:37:39 +00:00
|
|
|
Altimeter::Altimeter ( SGPropertyNode *node )
|
2005-04-06 08:24:30 +00:00
|
|
|
: name("altimeter"),
|
2004-10-16 12:37:39 +00:00
|
|
|
num(0),
|
2005-04-06 08:24:30 +00:00
|
|
|
static_port("/systems/static"),
|
|
|
|
_altitude_table(new SGInterpTable)
|
2004-10-16 12:37:39 +00:00
|
|
|
{
|
2004-10-20 08:12:55 +00:00
|
|
|
int i;
|
|
|
|
for (i = 0; altitude_data[i][0] != -1; i++)
|
2004-10-16 12:37:39 +00:00
|
|
|
_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 {
|
2004-10-24 11:05:14 +00:00
|
|
|
SG_LOG( SG_INSTR, SG_WARN, "Error in altimeter config logic" );
|
2004-10-16 12:37:39 +00:00
|
|
|
if ( name.length() ) {
|
2004-10-24 11:05:14 +00:00
|
|
|
SG_LOG( SG_INSTR, SG_WARN, "Section = " << name );
|
2004-10-16 12:37:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-09-27 18:27:58 +00:00
|
|
|
Altimeter::Altimeter ()
|
|
|
|
: _altitude_table(new SGInterpTable)
|
|
|
|
{
|
|
|
|
|
|
|
|
for (int i = 0; altitude_data[i][0] != -1; i++)
|
|
|
|
_altitude_table->addEntry(altitude_data[i][0], altitude_data[i][1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
Altimeter::~Altimeter ()
|
|
|
|
{
|
|
|
|
delete _altitude_table;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Altimeter::init ()
|
|
|
|
{
|
2004-10-16 12:37:39 +00:00
|
|
|
string branch;
|
|
|
|
branch = "/instrumentation/" + name;
|
|
|
|
static_port += "/pressure-inhg";
|
|
|
|
|
|
|
|
SGPropertyNode *node = fgGetNode(branch.c_str(), num, true );
|
|
|
|
|
|
|
|
_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);
|
2002-09-27 18:27:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Altimeter::update (double dt)
|
|
|
|
{
|
|
|
|
if (_serviceable_node->getBoolValue()) {
|
|
|
|
double pressure = _pressure_node->getDoubleValue();
|
|
|
|
double setting = _setting_node->getDoubleValue();
|
2003-02-12 18:35:04 +00:00
|
|
|
|
|
|
|
// 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));
|
2002-09-27 18:27:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// end of altimeter.cxx
|