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:
parent
a9463a8399
commit
a32c7d50bb
2 changed files with 122 additions and 26 deletions
|
@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue