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 );
{ "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
};
}
+// 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;
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
}
-// 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() ) {
// 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 );
};
// 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)];
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);
}
}
+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;
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 = "
// 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);
};
// 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;
}
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" )
{