1
0
Fork 0

Refactored some of the navlist code and removed the built in "fail to find"

if the station is too far away.  Instead, simply return the closest station.
All the code that searches navaids does it's own range checking anyway.
This will make the navlist query functions a bit more useful for other
types of functionality where you may need to lookup a station without
consideration of range (i.e. presetting your position relative to a navaid.)
This commit is contained in:
curt 2003-01-25 20:45:39 +00:00
parent 677c3e3e9a
commit 8cc7b283d5
8 changed files with 113 additions and 130 deletions

View file

@ -218,7 +218,7 @@ void FGDME::search()
} }
FGILS ils; FGILS ils;
FGNav nav; FGNav *nav;
if ( current_ilslist->query( lon, lat, elev, freq, &ils ) ) { if ( current_ilslist->query( lon, lat, elev, freq, &ils ) ) {
if (ils.get_has_dme()) { if (ils.get_has_dme()) {
@ -232,17 +232,17 @@ void FGDME::search()
y = ils.get_dme_y(); y = ils.get_dme_y();
z = ils.get_dme_z(); z = ils.get_dme_z();
} }
} else if ( current_navlist->query( lon, lat, elev, freq, &nav ) ) { } else if ( (nav = current_navlist->findByFreq(freq, lon, lat, elev)) != NULL ) {
if (nav.get_has_dme()) { if (nav->get_has_dme()) {
valid = true; valid = true;
lon = nav.get_lon(); lon = nav->get_lon();
lat = nav.get_lat(); lat = nav->get_lat();
elev = nav.get_elev(); elev = nav->get_elev();
range = nav.get_range(); range = nav->get_range();
effective_range = kludgeRange(elev, elev, range); effective_range = kludgeRange(elev, elev, range);
x = nav.get_x(); x = nav->get_x();
y = nav.get_y(); y = nav->get_y();
z = nav.get_z(); z = nav->get_z();
} }
} else { } else {
valid = false; valid = false;

View file

@ -482,33 +482,34 @@ void FGKR_87::search() {
double acft_elev = alt_node->getDoubleValue() * SG_FEET_TO_METER; double acft_elev = alt_node->getDoubleValue() * SG_FEET_TO_METER;
// FIXME: the panel should handle this // FIXME: the panel should handle this
FGNav nav;
static string last_ident = ""; static string last_ident = "";
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// ADF. // ADF.
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
if ( current_navlist->query( acft_lon, acft_lat, acft_elev, freq, &nav ) ) { FGNav *nav
= current_navlist->findByFreq(freq, acft_lon, acft_lat, acft_elev);
if ( nav != NULL ) {
char sfreq[128]; char sfreq[128];
snprintf( sfreq, 10, "%.0f", freq ); snprintf( sfreq, 10, "%.0f", freq );
ident = sfreq; ident = sfreq;
ident += nav.get_ident(); ident += nav->get_ident();
// cout << "adf ident = " << ident << endl; // cout << "adf ident = " << ident << endl;
valid = true; valid = true;
if ( last_ident != ident ) { if ( last_ident != ident ) {
last_ident = ident; last_ident = ident;
trans_ident = nav.get_trans_ident(); trans_ident = nav->get_trans_ident();
stn_lon = nav.get_lon(); stn_lon = nav->get_lon();
stn_lat = nav.get_lat(); stn_lat = nav->get_lat();
stn_elev = nav.get_elev(); stn_elev = nav->get_elev();
range = nav.get_range(); range = nav->get_range();
effective_range = kludgeRange(stn_elev, acft_elev, range); effective_range = kludgeRange(stn_elev, acft_elev, range);
x = nav.get_x(); x = nav->get_x();
y = nav.get_y(); y = nav->get_y();
z = nav.get_z(); z = nav->get_z();
if ( globals->get_soundmgr()->exists( "adf-ident" ) ) { if ( globals->get_soundmgr()->exists( "adf-ident" ) ) {
globals->get_soundmgr()->remove( "adf-ident" ); globals->get_soundmgr()->remove( "adf-ident" );
@ -528,7 +529,7 @@ void FGKR_87::search() {
// << globals->get_time_params()->get_cur_time() << endl; // << globals->get_time_params()->get_cur_time() << endl;
// cout << "Found an adf station in range" << endl; // cout << "Found an adf station in range" << endl;
// cout << " id = " << nav.get_ident() << endl; // cout << " id = " << nav->get_ident() << endl;
} }
} else { } else {
valid = false; valid = false;

View file

@ -451,7 +451,7 @@ void FGNavCom::search()
double elev = alt_node->getDoubleValue() * SG_FEET_TO_METER; double elev = alt_node->getDoubleValue() * SG_FEET_TO_METER;
FGILS ils; FGILS ils;
FGNav nav; FGNav *nav;
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Nav. // Nav.
@ -515,27 +515,27 @@ void FGNavCom::search()
// cout << "Found an ils station in range" << endl; // cout << "Found an ils station in range" << endl;
// cout << " id = " << ils.get_locident() << endl; // cout << " id = " << ils.get_locident() << endl;
} }
} else if ( current_navlist->query( lon, lat, elev, nav_freq, &nav ) ) { } else if ( (nav = current_navlist->findByFreq(nav_freq, lon, lat, elev)) != NULL ) {
nav_id = nav.get_ident(); nav_id = nav->get_ident();
nav_valid = true; nav_valid = true;
if ( last_nav_id != nav_id || !last_nav_vor ) { if ( last_nav_id != nav_id || !last_nav_vor ) {
last_nav_id = nav_id; last_nav_id = nav_id;
last_nav_vor = true; last_nav_vor = true;
nav_trans_ident = nav.get_trans_ident(); nav_trans_ident = nav->get_trans_ident();
nav_loc = false; nav_loc = false;
nav_has_dme = nav.get_has_dme(); nav_has_dme = nav->get_has_dme();
nav_has_gs = false; nav_has_gs = false;
nav_loclon = nav.get_lon(); nav_loclon = nav->get_lon();
nav_loclat = nav.get_lat(); nav_loclat = nav->get_lat();
nav_elev = nav.get_elev(); nav_elev = nav->get_elev();
nav_magvar = nav.get_magvar(); nav_magvar = nav->get_magvar();
nav_range = nav.get_range(); nav_range = nav->get_range();
nav_effective_range = adjustNavRange(nav_elev, elev, nav_range); nav_effective_range = adjustNavRange(nav_elev, elev, nav_range);
nav_target_gs = 0.0; nav_target_gs = 0.0;
nav_radial = nav_sel_radial; nav_radial = nav_sel_radial;
nav_x = nav.get_x(); nav_x = nav->get_x();
nav_y = nav.get_y(); nav_y = nav->get_y();
nav_z = nav.get_z(); nav_z = nav->get_z();
if ( globals->get_soundmgr()->exists( nav_fx_name ) ) { if ( globals->get_soundmgr()->exists( nav_fx_name ) ) {
globals->get_soundmgr()->remove( nav_fx_name ); globals->get_soundmgr()->remove( nav_fx_name );
@ -566,7 +566,7 @@ void FGNavCom::search()
// << globals->get_time_params()->get_cur_time() << endl; // << globals->get_time_params()->get_cur_time() << endl;
// cout << "Found a vor station in range" << endl; // cout << "Found a vor station in range" << endl;
// cout << " id = " << nav.get_ident() << endl; // cout << " id = " << nav->get_ident() << endl;
} }
} else { } else {
nav_valid = false; nav_valid = false;

View file

@ -960,15 +960,15 @@ static void fgSetDistOrAltFromGlideSlope() {
// Set current_options lon/lat given an airport id and heading (degrees) // Set current_options lon/lat given an airport id and heading (degrees)
static bool fgSetPosFromNAV( const string& id, const double& freq ) { static bool fgSetPosFromNAV( const string& id, const double& freq ) {
FGNav nav; FGNav *nav = current_navlist->findByIdentAndFreq( id.c_str(), freq );
// set initial position from runway and heading // set initial position from runway and heading
if ( current_navlist->findByIdentAndFreq( id.c_str(), freq, &nav ) ) { if ( nav != NULL ) {
SG_LOG( SG_GENERAL, SG_INFO, "Attempting to set starting position for " SG_LOG( SG_GENERAL, SG_INFO, "Attempting to set starting position for "
<< id << ":" << freq ); << id << ":" << freq );
double lon = nav.get_lon(); double lon = nav->get_lon();
double lat = nav.get_lat(); double lat = nav->get_lat();
if ( fabs( fgGetDouble("/sim/presets/offset-distance") ) > SG_EPSILON ) if ( fabs( fgGetDouble("/sim/presets/offset-distance") ) > SG_EPSILON )
{ {

View file

@ -79,15 +79,6 @@ public:
inline string get_trans_ident() { return trans_ident; } inline string get_trans_ident() { return trans_ident; }
inline double get_magvar () const { return magvar; } inline double get_magvar () const { return magvar; }
/* inline void set_type( char t ) { type = t; }
inline void set_lon( double l ) { lon = l; }
inline void set_lat( double l ) { lat = l; }
inline void set_elev( double e ) { elev = e; }
inline void set_freq( int f ) { freq = f; }
inline void set_range( int r ) { range = r; }
inline void set_dme( bool b ) { dme = b; }
inline void set_ident( char *i ) { strncpy( ident, i, 5 ); } */
friend istream& operator>> ( istream&, FGNav& ); friend istream& operator>> ( istream&, FGNav& );
}; };

View file

@ -108,75 +108,74 @@ bool FGNavList::init( SGPath path ) {
} }
// query the database for the specified frequency, lon and lat are in // Query the database for the specified frequency. It is assumed that
// degrees, elev is in meters // there will be multiple stations with matching frequencies so a
bool FGNavList::query( double lon, double lat, double elev, double freq, // position must be specified. Lon and lat are in degrees, elev is in
FGNav *nav ) // meters.
FGNav *FGNavList::findByFreq( double freq, double lon, double lat, double elev )
{ {
nav_list_type stations = navaids[(int)(freq*100.0 + 0.5)]; nav_list_type stations = navaids[(int)(freq*100.0 + 0.5)];
nav_list_iterator current = stations.begin();
nav_list_iterator last = stations.end();
Point3D aircraft = sgGeodToCart( Point3D(lon, lat, elev) ); Point3D aircraft = sgGeodToCart( Point3D(lon, lat, elev) );
return findNavFromList(aircraft, current, last, nav);
return findNavFromList( aircraft, stations );
} }
bool FGNavList::findByIdent(const char* ident, double lon, double lat, FGNav *FGNavList::findByIdent( const char* ident,
FGNav *nav) const double lon, const double lat )
{ {
nav_list_type stations = ident_navaids[ident]; nav_list_type stations = ident_navaids[ident];
nav_list_iterator current = stations.begin();
nav_list_iterator last = stations.end();
Point3D aircraft = sgGeodToCart( Point3D(lon, lat, 0.0) ); Point3D aircraft = sgGeodToCart( Point3D(lon, lat, 0.0) );
return findNavFromList(aircraft, current, last, nav);
return findNavFromList( aircraft, stations );
} }
bool FGNavList::findByIdentAndFreq(const char* ident, const double& freq, // Given an Ident and optional freqency, return the first matching
FGNav *nav) // station.
FGNav *FGNavList::findByIdentAndFreq( const char* ident, const double freq )
{ {
cout << "ident = " << ident << endl;
nav_list_type stations = ident_navaids[ident]; nav_list_type stations = ident_navaids[ident];
cout << " matches = " << stations.size() << endl;
nav_list_iterator current = stations.begin();
nav_list_iterator last = stations.end();
if ( stations.size() > 1 ) { if ( freq > 0.0 ) {
// more than one match on this ident, use freq to refine // sometimes there can be duplicated idents. If a freq is
// specified, use it to refine the search.
int f = (int)(freq*100.0 + 0.5); int f = (int)(freq*100.0 + 0.5);
for ( ; current != last ; ++current ) { for ( unsigned int i = 0; i < stations.size(); ++i ) {
if ( f == (*current)->get_freq() ) { if ( f == stations[i]->get_freq() ) {
*nav = (**current); return stations[i];
return true;
} }
} }
} else { } else {
*nav = (**current); return stations[0];
return true;
} }
return false; return NULL;
} }
bool FGNavList::findNavFromList(const Point3D &aircraft, // Given a point and a list of stations, return the closest one to the
nav_list_iterator current, // specified point.
nav_list_iterator end, FGNav *nav) FGNav *FGNavList::findNavFromList( const Point3D &aircraft,
const nav_list_type &stations )
{ {
// double az1, az2, s; FGNav *nav = NULL;
Point3D station; Point3D station;
double d2; double d2;
double min_dist = 99999999999999.9; double min_dist;
bool found_one = false;
for ( ; current != end ; ++current ) { // prime the pump with info from stations[0]
if ( stations.size() > 0 ) {
nav = stations[0];
station = Point3D( nav->get_x(), nav->get_y(), nav->get_z());
min_dist = aircraft.distance3Dsquared( station );
}
// check if any of the remaining stations are closer
for ( unsigned int i = 1; i < stations.size(); ++i ) {
// cout << "testing " << current->get_ident() << endl; // cout << "testing " << current->get_ident() << endl;
station = Point3D((*current)->get_x(), (*current)->get_y(), station = Point3D( stations[i]->get_x(), stations[i]->get_y(),
(*current)->get_z()); stations[i]->get_z());
d2 = aircraft.distance3Dsquared( station ); d2 = aircraft.distance3Dsquared( station );
@ -184,22 +183,11 @@ bool FGNavList::findNavFromList(const Point3D &aircraft,
// << " range = " << current->get_range() * SG_NM_TO_METER // << " range = " << current->get_range() * SG_NM_TO_METER
// << endl; // << endl;
// match d^2 < 2 * range^2 the published range so we can model
// reduced signal strength
double twiceRange = 2 * (*current)->get_range() * SG_NM_TO_METER;
if ( d2 < (twiceRange * twiceRange)) {
// cout << "d2 = " << d2 << " min_dist = " << min_dist << endl;
if ( d2 < min_dist ) { if ( d2 < min_dist ) {
min_dist = d2; min_dist = d2;
found_one = true; nav = stations[i];
*nav = (**current);
// cout << "matched = " << (*current)->get_ident() << endl;
} else {
// cout << "matched, but too far away = "
// << (*current)->get_ident() << endl;
}
} }
} }
return found_one; return nav;
} }

View file

@ -54,12 +54,10 @@ class FGNavList {
nav_map_type navaids; nav_map_type navaids;
nav_ident_map_type ident_navaids; nav_ident_map_type ident_navaids;
// internal helper to pick a Nav item from a nav_list based on // Given a point and a list of stations, return the closest one to
// distance from the aircraft point // the specified point.
bool findNavFromList(const Point3D &aircraft, FGNav *findNavFromList( const Point3D &aircraft,
nav_list_iterator current, const nav_list_type &stations );
nav_list_iterator last,
FGNav *n);
public: public:
@ -69,15 +67,18 @@ public:
// load the navaids and build the map // load the navaids and build the map
bool init( SGPath path ); bool init( SGPath path );
// query the database for the specified frequency, lon and lat are // Query the database for the specified frequency. It is assumed
// in degrees, elev is in meters // that there will be multiple stations with matching frequencies
bool query( double lon, double lat, double elev, double freq, FGNav *nav ); // so a position must be specified. Lon and lat are in degrees,
// elev is in meters.
FGNav *findByFreq( double freq, double lon, double lat, double elev );
// locate closest item in the DB matching the requested ident // locate closest item in the DB matching the requested ident
bool findByIdent(const char* ident, double lon, double lat, FGNav *nav); FGNav *findByIdent( const char* ident, const double lon, const double lat );
// locate item in the DB matching the requested ident // Given an Ident and optional freqency, return the first matching
bool findByIdentAndFreq(const char* ident, const double& freq, FGNav *nav); // station.
FGNav *findByIdentAndFreq( const char* ident, const double freq = 0.0 );
}; };

View file

@ -16,25 +16,27 @@ int main() {
current_navlist->init( p_nav ); current_navlist->init( p_nav );
FGNav n; FGNav *n;
if ( current_navlist->query( -93.2 * SG_DEGREES_TO_RADIANS, if ( (n = current_navlist->findByFreq( -93.2 * SG_DEGREES_TO_RADIANS,
45.14 * SG_DEGREES_TO_RADIANS, 45.14 * SG_DEGREES_TO_RADIANS,
3000, 117.30, &n) ) 3000, 117.30)) != NULL )
{ {
cout << "Found a vor station in range" << endl; cout << "Found a vor station in range" << endl;
cout << " id = " << n.get_ident() << endl; cout << " id = " << n->get_ident() << endl;
} else { } else {
cout << "not picking up vor. :-(" << endl; cout << "not picking up vor. :-(" << endl;
} }
FGNav dcs; FGNav *dcs;
if (current_navlist->findByIdent("DCS", -3.3 * SG_DEGREES_TO_RADIANS, if ( (dcs = current_navlist->findByIdent( "DCS",
55.9 * SG_DEGREES_TO_RADIANS, &dcs)) { -3.3 * SG_DEGREES_TO_RADIANS,
55.9 * SG_DEGREES_TO_RADIANS))
!= NULL ) {
cout << "Found DCS by ident" << endl; cout << "Found DCS by ident" << endl;
if (dcs.get_freq() != 11520) if (dcs->get_freq() != 11520)
cout << "Frequency for DCS VOR is wrong (should be 115.20), it's " cout << "Frequency for DCS VOR is wrong (should be 115.20), it's "
<< dcs.get_freq() << endl; << dcs->get_freq() << endl;
} else { } else {
cout << "couldn't locate DCS (Dean-Cross) VOR" << endl; cout << "couldn't locate DCS (Dean-Cross) VOR" << endl;
} }