X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FTraffic%2FSchedule.cxx;h=a47dfd2ca3493c2485be2d0b1181736b07747e0d;hb=070dba29f9390806457206c2660f2daebd3d847c;hp=4421762444f9315af1933fe42c3dde7a6a997941;hpb=bb494e52e519b6b3bc2700f685a58dab0abd8459;p=flightgear.git diff --git a/src/Traffic/Schedule.cxx b/src/Traffic/Schedule.cxx index 442176244..a47dfd2ca 100644 --- a/src/Traffic/Schedule.cxx +++ b/src/Traffic/Schedule.cxx @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -47,28 +48,34 @@ #include #include #include -#include +#include #include
// That's pretty ugly, but I need fgFindAirportID #include "SchedFlight.hxx" #include "TrafficMgr.hxx" +using std::string; + /****************************************************************************** * the FGAISchedule class contains data members and code to maintain a * schedule of Flights for an artificially controlled aircraft. *****************************************************************************/ FGAISchedule::FGAISchedule() + : heavy(false), + radius(0), + groundOffset(0), + distanceToUser(0), + score(0), + runCount(0), + hits(0), + lastRun(0), + firstRun(false), + courseToDest(0), + initialized(false), + valid(false), + scheduleComplete(false) { - firstRun = true; - - heavy = false; - radius = 0; - groundOffset = 0; - distanceToUser = 0; - valid = true; - lastRun = 0; - //score = 0; } @@ -84,6 +91,19 @@ FGAISchedule::FGAISchedule(const string& model, const string& fltpe, double rad, double grnd) + : heavy(hvy), + radius(rad), + groundOffset(grnd), + distanceToUser(0), + score(0), + runCount(0), + hits(0), + lastRun(0), + firstRun(true), + courseToDest(0), + initialized(false), + valid(true), + scheduleComplete(false) { modelPath = model; livery = lvry; @@ -94,21 +114,10 @@ FGAISchedule::FGAISchedule(const string& model, airline = arln; m_class = mclass; flightType = fltpe; - radius = rad; - groundOffset = grnd; - distanceToUser = 0; - heavy = hvy; /*for (FGScheduledFlightVecIterator i = flt.begin(); i != flt.end(); i++) flights.push_back(new FGScheduledFlight((*(*i))));*/ - score = 0; - firstRun = true; - runCount = 0; - hits = 0; - lastRun = 0; - initialized = false; - valid = true; } FGAISchedule::FGAISchedule(const FGAISchedule &other) @@ -135,8 +144,10 @@ FGAISchedule::FGAISchedule(const FGAISchedule &other) runCount = other.runCount; hits = other.hits; lastRun = other.lastRun; + courseToDest = other.courseToDest; initialized = other.initialized; valid = other.valid; + scheduleComplete = other.scheduleComplete; } @@ -182,22 +193,37 @@ bool FGAISchedule::init() return true; } +/** + * Returns true when processing is complete. + * Returns false when processing was aborted due to timeout, so + * more time required - and another call is requested (next sim iteration). + */ bool FGAISchedule::update(time_t now, const SGVec3d& userCart) -{ - time_t - totalTimeEnroute, - elapsedTimeEnroute, - //remainingTimeEnroute, - deptime = 0; +{ + + time_t totalTimeEnroute, + elapsedTimeEnroute, + //remainingTimeEnroute, + deptime = 0; + if (!valid) { - return false; + return true; // processing complete } - scheduleFlights(now); + + if (!scheduleComplete) { + scheduleComplete = scheduleFlights(now); + } + + if (!scheduleComplete) { + return false; // not ready yet, continue processing in next iteration + } + if (flights.empty()) { // No flights available for this aircraft valid = false; - return false; + return true; // processing complete } - + + // Sort all the scheduled flights according to scheduled departure time. // Because this is done at every update, we only need to check the status // of the first listed flight. @@ -234,13 +260,13 @@ bool FGAISchedule::update(time_t now, const SGVec3d& userCart) // and detach it from the current list of aircraft. flight->update(); flights.erase(flights.begin()); // pop_front(), effectively - return true; + return true; // processing complete } FGAirport* dep = flight->getDepartureAirport(); FGAirport* arr = flight->getArrivalAirport(); if (!dep || !arr) { - return false; + return true; // processing complete } double speed = 450.0; @@ -281,7 +307,8 @@ bool FGAISchedule::update(time_t now, const SGVec3d& userCart) // large distances involved here: see bug #80 distanceToUser = dist(userCart, SGVec3d::fromGeod(position)) * SG_METER_TO_NM; - // If distance between user and simulated aircaft is less + + // If distance between user and simulated aircraft is less // then 500nm, create this flight. At jet speeds 500 nm is roughly // one hour flight time, so that would be a good approximate point // to start a more detailed simulation of this aircraft. @@ -291,19 +318,39 @@ bool FGAISchedule::update(time_t now, const SGVec3d& userCart) if (distanceToUser >= TRAFFICTOAIDISTTOSTART) { return true; // out of visual range, for the moment. } - return createAIAircraft(flight, speed, deptime); + + if (!createAIAircraft(flight, speed, deptime)) { + valid = false; + } + + + return true; // processing complete } bool FGAISchedule::validModelPath(const std::string& modelPath) { - SGPath mp(globals->get_fg_root()); - SGPath mp_ai = mp; + return (resolveModelPath(modelPath) != SGPath()); +} - mp.append(modelPath); - mp_ai.append("AI"); - mp_ai.append(modelPath); +SGPath FGAISchedule::resolveModelPath(const std::string& modelPath) +{ + BOOST_FOREACH(SGPath aiPath, globals->get_data_paths("AI")) { + aiPath.append(modelPath); + if (aiPath.exists()) { + return aiPath; + } + } + + // check aircraft dirs + BOOST_FOREACH(std::string aircraftPath, globals->get_aircraft_paths()) { + SGPath mp(aircraftPath); + mp.append(modelPath); + if (mp.exists()) { + return mp; + } + } - return mp.exists() || mp_ai.exists(); + return SGPath(); } bool FGAISchedule::createAIAircraft(FGScheduledFlight* flight, double speedKnots, time_t deptime) @@ -311,20 +358,7 @@ bool FGAISchedule::createAIAircraft(FGScheduledFlight* flight, double speedKnots FGAirport* dep = flight->getDepartureAirport(); FGAirport* arr = flight->getArrivalAirport(); string flightPlanName = dep->getId() + "-" + arr->getId() + ".xml"; - SG_LOG(SG_AI, SG_INFO, "Traffic manager: Creating AIModel from:" << flightPlanName); - - // Only allow traffic to be created when the model path (or the AI version of mp) exists - SGPath mp(globals->get_fg_root()); - SGPath mp_ai = mp; - - mp.append(modelPath); - mp_ai.append("AI"); - mp_ai.append(modelPath); - - if (!mp.exists() && !mp_ai.exists()) { - SG_LOG(SG_AI, SG_WARN, "TrafficManager: Could not load model " << mp_ai.str()); - return true; - } + SG_LOG(SG_AI, SG_DEBUG, "Traffic manager: Creating AIModel from:" << flightPlanName); aiAircraft = new FGAIAircraft(this); aiAircraft->setPerformance(acType, m_class); //"jet_transport"; @@ -369,30 +403,32 @@ void FGAISchedule::setHeading() courseToDest = SGGeodesy::courseDeg((*flights.begin())->getDepartureAirport()->geod(), (*flights.begin())->getArrivalAirport()->geod()); } -void FGAISchedule::scheduleFlights(time_t now) +bool FGAISchedule::scheduleFlights(time_t now) { - if (!flights.empty()) { - return; - } //string startingPort; - string userPort = fgGetString("/sim/presets/airport-id"); + const string& userPort = fgGetString("/sim/presets/airport-id"); SG_LOG(SG_AI, SG_BULK, "Scheduling Flights for : " << modelPath << " " << registration << " " << homePort); FGScheduledFlight *flight = NULL; + SGTimeStamp start; + start.stamp(); + + bool first = true; + if (currentDestination.empty()) + flight = findAvailableFlight(userPort, flightIdentifier, now, (now+6400)); + do { - if (currentDestination.empty()) { - flight = findAvailableFlight(userPort, flightIdentifier, now, (now+6400)); - if (!flight) - flight = findAvailableFlight(currentDestination, flightIdentifier); - } else { + if ((!flight)||(!first)) { flight = findAvailableFlight(currentDestination, flightIdentifier); } if (!flight) { break; } + + first = false; currentDestination = flight->getArrivalAirport()->getId(); //cerr << "Current destination " << currentDestination << endl; if (!initialized) { - string departurePort = flight->getDepartureAirport()->getId(); + const string& departurePort = flight->getDepartureAirport()->getId(); if (userPort == departurePort) { lastRun = 1; hits++; @@ -403,23 +439,36 @@ void FGAISchedule::scheduleFlights(time_t now) initialized = true; } - time_t arr, dep; - dep = flight->getDepartureTime(); - arr = flight->getArrivalTime(); - string depT = asctime(gmtime(&dep)); - string arrT = asctime(gmtime(&arr)); - - depT = depT.substr(0,24); - arrT = arrT.substr(0,24); - SG_LOG(SG_AI, SG_BULK, " Flight " << flight->getCallSign() << ":" - << " " << flight->getDepartureAirport()->getId() << ":" - << " " << depT << ":" - << " \"" << flight->getArrivalAirport()->getId() << "\"" << ":" - << " " << arrT << ":"); + if (sglog().would_log(SG_AI, SG_BULK)) + { + time_t arr, dep; + dep = flight->getDepartureTime(); + arr = flight->getArrivalTime(); + string depT = asctime(gmtime(&dep)); + string arrT = asctime(gmtime(&arr)); + depT = depT.substr(0,24); + arrT = arrT.substr(0,24); + SG_LOG(SG_AI, SG_BULK, " Flight " << flight->getCallSign() << ":" + << " " << flight->getDepartureAirport()->getId() << ":" + << " " << depT << ":" + << " \"" << flight->getArrivalAirport()->getId() << "\"" << ":" + << " " << arrT << ":"); + } flights.push_back(flight); - } while (currentDestination != homePort); + + // continue processing until complete, or preempt after timeout + } while ((currentDestination != homePort)&& + (start.elapsedMSec()<3.0)); + + if (flight && (currentDestination != homePort)) + { + // processing preempted, need to continue in next iteration + return false; + } + SG_LOG(SG_AI, SG_BULK, " Done "); + return true; } bool FGAISchedule::next() @@ -500,7 +549,7 @@ FGScheduledFlight* FGAISchedule::findAvailableFlight (const string ¤tDesti continue; } } - if (flights.size()) { + if (! flights.empty()) { time_t arrival = flights.back()->getArrivalTime(); int groundTime = groundTimeFromRadius(); if ((*i)->getDepartureTime() < (arrival+(groundTime)))