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_HeadingEnabled( true );
globals->get_autopilot()->set_HeadingMode( FGAutopilot::FG_HEADING_WAYPOINT ); globals->get_autopilot()->set_HeadingMode( FGAutopilot::FG_HEADING_WAYPOINT );
} else if ( current_fixlist->query( TgtAptId, 0.0, 0.0, 0.0, } else if ( current_fixlist->query( TgtAptId, &f ) )
&f, &t1, &t2 ) )
{ {
SG_LOG( SG_GENERAL, SG_INFO, SG_LOG( SG_GENERAL, SG_INFO,
"Adding waypoint (fix) = " << TgtAptId ); "Adding waypoint (fix) = " << TgtAptId );

View file

@ -662,7 +662,7 @@ static struct {
{ "dialog-show", do_dialog_show }, { "dialog-show", do_dialog_show },
{ "dialog-update", do_dialog_update }, { "dialog-update", do_dialog_update },
{ "dialog-apply", do_dialog_apply }, { "dialog-apply", do_dialog_apply },
{ "presets_commit", do_presets_commit }, { "presets-commit", do_presets_commit },
{ 0, 0 } // zero-terminated { 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) // Set the initial position based on presets (or defaults)
bool fgInitPosition() { bool fgInitPosition() {
bool set_pos = false; bool set_pos = false;
@ -981,26 +1079,64 @@ bool fgInitPosition() {
string apt = fgGetString("/sim/presets/airport-id"); string apt = fgGetString("/sim/presets/airport-id");
string rwy_no = fgGetString("/sim/presets/runway"); string rwy_no = fgGetString("/sim/presets/runway");
double hdg = fgGetDouble("/sim/presets/heading-deg"); 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() ) { if ( !set_pos && !apt.empty() && !rwy_no.empty() ) {
// An airport + runway is requested // An airport + runway is requested
if ( fgSetPosFromAirportIDandRwy( apt, rwy_no ) ) { 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) // runway airports)
fgSetTowerPosFromAirportID( apt, hdg ); fgSetTowerPosFromAirportID( apt, hdg );
set_pos = true; set_pos = true;
} }
} }
if ( !set_pos && !apt.empty() ) { if ( !set_pos && !apt.empty() ) {
// An airport is requested (find runway closest to hdg)
if ( fgSetPosFromAirportIDandHdg( apt, 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) // runway airports)
fgSetTowerPosFromAirportID( apt, hdg ); fgSetTowerPosFromAirportID( apt, hdg );
set_pos = true; 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 ) { if ( !set_pos ) {
// No lon/lat specified, no airport specified, default to // 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 // degrees, elev is in meters
bool FGFixList::query( const string& ident, double lon, double lat, double elev, bool FGFixList::query( const string& ident, FGFix *fix ) {
FGFix *fix, double *heading, double *dist ) *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]; *fix = fixlist[ident];
if ( fix->get_ident().empty() ) { if ( fix->get_ident().empty() ) {

View file

@ -56,10 +56,14 @@ 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 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 // in degrees, elev is in meters
bool query( const string& ident, double lon, double lat, double elev, bool query_and_offset( const string& ident, double lon, double lat,
FGFix *f, double *heading, double *dist); 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 // query the database for the specified frequency, lon and lat are in
// degrees, elev is in meters // degrees, elev is in meters
bool FGNavList::query( double lon, double lat, double elev, double freq, 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)]; 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(); 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, 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, bool FGNavList::findNavFromList(const Point3D &aircraft,
nav_list_iterator current, nav_list_iterator current,
nav_list_iterator end, FGNav *n) nav_list_iterator end, FGNav *nav)
{ {
// double az1, az2, s; // double az1, az2, s;
@ -165,7 +192,7 @@ bool FGNavList::findNavFromList(const Point3D &aircraft,
if ( d2 < min_dist ) { if ( d2 < min_dist ) {
min_dist = d2; min_dist = d2;
found_one = true; found_one = true;
*n = (**current); *nav = (**current);
// cout << "matched = " << (*current)->get_ident() << endl; // cout << "matched = " << (*current)->get_ident() << endl;
} else { } else {
// cout << "matched, but too far away = " // cout << "matched, but too far away = "

View file

@ -71,10 +71,13 @@ public:
// query the database for the specified frequency, lon and lat are // query the database for the specified frequency, lon and lat are
// in degrees, elev is in meters // 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 // locate closest item in the DB matching the requested ident
bool findByIdent(const char* ident, double lon, double lat, FGNav *nav); 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 // attempting to get the position relative to the OTR VOR; heading
// should be 108 degrees, distance 74nm (according to my SimCharts // should be 108 degrees, distance 74nm (according to my SimCharts
// v1.5) // v1.5)
if ( current_fixlist->query( "DOGGA", -0.103 * SG_DEGREES_TO_RADIANS, if ( current_fixlist->query_and_offset( "DOGGA",
53.698 * SG_DEGREES_TO_RADIANS, 3000, -0.103 * SG_DEGREES_TO_RADIANS,
&fix, &heading, &dist) ) 53.698 * SG_DEGREES_TO_RADIANS,
3000, &fix, &heading, &dist) )
{ {
cout << "Found a matching fix" << endl; cout << "Found a matching fix" << endl;
cout << " id = " << fix.get_ident() << endl; cout << " id = " << fix.get_ident() << endl;

View file

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