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 <Main/fg_props.hxx>
29 #include <Main/globals.hxx>
30 #include "rad_alt.hxx"
33 radAlt::radAlt(SGPropertyNode *node) : agRadar(node)
36 _name = node->getStringValue("name", "radar-altimeter");
37 _num = node->getIntValue("number", 0);
50 _user_alt_agl_node = fgGetNode("/position/altitude-agl-ft", true);
51 _rad_alt_warning_node = fgGetNode("/sim/alarms/rad-alt-warning", true);
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
64 _Instrument->setFloatValue("tilt",-85);
65 _Instrument->setStringValue("status","RA");
67 //_Instrument->setIntValue("mode-control", 10);
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);
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);
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");
94 //cout << " radar alt init done" << endl;
98 radAlt::update (double delta_time_sec)
100 if ( ! _sim_init_done ) {
102 if ( ! fgGetBool("sim/sceneryloaded", false) )
105 _sim_init_done = true;
108 if ( !_odg || ! _serviceable_node->getBoolValue() ) {
109 _Instrument->setStringValue("status","");
113 _time += delta_time_sec;
115 if (_time < _interval)
125 radAlt::getDistanceAntennaToHit(SGVec3d nearestHit) const
127 //calculate the distance antenna to hit
129 SGVec3d cartantennapos = getCartAntennaPos();;
131 SGVec3d diff = nearestHit - cartantennapos;
132 double distance = norm(diff);
137 radAlt::update_altitude()
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);
150 _min_radalt = max_range;
154 SGVec3d cartantennapos = getCartAntennaPos();
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);
161 globals->get_scenery()->get_cart_ground_intersection(cartantennapos, uservec, nearestHit);
162 SGGeodesy::SGCartToGeod(nearestHit, hitpos);
164 double radalt = getDistanceAntennaToHit(nearestHit);
165 double course1, course2, distance;
167 SGGeodesy::inverse(hitpos, antennapos, course1, course2, distance);
168 _Instrument->setDoubleValue("hit/altitude-agl-ft",
169 _user_alt_agl_node->getDoubleValue());
171 if (radalt >= min_range && radalt <= max_range) {
174 if (radalt < _min_radalt)
175 _min_radalt = radalt;
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);
184 if (set_ht_ft!= 9999){
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);
191 _rad_alt_warning_node->setIntValue(0);
194 _rad_alt_warning_node->setIntValue(9999);
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);
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