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++)
|
i++)
|
||||||
flights.push_back(new FGScheduledFlight((*(*i))));*/
|
flights.push_back(new FGScheduledFlight((*(*i))));*/
|
||||||
AIManagerRef = 0;
|
AIManagerRef = 0;
|
||||||
//score = scre;
|
score = 0;
|
||||||
firstRun = true;
|
firstRun = true;
|
||||||
|
runCount = 0;
|
||||||
|
hits = 0;
|
||||||
|
initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FGAISchedule::FGAISchedule(const FGAISchedule &other)
|
FGAISchedule::FGAISchedule(const FGAISchedule &other)
|
||||||
|
@ -136,13 +139,17 @@ FGAISchedule::FGAISchedule(const FGAISchedule &other)
|
||||||
radius = other.radius;
|
radius = other.radius;
|
||||||
groundOffset = other.groundOffset;
|
groundOffset = other.groundOffset;
|
||||||
flightType = other.flightType;
|
flightType = other.flightType;
|
||||||
//score = other.score;
|
score = other.score;
|
||||||
distanceToUser = other.distanceToUser;
|
distanceToUser = other.distanceToUser;
|
||||||
currentDestination = other.currentDestination;
|
currentDestination = other.currentDestination;
|
||||||
firstRun = other.firstRun;
|
firstRun = other.firstRun;
|
||||||
|
runCount = other.runCount;
|
||||||
|
hits = other.hits;
|
||||||
|
initialized = other.initialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FGAISchedule::~FGAISchedule()
|
FGAISchedule::~FGAISchedule()
|
||||||
{
|
{
|
||||||
/* for (FGScheduledFlightVecIterator flt = flights.begin(); flt != flights.end(); flt++)
|
/* for (FGScheduledFlightVecIterator flt = flights.begin(); flt != flights.end(); flt++)
|
||||||
|
@ -355,6 +362,14 @@ void FGAISchedule::scheduleFlights()
|
||||||
}
|
}
|
||||||
|
|
||||||
currentDestination = flight->getArrivalAirport()->getId();
|
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;
|
time_t arr, dep;
|
||||||
dep = flight->getDepartureTime();
|
dep = flight->getDepartureTime();
|
||||||
|
@ -481,12 +496,12 @@ double FGAISchedule::getSpeed()
|
||||||
SG_CLAMP_RANGE(speed, 300.0, 500.0);
|
SG_CLAMP_RANGE(speed, 300.0, 500.0);
|
||||||
return speed;
|
return speed;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
bool compareSchedules(FGAISchedule*a, FGAISchedule*b)
|
bool compareSchedules(FGAISchedule*a, FGAISchedule*b)
|
||||||
{
|
{
|
||||||
//return (*a) < (*b);
|
return (*a) < (*b);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
// void FGAISchedule::setClosestDistanceToUser()
|
// void FGAISchedule::setClosestDistanceToUser()
|
||||||
// {
|
// {
|
||||||
|
|
|
@ -53,9 +53,12 @@ class FGAISchedule
|
||||||
double groundOffset;
|
double groundOffset;
|
||||||
double distanceToUser;
|
double distanceToUser;
|
||||||
int AIManagerRef;
|
int AIManagerRef;
|
||||||
//int score;
|
double score;
|
||||||
|
unsigned int runCount;
|
||||||
|
unsigned int hits;
|
||||||
bool firstRun;
|
bool firstRun;
|
||||||
double courseToDest;
|
double courseToDest;
|
||||||
|
bool initialized;
|
||||||
|
|
||||||
void scheduleFlights();
|
void scheduleFlights();
|
||||||
|
|
||||||
|
@ -107,10 +110,17 @@ class FGAISchedule
|
||||||
const string& getFlightRules () { return (*flights.begin())->getFlightRules (); };
|
const string& getFlightRules () { return (*flights.begin())->getFlightRules (); };
|
||||||
bool getHeavy () { return heavy; };
|
bool getHeavy () { return heavy; };
|
||||||
double getCourse () { return courseToDest; };
|
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);
|
FGScheduledFlight*findAvailableFlight (const string ¤tDestination, const string &req);
|
||||||
// used to sort in decending order of score: I've probably found a better way to
|
// 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.
|
// 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; };
|
//void * getAiRef () { return AIManagerRef; };
|
||||||
//FGAISchedule* getAddress () { return this;};
|
//FGAISchedule* getAddress () { return this;};
|
||||||
|
|
||||||
|
|
|
@ -85,10 +85,39 @@ FGTrafficManager::FGTrafficManager()
|
||||||
|
|
||||||
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);
|
delete (*sched);
|
||||||
}
|
}
|
||||||
|
if (saveData) {
|
||||||
|
cachefile.close();
|
||||||
|
}
|
||||||
scheduledAircraft.clear();
|
scheduledAircraft.clear();
|
||||||
flights.clear();
|
flights.clear();
|
||||||
}
|
}
|
||||||
|
@ -99,8 +128,10 @@ void FGTrafficManager::init()
|
||||||
ulDir* d, *d2;
|
ulDir* d, *d2;
|
||||||
ulDirEnt* dent, *dent2;
|
ulDirEnt* dent, *dent2;
|
||||||
SGPath aircraftDir = globals->get_fg_root();
|
SGPath aircraftDir = globals->get_fg_root();
|
||||||
|
|
||||||
SGPath path = aircraftDir;
|
SGPath path = aircraftDir;
|
||||||
|
heuristicsVector heuristics;
|
||||||
|
HeuristicMap heurMap;
|
||||||
|
|
||||||
|
|
||||||
aircraftDir.append("AI/Traffic");
|
aircraftDir.append("AI/Traffic");
|
||||||
if ((d = ulOpenDir(aircraftDir.c_str())) != NULL)
|
if ((d = ulOpenDir(aircraftDir.c_str())) != NULL)
|
||||||
|
@ -130,7 +161,53 @@ void FGTrafficManager::init()
|
||||||
}
|
}
|
||||||
ulCloseDir(d);
|
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();
|
currAircraft = scheduledAircraft.begin();
|
||||||
currAircraftClosest = scheduledAircraft.begin();
|
currAircraftClosest = scheduledAircraft.begin();
|
||||||
}
|
}
|
||||||
|
@ -153,6 +230,7 @@ void FGTrafficManager::update(double /*dt*/)
|
||||||
{
|
{
|
||||||
currAircraft = scheduledAircraft.begin();
|
currAircraft = scheduledAircraft.begin();
|
||||||
}
|
}
|
||||||
|
//cerr << "Processing << " << (*currAircraft)->getRegistration() << " with score " << (*currAircraft)->getScore() << endl;
|
||||||
if (!((*currAircraft)->update(now, userCart)))
|
if (!((*currAircraft)->update(now, userCart)))
|
||||||
{
|
{
|
||||||
// NOTE: With traffic manager II, this statement below is no longer true
|
// NOTE: With traffic manager II, this statement below is no longer true
|
||||||
|
|
|
@ -57,6 +57,22 @@
|
||||||
typedef vector<int> IdList;
|
typedef vector<int> IdList;
|
||||||
typedef vector<int>::iterator IdListIterator;
|
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
|
class FGTrafficManager : public SGSubsystem, public XMLVisitor
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue