]> git.mxchange.org Git - flightgear.git/commitdiff
Bug 974, GPS exceptions at end-of-route.
authorJames Turner <jmt@Bishop.local>
Sat, 29 Dec 2012 13:45:27 +0000 (13:45 +0000)
committerJames Turner <jmt@Bishop.local>
Sat, 29 Dec 2012 13:45:27 +0000 (13:45 +0000)
One of the two route termination conditions was improperly handled, leading to bad leg/wpt indices and exceptions from the GPS code. Detect passing the final waypoint in a more robust way now.

Also fix the GPS code to avoid turn computation on the final leg.

src/Autopilot/route_mgr.cxx
src/Autopilot/route_mgr.hxx
src/Instrumentation/gps.cxx

index b084c45ad6d7ae835796c69ed92b8d391f01b081..5fe1466cbca4ebe18a1cccd87ce629b636e080fe 100644 (file)
@@ -453,7 +453,7 @@ void FGRouteMgr::update( double dt )
   }
 
   if (checkFinished()) {
-    // maybe we're done
+    endOfRoute();
   }
   
 // basic course/distance information
@@ -535,14 +535,11 @@ int FGRouteMgr::currentIndex() const
 
 Waypt* FGRouteMgr::wayptAtIndex(int index) const
 {
-  if (_plan) {
-    FlightPlan::Leg* leg = _plan->legAtIndex(index);
-    if (leg) {
-      return leg->waypoint();
-    }
+  if (!_plan) {
+    throw sg_range_exception("wayptAtindex: no flightplan");
   }
   
-  return NULL;
+  return _plan->legAtIndex(index)->waypoint();
 }
 
 int FGRouteMgr::numLegs() const
@@ -590,8 +587,12 @@ void FGRouteMgr::removeLegAtIndex(int aIndex)
 void FGRouteMgr::waypointsChanged()
 {
   update_mirror();
-   _edited->fireValueChanged();
-  checkFinished();
+  _edited->fireValueChanged();
+  
+// removing waypoints, deactivate if we hit the end.
+  if (currentIndex() >= numLegs()) {
+    endOfRoute();
+  }
 }
 
 // mirror internal route to the property system for inspection by other subsystems
@@ -802,11 +803,21 @@ void FGRouteMgr::sequence()
     return;
   }
   
-  if (checkFinished()) {
+  int nextIndex = _plan->currentIndex() + 1;
+  if (nextIndex >= _plan->numLegs()) {
+    SG_LOG(SG_AUTOPILOT, SG_INFO, "sequenced on final leg, deactivating route");
+    endOfRoute();
     return;
   }
-  
-  _plan->setCurrentIndex(_plan->currentIndex() + 1);
+
+  _plan->setCurrentIndex(nextIndex);
+}
+
+void FGRouteMgr::endOfRoute()
+{
+  SG_LOG(SG_AUTOPILOT, SG_INFO, "reached end of active route");
+  _finished->fireValueChanged();
+  active->setBoolValue(false);
 }
 
 bool FGRouteMgr::checkFinished()
@@ -824,15 +835,8 @@ bool FGRouteMgr::checkFinished()
     done = weightOnWheels->getBoolValue() && (gs < 25);
   }
   
-// also done if we hit the final waypoint
-  if (_plan->currentIndex() >= _plan->numLegs()) {
-    done = true;
-  }
-  
   if (done) {
-    SG_LOG(SG_AUTOPILOT, SG_INFO, "reached end of active route");
-    _finished->fireValueChanged();
-    active->setBoolValue(false);
+    SG_LOG(SG_AUTOPILOT, SG_INFO, "checkFinished: on the ground on destination runway, we're done");
   }
   
   return done;
index baa5e2c50f707d475a618074021dc06eb55cfd2f..b66a06b72f4cb697a4113c1f66c0083378a0a045 100644 (file)
@@ -194,6 +194,11 @@ private:
      */
     bool checkFinished();
     
+    /*
+     * update state when we pass the final waypoint
+     */
+    void endOfRoute();
+    
     /**
      * Predicate for helping the UI - test if at least one waypoint was
      * entered by the user (as opposed to being generated by the route-manager)
index 84ef13e35300c2f289167eff555194a8b3afdd94..5f04de2e62c02c4f52ab2ca82e4dc4fdc4ffefc5 100644 (file)
@@ -877,18 +877,14 @@ double GPS::computeTurnProgress(double aBearing) const
 void GPS::computeTurnData()
 {
   _computeTurnData = false;
-  if (_mode != "leg") { // and approach modes in the future
+  int nextIndex = _routeMgr->currentIndex() + 1;
+  if ((_mode != "leg") || (nextIndex >= _routeMgr->numWaypts())) {
     _anticipateTurn = false;
     return;
   }
   
-  WayptRef next = _routeMgr->wayptAtIndex(_routeMgr->currentIndex() + 1);
-  if (!next || next->flag(WPT_DYNAMIC)) {
-    _anticipateTurn = false;
-    return;
-  }
-  
-  if (!_config.turnAnticipationEnabled()) {
+  WayptRef next = _routeMgr->wayptAtIndex(nextIndex);
+  if (next->flag(WPT_DYNAMIC) || !_config.turnAnticipationEnabled()) {
     _anticipateTurn = false;
     return;
   }