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
--- /dev/null
+// 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<string>& 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;
+
+ }
+ }
+}
+
+
--- /dev/null
+// 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 <simgear/structure/subsystem_mgr.hxx>
+#include <Scenery/scenery.hxx>
+#include <simgear/scene/material/mat.hxx>
+
+#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
#include "mk_viii.hxx"
#include "mrg.hxx"
#include "groundradar.hxx"
+#include "agradar.hxx"
+#include "rad_alt.hxx"
FGInstrumentMgr::FGInstrumentMgr ()
{
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 ) );
} 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 );
--- /dev/null
+// 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;
+
+ }
+ }
+}
+
+
--- /dev/null
+// 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 <simgear/structure/subsystem_mgr.hxx>
+#include <Scenery/scenery.hxx>
+#include <simgear/scene/material/mat.hxx>
+
+#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
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();
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;
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);
}
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;
}
//
// 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;
}
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;
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;
list_of_SGWxRadarEcho _radarEchoBuffer;
- FGODGauge *_odg;
FGAIManager* _ai;
void update_weather();
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();
+ void updateFont();
+ void calcRangeBearing(double lat, double lon, double lat2, double lon2,
+ double &range, double &bearing) const;
+
bool withinRadarHorizon(double user_alt, double alt, double range);
bool inRadarRange(int type, double range);
+
float calcRelBearing(float bearing, float heading);
- void calcRangeBearing(double lat, double lon, double lat2, double lon2,
- double &range, double &bearing) const;
- void updateFont();
+
};
#endif // _INST_WXRADAR_HXX