3 // Written by Vivian MEAZZA, started Feb 2008.
6 // Copyright (C) 2008 Vivian Meazza
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.
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.
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.
28 #include "rad_alt.hxx"
31 radAlt::radAlt(SGPropertyNode *node) : agRadar(node)
34 _name = node->getStringValue("name", "radar-altimeter");
35 _num = node->getIntValue("number", 0);
48 _user_alt_agl_node = fgGetNode("/position/altitude-agl-ft", true);
49 _rad_alt_warning_node = fgGetNode("/sim/alarms/rad-alt-warning", true);
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
62 _Instrument->setFloatValue("tilt",-85);
63 _Instrument->setStringValue("status","RA");
65 //_Instrument->setIntValue("mode-control", 10);
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);
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);
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");
92 //cout << " radar alt init done" << endl;
96 radAlt::update (double delta_time_sec)
98 if ( ! _sim_init_done ) {
100 if ( ! fgGetBool("sim/sceneryloaded", false) )
103 _sim_init_done = true;
106 if ( !_odg || ! _serviceable_node->getBoolValue() ) {
107 _Instrument->setStringValue("status","");
111 _time += delta_time_sec;
113 if (_time < _interval)
123 radAlt::getDistanceAntennaToHit(SGVec3d nearestHit) const
125 //calculate the distance antenna to hit
127 SGVec3d cartantennapos = getCartAntennaPos();;
129 SGVec3d diff = nearestHit - cartantennapos;
130 double distance = norm(diff);
135 radAlt::update_altitude()
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);
148 _min_radalt = max_range;
152 SGVec3d cartantennapos = getCartAntennaPos();
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);
159 globals->get_scenery()->get_cart_ground_intersection(cartantennapos, uservec, nearestHit);
160 SGGeodesy::SGCartToGeod(nearestHit, hitpos);
162 double radalt = getDistanceAntennaToHit(nearestHit);
163 double course1, course2, distance;
165 SGGeodesy::inverse(hitpos, antennapos, course1, course2, distance);
166 _Instrument->setDoubleValue("hit/altitude-agl-ft",
167 _user_alt_agl_node->getDoubleValue());
169 if (radalt >= min_range && radalt <= max_range) {
172 if (radalt < _min_radalt)
173 _min_radalt = radalt;
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);
182 if (set_ht_ft!= 9999){
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);
189 _rad_alt_warning_node->setIntValue(0);
192 _rad_alt_warning_node->setIntValue(9999);
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);
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