]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/rad_alt.cxx
Merge branch 'maint2' into next
[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 "rad_alt.hxx"
29
30
31 radAlt::radAlt(SGPropertyNode *node) : agRadar(node) 
32 {
33
34     _name = node->getStringValue("name", "radar-altimeter");
35     _num = node->getIntValue("number", 0);
36
37 }
38
39 radAlt::~radAlt()
40 {
41 }
42
43 void
44 radAlt::init ()
45 {
46     agRadar::init();
47
48     _user_alt_agl_node     = fgGetNode("/position/altitude-agl-ft", true);
49     _rad_alt_warning_node   = fgGetNode("/sim/alarms/rad-alt-warning", true);
50
51     //// those properties are used by a radar instrument of a MFD
52     //// input switch = OFF | TST | STBY | ON
53     //// input mode = WX | WXA | MAP | TW
54     //// output status = STBY | TEST | WX | WXA | MAP | blank
55     //// input lightning = true | false
56     //// input TRK = +/- n degrees
57     //// input TILT = +/- n degree
58     //// input autotilt = true | false
59     //// input range = n nm (20/40/80)
60     //// input display-mode = arc | rose | map | plan
61
62     _Instrument->setFloatValue("tilt",-85);
63     _Instrument->setStringValue("status","RA");
64
65     //_Instrument->setIntValue("mode-control", 10);
66
67     _Instrument->getDoubleValue("elev-limit", true);
68     _Instrument->getDoubleValue("elev-step-deg", true);
69     _Instrument->getDoubleValue("az-limit-deg", true);
70     _Instrument->getDoubleValue("az-step-deg", true);
71     _Instrument->getDoubleValue("max-range-m", true);
72     _Instrument->getDoubleValue("min-range-m", true);
73     _Instrument->getDoubleValue("tilt", true);
74     _Instrument->getDoubleValue("set-height-ft", true);
75     _Instrument->getDoubleValue("set-excursion-percent", true);
76
77     _Instrument->setDoubleValue("hit/brg-deg", 0);
78     _Instrument->setDoubleValue("hit/range-m", 0);
79     _Instrument->setStringValue("hit/material", "");
80     _Instrument->setDoubleValue("hit/bumpiness", 0);
81
82
83
84     _Instrument->removeChild("terrain-warning");
85     _Instrument->removeChild("mode-control");
86     _Instrument->removeChild("limit-deg");
87     _Instrument->removeChild("reference-range-nm");
88     _Instrument->removeChild("heading-marker");
89     _Instrument->removeChild("display-controls");
90     _Instrument->removeChild("font");
91
92     //cout << " radar alt init done" << endl;
93 }
94
95 void
96 radAlt::update (double delta_time_sec)
97 {
98     if ( ! _sim_init_done ) {
99
100         if ( ! fgGetBool("sim/sceneryloaded", false) )
101             return;
102
103         _sim_init_done = true;
104     }
105
106     if ( !_odg || ! _serviceable_node->getBoolValue() ) {
107         _Instrument->setStringValue("status","");
108         return;
109     }
110
111     _time += delta_time_sec;
112
113     if (_time < _interval)
114         return;
115
116     _time = 0.0;
117     update_altitude();
118 }
119
120
121
122 double
123 radAlt::getDistanceAntennaToHit(SGVec3d nearestHit) const 
124 {
125     //calculate the distance antenna to hit
126
127     SGVec3d cartantennapos = getCartAntennaPos();;
128
129     SGVec3d diff = nearestHit - cartantennapos;
130     double distance = norm(diff);
131     return distance ;
132 }
133
134 void
135 radAlt::update_altitude()
136 {
137     int mode           = _radar_mode_control_node->getIntValue();
138     double tilt        = _Instrument->getDoubleValue("tilt", -85);
139     double el_limit    = _Instrument->getDoubleValue("elev-limit", 15);
140     double el_step     = _Instrument->getDoubleValue("elev-step-deg", 15);
141     double az_limit    = _Instrument->getDoubleValue("az-limit-deg", 15);
142     double az_step     = _Instrument->getDoubleValue("az-step-deg", 15);
143     double max_range   = _Instrument->getDoubleValue("max-range-m", 1500);
144     double min_range   = _Instrument->getDoubleValue("min-range-m", 0.001);
145     double set_ht_ft   = _Instrument->getDoubleValue("set-height-ft", 9999);
146     double set_excur   = _Instrument->getDoubleValue("set-excursion-percent", 0);
147
148     _min_radalt = max_range;
149
150     setUserPos();
151     setAntennaPos();
152     SGVec3d cartantennapos = getCartAntennaPos();
153
154     for(double brg = -az_limit; brg <= az_limit; brg += az_step){
155         for(double elev = el_limit; elev >= - el_limit; elev -= el_step){
156             setUserVec(brg, elev);
157
158             SGVec3d nearestHit;
159             globals->get_scenery()->get_cart_ground_intersection(cartantennapos, uservec, nearestHit);
160             SGGeodesy::SGCartToGeod(nearestHit, hitpos);
161
162             double radalt = getDistanceAntennaToHit(nearestHit);
163             double course1, course2, distance;
164
165             SGGeodesy::inverse(hitpos, antennapos, course1, course2, distance);
166             _Instrument->setDoubleValue("hit/altitude-agl-ft",
167                      _user_alt_agl_node->getDoubleValue());
168
169             if (radalt >= min_range && radalt <= max_range) {
170                 getMaterial();
171                 
172                 if (radalt < _min_radalt)
173                     _min_radalt = radalt;
174
175                 _Instrument->setDoubleValue("radar-altitude-ft", _min_radalt * SG_METER_TO_FEET);
176                 _Instrument->setDoubleValue("hit/radar-altitude-ft", radalt * SG_METER_TO_FEET);
177                 _Instrument->setDoubleValue("hit/brg-deg", course2);
178                 _Instrument->setDoubleValue("hit/range-m", distance);
179                 _Instrument->setStringValue("hit/material", _mat_name.c_str());
180                 _Instrument->setDoubleValue("hit/bumpiness", _bumpinessFactor);
181
182                 if (set_ht_ft!= 9999){
183
184                     if (_min_radalt * SG_METER_TO_FEET < set_ht_ft * (100 - set_excur)/100)
185                         _rad_alt_warning_node->setIntValue(-1);
186                     else if (_min_radalt * SG_METER_TO_FEET > set_ht_ft * (100 + set_excur)/100)
187                         _rad_alt_warning_node->setIntValue(1);
188                     else
189                         _rad_alt_warning_node->setIntValue(0);
190
191                 } else
192                     _rad_alt_warning_node->setIntValue(9999);
193
194             } else {
195                 _rad_alt_warning_node->setIntValue(9999);
196                 _Instrument->setDoubleValue("radar-altitude-ft", _min_radalt * SG_METER_TO_FEET);
197                 _Instrument->setDoubleValue("hit/radar-altitude-ft",0);
198                 _Instrument->setDoubleValue("hit/brg-deg", 0);
199                 _Instrument->setDoubleValue("hit/range-m", 0);
200                 _Instrument->setStringValue("hit/material", "");
201                 _Instrument->setDoubleValue("hit/bumpiness", 0);
202             }
203
204             //cout  << "usr hdg " << _user_hdg_deg_node->getDoubleValue()
205             //    << " ant brg " << course2 
206             //    << " elev " << _Instrument->getDoubleValue("tilt")
207             //    << " gnd rng nm " << distance * SG_METER_TO_NM
208             //    << " ht " << hitpos.getElevationFt()
209             //    << " mat " << _mat_name
210             //    << " solid " << _solid
211             //    << " bumpiness " << _bumpinessFactor
212             //    << endl;
213
214         }
215     }
216 }
217
218