1
0
Fork 0

Initial revision of mkrbeacons.[ch]xx

Additions to query and report if we are over a marker beacon.
This commit is contained in:
curt 2001-03-16 23:57:38 +00:00
parent 99c54d976a
commit 7d38baf850
4 changed files with 340 additions and 0 deletions

View file

@ -5,6 +5,7 @@ noinst_PROGRAMS = testnavs
libNavaids_a_SOURCES = \
fix.hxx fixlist.hxx fixlist.cxx \
ils.hxx ilslist.hxx ilslist.cxx \
mkrbeacons.hxx mkrbeacons.cxx \
nav.hxx navlist.hxx navlist.cxx
testnavs_SOURCES = testnavs.cxx

View file

@ -25,6 +25,7 @@
#include <simgear/misc/fgstream.hxx>
#include <simgear/math/sg_geodesy.hxx>
#include "mkrbeacons.hxx"
#include "ilslist.hxx"
@ -95,6 +96,23 @@ bool FGILSList::init( FGPath path ) {
if ( ils.get_locfreq() > max ) {
max = ils.get_locfreq();
}
// update the marker beacon list
if ( fabs(ils.get_omlon()) > FG_EPSILON ||
fabs(ils.get_omlat()) > FG_EPSILON ) {
current_beacons->add( ils.get_omlon(), ils.get_omlat(),
ils.get_gselev(), FGBeacon::OUTER );
}
if ( fabs(ils.get_mmlon()) > FG_EPSILON ||
fabs(ils.get_mmlat()) > FG_EPSILON ) {
current_beacons->add( ils.get_mmlon(), ils.get_mmlat(),
ils.get_gselev(), FGBeacon::MIDDLE );
}
if ( fabs(ils.get_imlon()) > FG_EPSILON ||
fabs(ils.get_imlat()) > FG_EPSILON ) {
current_beacons->add( ils.get_imlon(), ils.get_imlat(),
ils.get_gselev(), FGBeacon::INNER );
}
}
// cout << "min freq = " << min << endl;

209
src/Navaids/mkrbeacons.cxx Normal file
View file

@ -0,0 +1,209 @@
// mkrbeacons.cxx -- marker beacon management class
//
// Written by Curtis Olson, started March 2001.
//
// Copyright (C) 2001 Curtis L. Olson - curt@flightgear.org
//
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
#include "mkrbeacons.hxx"
// constructor
FGBeacon::FGBeacon() {
FGBeacon( 0, 0, 0, NOBEACON );
}
FGBeacon::FGBeacon( double _lon, double _lat, double _elev,
fgMkrBeacType _type ) {
lon = _lon;
lat = _lat;
elev = _elev;
type = _type;
Point3D pos = sgGeodToCart(Point3D(lon * DEG_TO_RAD, lat * DEG_TO_RAD, 0));
// cout << "pos = " << pos << endl;
x = pos.x();
y = pos.y();
z = pos.z();
}
// destructor
FGBeacon::~FGBeacon() {
}
// constructor
FGMarkerBeacons::FGMarkerBeacons() {
}
// destructor
FGMarkerBeacons::~FGMarkerBeacons() {
}
// initialize the structures
bool FGMarkerBeacons::init() {
// erase the beacon map
beacon_map.clear();
return true;
}
// real add a marker beacon
bool FGMarkerBeacons::real_add( const int master_index, const FGBeacon& b ) {
// cout << "Master index = " << master_index << endl;
beacon_map[master_index].push_back( b );
return true;
}
// front end for add a marker beacon
bool FGMarkerBeacons::add( double lon, double lat, double elev,
FGBeacon::fgMkrBeacType type ) {
double diff;
int lonidx = (int)lon;
diff = lon - (double)lonidx;
if ( (lon < 0.0) && (fabs(diff) > FG_EPSILON) ) {
lonidx -= 1;
}
double lonfrac = lon - (double)lonidx;
lonidx += 180;
int latidx = (int)lat;
diff = lat - (double)latidx;
if ( (lat < 0.0) && (fabs(diff) > FG_EPSILON) ) {
latidx -= 1;
}
double latfrac = lat - (double)latidx;
latidx += 90;
int master_index = lonidx * 1000 + latidx;
FGBeacon b( lon, lat, elev, type );
// add to the actual bucket
real_add( master_index, b );
// if we are close to the edge, add to adjacent buckets so we only
// have to search one bucket at run time
// there are 8 cases since there are 8 adjacent tiles
if ( lonfrac < 0.2 ) {
real_add( master_index - 1000, b );
if ( latfrac < 0.2 ) {
real_add( master_index - 1000 - 1, b );
} else if ( latfrac > 0.8 ) {
real_add( master_index - 1000 + 1, b );
}
} else if ( lonfrac > 0.8 ) {
real_add( master_index + 1000, b );
if ( latfrac < 0.2 ) {
real_add( master_index + 1000 - 1, b );
} else if ( latfrac > 0.8 ) {
real_add( master_index+- 1000 + 1, b );
}
} else if ( latfrac < 0.2 ) {
real_add( master_index - 1, b );
} else if ( latfrac > 0.8 ) {
real_add( master_index + 1, b );
}
return true;
}
// returns marker beacon type if we are over a marker beacon, NOBEACON
// otherwise
FGBeacon::fgMkrBeacType FGMarkerBeacons::query( double lon, double lat,
double elev ) {
double diff;
int lonidx = (int)lon;
diff = lon - (double)lonidx;
if ( (lon < 0.0) && (fabs(diff) > FG_EPSILON) ) {
lonidx -= 1;
}
lonidx += 180;
int latidx = (int)lat;
diff = lat - (double)latidx;
if ( (lat < 0.0) && (fabs(diff) > FG_EPSILON) ) {
latidx -= 1;
}
latidx += 90;
int master_index = lonidx * 1000 + latidx;
beacon_list_type beacons = beacon_map[ master_index ];
// cout << "Master index = " << master_index << endl;
// cout << "beacon search length = " << beacons.size() << endl;
beacon_list_iterator current = beacons.begin();
beacon_list_iterator last = beacons.end();
Point3D aircraft = sgGeodToCart(Point3D(lon*DEG_TO_RAD, lat*DEG_TO_RAD, 0));
double min_dist = 999999999.0;
for ( ; current != last ; ++current ) {
// cout << " testing " << current->get_locident() << endl;
Point3D station = Point3D( current->get_x(),
current->get_y(),
current->get_z() );
// cout << " aircraft = " << aircraft << " station = " << station
// << endl;
double d = aircraft.distance3Dsquared( station );
// cout << " distance = " << d << " ("
// << FG_ILS_DEFAULT_RANGE * NM_TO_METER
// * FG_ILS_DEFAULT_RANGE * NM_TO_METER
// << ")" << endl;
// cout << " range = " << sqrt(d) << endl;
if ( d < min_dist ) {
min_dist = d;
}
// cout << "elev = " << elev * METER_TO_FEET
// << " current->get_elev() = " << current->get_elev() << endl;
double delev = elev * METER_TO_FEET - current->get_elev();
double maxrange = 4200 * delev / 1000;
// cout << "delev = " << delev << " maxrange = " << maxrange << endl;
// match up to twice the published range so we can model
// reduced signal strength
if ( d < maxrange * maxrange ) {
// cout << "lon = " << lon << " lat = " << lat
// << " closest beacon = " << sqrt( min_dist ) << endl;
return current->get_type();
}
}
// cout << "lon = " << lon << " lat = " << lat
<< " closest beacon = " << sqrt( min_dist ) << endl;
return FGBeacon::NOBEACON;
}
FGMarkerBeacons *current_beacons;

