1
0
Fork 0

Add support for in-air preset starts relative to a VOR, NDB, or Fix.

This commit is contained in:
curt 2003-01-05 00:10:36 +00:00
parent 30dc5aab90
commit be703a92b4
9 changed files with 216 additions and 26 deletions

View file

@ -641,8 +641,7 @@ void TgtAptDialog_OK (puObject *)
globals->get_autopilot()->set_HeadingEnabled( true );
globals->get_autopilot()->set_HeadingMode( FGAutopilot::FG_HEADING_WAYPOINT );
} else if ( current_fixlist->query( TgtAptId, 0.0, 0.0, 0.0,
&f, &t1, &t2 ) )
} else if ( current_fixlist->query( TgtAptId, &f ) )
{
SG_LOG( SG_GENERAL, SG_INFO,
"Adding waypoint (fix) = " << TgtAptId );

View file

@ -662,7 +662,7 @@ static struct {
{ "dialog-show", do_dialog_show },
{ "dialog-update", do_dialog_update },
{ "dialog-apply", do_dialog_apply },
{ "presets_commit", do_presets_commit },
{ "presets-commit", do_presets_commit },
{ 0, 0 } // zero-terminated
};

View file

@ -955,6 +955,104 @@ static void fgSetDistOrAltFromGlideSlope() {
}
// Set current_options lon/lat given an airport id and heading (degrees)
static bool fgSetPosFromNAV( const string& id, const double& freq ) {
FGNav nav;
// set initial position from runway and heading
if ( current_navlist->findByIdentAndFreq( id.c_str(), freq, &nav ) ) {
SG_LOG( SG_GENERAL, SG_INFO, "Attempting to set starting position for "
<< id << ":" << freq );
double lon = nav.get_lon();
double lat = nav.get_lat();
if ( fabs( fgGetDouble("/sim/presets/offset-distance") ) > SG_EPSILON )
{
double odist = fgGetDouble("/sim/presets/offset-distance")
* SG_NM_TO_METER;
double oaz = fabs(fgGetDouble("/sim/presets/offset-azimuth"))
+ 180.0;
while ( oaz >= 360.0 ) { oaz -= 360.0; }
double olat, olon, az2;
geo_direct_wgs_84 ( 0, lat, lon, oaz, odist, &olat, &olon, &az2 );
lat = olat;
lon = olon;
}
// presets
fgSetDouble("/sim/presets/longitude-deg", lon );
fgSetDouble("/sim/presets/latitude-deg", lat );
// other code depends on the actual values being set ...
fgSetDouble("/position/longitude-deg", lon );
fgSetDouble("/position/latitude-deg", lat );
fgSetDouble("/orientation/heading-deg",
fgGetDouble("/sim/presets/heading-deg") );
SG_LOG( SG_GENERAL, SG_INFO,
"Position for " << id << ":" << freq << " is ("
<< lon << ", "<< lat << ")" );
return true;
} else {
SG_LOG( SG_GENERAL, SG_ALERT, "Failed to locate NAV = "
<< id << ":" << freq );
return false;
}
}
// Set current_options lon/lat given an airport id and heading (degrees)
static bool fgSetPosFromFix( const string& id ) {
FGFix fix;
// set initial position from runway and heading
if ( current_fixlist->query( id.c_str(), &fix ) ) {
SG_LOG( SG_GENERAL, SG_INFO, "Attempting to set starting position for "
<< id );
double lon = fix.get_lon();
double lat = fix.get_lat();
if ( fabs( fgGetDouble("/sim/presets/offset-distance") ) > SG_EPSILON )
{
double odist = fgGetDouble("/sim/presets/offset-distance")
* SG_NM_TO_METER;
double oaz = fabs(fgGetDouble("/sim/presets/offset-azimuth"))
+ 180.0;
while ( oaz >= 360.0 ) { oaz -= 360.0; }
double olat, olon, az2;
geo_direct_wgs_84 ( 0, lat, lon, oaz, odist, &olat, &olon, &az2 );
lat = olat;
lon = olon;
}
// presets
fgSetDouble("/sim/presets/longitude-deg", lon );
fgSetDouble("/sim/presets/latitude-deg", lat );
// other code depends on the actual values being set ...
fgSetDouble("/position/longitude-deg", lon );
fgSetDouble("/position/latitude-deg", lat );
fgSetDouble("/orientation/heading-deg",
fgGetDouble("/sim/presets/heading-deg") );
SG_LOG( SG_GENERAL, SG_INFO,
"Position for " << id << " is ("
<< lon << ", "<< lat << ")" );
return true;
} else {
SG_LOG( SG_GENERAL, SG_ALERT, "Failed to locate NAV = "
<< id );
return false;
}
}
// Set the initial position based on presets (or defaults)
bool fgInitPosition() {
bool set_pos = false;
@ -981,26 +1079,64 @@ bool fgInitPosition() {
string apt = fgGetString("/sim/presets/airport-id");
string rwy_no = fgGetString("/sim/presets/runway");
double hdg = fgGetDouble("/sim/presets/heading-deg");
string vor = fgGetString("/sim/presets/vor-id");
double vor_freq = fgGetDouble("/sim/presets/vor-freq");
string ndb = fgGetString("/sim/presets/ndb-id");
double ndb_freq = fgGetDouble("/sim/presets/ndb-freq");
string fix = fgGetString("/sim/presets/fix");
if ( !set_pos && !apt.empty() && !rwy_no.empty() ) {
// An airport + runway is requested
if ( fgSetPosFromAirportIDandRwy( apt, rwy_no ) ) {
// set tower position (a little off the heading for single
// set position (a little off the heading for single
// runway airports)
fgSetTowerPosFromAirportID( apt, hdg );
set_pos = true;
}
}
if ( !set_pos && !apt.empty() ) {
// An airport is requested (find runway closest to hdg)
if ( fgSetPosFromAirportIDandHdg( apt, hdg ) ) {
// set tower position (a little off the heading for single
// set position (a little off the heading for single
// runway airports)
fgSetTowerPosFromAirportID( apt, hdg );
set_pos = true;
}
}
if ( !set_pos && !vor.empty() ) {
// a VOR is requested
if ( fgSetPosFromNAV( vor, vor_freq ) ) {
if ( fgGetDouble("/sim/presets/altitude-ft") > -9990.0 ) {
fgSetBool("/sim/presets/onground", false);
} else {
fgSetBool("/sim/presets/onground", true);
}
set_pos = true;
}
}
if ( !set_pos && !ndb.empty() ) {
// an NDB is requested
if ( fgSetPosFromNAV( ndb, ndb_freq ) ) {
if ( fgGetDouble("/sim/presets/altitude-ft") > -9990.0 ) {
fgSetBool("/sim/presets/onground", false);
} else {
fgSetBool("/sim/presets/onground", true);
}
set_pos = true;
}
}
if ( !set_pos && !fix.empty() ) {
// a Fix is requested
if ( fgSetPosFromFix( fix ) ) {
if ( fgGetDouble("/sim/presets/altitude-ft") > -9990.0 ) {
fgSetBool("/sim/presets/onground", false);
} else {
fgSetBool("/sim/presets/onground", true);
}
set_pos = true;
}
}
if ( !set_pos ) {
// No lon/lat specified, no airport specified, default to

View file

@ -87,10 +87,23 @@ bool FGFixList::init( SGPath path ) {
}
// query the database for the specified frequency, lon and lat are in
// query the database for the specified fix, lon and lat are in
// degrees, elev is in meters
bool FGFixList::query( const string& ident, double lon, double lat, double elev,
FGFix *fix, double *heading, double *dist )
bool FGFixList::query( const string& ident, FGFix *fix ) {
*fix = fixlist[ident];
if ( ! fix->get_ident().empty() ) {
return true;
} else {
return false;
}
}
// query the database for the specified fix, lon and lat are in
// degrees, elev is in meters
bool FGFixList::query_and_offset( const string& ident, double lon, double lat,
double elev, FGFix *fix, double *heading,
double *dist )
{
*fix = fixlist[ident];
if ( fix->get_ident().empty() ) {

View file

@ -56,10 +56,14 @@ public:
// load the navaids and build the map
bool init( SGPath path );
// query the database for the specified frequency, lon and lat are
// query the database for the specified fix
bool query( const string& ident, FGFix *f );
// query the database for the specified fix, lon and lat are
// in degrees, elev is in meters
bool query( const string& ident, double lon, double lat, double elev,
FGFix *f, double *heading, double *dist);
bool query_and_offset( const string& ident, double lon, double lat,
double elev, FGFix *f, double *heading,
double *dist );
};

View file

@ -111,7 +111,7 @@ bool FGNavList::init( SGPath path ) {
// query the database for the specified frequency, lon and lat are in
// degrees, elev is in meters
bool FGNavList::query( double lon, double lat, double elev, double freq,
FGNav *n )
FGNav *nav )
{
nav_list_type stations = navaids[(int)(freq*100.0 + 0.5)];
@ -119,7 +119,7 @@ bool FGNavList::query( double lon, double lat, double elev, double freq,
nav_list_iterator last = stations.end();
Point3D aircraft = sgGeodToCart( Point3D(lon, lat, elev) );
return findNavFromList(aircraft, current, last, n);
return findNavFromList(aircraft, current, last, nav);
}
@ -136,9 +136,36 @@ bool FGNavList::findByIdent(const char* ident, double lon, double lat,
}
bool FGNavList::findByIdentAndFreq(const char* ident, const double& freq,
FGNav *nav)
{
cout << "ident = " << ident << endl;
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 ) {
// more than one match on this ident, use freq to refine
int f = (int)(freq*100.0 + 0.5);
for ( ; current != last ; ++current ) {
if ( f == (*current)->get_freq() ) {
*nav = (**current);
return true;
}
}
} else {
*nav = (**current);
return true;
}
return false;
}
bool FGNavList::findNavFromList(const Point3D &aircraft,
nav_list_iterator current,
nav_list_iterator end, FGNav *n)
nav_list_iterator end, FGNav *nav)
{
// double az1, az2, s;
@ -165,7 +192,7 @@ bool FGNavList::findNavFromList(const Point3D &aircraft,
if ( d2 < min_dist ) {
min_dist = d2;
found_one = true;
*n = (**current);
*nav = (**current);
// cout << "matched = " << (*current)->get_ident() << endl;
} else {
// cout << "matched, but too far away = "

View file

@ -71,10 +71,13 @@ public:
// query the database for the specified frequency, lon and lat are
// in degrees, elev is in meters
bool query( double lon, double lat, double elev, double freq, FGNav *n );
bool query( double lon, double lat, double elev, double freq, FGNav *nav );
// locate closest item in the DB matching the requested ident
bool findByIdent(const char* ident, double lon, double lat, FGNav *nav);
// locate item in the DB matching the requested ident
bool findByIdentAndFreq(const char* ident, const double& freq, FGNav *nav);
};

View file

@ -66,9 +66,10 @@ int main() {
// attempting to get the position relative to the OTR VOR; heading
// should be 108 degrees, distance 74nm (according to my SimCharts
// v1.5)
if ( current_fixlist->query( "DOGGA", -0.103 * SG_DEGREES_TO_RADIANS,
53.698 * SG_DEGREES_TO_RADIANS, 3000,
&fix, &heading, &dist) )
if ( current_fixlist->query_and_offset( "DOGGA",
-0.103 * SG_DEGREES_TO_RADIANS,
53.698 * SG_DEGREES_TO_RADIANS,
3000, &fix, &heading, &dist) )
{
cout << "Found a matching fix" << endl;
cout << " id = " << fix.get_ident() << endl;

View file

@ -311,22 +311,29 @@ PropsChannel::foundTerminator()
}
else if ( command == "set" )
{
if ( tokens.size() == 3 )
{
node->getNode( tokens[1].c_str(), true )->setStringValue(tokens[2].c_str());
if ( tokens.size() >= 2 )
{
string value, tmp;
if ( tokens.size() == 3 ) {
value = tokens[2];
} else {
value = "";
}
node->getNode( tokens[1].c_str(), true )
->setStringValue(value.c_str());
if ( mode == PROMPT )
{
// now fetch and write out the new value as confirmation
// of the change
string value = node->getStringValue ( tokens[1].c_str(), "" );
string tmp = tokens[1] + " = '" + value + "' (";
value = node->getStringValue ( tokens[1].c_str(), "" );
tmp = tokens[1] + " = '" + value + "' (";
tmp += getValueTypeString( node->getNode( tokens[1].c_str() ) );
tmp += ")";
push( tmp.c_str() );
push( getTerminator() );
}
}
}
}
else if ( command == "run" )
{