]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/encoder.cxx
fa01c40eae8db1b8285bc7be0aa9f4a14f7d8403
[flightgear.git] / src / Instrumentation / encoder.cxx
1 // encoder.cxx -- class to impliment an altitude encoder
2 //
3 // Written by Roy Vegard Ovesen, started September 2004.
4 //
5 // Copyright (C) 2004  Roy Vegard Ovesen - rvovesen@tiscali.no
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 #ifdef HAVE_CONFIG_H
22 #  include <config.h>
23 #endif
24
25 #include "encoder.hxx"
26
27
28 // Altitude based on pressure difference from sea level.
29 // pressure difference inHG, altitude ft
30 static double altitude_data[][2] = {
31  { -8.41, -8858.27 },
32  { 0.00, 0.00 },
33  { 3.05, 2952.76 },
34  { 5.86, 5905.51 },
35  { 8.41, 8858.27 },
36  { 10.74, 11811.02 },
37  { 12.87, 14763.78 },
38  { 14.78, 17716.54 },
39  { 16.55, 20669.29 },
40  { 18.13, 23622.05 },
41  { 19.62, 26574.80 },
42  { 20.82, 29527.56 },
43  { 21.96, 32480.31 },
44  { 23.01, 35433.07 },
45  { 23.91, 38385.83 },
46  { 24.71, 41338.58 },
47  { 25.40, 44291.34 },
48  { 26.00, 47244.09 },
49  { 26.51, 50196.85 },
50  { 26.96, 53149.61 },
51  { 27.35, 56102.36 },
52  { 27.68, 59055.12 },
53  { 27.98, 62007.87 },
54  { 29.62, 100000.00 },            // just to fill it in
55  { -1, -1 }
56 };
57
58 int round (double value, int nearest=1)
59 {
60     return ((int) (value/nearest + 0.5)) * nearest;
61 }
62
63 Encoder::Encoder(SGPropertyNode *node)
64     :
65     altitudeTable(new SGInterpTable),
66     name("encoder"),
67     num(0),
68     staticPort("/systems/static")
69 {
70     int i;
71     for ( i = 0; altitude_data[i][0] != -1; i++ )
72         altitudeTable->addEntry(altitude_data[i][0], altitude_data[i][1]);
73
74     for ( i = 0; i < node->nChildren(); ++i ) {
75         SGPropertyNode *child = node->getChild(i);
76         string cname = child->getName();
77         string cval = child->getStringValue();
78         if ( cname == "name" ) {
79             name = cval;
80         } else if ( cname == "number" ) {
81             num = child->getIntValue();
82         } else if ( cname == "static-port" ) {
83             staticPort = cval;
84         } else {
85             SG_LOG( SG_INSTR, SG_WARN, 
86                     "Error in encoder config logic" );
87             if ( name.length() ) {
88                 SG_LOG( SG_INSTR, SG_WARN, "Section = " << name );
89             }
90         }
91     }
92 }
93
94
95 Encoder::~Encoder()
96 {
97     delete altitudeTable;
98 }
99
100
101 void Encoder::init()
102 {
103     string branch;
104     branch = "/instrumentation/" + name;
105     staticPort += "/pressure-inhg";
106
107     SGPropertyNode *node = fgGetNode(branch.c_str(), num, true );
108     // Inputs
109     staticPressureNode = fgGetNode(staticPort.c_str(), true);
110     busPowerNode = fgGetNode("/systems/electrical/outputs/encoder", true);
111     serviceableNode = node->getChild("serviceable", 0, true);
112     // Outputs
113     pressureAltitudeNode = node->getChild("pressure-alt-ft", 0, true);
114     modeCAltitudeNode = node->getChild("mode-c-alt-ft", 0, true);
115 }
116
117
118 void Encoder::update(double dt)
119 {
120     if (serviceableNode->getBoolValue())
121     {
122         double staticPressure = staticPressureNode->getDoubleValue();
123         double pressureAltitude =
124             altitudeTable->interpolate(29.92 - staticPressure);
125         int pressureAlt = round(pressureAltitude, 10);
126         int modeCAltitude = round(pressureAltitude, 100);
127
128         pressureAltitudeNode->setIntValue(pressureAlt);
129         modeCAltitudeNode->setIntValue(modeCAltitude);
130     }
131 }