1
0
Fork 0

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.
This commit is contained in:
James Turner 2013-07-04 00:11:40 +01:00
parent 8ccc1c4d35
commit a65f24c137
2 changed files with 69 additions and 52 deletions

View 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();
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;
}
// 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);
}
}

View 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