]> git.mxchange.org Git - flightgear.git/blobdiff - src/Autopilot/route_mgr.cxx
header cleanups
[flightgear.git] / src / Autopilot / route_mgr.cxx
index 915f9de2f73e460b8292c0061de1d1f5df692e7a..79566bbdbff057098703ef632c3e6c822cd97da7 100644 (file)
@@ -68,8 +68,8 @@ FGRouteMgr::FGRouteMgr() :
 
 
 FGRouteMgr::~FGRouteMgr() {
-    delete route;
     input->removeChangeListener(listener);
+    delete route;
 }
 
 
@@ -140,10 +140,12 @@ void FGRouteMgr::update( double dt ) {
         true_hdg_deg->setDoubleValue( wp_course );
         double target_alt = wp.get_target_alt();
 
-        if (!altitude_set && target_alt > -9990) {
+        if ( !altitude_set && target_alt > -9990 ) {
             target_altitude_ft->setDoubleValue( target_alt * SG_METER_TO_FEET );
-            altitude_lock->setStringValue( "altitude-hold" );
             altitude_set = true;
+
+            if ( !near_ground() )
+                altitude_lock->setStringValue( "altitude-hold" );
         }
 
         if ( wp_distance < 200.0 ) {
@@ -229,7 +231,7 @@ void FGRouteMgr::update( double dt ) {
 
 
 void FGRouteMgr::add_waypoint( const SGWayPoint& wp, int n ) {
-    if ( n == 0 || !route->size())
+    if ( n == 0 || !route->size() )
         altitude_set = false;
 
     route->add_waypoint( wp, n );
@@ -278,33 +280,32 @@ bool FGRouteMgr::build() {
 }
 
 
-
-int FGRouteMgr::new_waypoint( const string& Tgt_Alt, int n ) {
-    string target = Tgt_Alt;
-
-    // make upper case
-    for (unsigned int i = 0; i < target.size(); i++)
-        if (target[i] >= 'a' && target[i] <= 'z')
-            target[i] -= 'a' - 'A';
-
+int FGRouteMgr::new_waypoint( const string& target, int n ) {
     SGWayPoint *wp = 0;
     int type = make_waypoint( &wp, target );
 
     if (wp) {
         add_waypoint( *wp, n );
-        fgSetString( "/autopilot/locks/heading", "true-heading-hold" );
         delete wp;
+
+        if ( !near_ground() )
+            fgSetString( "/autopilot/locks/heading", "true-heading-hold" );
     }
     return type;
 }
 
 
+int FGRouteMgr::make_waypoint( SGWayPoint **wp, const string& tgt ) {
+    string target = tgt;
 
-int FGRouteMgr::make_waypoint(SGWayPoint **wp, string& target) {
-    double alt = -9999.0;
+    // make upper case
+    for (unsigned int i = 0; i < target.size(); i++)
+        if (target[i] >= 'a' && target[i] <= 'z')
+            target[i] -= 'a' - 'A';
 
     // extract altitude
-    unsigned int pos = target.find( '@' );
+    double alt = -9999.0;
+    size_t pos = target.find( '@' );
     if ( pos != string::npos ) {
         alt = atof( target.c_str() + pos + 1 );
         target = target.substr( 0, pos );
@@ -331,15 +332,6 @@ int FGRouteMgr::make_waypoint(SGWayPoint **wp, string& target) {
         return 2;
     }
 
-    // check for fix id
-    FGFix f;
-    if ( globals->get_fixlist()->query( target, &f ) ) {
-        SG_LOG( SG_GENERAL, SG_INFO, "Adding waypoint (fix) = " << target );
-        *wp = new SGWayPoint( f.get_lon(), f.get_lat(), alt, SGWayPoint::WGS84, target );
-        return 3;
-    }
-
-    // Try finding a nav matching the ID
     double lat, lon;
     // The base lon/lat are determined by the last WP,
     // or the current pos if the WP list is empty.
@@ -354,6 +346,18 @@ int FGRouteMgr::make_waypoint(SGWayPoint **wp, string& target) {
         lon = fgGetNode("/position/longitude-deg")->getDoubleValue();
     }
 
+    // check for fix id
+    FGFix f;
+    double heading;
+    double dist;
+
+    if ( globals->get_fixlist()->query_and_offset( target, lon, lat, 0, &f, &heading, &dist ) ) {
+        SG_LOG( SG_GENERAL, SG_INFO, "Adding waypoint (fix) = " << target );
+        *wp = new SGWayPoint( f.get_lon(), f.get_lat(), alt, SGWayPoint::WGS84, target );
+        return 3;
+    }
+
+    // Try finding a nav matching the ID
     lat *= SGD_DEGREES_TO_RADIANS;
     lon *= SGD_DEGREES_TO_RADIANS;
 
@@ -389,24 +393,37 @@ void FGRouteMgr::update_mirror() {
 }
 
 
+bool FGRouteMgr::near_ground() {
+    SGPropertyNode *gear = fgGetNode( "/gear/gear/wow", false );
+    if ( !gear || gear->getType() == SGPropertyNode::NONE )
+        return fgGetBool( "/sim/presets/onground", true );
+
+    if ( fgGetDouble("/position/altitude-agl-ft", 300.0)
+            < fgGetDouble("/autopilot/route-manager/min-lock-altitude-agl-ft") )
+        return true;
+
+    return gear->getBoolValue();
+}
+
+
 // command interface /autopilot/route-manager/input:
 //
-//   @clear             ... clear route
-//   @pop               ... remove first entry
-//   @delete3           ... delete 4th entry
-//   @insert2:ksfo@900  ... insert "ksfo@900" as 3rd entry
-//   ksfo@900           ... append "ksfo@900"
+//   @CLEAR             ... clear route
+//   @POP               ... remove first entry
+//   @DELETE3           ... delete 4th entry
+//   @INSERT2:KSFO@900  ... insert "KSFO@900" as 3rd entry
+//   KSFO@900           ... append "KSFO@900"
 //
 void FGRouteMgr::Listener::valueChanged(SGPropertyNode *prop)
 {
     const char *s = prop->getStringValue();
-    if (!strcmp(s, "@clear"))
+    if (!strcmp(s, "@CLEAR"))
         mgr->init();
-    else if (!strcmp(s, "@pop"))
+    else if (!strcmp(s, "@POP"))
         mgr->pop_waypoint(0);
-    else if (!strncmp(s, "@delete", 7))
+    else if (!strncmp(s, "@DELETE", 7))
         mgr->pop_waypoint(atoi(s + 7));
-    else if (!strncmp(s, "@insert", 7)) {
+    else if (!strncmp(s, "@INSERT", 7)) {
         char *r;
         int pos = strtol(s + 7, &r, 10);
         if (*r++ != ':')