diff --git a/src/Instrumentation/Makefile.am b/src/Instrumentation/Makefile.am index 37a1a888b..fa7f85ea3 100644 --- a/src/Instrumentation/Makefile.am +++ b/src/Instrumentation/Makefile.am @@ -31,6 +31,7 @@ libInstrumentation_a_SOURCES = \ tacan.cxx tacan.hxx mk_viii.cxx mk_viii.hxx \ dclgps.cxx dclgps.hxx \ render_area_2d.cxx render_area_2d.hxx \ - groundradar.cxx groundradar.hxx + groundradar.cxx groundradar.hxx \ + agradar.cxx agradar.hxx rad_alt.cxx rad_alt.hxx INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_builddir)/src diff --git a/src/Instrumentation/agradar.cxx b/src/Instrumentation/agradar.cxx new file mode 100644 index 000000000..a1d293390 --- /dev/null +++ b/src/Instrumentation/agradar.cxx @@ -0,0 +1,333 @@ +// Air Ground Radar +// +// Written by Vivian MEAZZA, started Feb 2008. +// +// +// Copyright (C) 2008 Vivian Meazza +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "agradar.hxx" + + +agRadar::agRadar(SGPropertyNode *node) : wxRadarBg(node) +{ + + _name = node->getStringValue("name", "air-ground-radar"); + _num = node->getIntValue("number", 0); + +} + +agRadar::~agRadar () +{ +} + +void +agRadar::init () +{ + _user_hdg_deg_node = fgGetNode("/orientation/heading-deg", true); + _user_pitch_deg_node = fgGetNode("/orientation/pitch-deg", true); + _user_roll_deg_node = fgGetNode("/orientation/roll-deg", true); + + _terrain_warning_node = fgGetNode("/sim/alarms/terrain-warning", true); + _terrain_warning_node->setBoolValue(false); + + wxRadarBg::init(); + + // those properties are used by a radar instrument of a MFD + // input switch = OFF | TST | STBY | ON + // input mode = WX | WXA | MAP | TW + // output status = STBY | TEST | WX | WXA | MAP | blank + // input lightning = true | false + // input TRK = +/- n degrees + // input TILT = +/- n degree + // input autotilt = true | false + // input range = n nm (20/40/80) + // input display-mode = arc | rose | map | plan + + _Instrument->setFloatValue("trk", 0.0); + _Instrument->setFloatValue("tilt",-2.5); + _Instrument->setStringValue("status",""); + _Instrument->setIntValue("mode-control", 5); + + _Instrument->setBoolValue("stabilisation/roll", false); + _Instrument->setBoolValue("stabilisation/pitch", false); + + _Instrument->getNode("antenna/x-offset-m", true); + _Instrument->getNode("antenna/y-offset-m", true); + _Instrument->getNode("antenna/z-offset-m", true); + + _Instrument->getNode("terrain-warning/elev-limit-deg", true); + _Instrument->getNode("terrain-warning/elev-step-deg", true); + _Instrument->getNode("terrain-warning/az-limit-deg", true); + _Instrument->getNode("terrain-warning/az-step-deg", true); + _Instrument->getNode("terrain-warning/max-range-m", true); + _Instrument->getNode("terrain-warning/min-range-m", true); + _Instrument->getNode("terrain-warning/tilt",true); + + _Instrument->getNode("terrain-warning/hit/brg-deg", true); + _Instrument->getNode("terrain-warning/hit/range-m", true); + _Instrument->getNode("terrain-warning/hit/material", true); + _Instrument->getNode("terrain-warning/hit/bumpiness", true); + + _Instrument->getNode("terrain-warning/stabilisation/roll", true); + _Instrument->getNode("terrain-warning/stabilisation/pitch", true); +// cout << "init done" << endl; + +} + +void +agRadar::update (double delta_time_sec) +{ + if ( ! _sim_init_done ) { + + if ( ! fgGetBool("sim/sceneryloaded", false) ) + return; + + _sim_init_done = true; + } + + if ( !_odg || ! _serviceable_node->getBoolValue() ) { + _Instrument->setStringValue("status",""); + return; + } + + _time += delta_time_sec; + + if (_time < _interval) + return; + + _time = 0.0; + + + update_terrain(); +// wxRadarBg::update(delta_time_sec); +} + +void +agRadar::setUserPos() +{ + userpos.setLatitudeDeg(_user_lat_node->getDoubleValue()); + userpos.setLongitudeDeg(_user_lon_node->getDoubleValue()); + userpos.setElevationM(_user_alt_node->getDoubleValue() * SG_FEET_TO_METER); +} + +SGVec3d +agRadar::getCartUserPos() const { + SGVec3d cartUserPos = SGVec3d::fromGeod(userpos); + return cartUserPos; +} + +SGVec3d +agRadar::getCartAntennaPos() const { + + float yaw = _user_hdg_deg_node->getDoubleValue(); + float pitch = _user_pitch_deg_node->getDoubleValue(); + float roll = _user_roll_deg_node->getDoubleValue(); + + double x_offset_m =_Instrument->getDoubleValue("antenna/x-offset-m", 0); + double y_offset_m =_Instrument->getDoubleValue("antenna/y-offset-m", 0); + double z_offset_m =_Instrument->getDoubleValue("antenna/y-offset-m", 0); + + // convert geodetic positions to geocentered + SGVec3d cartuserPos = getCartUserPos(); + + // Transform to the right coordinate frame, configuration is done in + // the x-forward, y-right, z-up coordinates (feet), computation + // in the simulation usual body x-forward, y-right, z-down coordinates + // (meters) ) + SGVec3d _off(x_offset_m, y_offset_m, -z_offset_m); + + // Transform the user position to the horizontal local coordinate system. + SGQuatd hlTrans = SGQuatd::fromLonLat(userpos); + + // and postrotate the orientation of the user model wrt the horizontal + // local frame + hlTrans *= SGQuatd::fromYawPitchRollDeg(yaw,pitch,roll); + + // The offset converted to the usual body fixed coordinate system + // rotated to the earth-fixed coordinates axis + SGVec3d off = hlTrans.backTransform(_off); + + // Add the position offset of the user model to get the geocentered position + SGVec3d offsetPos = cartuserPos + off; + + return offsetPos; +} + +void +agRadar::setAntennaPos() { + SGGeodesy::SGCartToGeod(getCartAntennaPos(), antennapos); +} + +void +agRadar::setUserVec(int az, double el) +{ + float yaw = _user_hdg_deg_node->getDoubleValue(); + float pitch = _user_pitch_deg_node->getDoubleValue(); + float roll = _user_roll_deg_node->getDoubleValue(); + int mode = _radar_mode_control_node->getIntValue(); + double tilt = _Instrument->getDoubleValue("tilt"); + double trk = _Instrument->getDoubleValue("trk"); + bool roll_stab = _Instrument->getBoolValue("stabilisation/roll"); + bool pitch_stab = _Instrument->getBoolValue("stabilisation/pitch"); + + SGQuatd offset = SGQuatd::fromYawPitchRollDeg(az + trk, el + tilt, 0); + + // Transform the antenna position to the horizontal local coordinate system. + SGQuatd hlTrans = SGQuatd::fromLonLat(antennapos); + + // and postrotate the orientation of the radar wrt the horizontal + // local frame + hlTrans *= SGQuatd::fromYawPitchRollDeg(yaw, pitch, roll); + hlTrans *= offset; + + if (roll_stab) + hlTrans *= SGQuatd::fromYawPitchRollDeg(0, 0, -roll); + + if (pitch_stab) + hlTrans *= SGQuatd::fromYawPitchRollDeg(0, -pitch, 0); + + // now rotate the rotation vector back into the + // earth centered frames coordinates + SGVec3d angleaxis(1,0,0); + uservec = hlTrans.backTransform(angleaxis); + +} + +bool +agRadar::getMaterial(){ + + if (globals->get_scenery()->get_elevation_m(hitpos, _elevation_m, &_material)){ + //_ht_agl_ft = pos.getElevationFt() - _elevation_m * SG_METER_TO_FEET; + if (_material) { + const vector& names = _material->get_names(); + + _solid = _material->get_solid(); + _load_resistance = _material->get_load_resistance(); + _frictionFactor =_material->get_friction_factor(); + _bumpinessFactor = _material->get_bumpiness(); + + if (!names.empty()) + _mat_name = names[0].c_str(); + else + _mat_name = ""; + + } + /*cout << "material " << mat_name + << " solid " << _solid + << " load " << _load_resistance + << " frictionFactor " << frictionFactor + << " _bumpinessFactor " << _bumpinessFactor + << endl;*/ + return true; + } else { + return false; + } + +} + +void +agRadar::update_terrain() +{ + int mode = _radar_mode_control_node->getIntValue(); + + double el_limit = 1; + double el_step = 1; + double az_limit = 50; + double az_step = 10; + double max_range = 40000; + double min_range = 250; + double tilt = -2.5; + bool roll_stab = _Instrument->getBoolValue("stabilisation/roll"); + bool pitch_stab = _Instrument->getBoolValue("stabilisation/pitch"); + //string status = ""; + const char* status; + bool hdg_mkr = true; + + if (mode == 5){ + status = "TW"; + hdg_mkr = false; + roll_stab = _Instrument->getBoolValue("terrain-warning/stabilisation/roll", true); + pitch_stab = _Instrument->getBoolValue("terrain-warning/stabilisation/pitch", false); + tilt = _Instrument->getDoubleValue("terrain-warning/tilt", -2); + el_limit = _Instrument->getDoubleValue("terrain-warning/elev-limit-deg", 2); + el_step = _Instrument->getDoubleValue("terrain-warning/elev-step-deg", 1); + az_limit = _Instrument->getDoubleValue("terrain-warning/az-limit-deg", 1); + az_step = _Instrument->getDoubleValue("terrain-warning/az-step-deg", 1.5); + max_range = _Instrument->getDoubleValue("terrain-warning/max-range-m", 4000); + min_range = _Instrument->getDoubleValue("terrain-warning/min-range-m", 250); + } + + _Instrument->setDoubleValue("tilt", tilt); + _Instrument->setBoolValue("stabilisation/roll", roll_stab); + _Instrument->setBoolValue("stabilisation/pitch", pitch_stab); + _Instrument->setStringValue("status", status); + _Instrument->setDoubleValue("limit-deg", az_limit); + _Instrument->setBoolValue("heading-marker", hdg_mkr); + + for(double brg = -az_limit; brg <= az_limit; brg += az_step){ + setUserPos(); + setAntennaPos(); + SGVec3d cartantennapos = getCartAntennaPos(); + + for(double elev = el_limit; elev >= - el_limit; elev -= el_step){ + setUserVec(brg, elev); + SGVec3d nearestHit; + globals->get_scenery()->get_cart_ground_intersection(cartantennapos, uservec, nearestHit); + SGGeodesy::SGCartToGeod(nearestHit, hitpos); + + double course1, course2, distance; + + SGGeodesy::inverse(hitpos, antennapos, course1, course2, distance); + + if (distance >= min_range && distance <= max_range) { + _terrain_warning_node->setBoolValue(true); + getMaterial(); + _Instrument->setDoubleValue("terrain-warning/hit/brg-deg", course2); + _Instrument->setDoubleValue("terrain-warning/hit/range-m", distance); + _Instrument->setStringValue("terrain-warning/hit/material", _mat_name.c_str()); + _Instrument->setDoubleValue("terrain-warning/hit/bumpiness", _bumpinessFactor); + _Instrument->setDoubleValue("terrain-warning/hit/elevation-m", _elevation_m); + } else { + _terrain_warning_node->setBoolValue(false); + _Instrument->setDoubleValue("terrain-warning/hit/brg-deg", 0); + _Instrument->setDoubleValue("terrain-warning/hit/range-m", 0); + _Instrument->setStringValue("terrain-warning/hit/material", ""); + _Instrument->setDoubleValue("terrain-warning/hit/bumpiness", 0); + _Instrument->setDoubleValue("terrain-warning/hit/elevation-m",0); + } + + //cout << "usr hdg " << _user_hdg_deg_node->getDoubleValue() + // << " ant brg " << course2 + // << " elev " << _Instrument->getDoubleValue("tilt") + // << " gnd rng nm " << distance * SG_METER_TO_NM + // << " ht " << hitpos.getElevationFt() + // << " mat " << _mat_name + // << " solid " << _solid + // << " bumpiness " << _bumpinessFactor + // << endl; + + } + } +} + + diff --git a/src/Instrumentation/agradar.hxx b/src/Instrumentation/agradar.hxx new file mode 100644 index 000000000..abdf18e9e --- /dev/null +++ b/src/Instrumentation/agradar.hxx @@ -0,0 +1,75 @@ +// Air Ground Radar +// +// Written by Vivian MEAZZA, started Feb 2008. +// +// +// Copyright (C) 2008 Vivain MEAZZA - vivian.meazza@lineone.net +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// + +#ifndef _INST_AGRADAR_HXX +#define _INST_AGRADAR_HXX + +#include +#include +#include + +#include "wxradar.hxx" + +class agRadar : public wxRadarBg{ +public: + + agRadar ( SGPropertyNode *node ); + agRadar (); + virtual ~agRadar (); + + virtual void init (); + virtual void update (double dt); + + void setUserPos(); + void setUserVec(int az, double el); + void update_terrain(); + void setAntennaPos(); + + bool getMaterial(); + + double _load_resistance; // ground load resistanc N/m^2 + double _frictionFactor; // dimensionless modifier for Coefficient of Friction + double _bumpinessFactor; // dimensionless modifier for Bumpiness + double _elevation_m; // ground elevation in meters + bool _solid; // if true ground is solid for FDMs + + const SGMaterial* _material; + + string _mat_name; // ground material + + SGVec3d getCartUserPos() const; + SGVec3d getCartAntennaPos()const; + + SGVec3d uservec; + + SGPropertyNode_ptr _user_hdg_deg_node; + SGPropertyNode_ptr _user_roll_deg_node; + SGPropertyNode_ptr _user_pitch_deg_node; + SGPropertyNode_ptr _terrain_warning_node; + + SGGeod userpos; + SGGeod hitpos; + SGGeod antennapos; +}; + +#endif // _INST_AGRADAR_HXX diff --git a/src/Instrumentation/instrument_mgr.cxx b/src/Instrumentation/instrument_mgr.cxx index f1f7170de..99b8ddc12 100644 --- a/src/Instrumentation/instrument_mgr.cxx +++ b/src/Instrumentation/instrument_mgr.cxx @@ -48,6 +48,8 @@ #include "mk_viii.hxx" #include "mrg.hxx" #include "groundradar.hxx" +#include "agradar.hxx" +#include "rad_alt.hxx" FGInstrumentMgr::FGInstrumentMgr () { @@ -168,7 +170,7 @@ bool FGInstrumentMgr::build () set_subsystem( id, new VerticalSpeedIndicator( node ) ); } else if ( name == "radar" ) { - set_subsystem( id, new wxRadarBg ( node ), 0.5 ); + set_subsystem( id, new wxRadarBg ( node ), 1); } else if ( name == "inst-vertical-speed-indicator" ) { set_subsystem( id, new InstVerticalSpeedIndicator( node ) ); @@ -185,6 +187,12 @@ bool FGInstrumentMgr::build () } else if ( name == "groundradar" ) { set_subsystem( id, new GroundRadar( node ), 1 ); + } else if ( name == "air-ground-radar" ) { + set_subsystem( id, new agRadar( node ),1); + + } else if ( name == "radar-altimeter" ) { + set_subsystem( id, new radAlt( node ),1); + } else { SG_LOG( SG_ALL, SG_ALERT, "Unknown top level section: " << name ); diff --git a/src/Instrumentation/rad_alt.cxx b/src/Instrumentation/rad_alt.cxx new file mode 100644 index 000000000..4d06bb95f --- /dev/null +++ b/src/Instrumentation/rad_alt.cxx @@ -0,0 +1,218 @@ +// Radar Altimeter +// +// Written by Vivian MEAZZA, started Feb 2008. +// +// +// Copyright (C) 2008 Vivian Meazza +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "rad_alt.hxx" + + +radAlt::radAlt(SGPropertyNode *node) : agRadar(node) +{ + + _name = node->getStringValue("name", "radar-altimeter"); + _num = node->getIntValue("number", 0); + +} + +radAlt::~radAlt() +{ +} + +void +radAlt::init () +{ + agRadar::init(); + + _user_alt_agl_node = fgGetNode("/position/altitude-agl-ft", true); + _rad_alt_warning_node = fgGetNode("/sim/alarms/rad-alt-warning", true); + + //// those properties are used by a radar instrument of a MFD + //// input switch = OFF | TST | STBY | ON + //// input mode = WX | WXA | MAP | TW + //// output status = STBY | TEST | WX | WXA | MAP | blank + //// input lightning = true | false + //// input TRK = +/- n degrees + //// input TILT = +/- n degree + //// input autotilt = true | false + //// input range = n nm (20/40/80) + //// input display-mode = arc | rose | map | plan + + _Instrument->setFloatValue("tilt",-85); + _Instrument->setStringValue("status","RA"); + + //_Instrument->setIntValue("mode-control", 10); + + _Instrument->getDoubleValue("elev-limit", true); + _Instrument->getDoubleValue("elev-step-deg", true); + _Instrument->getDoubleValue("az-limit-deg", true); + _Instrument->getDoubleValue("az-step-deg", true); + _Instrument->getDoubleValue("max-range-m", true); + _Instrument->getDoubleValue("min-range-m", true); + _Instrument->getDoubleValue("tilt", true); + _Instrument->getDoubleValue("set-height-ft", true); + _Instrument->getDoubleValue("set-excursion-percent", true); + + _Instrument->setDoubleValue("hit/brg-deg", 0); + _Instrument->setDoubleValue("hit/range-m", 0); + _Instrument->setStringValue("hit/material", ""); + _Instrument->setDoubleValue("hit/bumpiness", 0); + + + + _Instrument->removeChild("terrain-warning"); + _Instrument->removeChild("mode-control"); + _Instrument->removeChild("limit-deg"); + _Instrument->removeChild("reference-range-nm"); + _Instrument->removeChild("heading-marker"); + _Instrument->removeChild("display-controls"); + _Instrument->removeChild("font"); + + //cout << " radar alt init done" << endl; +} + +void +radAlt::update (double delta_time_sec) +{ + if ( ! _sim_init_done ) { + + if ( ! fgGetBool("sim/sceneryloaded", false) ) + return; + + _sim_init_done = true; + } + + if ( !_odg || ! _serviceable_node->getBoolValue() ) { + _Instrument->setStringValue("status",""); + return; + } + + _time += delta_time_sec; + + if (_time < _interval) + return; + + _time = 0.0; + update_altitude(); +} + + + +double +radAlt::getDistanceAntennaToHit(SGVec3d nearestHit) const +{ + //calculate the distance antenna to hit + + SGVec3d cartantennapos = getCartAntennaPos();; + + SGVec3d diff = nearestHit - cartantennapos; + double distance = norm(diff); + return distance ; +} + +void +radAlt::update_altitude() +{ + int mode = _radar_mode_control_node->getIntValue(); + double tilt = _Instrument->getDoubleValue("tilt", -85); + double el_limit = _Instrument->getDoubleValue("elev-limit", 15); + double el_step = _Instrument->getDoubleValue("elev-step-deg", 15); + double az_limit = _Instrument->getDoubleValue("az-limit-deg", 15); + double az_step = _Instrument->getDoubleValue("az-step-deg", 15); + double max_range = _Instrument->getDoubleValue("max-range-m", 1500); + double min_range = _Instrument->getDoubleValue("min-range-m", 0.001); + double set_ht_ft = _Instrument->getDoubleValue("set-height-ft", 9999); + double set_excur = _Instrument->getDoubleValue("set-excursion-percent", 0); + + _min_radalt = max_range; + + for(double brg = -az_limit; brg <= az_limit; brg += az_step){ + setUserPos(); + setAntennaPos(); + SGVec3d cartantennapos = getCartAntennaPos(); + + for(double elev = el_limit; elev >= - el_limit; elev -= el_step){ + setUserVec(brg, elev); + + SGVec3d nearestHit; + globals->get_scenery()->get_cart_ground_intersection(cartantennapos, uservec, nearestHit); + SGGeodesy::SGCartToGeod(nearestHit, hitpos); + + double radalt = getDistanceAntennaToHit(nearestHit); + double course1, course2, distance; + + SGGeodesy::inverse(hitpos, antennapos, course1, course2, distance); + _Instrument->setDoubleValue("hit/altitude-agl-ft", + _user_alt_agl_node->getDoubleValue()); + + if (radalt >= min_range && radalt <= max_range) { + getMaterial(); + + if (radalt < _min_radalt) + _min_radalt = radalt; + + _Instrument->setDoubleValue("radar-altitude-ft", _min_radalt * SG_METER_TO_FEET); + _Instrument->setDoubleValue("hit/radar-altitude-ft", radalt * SG_METER_TO_FEET); + _Instrument->setDoubleValue("hit/brg-deg", course2); + _Instrument->setDoubleValue("hit/range-m", distance); + _Instrument->setStringValue("hit/material", _mat_name.c_str()); + _Instrument->setDoubleValue("hit/bumpiness", _bumpinessFactor); + + if (set_ht_ft!= 9999){ + + if (_min_radalt * SG_METER_TO_FEET < set_ht_ft * (100 - set_excur)/100) + _rad_alt_warning_node->setIntValue(-1); + else if (_min_radalt * SG_METER_TO_FEET > set_ht_ft * (100 + set_excur)/100) + _rad_alt_warning_node->setIntValue(1); + else + _rad_alt_warning_node->setIntValue(0); + + } else + _rad_alt_warning_node->setIntValue(9999); + + } else { + _rad_alt_warning_node->setIntValue(9999); + _Instrument->setDoubleValue("radar-altitude-ft", _min_radalt * SG_METER_TO_FEET); + _Instrument->setDoubleValue("hit/radar-altitude-ft",0); + _Instrument->setDoubleValue("hit/brg-deg", 0); + _Instrument->setDoubleValue("hit/range-m", 0); + _Instrument->setStringValue("hit/material", ""); + _Instrument->setDoubleValue("hit/bumpiness", 0); + } + + //cout << "usr hdg " << _user_hdg_deg_node->getDoubleValue() + // << " ant brg " << course2 + // << " elev " << _Instrument->getDoubleValue("tilt") + // << " gnd rng nm " << distance * SG_METER_TO_NM + // << " ht " << hitpos.getElevationFt() + // << " mat " << _mat_name + // << " solid " << _solid + // << " bumpiness " << _bumpinessFactor + // << endl; + + } + } +} + + diff --git a/src/Instrumentation/rad_alt.hxx b/src/Instrumentation/rad_alt.hxx new file mode 100644 index 000000000..7ab1e657f --- /dev/null +++ b/src/Instrumentation/rad_alt.hxx @@ -0,0 +1,55 @@ +// Radar Altimeter +// +// Written by Vivian MEAZZA, started Feb 2008. +// +// +// Copyright (C) 2008 Vivain MEAZZA - vivian.meazza@lineone.net +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// + +#ifndef _INST_RADALT_HXX +#define _INST_RADALT_HXX + +#include +#include +#include + +#include "agradar.hxx" + +class radAlt : public agRadar{ +public: + + radAlt ( SGPropertyNode *node ); + radAlt (); + virtual ~radAlt (); + +private: + + virtual void init (); + virtual void update (double dt); + + void update_altitude(); + double getDistanceAntennaToHit(SGVec3d h) const; + + SGPropertyNode_ptr _user_alt_agl_node; + SGPropertyNode_ptr _rad_alt_warning_node; + + double _min_radalt; + +}; + +#endif // _INST_AGRADAR_HXX diff --git a/src/Instrumentation/wxradar.cxx b/src/Instrumentation/wxradar.cxx index fa71560b9..e7df08b85 100644 --- a/src/Instrumentation/wxradar.cxx +++ b/src/Instrumentation/wxradar.cxx @@ -591,12 +591,12 @@ wxRadarBg::update_aircraft() return; radar_list_type radar_list = _ai->get_ai_list(); - SG_LOG(SG_GENERAL, SG_DEBUG, "Radar: AI submodel list size" << radar_list.size()); + //SG_LOG(SG_GENERAL, SG_DEBUG, "Radar: AI submodel list size" << radar_list.size()); if (radar_list.empty()) return; - SG_LOG(SG_GENERAL, SG_DEBUG, "Radar: Loading AI submodels "); - const double echo_radii[] = {0, 1, 1.5, 1.5, 0.001, 0.1, 1.5, 2, 1.5, 1.5}; + //SG_LOG(SG_GENERAL, SG_DEBUG, "Radar: Loading AI submodels "); + const double echo_radii[] = {0, 1, 1.5, 1.5, 0.001, 0.1, 1.5, 2, 1.5, 1.5, 1.5}; double user_lat = _user_lat_node->getDoubleValue(); double user_lon = _user_lon_node->getDoubleValue(); @@ -628,16 +628,16 @@ wxRadarBg::update_aircraft() calcRangeBearing(user_lat, user_lon, lat, lon, range, bearing); //SG_LOG(SG_GENERAL, SG_DEBUG, - // "Radar: ID=" << ac->getID() << "(" << radar_list.size() << ")" - // << " type=" << type - // << " view_heading=" << _view_heading * SG_RADIANS_TO_DEGREES - // << " alt=" << alt - // << " heading=" << heading - // << " range=" << range - // << " bearing=" << bearing); + /* "Radar: ID=" << ac->getID() << "(" << radar_list.size() << ")" + << " type=" << type + << " view_heading=" << _view_heading * SG_RADIANS_TO_DEGREES + << " alt=" << alt + << " heading=" << heading + << " range=" << range + << " bearing=" << bearing);*/ bool isVisible = withinRadarHorizon(user_alt, alt, range); - SG_LOG(SG_GENERAL, SG_DEBUG, "Radar: visible " << isVisible); + //SG_LOG(SG_GENERAL, SG_DEBUG, "Radar: visible " << isVisible); if (!isVisible) continue; @@ -668,7 +668,8 @@ wxRadarBg::update_aircraft() addQuad(_vertices, _texCoords, m, texBase); //SG_LOG(SG_GENERAL, SG_DEBUG, "Radar: drawing AI" - // << " x=" << x << " y=" << y + //<< " ID=" << ac->getID() + //<< " type=" << type // << " radius=" << radius // << " angle=" << angle * SG_RADIANS_TO_DEGREES); } @@ -797,7 +798,7 @@ wxRadarBg::withinRadarHorizon(double user_alt, double alt, double range_nm) alt = 0; double radarhorizon = 1.23 * (sqrt(alt) + sqrt(user_alt)); - SG_LOG(SG_GENERAL, SG_DEBUG, "Radar: horizon " << radarhorizon); + //SG_LOG(SG_GENERAL, SG_DEBUG, "Radar: horizon " << radarhorizon); return radarhorizon >= range_nm; } @@ -819,14 +820,14 @@ wxRadarBg::inRadarRange(int type, double range_nm) // // TODO - make the maximum range adjustable at runtime - const double sigma[] = {0, 1, 100, 100, 0.001, 0.1, 100, 100, 1, 1}; + const double sigma[] = {0, 1, 100, 100, 0.001, 0.1, 100, 100, 1, 1, 1}; double constant = _radar_ref_rng; if (constant <= 0) constant = 35; double maxrange = constant * pow(sigma[type], 0.25); - SG_LOG(SG_GENERAL, SG_DEBUG, "Radar: max range " << maxrange); + //SG_LOG(SG_GENERAL, SG_DEBUG, "Radar: max range " << maxrange); return maxrange >= range_nm; } diff --git a/src/Instrumentation/wxradar.hxx b/src/Instrumentation/wxradar.hxx index f42e8d21b..287ea7e77 100644 --- a/src/Instrumentation/wxradar.hxx +++ b/src/Instrumentation/wxradar.hxx @@ -56,36 +56,47 @@ public: virtual void update (double dt); virtual void valueChanged(SGPropertyNode*); -private: - string _name; - int _num; double _interval; double _time; + + bool _sim_init_done; + + string _name; + + int _num; + + SGPropertyNode_ptr _serviceable_node; + SGPropertyNode_ptr _Instrument; + SGPropertyNode_ptr _radar_mode_control_node; + + SGPropertyNode_ptr _user_lat_node; + SGPropertyNode_ptr _user_lon_node; + SGPropertyNode_ptr _user_heading_node; + SGPropertyNode_ptr _user_alt_node; + + FGODGauge *_odg; + +private: + string _texture_path; typedef enum { ARC, MAP, PLAN, ROSE } DisplayMode; DisplayMode _display_mode; string _last_switchKnob; - bool _sim_init_done; float _range_nm; float _scale; // factor to convert nm to display units - double _radar_ref_rng; float _angle_offset; float _view_heading; - double _lat, _lon; float _x_offset, _y_offset; - SGPropertyNode_ptr _serviceable_node; - SGPropertyNode_ptr _Instrument; + double _radar_ref_rng; + double _lat, _lon; + SGPropertyNode_ptr _Tacan; SGPropertyNode_ptr _Radar_controls; - SGPropertyNode_ptr _user_lat_node; - SGPropertyNode_ptr _user_lon_node; - SGPropertyNode_ptr _user_heading_node; - SGPropertyNode_ptr _user_alt_node; SGPropertyNode_ptr _user_speed_east_fps_node; SGPropertyNode_ptr _user_speed_north_fps_node; @@ -99,7 +110,7 @@ private: SGPropertyNode_ptr _radar_position_node; SGPropertyNode_ptr _radar_data_node; SGPropertyNode_ptr _radar_symbol_node; - SGPropertyNode_ptr _radar_mode_control_node; + SGPropertyNode_ptr _radar_centre_node; SGPropertyNode_ptr _radar_coverage_node; SGPropertyNode_ptr _radar_ref_rng_node; @@ -121,7 +132,6 @@ private: list_of_SGWxRadarEcho _radarEchoBuffer; - FGODGauge *_odg; FGAIManager* _ai; void update_weather(); @@ -129,15 +139,17 @@ private: void update_tacan(); void update_heading_marker(); void update_data(FGAIBase* ac, double radius, double bearing, bool selected); - void center_map(); void apply_map_offset(); - bool withinRadarHorizon(double user_alt, double alt, double range); - bool inRadarRange(int type, double range); - float calcRelBearing(float bearing, float heading); + void updateFont(); void calcRangeBearing(double lat, double lon, double lat2, double lon2, double &range, double &bearing) const; - void updateFont(); + + bool withinRadarHorizon(double user_alt, double alt, double range); + bool inRadarRange(int type, double range); + + float calcRelBearing(float bearing, float heading); + }; #endif // _INST_WXRADAR_HXX