]> git.mxchange.org Git - flightgear.git/commitdiff
ground radar from Vivian Mezza
authortimoore <timoore>
Mon, 17 Mar 2008 08:47:16 +0000 (08:47 +0000)
committertimoore <timoore>
Mon, 17 Mar 2008 08:47:16 +0000 (08:47 +0000)
src/Instrumentation/Makefile.am
src/Instrumentation/agradar.cxx [new file with mode: 0644]
src/Instrumentation/agradar.hxx [new file with mode: 0644]
src/Instrumentation/instrument_mgr.cxx
src/Instrumentation/rad_alt.cxx [new file with mode: 0644]
src/Instrumentation/rad_alt.hxx [new file with mode: 0644]
src/Instrumentation/wxradar.cxx
src/Instrumentation/wxradar.hxx

index 37a1a888b827438d402fc7cdecf3f47453af88ec..fa7f85ea322590eafec56fbf1577ed6e57a3e4ee 100644 (file)
@@ -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 (file)
index 0000000..a1d2933
--- /dev/null
@@ -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<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;
+
+        }
+    }
+}
+
+
diff --git a/src/Instrumentation/agradar.hxx b/src/Instrumentation/agradar.hxx
new file mode 100644 (file)
index 0000000..abdf18e
--- /dev/null
@@ -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 <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
index f1f7170de7dd404902790f658ea070e9f15cb463..99b8ddc1202cbecc7b6766a31b73ed398229a1ca 100644 (file)
@@ -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 (file)
index 0000000..4d06bb9
--- /dev/null
@@ -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 (file)
index 0000000..7ab1e65
--- /dev/null
@@ -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 <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
index fa71560b98b331be8d9391367238a69adc2e730f..e7df08b854a1bb4cc027af95446969d8404e716b 100644 (file)
@@ -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;
 }
 
index f42e8d21b54c2cc11a3ad72c8722ba060fbd355f..287ea7e779b35fbddbba564dbbe2866c45104ed3 100644 (file)
@@ -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();
+    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