1
0
Fork 0

FGAIMgr now searches for proximity to airports with logical networks defined at startup and periodically thereafter, and only starts AI traffic when a suitable airport is found in range (currently only KEMT). In theory it should now be possible for a user to drop in a *.taxi file in my undocumented-shortly-to-change format into fgfsbase/ATC and have an AI Cessna appear at that airport and fly a circuit if they start there or fly near there. In practice its probably better until we start using the output from Bernie's taxiway editor, and there's bound to be glitches once other networks are tried

This commit is contained in:
daveluff 2003-03-09 17:39:44 +00:00
parent a9463a8399
commit a32c7d50bb
2 changed files with 122 additions and 26 deletions

View file

@ -50,6 +50,11 @@ FGAIMgr::~FGAIMgr() {
}
void FGAIMgr::init() {
// Pointers to user's position
lon_node = fgGetNode("/position/longitude-deg", true);
lat_node = fgGetNode("/position/latitude-deg", true);
elev_node = fgGetNode("/position/altitude-ft", true);
// go through the $FG_ROOT/ATC directory and find all *.taxi files
SGPath path(globals->get_fg_root());
path.append("ATC/");
@ -81,7 +86,13 @@ void FGAIMgr::init() {
if(dclFindAirportID(f_ident, &a)) {
SGBucket sgb(a.longitude, a.latitude);
int idx = sgb.gen_index();
airports[idx] = f_ident;
if(airports.find(idx) != airports.end()) {
airports[idx]->push_back(f_ident);
} else {
aptID_list_type* apts = new aptID_list_type;
apts->push_back(f_ident);
airports[idx] = apts;
}
cout << "Mapping " << f_ident << " to bucket " << idx << '\n';
}
}
@ -111,7 +122,13 @@ void FGAIMgr::init() {
if(dclFindAirportID(f_ident, &a)) {
SGBucket sgb(a.longitude, a.latitude);
int idx = sgb.gen_index();
airports[idx] = f_ident;
if(airports.find(idx) != airports.end()) {
airports[idx]->push_back(f_ident);
} else {
aptID_list_type* apts = new aptID_list_type;
apts->push_back(f_ident);
airports[idx] = apts;
}
cout << "Mapping " << f_ident << " to bucket " << idx << '\n';
}
}
@ -120,14 +137,8 @@ void FGAIMgr::init() {
}
#endif
// Hard wire some local traffic for now.
// This is regardless of location and hence *very* ugly but it is a start.
ATC->AIRegisterAirport("KEMT");
FGAILocalTraffic* local_traffic = new FGAILocalTraffic;
//local_traffic->Init("KEMT", IN_PATTERN, TAKEOFF_ROLL);
local_traffic->Init("KEMT");
local_traffic->FlyCircuits(1, true); // Fly 2 circuits with touch & go in between
ai_list.push_back(local_traffic);
// See if are in range at startup and activate if necessary
SearchByPos(10.0);
}
void FGAIMgr::bind() {
@ -137,13 +148,25 @@ void FGAIMgr::unbind() {
}
void FGAIMgr::update(double dt) {
// Don't update any planes for first 50 runs through - this avoids some possible initialisation anomalies
static int i = 0;
static int j = 0;
// Don't update any planes for first 50 runs through - this avoids some possible initialisation anomalies
// Might not need it now we have fade-in though?
if(i < 50) {
i++;
++i;
return;
}
if(j == 215) {
SearchByPos(15.0);
j = 0;
}
++j;
// TODO - need to add a check of if any activated airports have gone out of range
// Traverse the list of active planes and run all their update methods
// TODO - spread the load - not all planes should need updating every frame.
// Note that this will require dt to be calculated for each plane though
@ -154,3 +177,68 @@ void FGAIMgr::update(double dt) {
++ai_list_itr;
}
}
// Activate AI traffic at an airport
void FGAIMgr::ActivateAirport(string ident) {
ATC->AIRegisterAirport(ident);
// TODO - need to start the traffic more randomly
FGAILocalTraffic* local_traffic = new FGAILocalTraffic;
//local_traffic->Init(ident, IN_PATTERN, TAKEOFF_ROLL);
local_traffic->Init(ident);
local_traffic->FlyCircuits(1, true); // Fly 2 circuits with touch & go in between
ai_list.push_back(local_traffic);
activated[ident] = 1;
}
// Search for valid airports in the vicinity of the user and activate them if necessary
void FGAIMgr::SearchByPos(double range)
{
//cout << "In SearchByPos(...)\n";
// get bucket number for plane position
lon = lon_node->getDoubleValue();
lat = lat_node->getDoubleValue();
SGBucket buck(lon, lat);
// get neigboring buckets
int bx = (int)( range*SG_NM_TO_METER / buck.get_width_m() / 2);
//cout << "bx = " << bx << '\n';
int by = (int)( range*SG_NM_TO_METER / buck.get_height_m() / 2 );
//cout << "by = " << by << '\n';
// loop over bucket range
for ( int i=-bx; i<=bx; i++) {
//cout << "i loop\n";
for ( int j=-by; j<=by; j++) {
//cout << "j loop\n";
buck = sgBucketOffset(lon, lat, i, j);
long int bucket = buck.gen_index();
//cout << "bucket is " << bucket << '\n';
aptID_list_type* apts = airports[bucket];
aptID_list_iterator current = apts->begin();
aptID_list_iterator last = apts->end();
//cout << "Size of apts is " << apts->size() << '\n';
//double rlon = lon * SGD_DEGREES_TO_RADIANS;
//double rlat = lat * SGD_DEGREES_TO_RADIANS;
//Point3D aircraft = sgGeodToCart( Point3D(rlon, rlat, elev) );
//Point3D airport;
for(; current != last; ++current) {
//cout << "Found " << *current << '\n';
if(activated.find(*current) == activated.end()) {
//cout << "Activating " << *current << '\n';
//FGAirport a;
//if(dclFindAirportID(*current, &a)) {
// // We can do something here based on distance from the user if we wish.
//}
ActivateAirport(*current);
} else {
//cout << *current << " already activated\n";
}
}
}
}
}

View file

@ -53,26 +53,28 @@ private:
// at any point in or at the end of the list.
// Hence any new access must explicitly first check for atc_list.end() before dereferencing.
// A list of airport ID's
typedef list < string > aptID_list_type;
typedef aptID_list_type::iterator aptID_list_iterator;
// A map of airport-IDs that have taxiway network files against bucket number
typedef map < int, string > ai_apt_map_type;
typedef map < int, aptID_list_type* > ai_apt_map_type;
typedef ai_apt_map_type::iterator ai_apt_map_iterator;
ai_apt_map_type airports;
// A map of airport ID's that we've activated AI traffic at
typedef map < string, int > ai_activated_map_type;
typedef ai_activated_map_type::iterator ai_activated_map_iterator;
ai_activated_map_type activated;
// Position of the Users Aircraft
// (This may be needed to calculate the distance from the user when deciding which 3D model to render)
double current_lon;
double current_lat;
double current_elev;
double lon;
double lat;
double elev;
// Pointers to current users position
SGPropertyNode *current_lon_node;
SGPropertyNode *current_lat_node;
SGPropertyNode *current_elev_node;
//FGATIS atis;
//FGGround ground;
//FGTower tower;
//FGApproach approach;
//FGDeparture departure;
SGPropertyNode *lon_node;
SGPropertyNode *lat_node;
SGPropertyNode *elev_node;
public:
@ -91,6 +93,12 @@ private:
// Remove a class from the ai_list and delete it from memory
//void RemoveFromList(const char* id, atc_type tp);
// Activate AI traffic at an airport
void ActivateAirport(string id);
// Search for valid airports in the vicinity of the user and activate them if necessary
void SearchByPos(double range);
};