i++)
flights.push_back(new FGScheduledFlight((*(*i))));*/
AIManagerRef = 0;
- //score = scre;
+ score = 0;
firstRun = true;
+ runCount = 0;
+ hits = 0;
+ initialized = false;
}
FGAISchedule::FGAISchedule(const FGAISchedule &other)
radius = other.radius;
groundOffset = other.groundOffset;
flightType = other.flightType;
- //score = other.score;
+ score = other.score;
distanceToUser = other.distanceToUser;
currentDestination = other.currentDestination;
firstRun = other.firstRun;
+ runCount = other.runCount;
+ hits = other.hits;
+ initialized = other.initialized;
}
+
FGAISchedule::~FGAISchedule()
{
/* for (FGScheduledFlightVecIterator flt = flights.begin(); flt != flights.end(); flt++)
}
currentDestination = flight->getArrivalAirport()->getId();
+ if (!initialized) {
+ string departurePort = flight->getDepartureAirport()->getId();
+ if (fgGetString("/sim/presets/airport-id") == departurePort) {
+ hits++;
+ }
+ runCount++;
+ initialized = true;
+ }
time_t arr, dep;
dep = flight->getDepartureTime();
SG_CLAMP_RANGE(speed, 300.0, 500.0);
return speed;
}
-/*
+
bool compareSchedules(FGAISchedule*a, FGAISchedule*b)
{
- //return (*a) < (*b);
+ return (*a) < (*b);
}
-*/
+
// void FGAISchedule::setClosestDistanceToUser()
// {
double groundOffset;
double distanceToUser;
int AIManagerRef;
- //int score;
+ double score;
+ unsigned int runCount;
+ unsigned int hits;
bool firstRun;
double courseToDest;
+ bool initialized;
void scheduleFlights();
const string& getFlightRules () { return (*flights.begin())->getFlightRules (); };
bool getHeavy () { return heavy; };
double getCourse () { return courseToDest; };
+ unsigned int getRunCount () { return runCount; };
+ unsigned int getHits () { return hits; };
+
+ void setrunCount(unsigned int count) { runCount = count; };
+ void setHits (unsigned int count) { hits = count; };
+ void setScore () { score = runCount ? ((double) hits / (double) runCount) : 0; };
+ double getScore () { return score; };
FGScheduledFlight*findAvailableFlight (const string ¤tDestination, const string &req);
// used to sort in decending order of score: I've probably found a better way to
// decending order sorting, but still need to test that.
- //bool operator< (const FGAISchedule &other) const { return (score > other.score); };
+ bool operator< (const FGAISchedule &other) const { return (score > other.score); };
//void * getAiRef () { return AIManagerRef; };
//FGAISchedule* getAddress () { return this;};
FGTrafficManager:: ~FGTrafficManager()
{
- for (ScheduleVectorIterator sched = scheduledAircraft.begin(); sched != scheduledAircraft.end(); sched++)
- {
+ // Save the heuristics data
+ bool saveData = false;
+ ofstream cachefile;
+ if (fgGetBool("/sim/traffic-manager/heuristics")) {
+ SGPath cacheData(fgGetString("/sim/fg-home"));
+ cacheData.append("ai");
+ string airport = fgGetString("/sim/presets/airport-id");
+
+ if ((airport) != "") {
+ char buffer[128];
+ ::snprintf(buffer, 128, "%c/%c/%c/",
+ airport[0], airport[1], airport[2]);
+ cacheData.append(buffer);
+ if (!cacheData.exists()) {
+ cacheData.create_dir(0777);
+ }
+ cacheData.append(airport + "-cache.txt");
+ //cerr << "Saving AI traffic heuristics" << endl;
+ saveData = true;
+ cachefile.open(cacheData.str().c_str());
+ }
+ }
+ for (ScheduleVectorIterator sched = scheduledAircraft.begin(); sched != scheduledAircraft.end(); sched++) {
+ if (saveData) {
+ cachefile << (*sched)->getRegistration() << " "
+ << (*sched)-> getRunCount() << " "
+ << (*sched)->getHits() << endl;
+ }
delete (*sched);
}
+ if (saveData) {
+ cachefile.close();
+ }
scheduledAircraft.clear();
flights.clear();
}
ulDir* d, *d2;
ulDirEnt* dent, *dent2;
SGPath aircraftDir = globals->get_fg_root();
-
SGPath path = aircraftDir;
+ heuristicsVector heuristics;
+ HeuristicMap heurMap;
+
aircraftDir.append("AI/Traffic");
if ((d = ulOpenDir(aircraftDir.c_str())) != NULL)
{
}
ulCloseDir(d);
}
-
+ if (fgGetBool("/sim/traffic-manager/heuristics")) {
+ //cerr << "Processing Heuristics" << endl;
+ // Load the heuristics data
+ SGPath cacheData(fgGetString("/sim/fg-home"));
+ cacheData.append("ai");
+ string airport = fgGetString("/sim/presets/airport-id");
+ if ((airport) != "") {
+ char buffer[128];
+ ::snprintf(buffer, 128, "%c/%c/%c/",
+ airport[0], airport[1], airport[2]);
+ cacheData.append(buffer);
+ cacheData.append(airport + "-cache.txt");
+ if (cacheData.exists()) {
+ ifstream data(cacheData.c_str());
+ while (1) {
+ Heuristic *h = new Heuristic;
+ data >> h->registration >> h->runCount >> h->hits;
+ if (data.eof())
+ break;
+ heurMap[h->registration] = h;
+ heuristics.push_back(h);
+ }
+ }
+ }
+ for (currAircraft = scheduledAircraft.begin();
+ currAircraft != scheduledAircraft.end();
+ currAircraft++) {
+ string registration = (*currAircraft)->getRegistration();
+ HeuristicMapIterator itr = heurMap.find(registration);
+ //cerr << "Processing heuristics for" << (*currAircraft)->getRegistration() << endl;
+ if (itr == heurMap.end()) {
+ //cerr << "No heuristics found for " << registration << endl;
+ } else {
+ (*currAircraft)->setrunCount(itr->second->runCount);
+ (*currAircraft)->setHits (itr->second->hits);
+ (*currAircraft)->setScore();
+ //cerr <<"Runcount " << itr->second->runCount << ".Hits " << itr->second->hits << endl;
+ }
+ }
+ //cerr << "Done" << endl;
+ for (heuristicsVectorIterator hvi = heuristics.begin();
+ hvi != heuristics.end();
+ hvi++) {
+ delete (*hvi);
+ }
+ sort (scheduledAircraft.begin(), scheduledAircraft.end(), compareSchedules);
+ }
currAircraft = scheduledAircraft.begin();
currAircraftClosest = scheduledAircraft.begin();
}
{
currAircraft = scheduledAircraft.begin();
}
+ //cerr << "Processing << " << (*currAircraft)->getRegistration() << " with score " << (*currAircraft)->getScore() << endl;
if (!((*currAircraft)->update(now, userCart)))
{
// NOTE: With traffic manager II, this statement below is no longer true