Enable the collection of AI aircraft position statistics. This will allow for a dramatic speedup of the establishment of AI traffic after program initialization.
This commit is contained in:
parent
9197057784
commit
b090d3dabc
4 changed files with 130 additions and 11 deletions
|
@ -115,8 +115,11 @@ FGAISchedule::FGAISchedule(string model,
|
|||
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)
|
||||
|
@ -136,13 +139,17 @@ 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++)
|
||||
|
@ -355,6 +362,14 @@ void FGAISchedule::scheduleFlights()
|
|||
}
|
||||
|
||||
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();
|
||||
|
@ -481,12 +496,12 @@ double FGAISchedule::getSpeed()
|
|||
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()
|
||||
// {
|
||||
|
|
|
@ -53,9 +53,12 @@ class FGAISchedule
|
|||
double groundOffset;
|
||||
double distanceToUser;
|
||||
int AIManagerRef;
|
||||
//int score;
|
||||
double score;
|
||||
unsigned int runCount;
|
||||
unsigned int hits;
|
||||
bool firstRun;
|
||||
double courseToDest;
|
||||
bool initialized;
|
||||
|
||||
void scheduleFlights();
|
||||
|
||||
|
@ -107,10 +110,17 @@ class FGAISchedule
|
|||
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;};
|
||||
|
||||
|
|
|
@ -85,10 +85,39 @@ FGTrafficManager::FGTrafficManager()
|
|||
|
||||
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();
|
||||
}
|
||||
|
@ -99,8 +128,10 @@ void FGTrafficManager::init()
|
|||
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)
|
||||
|
@ -130,7 +161,53 @@ void FGTrafficManager::init()
|
|||
}
|
||||
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();
|
||||
}
|
||||
|
@ -153,6 +230,7 @@ void FGTrafficManager::update(double /*dt*/)
|
|||
{
|
||||
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
|
||||
|
|
|
@ -57,6 +57,22 @@
|
|||
typedef vector<int> IdList;
|
||||
typedef vector<int>::iterator IdListIterator;
|
||||
|
||||
class Heuristic
|
||||
{
|
||||
public:
|
||||
string registration;
|
||||
unsigned int runCount;
|
||||
unsigned int hits;
|
||||
};
|
||||
|
||||
typedef vector<Heuristic*> heuristicsVector;
|
||||
typedef vector<Heuristic*>::iterator heuristicsVectorIterator;
|
||||
|
||||
typedef std::map < std::string, Heuristic *> HeuristicMap;
|
||||
typedef HeuristicMap::iterator HeuristicMapIterator;
|
||||
|
||||
|
||||
|
||||
|
||||
class FGTrafficManager : public SGSubsystem, public XMLVisitor
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue