From: James Turner Date: Wed, 3 Jul 2013 23:11:40 +0000 (+0100) Subject: Bug 1153, guard against no current waypoint. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=a65f24c1378fb7535801557712d249060ec8ac50;p=flightgear.git Bug 1153, guard against no current waypoint. 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. --- diff --git a/src/AIModel/AIAircraft.cxx b/src/AIModel/AIAircraft.cxx index cd06265fb..bd8830e4b 100644 --- a/src/AIModel/AIAircraft.cxx +++ b/src/AIModel/AIAircraft.cxx @@ -30,6 +30,8 @@ #include #include
+#include + #include #include #include @@ -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); } } diff --git a/src/AIModel/AIManager.cxx b/src/AIModel/AIManager.cxx index 0e14b015c..18d1d648a 100644 --- a/src/AIModel/AIManager.cxx +++ b/src/AIModel/AIManager.cxx @@ -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