112
src/Navaids/mkrbeacons.hxx Normal file
View file

@ -0,0 +1,112 @@
// mkrbeacons.hxx -- marker beacon management class
//
// Written by Curtis Olson, started March 2001.
//
// Copyright (C) 2001 Curtis L. Olson - curt@flightgear.org
//
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
#ifndef _FG_MKRBEACON_HXX
#define _FG_MKRBEACON_HXX
#include <simgear/compiler.h>
#include <simgear/misc/fgpath.hxx>
#include <map>
#include <vector>
#include "nav.hxx"
FG_USING_STD(map);
FG_USING_STD(vector);
class FGBeacon {
public:
enum fgMkrBeacType {
NOBEACON = 0,
INNER,
MIDDLE,
OUTER
};
private:
double lon;
double lat;
double elev;
fgMkrBeacType type;
double x, y, z;
public:
FGBeacon();
FGBeacon( double _lon, double _lat, double _elev, fgMkrBeacType _type );
~FGBeacon();
inline double get_elev() const { return elev; }
inline fgMkrBeacType get_type() const { return type; }
inline double get_x() const { return x; }
inline double get_y() const { return y; }
inline double get_z() const { return z; }
};
class FGMarkerBeacons {
// convenience types
typedef vector < FGBeacon > beacon_list_type;
typedef beacon_list_type::iterator beacon_list_iterator;
typedef beacon_list_type::const_iterator beacon_list_const_iterator;
typedef map < int, beacon_list_type > beacon_map_type;
typedef beacon_map_type::iterator beacon_map_iterator;
typedef beacon_map_type::const_iterator beacon_map_const_iterator;
beacon_map_type beacon_map;
// real add a marker beacon
bool FGMarkerBeacons::real_add( const int master_index, const FGBeacon& b );
public:
FGMarkerBeacons();
~FGMarkerBeacons();
// initialize the structures
bool init();
// add a marker beacon
bool add( double lon, double lat, double elev,
FGBeacon::fgMkrBeacType type );
// returns marker beacon type if we are over a marker beacon, NOBEACON
// otherwise
FGBeacon::fgMkrBeacType query( double lon, double lat, double elev );
};
extern FGMarkerBeacons *current_beacons;
#endif // _FG_MKRBEACON_HXX