1
0
Fork 0

ground radar from Vivian Mezza

This commit is contained in:
timoore 2008-03-17 08:47:16 +00:00
parent d03e63a059
commit c2040f30a2
8 changed files with 739 additions and 36 deletions

View file

@ -31,6 +31,7 @@ libInstrumentation_a_SOURCES = \
tacan.cxx tacan.hxx mk_viii.cxx mk_viii.hxx \ tacan.cxx tacan.hxx mk_viii.cxx mk_viii.hxx \
dclgps.cxx dclgps.hxx \ dclgps.cxx dclgps.hxx \
render_area_2d.cxx render_area_2d.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 INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_builddir)/src

View file

@ -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;
}
}
}

View file

@ -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

View file

@ -48,6 +48,8 @@
#include "mk_viii.hxx" #include "mk_viii.hxx"
#include "mrg.hxx" #include "mrg.hxx"
#include "groundradar.hxx" #include "groundradar.hxx"
#include "agradar.hxx"
#include "rad_alt.hxx"
FGInstrumentMgr::FGInstrumentMgr () FGInstrumentMgr::FGInstrumentMgr ()
{ {
@ -168,7 +170,7 @@ bool FGInstrumentMgr::build ()
set_subsystem( id, new VerticalSpeedIndicator( node ) ); set_subsystem( id, new VerticalSpeedIndicator( node ) );
} else if ( name == "radar" ) { } 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" ) { } else if ( name == "inst-vertical-speed-indicator" ) {
set_subsystem( id, new InstVerticalSpeedIndicator( node ) ); set_subsystem( id, new InstVerticalSpeedIndicator( node ) );
@ -185,6 +187,12 @@ bool FGInstrumentMgr::build ()
} else if ( name == "groundradar" ) { } else if ( name == "groundradar" ) {
set_subsystem( id, new GroundRadar( node ), 1 ); 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 { } else {
SG_LOG( SG_ALL, SG_ALERT, "Unknown top level section: " SG_LOG( SG_ALL, SG_ALERT, "Unknown top level section: "
<< name ); << name );

View file

@ -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;
}
}
}

View file

@ -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

View file

@ -591,12 +591,12 @@ wxRadarBg::update_aircraft()
return; return;
radar_list_type radar_list = _ai->get_ai_list(); 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()) if (radar_list.empty())
return; return;
SG_LOG(SG_GENERAL, SG_DEBUG, "Radar: Loading AI submodels "); //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}; 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_lat = _user_lat_node->getDoubleValue();
double user_lon = _user_lon_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); calcRangeBearing(user_lat, user_lon, lat, lon, range, bearing);
//SG_LOG(SG_GENERAL, SG_DEBUG, //SG_LOG(SG_GENERAL, SG_DEBUG,
// "Radar: ID=" << ac->getID() << "(" << radar_list.size() << ")" /* "Radar: ID=" << ac->getID() << "(" << radar_list.size() << ")"
// << " type=" << type << " type=" << type
// << " view_heading=" << _view_heading * SG_RADIANS_TO_DEGREES << " view_heading=" << _view_heading * SG_RADIANS_TO_DEGREES
// << " alt=" << alt << " alt=" << alt
// << " heading=" << heading << " heading=" << heading
// << " range=" << range << " range=" << range
// << " bearing=" << bearing); << " bearing=" << bearing);*/
bool isVisible = withinRadarHorizon(user_alt, alt, range); 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) if (!isVisible)
continue; continue;
@ -668,7 +668,8 @@ wxRadarBg::update_aircraft()
addQuad(_vertices, _texCoords, m, texBase); addQuad(_vertices, _texCoords, m, texBase);
//SG_LOG(SG_GENERAL, SG_DEBUG, "Radar: drawing AI" //SG_LOG(SG_GENERAL, SG_DEBUG, "Radar: drawing AI"
// << " x=" << x << " y=" << y //<< " ID=" << ac->getID()
//<< " type=" << type
// << " radius=" << radius // << " radius=" << radius
// << " angle=" << angle * SG_RADIANS_TO_DEGREES); // << " angle=" << angle * SG_RADIANS_TO_DEGREES);
} }
@ -797,7 +798,7 @@ wxRadarBg::withinRadarHorizon(double user_alt, double alt, double range_nm)
alt = 0; alt = 0;
double radarhorizon = 1.23 * (sqrt(alt) + sqrt(user_alt)); 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; return radarhorizon >= range_nm;
} }
@ -819,14 +820,14 @@ wxRadarBg::inRadarRange(int type, double range_nm)
// //
// TODO - make the maximum range adjustable at runtime // 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; double constant = _radar_ref_rng;
if (constant <= 0) if (constant <= 0)
constant = 35; constant = 35;
double maxrange = constant * pow(sigma[type], 0.25); 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; return maxrange >= range_nm;
} }

