]> git.mxchange.org Git - flightgear.git/commitdiff
Add support for in-air preset starts relative to a VOR, NDB, or Fix.
authorcurt <curt>
Sun, 5 Jan 2003 00:10:36 +0000 (00:10 +0000)
committercurt <curt>
Sun, 5 Jan 2003 00:10:36 +0000 (00:10 +0000)
src/Autopilot/auto_gui.cxx
src/Main/fg_commands.cxx
src/Main/fg_init.cxx
src/Navaids/fixlist.cxx
src/Navaids/fixlist.hxx
src/Navaids/navlist.cxx
src/Navaids/navlist.hxx
src/Navaids/testnavs.cxx
src/Network/props.cxx

index 4aca7092e27d7e1524ec39c712d0bb21bde84759..047a75d981fb9d5fb3ffb6f5be5f674807cbf928 100644 (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 );
index dec9776793a84f879cee722b7be3eb89a3217e36..82e7f47c9db4a18738e473f0b7a9bb241129cbe2 100644 (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
 };
 
index ca47053c17813bc0a4666642ae48a09ff9ec2b1c..223ad80f2c25057e66284e7fa37dd4a94f431da5 100644 (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
index 3fa380e4b56191107d0a85e5fecb1e923c112be2..31537e1d2b3dd898cd916a14fa64f5fb93a3255c 100644 (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() ) {
index 75d48e2440751424173025656ef041147152b0da..c23d4b75942440ae70270dd86c63054ddaaaddcc 100644 (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 );
 };
 
 
index b46b4b840e2e197ddab2ceb952d6cbb90d11a4dd..aba88dddcbf61c83215d0469e35aaf7aee6ac540 100644 (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 = "
index 1d6bea2c640297693f182761cfe093df38acd502..c890e0ef8d2971621b03129dfe50764fff3e3863 100644 (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);
 };
 
 
index a6b839f4443671553bef28568adc50288f08586e..3e95bbcff9be88186df6f98887112c964a77b0b5 100644 (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;
index 253aac701c636b843c914f18153bb3d633217450..eb4e9b0ce281fe3714026c26580a22351a337a7a 100644 (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" )
        {