]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/altimeter.cxx
5b7e3decc3cc52345386b4cff5325b55b851f3c0
[flightgear.git] / src / Instrumentation / altimeter.cxx
1 // altimeter.cxx - an altimeter tied to the static port.
2 // Written by David Megginson, started 2002.
3 //
4 // This file is in the Public Domain and comes with no warranty.
5
6 #include <simgear/math/interpolater.hxx>
7
8 #include "altimeter.hxx"
9 #include <Main/fg_props.hxx>
10 #include <Main/util.hxx>
11
12
13 // A higher number means more responsive
14 #define RESPONSIVENESS 10.0
15
16
17 // Altitude based on pressure difference from sea level.
18 // pressure difference inHG, altitude ft
19 static double altitude_data[][2] = {
20  { -8.41, -8858.27 },
21  { 0.00, 0.00 },
22  { 3.05, 2952.76 },
23  { 5.86, 5905.51 },
24  { 8.41, 8858.27 },
25  { 10.74, 11811.02 },
26  { 12.87, 14763.78 },
27  { 14.78, 17716.54 },
28  { 16.55, 20669.29 },
29  { 18.13, 23622.05 },
30  { 19.62, 26574.80 },
31  { 20.82, 29527.56 },
32  { 21.96, 32480.31 },
33  { 23.01, 35433.07 },
34  { 23.91, 38385.83 },
35  { 24.71, 41338.58 },
36  { 25.40, 44291.34 },
37  { 26.00, 47244.09 },
38  { 26.51, 50196.85 },
39  { 26.96, 53149.61 },
40  { 27.35, 56102.36 },
41  { 27.68, 59055.12 },
42  { 27.98, 62007.87 },
43  { 29.62, 100000.00 },            // just to fill it in
44  { -1, -1 }
45 };
46
47
48 Altimeter::Altimeter ( SGPropertyNode *node )
49     : _altitude_table(new SGInterpTable),
50       name("altimeter"),
51       num(0),
52       static_port("/systems/static")
53 {
54     int i;
55     for (i = 0; altitude_data[i][0] != -1; i++)
56         _altitude_table->addEntry(altitude_data[i][0], altitude_data[i][1]);
57
58     for ( i = 0; i < node->nChildren(); ++i ) {
59         SGPropertyNode *child = node->getChild(i);
60         string cname = child->getName();
61         string cval = child->getStringValue();
62         if ( cname == "name" ) {
63             name = cval;
64         } else if ( cname == "number" ) {
65             num = child->getIntValue();
66         } else if ( cname == "static-port" ) {
67             static_port = cval;
68         } else {
69             SG_LOG( SG_INSTR, SG_WARN, "Error in altimeter config logic" );
70             if ( name.length() ) {
71                 SG_LOG( SG_INSTR, SG_WARN, "Section = " << name );
72             }
73         }
74     }
75 }
76
77 Altimeter::Altimeter ()
78     : _altitude_table(new SGInterpTable)
79 {
80
81     for (int i = 0; altitude_data[i][0] != -1; i++)
82         _altitude_table->addEntry(altitude_data[i][0], altitude_data[i][1]);
83 }
84
85 Altimeter::~Altimeter ()
86 {
87     delete _altitude_table;
88 }
89
90 void
91 Altimeter::init ()
92 {
93     string branch;
94     branch = "/instrumentation/" + name;
95     static_port += "/pressure-inhg";
96
97     SGPropertyNode *node = fgGetNode(branch.c_str(), num, true );
98
99     _serviceable_node = node->getChild("serviceable", 0, true);
100     _setting_node = node->getChild("setting-inhg", 0, true);
101     _pressure_node = fgGetNode(static_port.c_str(), true);
102     _altitude_node = node->getChild("indicated-altitude-ft", 0, true);
103 }
104
105 void
106 Altimeter::update (double dt)
107 {
108     if (_serviceable_node->getBoolValue()) {
109         double pressure = _pressure_node->getDoubleValue();
110         double setting = _setting_node->getDoubleValue();
111
112                                 // Move towards the current setting
113         double last_altitude = _altitude_node->getDoubleValue();
114         double current_altitude =
115             _altitude_table->interpolate(setting - pressure);
116         _altitude_node->setDoubleValue(fgGetLowPass(last_altitude,
117                                                     current_altitude,
118                                                     dt * RESPONSIVENESS));
119     }
120 }
121
122 // end of altimeter.cxx