View file

@ -56,36 +56,47 @@ public:
virtual void update (double dt); virtual void update (double dt);
virtual void valueChanged(SGPropertyNode*); virtual void valueChanged(SGPropertyNode*);
private:
string _name;
int _num;
double _interval; double _interval;
double _time; 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; string _texture_path;
typedef enum { ARC, MAP, PLAN, ROSE } DisplayMode; typedef enum { ARC, MAP, PLAN, ROSE } DisplayMode;
DisplayMode _display_mode; DisplayMode _display_mode;
string _last_switchKnob; string _last_switchKnob;
bool _sim_init_done;
float _range_nm; float _range_nm;
float _scale; // factor to convert nm to display units float _scale; // factor to convert nm to display units
double _radar_ref_rng;
float _angle_offset; float _angle_offset;
float _view_heading; float _view_heading;
double _lat, _lon;
float _x_offset, _y_offset; float _x_offset, _y_offset;
SGPropertyNode_ptr _serviceable_node; double _radar_ref_rng;
SGPropertyNode_ptr _Instrument; double _lat, _lon;
SGPropertyNode_ptr _Tacan; SGPropertyNode_ptr _Tacan;
SGPropertyNode_ptr _Radar_controls; 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_east_fps_node;
SGPropertyNode_ptr _user_speed_north_fps_node; SGPropertyNode_ptr _user_speed_north_fps_node;
@ -99,7 +110,7 @@ private:
SGPropertyNode_ptr _radar_position_node; SGPropertyNode_ptr _radar_position_node;
SGPropertyNode_ptr _radar_data_node; SGPropertyNode_ptr _radar_data_node;
SGPropertyNode_ptr _radar_symbol_node; SGPropertyNode_ptr _radar_symbol_node;
SGPropertyNode_ptr _radar_mode_control_node;
SGPropertyNode_ptr _radar_centre_node; SGPropertyNode_ptr _radar_centre_node;
SGPropertyNode_ptr _radar_coverage_node; SGPropertyNode_ptr _radar_coverage_node;
SGPropertyNode_ptr _radar_ref_rng_node; SGPropertyNode_ptr _radar_ref_rng_node;
@ -121,7 +132,6 @@ private:
list_of_SGWxRadarEcho _radarEchoBuffer; list_of_SGWxRadarEcho _radarEchoBuffer;
FGODGauge *_odg;
FGAIManager* _ai; FGAIManager* _ai;
void update_weather(); void update_weather();
@ -129,15 +139,17 @@ private:
void update_tacan(); void update_tacan();
void update_heading_marker(); void update_heading_marker();
void update_data(FGAIBase* ac, double radius, double bearing, bool selected); void update_data(FGAIBase* ac, double radius, double bearing, bool selected);
void center_map(); void center_map();
void apply_map_offset(); void apply_map_offset();
bool withinRadarHorizon(double user_alt, double alt, double range); void updateFont();
bool inRadarRange(int type, double range);
float calcRelBearing(float bearing, float heading);
void calcRangeBearing(double lat, double lon, double lat2, double lon2, void calcRangeBearing(double lat, double lon, double lat2, double lon2,
double &range, double &bearing) const; 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 #endif // _INST_WXRADAR_HXX