]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/rad_alt.cxx
fix NAV receiver vs GPS bugs
[flightgear.git] / src / Instrumentation / rad_alt.cxx
1 // Radar Altimeter
2 //
3 // Written by Vivian MEAZZA, started Feb 2008.
4 //
5 //
6 // Copyright (C) 2008  Vivian Meazza
7 //
8 // This program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License as
10 // published by the Free Software Foundation; either version 2 of the
11 // License, or (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful, but
14 // WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 // General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 //
22 //
23
24 #ifdef HAVE_CONFIG_H
25 #  include "config.h"
26 #endif
27
28 #include <Main/fg_props.hxx>
29 #include <Main/globals.hxx>
30 #include "rad_alt.hxx"
31
32
33 radAlt::radAlt(SGPropertyNode *node) : agRadar(node) 
34 {
35
36     _name = node->getStringValue("name", "radar-altimeter");
37     _num = node->getIntValue("number", 0);
38
39 }
40
41 radAlt::~radAlt()
42 {
43 }
44
45 void
46 radAlt::init ()
47 {
48     agRadar::init();
49
50     _user_alt_agl_node     = fgGetNode("/position/altitude-agl-ft", true);
51     _rad_alt_warning_node   = fgGetNode("/sim/alarms/rad-alt-warning", true);
52
53     //// those properties are used by a radar instrument of a MFD
54     //// input switch = OFF | TST | STBY | ON
55     //// input mode = WX | WXA | MAP | TW
56     //// output status = STBY | TEST | WX | WXA | MAP | blank
57     //// input lightning = true | false
58     //// input TRK = +/- n degrees
59     //// input TILT = +/- n degree
60     //// input autotilt = true | false
61     //// input range = n nm (20/40/80)
62     //// input display-mode = arc | rose | map | plan
63
64     _Instrument->setFloatValue("tilt",-85);
65     _Instrument->setStringValue("status","RA");
66
67     //_Instrument->setIntValue("mode-control", 10);
68
69     _Instrument->getDoubleValue("elev-limit", true);
70     _Instrument->getDoubleValue("elev-step-deg", true);
71     _Instrument->getDoubleValue("az-limit-deg", true);
72     _Instrument->getDoubleValue("az-step-deg", true);
73     _Instrument->getDoubleValue("max-range-m", true);
74     _Instrument->getDoubleValue("min-range-m", true);
75     _Instrument->getDoubleValue("tilt", true);
76     _Instrument->getDoubleValue("set-height-ft", true);
77     _Instrument->getDoubleValue("set-excursion-percent", true);
78
79     _Instrument->setDoubleValue("hit/brg-deg", 0);
80     _Instrument->setDoubleValue("hit/range-m", 0);
81     _Instrument->setStringValue("hit/material", "");
82     _Instrument->setDoubleValue("hit/bumpiness", 0);
83
84
85
86     _Instrument->removeChild("terrain-warning");
87     _Instrument->removeChild("mode-control");
88     _Instrument->removeChild("limit-deg");
89     _Instrument->removeChild("reference-range-nm");
90     _Instrument->removeChild("heading-marker");
91     _Instrument->removeChild("display-controls");
92     _Instrument->removeChild("font");
93
94     //cout << " radar alt init done" << endl;
95 }
96
97 void
98 radAlt::update (double delta_time_sec)
99 {
100     if ( ! _sim_init_done ) {
101
102         if ( ! fgGetBool("sim/sceneryloaded", false) )
103             return;
104
105         _sim_init_done = true;
106     }
107
108     if ( !_odg || ! _serviceable_node->getBoolValue() ) {
109         _Instrument->setStringValue("status","");
110         return;
111     }
112
113     _time += delta_time_sec;
114
115     if (_time < _interval)
116         return;
117
118     _time = 0.0;
119     update_altitude();
120 }
121
122
123
124 double
125 radAlt::getDistanceAntennaToHit(SGVec3d nearestHit) const 
126 {
127     //calculate the distance antenna to hit
128
129     SGVec3d cartantennapos = getCartAntennaPos();;
130
131     SGVec3d diff = nearestHit - cartantennapos;
132     double distance = norm(diff);
133     return distance ;
134 }
135
136 void
137 radAlt::update_altitude()
138 {
139 //    int mode           = _radar_mode_control_node->getIntValue();
140 //    double tilt        = _Instrument->getDoubleValue("tilt", -85);
141     double el_limit    = _Instrument->getDoubleValue("elev-limit", 15);
142     double el_step     = _Instrument->getDoubleValue("elev-step-deg", 15);
143     double az_limit    = _Instrument->getDoubleValue("az-limit-deg", 15);
144     double az_step     = _Instrument->getDoubleValue("az-step-deg", 15);
145     double max_range   = _Instrument->getDoubleValue("max-range-m", 1500);
146     double min_range   = _Instrument->getDoubleValue("min-range-m", 0.001);
147     double set_ht_ft   = _Instrument->getDoubleValue("set-height-ft", 9999);
148     double set_excur   = _Instrument->getDoubleValue("set-excursion-percent", 0);
149
150     _min_radalt = max_range;
151
152     setUserPos();
153     setAntennaPos();
154     SGVec3d cartantennapos = getCartAntennaPos();
155
156     for(double brg = -az_limit; brg <= az_limit; brg += az_step){
157         for(double elev = el_limit; elev >= - el_limit; elev -= el_step){
158             setUserVec(brg, elev);
159
160             SGVec3d nearestHit;
161             globals->get_scenery()->get_cart_ground_intersection(cartantennapos, uservec, nearestHit);
162             SGGeodesy::SGCartToGeod(nearestHit, hitpos);
163
164             double radalt = getDistanceAntennaToHit(nearestHit);
165             double course1, course2, distance;
166
167             SGGeodesy::inverse(hitpos, antennapos, course1, course2, distance);
168             _Instrument->setDoubleValue("hit/altitude-agl-ft",
169                      _user_alt_agl_node->getDoubleValue());
170
171             if (radalt >= min_range && radalt <= max_range) {
172                 getMaterial();
173                 
174                 if (radalt < _min_radalt)
175                     _min_radalt = radalt;
176
177                 _Instrument->setDoubleValue("radar-altitude-ft", _min_radalt * SG_METER_TO_FEET);
178                 _Instrument->setDoubleValue("hit/radar-altitude-ft", radalt * SG_METER_TO_FEET);
179                 _Instrument->setDoubleValue("hit/brg-deg", course2);
180                 _Instrument->setDoubleValue("hit/range-m", distance);
181                 _Instrument->setStringValue("hit/material", _mat_name.c_str());
182                 _Instrument->setDoubleValue("hit/bumpiness", _bumpinessFactor);
183
184                 if (set_ht_ft!= 9999){
185
186                     if (_min_radalt * SG_METER_TO_FEET < set_ht_ft * (100 - set_excur)/100)
187                         _rad_alt_warning_node->setIntValue(-1);
188                     else if (_min_radalt * SG_METER_TO_FEET > set_ht_ft * (100 + set_excur)/100)
189                         _rad_alt_warning_node->setIntValue(1);
190                     else
191                         _rad_alt_warning_node->setIntValue(0);
192
193                 } else
194                     _rad_alt_warning_node->setIntValue(9999);
195
196             } else {
197                 _rad_alt_warning_node->setIntValue(9999);
198                 _Instrument->setDoubleValue("radar-altitude-ft", _min_radalt * SG_METER_TO_FEET);
199                 _Instrument->setDoubleValue("hit/radar-altitude-ft",0);
200                 _Instrument->setDoubleValue("hit/brg-deg", 0);
201                 _Instrument->setDoubleValue("hit/range-m", 0);
202                 _Instrument->setStringValue("hit/material", "");
203                 _Instrument->setDoubleValue("hit/bumpiness", 0);
204             }
205
206             //cout  << "usr hdg " << _user_hdg_deg_node->getDoubleValue()
207             //    << " ant brg " << course2 
208             //    << " elev " << _Instrument->getDoubleValue("tilt")
209             //    << " gnd rng nm " << distance * SG_METER_TO_NM
210             //    << " ht " << hitpos.getElevationFt()
211             //    << " mat " << _mat_name
212             //    << " solid " << _solid
213             //    << " bumpiness " << _bumpinessFactor
214             //    << endl;
215
216         }
217     }
218 }
219
220