]> git.mxchange.org Git - flightgear.git/commitdiff
Bug 1153, guard against no current waypoint.
authorJames Turner <zakalawe@mac.com>
Wed, 3 Jul 2013 23:11:40 +0000 (00:11 +0100)
committerJames Turner <zakalawe@mac.com>
Thu, 4 Jul 2013 09:30:04 +0000 (10:30 +0100)
This is a work-around, probably indicates some glitch in the traffic
module flight-plans. Avoid a crash, also refine the exception logic
so individual AI objects can fail.

src/AIModel/AIAircraft.cxx
src/AIModel/AIManager.cxx

index cd06265fb1d14668bb022379da3721c8572a6651..bd8830e4bb71b3266c2ac9d915552d7301f16be1 100644 (file)
@@ -30,6 +30,8 @@
 #include <Airports/airport.hxx>
 #include <Main/util.hxx>
 
+#include <simgear/structure/exception.hxx>
+
 #include <string>
 #include <math.h>
 #include <time.h>
@@ -557,54 +559,61 @@ void FGAIAircraft::doGroundAltitude() {
 
 
 void FGAIAircraft::announcePositionToController() {
-    if (trafficRef) {
-        int leg = fp->getLeg();
-
-        // Note that leg has been incremented after creating the current leg, so we should use
-        // leg numbers here that are one higher than the number that is used to create the leg
-        // NOTE: As of July, 30, 2011, the post-creation leg updating is no longer happening. 
-        // Leg numbers are updated only once the aircraft passes the last waypoint created for that legm so I should probably just use
-        // the original leg numbers here!
-        switch (leg) {
-          case 1:              // Startup and Push back
-            if (trafficRef->getDepartureAirport()->getDynamics())
-                controller = trafficRef->getDepartureAirport()->getDynamics()->getStartupController();
-            break;
-        case 2:              // Taxiing to runway
-            if (trafficRef->getDepartureAirport()->getDynamics()->getGroundNetwork()->exists())
-                controller = trafficRef->getDepartureAirport()->getDynamics()->getGroundNetwork();
-            break;
-        case 3:              //Take off tower controller
-            if (trafficRef->getDepartureAirport()->getDynamics()) {
-                controller = trafficRef->getDepartureAirport()->getDynamics()->getTowerController();
-                towerController = 0;
-            } else {
-                cerr << "Error: Could not find Dynamics at airport : " << trafficRef->getDepartureAirport()->getId() << endl;
-            }
-            break;
-        case 6:
-             if (trafficRef->getDepartureAirport()->getDynamics()) {
-                 controller = trafficRef->getArrivalAirport()->getDynamics()->getApproachController();
-              }
-              break;
-        case 8:              // Taxiing for parking
-            if (trafficRef->getArrivalAirport()->getDynamics()->getGroundNetwork()->exists())
-                controller = trafficRef->getArrivalAirport()->getDynamics()->getGroundNetwork();
-            break;
-        default:
-            controller = 0;
-            break;
+    if (!trafficRef) {
+        return;
+    }
+    
+    int leg = fp->getLeg();
+    if (!fp->getCurrentWaypoint()) {
+        // http://code.google.com/p/flightgear-bugs/issues/detail?id=1153
+        // throw an exception so this aircraft gets killed by the AIManager.
+        throw sg_exception("bad AI flight plan");
+    }
+    
+    // Note that leg has been incremented after creating the current leg, so we should use
+    // leg numbers here that are one higher than the number that is used to create the leg
+    // NOTE: As of July, 30, 2011, the post-creation leg updating is no longer happening. 
+    // Leg numbers are updated only once the aircraft passes the last waypoint created for that legm so I should probably just use
+    // the original leg numbers here!
+    switch (leg) {
+      case 1:              // Startup and Push back
+        if (trafficRef->getDepartureAirport()->getDynamics())
+            controller = trafficRef->getDepartureAirport()->getDynamics()->getStartupController();
+        break;
+    case 2:              // Taxiing to runway
+        if (trafficRef->getDepartureAirport()->getDynamics()->getGroundNetwork()->exists())
+            controller = trafficRef->getDepartureAirport()->getDynamics()->getGroundNetwork();
+        break;
+    case 3:              //Take off tower controller
+        if (trafficRef->getDepartureAirport()->getDynamics()) {
+            controller = trafficRef->getDepartureAirport()->getDynamics()->getTowerController();
+            towerController = 0;
+        } else {
+            cerr << "Error: Could not find Dynamics at airport : " << trafficRef->getDepartureAirport()->getId() << endl;
         }
+        break;
+    case 6:
+         if (trafficRef->getDepartureAirport()->getDynamics()) {
+             controller = trafficRef->getArrivalAirport()->getDynamics()->getApproachController();
+          }
+          break;
+    case 8:              // Taxiing for parking
+        if (trafficRef->getArrivalAirport()->getDynamics()->getGroundNetwork()->exists())
+            controller = trafficRef->getArrivalAirport()->getDynamics()->getGroundNetwork();
+        break;
+    default:
+        controller = 0;
+        break;
+    }
 
-        if ((controller != prevController) && (prevController != 0)) {
-            prevController->signOff(getID());
-        }
-        prevController = controller;
-        if (controller) {
-            controller->announcePosition(getID(), fp, fp->getCurrentWaypoint()->getRouteIndex(),
-                                         _getLatitude(), _getLongitude(), hdg, speed, altitude_ft,
-                                         trafficRef->getRadius(), leg, this);
-        }
+    if ((controller != prevController) && (prevController != 0)) {
+        prevController->signOff(getID());
+    }
+    prevController = controller;
+    if (controller) {
+        controller->announcePosition(getID(), fp, fp->getCurrentWaypoint()->getRouteIndex(),
+                                     _getLatitude(), _getLongitude(), hdg, speed, altitude_ft,
+                                     trafficRef->getRadius(), leg, this);
     }
 }
 
index 0e14b015cee218faf6c00f5e107eb7dec7c8a612..18d1d648a8788d5741bcfcc56f2a47a93bd141e8 100644 (file)
@@ -227,12 +227,20 @@ FGAIManager::update(double dt) {
   
     ai_list.erase(ai_list.begin(), firstAlive);
   
-    // every remaining item is alive
+    // every remaining item is alive. update them in turn, but guard for
+    // exceptions, so a single misbehaving AI object doesn't bring down the
+    // entire subsystem.
     BOOST_FOREACH(FGAIBase* base, ai_list) {
-        if (base->isa(FGAIBase::otThermal)) {
-            processThermal(dt, (FGAIThermal*)base);
-        } else {
-            base->update(dt);
+        try {
+            if (base->isa(FGAIBase::otThermal)) {
+                processThermal(dt, (FGAIThermal*)base);
+            } else {
+                base->update(dt);
+            }
+        } catch (sg_exception& e) {
+            SG_LOG(SG_AI, SG_WARN, "caught exception updating AI model:" << base->_getName()<< ", which will be killed."
+                   "\n\tError:" << e.getFormattedMessage());
+            base->setDie(true);
         }
     } // of live AI objects iteration