1
0
Fork 0

More stuff to make the AI/ATC system less hardwired and more generic. Most of the hardwired stuff is now gone - there's just a little bit left in FGAIMgr

This commit is contained in:
daveluff 2003-03-07 13:58:33 +00:00
parent 1154a0dae2
commit 96970dcbaf
9 changed files with 232 additions and 40 deletions

View file

@ -41,6 +41,8 @@ SG_USING_STD(string);
#include "ATCutils.hxx" #include "ATCutils.hxx"
FGAILocalTraffic::FGAILocalTraffic() { FGAILocalTraffic::FGAILocalTraffic() {
ATC = globals->get_ATC_mgr();
roll = 0.0; roll = 0.0;
pitch = 0.0; pitch = 0.0;
hdg = 270.0; hdg = 270.0;
@ -159,24 +161,38 @@ bool FGAILocalTraffic::Init(string ICAO, OperatingState initialState, PatternLeg
// Find the tower frequency - this is dependent on the ATC system being initialised before the AI system // Find the tower frequency - this is dependent on the ATC system being initialised before the AI system
airportID = ICAO; airportID = ICAO;
AirportATC a; AirportATC a;
if(globals->get_ATC_mgr()->GetAirportATCDetails(airportID, &a)) { if(ATC->GetAirportATCDetails(airportID, &a)) {
if(a.tower_freq) { // Has a tower if(a.tower_freq) { // Has a tower
tower = (FGTower*)globals->get_ATC_mgr()->GetATCPointer((string)airportID, TOWER); // Maybe need some error checking here tower = (FGTower*)ATC->GetATCPointer((string)airportID, TOWER); // Maybe need some error checking here
if(tower == NULL) {
// Something has gone wrong - abort or carry on with un-towered operation?
return(false);
}
freq = (double)tower->get_freq() / 100.0; freq = (double)tower->get_freq() / 100.0;
//cout << "***********************************AILocalTraffic freq = " << freq << '\n';
} else { } else {
// Check CTAF, unicom etc // Check CTAF, unicom etc
} }
if(a.ground_freq) { // Ground control
ground = (FGGround*)ATC->GetATCPointer((string)airportID, GROUND); // Maybe need some error checking here
if(ground == NULL) {
// Something has gone wrong :-(
cout << "ERROR - ground has frequency but can't get ground pointer :-(\n";
return(false);
}
freq = (double)tower->get_freq() / 100.0;
} else {
// Initialise ground anyway to do the shortest path stuff!
// This is a bit of a hack - might need to be altered sometime, but
// in theory AILocalTraffic doesn't get called unless we have a logical
// network for ground to use so it should work for now!
ground = new FGGround(airportID); // TODO - ought to set a flag saying that we're responsible
// for deleting ground in this instance, since normally we're not.
ground->Init();
}
} else { } else {
//cout << "Unable to find airport details in FGAILocalTraffic::Init()\n"; //cout << "Unable to find airport details in FGAILocalTraffic::Init()\n";
} }
// Initialise the relevant FGGround
// This needs a complete overhaul soon - what happens if we have 2 AI planes at same airport - they don't both need a structure
// This needs to be handled by the ATC manager or similar so only one set of physical data per airport is instantiated
// ie. TODO TODO FIXME FIXME
airport.Init();
// Get the airport elevation // Get the airport elevation
aptElev = dclGetAirportElev(airportID.c_str()) * SG_FEET_TO_METER; aptElev = dclGetAirportElev(airportID.c_str()) * SG_FEET_TO_METER;
//cout << "Airport elev in AILocalTraffic = " << aptElev << '\n'; //cout << "Airport elev in AILocalTraffic = " << aptElev << '\n';
@ -187,7 +203,7 @@ bool FGAILocalTraffic::Init(string ICAO, OperatingState initialState, PatternLeg
operatingState = initialState; operatingState = initialState;
switch(operatingState) { switch(operatingState) {
case PARKED: case PARKED:
ourGate = airport.GetGateNode(); ourGate = ground->GetGateNode();
if(ourGate == NULL) { if(ourGate == NULL) {
// Implies no available gates - what shall we do? // Implies no available gates - what shall we do?
// For now just vanish the plane - possibly we can make this more elegant in the future // For now just vanish the plane - possibly we can make this more elegant in the future
@ -282,7 +298,7 @@ void FGAILocalTraffic::FlyCircuits(int numCircuits, bool tag) {
GetRwyDetails(); GetRwyDetails();
// Get the takeoff node for the active runway, get a path to it and start taxiing // Get the takeoff node for the active runway, get a path to it and start taxiing
path = airport.GetPath(ourGate, rwy.rwyID); path = ground->GetPath(ourGate, rwy.rwyID);
if(path.size() < 2) { if(path.size() < 2) {
// something has gone wrong // something has gone wrong
SG_LOG(SG_GENERAL, SG_ALERT, "Invalid path from gate to theshold in FGAILocalTraffic::FlyCircuits\n"); SG_LOG(SG_GENERAL, SG_ALERT, "Invalid path from gate to theshold in FGAILocalTraffic::FlyCircuits\n");
@ -694,7 +710,7 @@ void FGAILocalTraffic::TransmitPatternPositionReport(void) {
void FGAILocalTraffic::ExitRunway(Point3D orthopos) { void FGAILocalTraffic::ExitRunway(Point3D orthopos) {
//cout << "In ExitRunway" << endl; //cout << "In ExitRunway" << endl;
//cout << "Runway ID is " << rwy.ID << endl; //cout << "Runway ID is " << rwy.ID << endl;
node_array_type exitNodes = airport.GetExits(rwy.ID); //I suppose we ought to have some fallback for rwy with no defined exits? node_array_type exitNodes = ground->GetExits(rwy.ID); //I suppose we ought to have some fallback for rwy with no defined exits?
/* /*
cout << "Node ID's of exits are "; cout << "Node ID's of exits are ";
for(unsigned int i=0; i<exitNodes.size(); ++i) { for(unsigned int i=0; i<exitNodes.size(); ++i) {
@ -725,7 +741,7 @@ void FGAILocalTraffic::ExitRunway(Point3D orthopos) {
} }
++nItr; ++nItr;
} }
ourGate = airport.GetGateNode(); ourGate = ground->GetGateNode();
if(ourGate == NULL) { if(ourGate == NULL) {
// Implies no available gates - what shall we do? // Implies no available gates - what shall we do?
// For now just vanish the plane - possibly we can make this more elegant in the future // For now just vanish the plane - possibly we can make this more elegant in the future
@ -734,7 +750,7 @@ void FGAILocalTraffic::ExitRunway(Point3D orthopos) {
operatingState = PARKED; operatingState = PARKED;
return; return;
} }
path = airport.GetPath(rwyExit, ourGate); path = ground->GetPath(rwyExit, ourGate);
/* /*
cout << "path returned was:" << endl; cout << "path returned was:" << endl;
for(unsigned int i=0; i<path.size(); ++i) { for(unsigned int i=0; i<path.size(); ++i) {

View file

@ -105,6 +105,9 @@ protected:
void ReturnToBase(double dt); void ReturnToBase(double dt);
private: private:
FGATCMgr* ATC;
// This is purely for synactic convienience to avoid writing globals->get_ATC_mgr()-> all through the code!
// High-level stuff // High-level stuff
OperatingState operatingState; OperatingState operatingState;
int circuitsToFly; //Number of circuits still to do in this session NOT INCLUDING THE CURRENT ONE int circuitsToFly; //Number of circuits still to do in this session NOT INCLUDING THE CURRENT ONE
@ -117,7 +120,7 @@ private:
// Airport/runway/pattern details // Airport/runway/pattern details
string airportID; // The ICAO code of the airport that we're operating around string airportID; // The ICAO code of the airport that we're operating around
double aptElev; // Airport elevation double aptElev; // Airport elevation
FGGround airport; // FIXME FIXME FIXME This is a complete hardwired cop-out at the moment - we need to connect to the correct ground in the same way we do to the tower. FGGround* ground; // A pointer to the ground control.
FGTower* tower; // A pointer to the tower control. FGTower* tower; // A pointer to the tower control.
RunwayDetails rwy; RunwayDetails rwy;
double patternDirection; // 1 for right, -1 for left (This is double because we multiply/divide turn rates double patternDirection; // 1 for right, -1 for left (This is double because we multiply/divide turn rates

View file

@ -19,26 +19,110 @@
// along with this program; if not, write to the Free Software // along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include <Airports/simple.hxx>
#include <Main/fgfs.hxx> #include <Main/fgfs.hxx>
#include <Main/fg_props.hxx> #include <Main/fg_props.hxx>
#include <Main/globals.hxx>
#include <Simgear/misc/sg_path.hxx>
#include <Simgear/bucket/newbucket.hxx>
#include <list> #include <list>
#ifdef _MSC_VER
# include <io.h>
#else
# include <sys/types.h> // for directory reading
# include <dirent.h> // for directory reading
#endif
#include "AIMgr.hxx" #include "AIMgr.hxx"
#include "AILocalTraffic.hxx" #include "AILocalTraffic.hxx"
#include "ATCutils.hxx"
SG_USING_STD(list); SG_USING_STD(list);
FGAIMgr::FGAIMgr() { FGAIMgr::FGAIMgr() {
ATC = globals->get_ATC_mgr();
} }
FGAIMgr::~FGAIMgr() { FGAIMgr::~FGAIMgr() {
} }
void FGAIMgr::init() { void FGAIMgr::init() {
// go through the $FG_ROOT/ATC directory and find all *.taxi files
SGPath path(globals->get_fg_root());
path.append("ATC/");
string dir = path.dir();
string ext;
string file, f_ident;
int pos;
// WARNING - I (DCL) haven't tested this on MSVC - this is simply cribbed from TerraGear
#ifdef _MSC_VER
long hfile;
struct _finddata_t de;
string path_str;
path_str = dir + "\\*.*";
if ( ( hfile = _findfirst( path.c_str(), &de ) ) == -1 ) {
cout << "cannot open directory " << dir << "\n";
} else {
// load all .taxi files
do {
file = de.name;
pos = file.find(".");
ext = file.substr(pos + 1);
if(ext == "taxi") {
cout << "TAXI FILE FOUND!!!\n";
f_ident = file.substr(0, pos);
FGAirport a;
if(dclFindAirportID(f_ident, &a)) {
SGBucket sgb(a.longitude, a.latitude);
int idx = sgb.gen_index();
airports[idx] = f_ident;
cout << "Mapping " << f_ident << " to bucket " << idx << '\n';
}
}
} while ( _findnext( hfile, &de ) == 0 );
}
#else
DIR *d;
struct dirent *de;
if ( (d = opendir( dir.c_str() )) == NULL ) {
cout << "cannot open directory " << dir << "\n";
} else {
cout << "Opened directory " << dir << " OK :-)\n";
cout << "Contents are:\n";
// load all .taxi files
while ( (de = readdir(d)) != NULL ) {
file = de->d_name;
pos = file.find(".");
cout << file << '\n';
ext = file.substr(pos + 1);
if(ext == "taxi") {
cout << "TAXI FILE FOUND!!!\n";
f_ident = file.substr(0, pos);
FGAirport a;
if(dclFindAirportID(f_ident, &a)) {
SGBucket sgb(a.longitude, a.latitude);
int idx = sgb.gen_index();
airports[idx] = f_ident;
cout << "Mapping " << f_ident << " to bucket " << idx << '\n';
}
}
}
closedir(d);
}
#endif
// Hard wire some local traffic for now. // Hard wire some local traffic for now.
// This is regardless of location and hence *very* ugly but it is a start. // This is regardless of location and hence *very* ugly but it is a start.
ATC->AIRegisterAirport("KEMT");
FGAILocalTraffic* local_traffic = new FGAILocalTraffic; FGAILocalTraffic* local_traffic = new FGAILocalTraffic;
//local_traffic->Init("KEMT", IN_PATTERN, TAKEOFF_ROLL); //local_traffic->Init("KEMT", IN_PATTERN, TAKEOFF_ROLL);
local_traffic->Init("KEMT"); local_traffic->Init("KEMT");

View file

@ -27,14 +27,18 @@
#include <list> #include <list>
#include "ATCMgr.hxx"
#include "AIEntity.hxx" #include "AIEntity.hxx"
SG_USING_STD(list); SG_USING_STD(list);
class FGAIMgr : public FGSubsystem class FGAIMgr : public FGSubsystem
{ {
private: private:
FGATCMgr* ATC;
// This is purely for synactic convienience to avoid writing globals->get_ATC_mgr()-> all through the code!
// A list of pointers to all currently active AI stuff // A list of pointers to all currently active AI stuff
typedef list <FGAIEntity*> ai_list_type; typedef list <FGAIEntity*> ai_list_type;
@ -48,6 +52,11 @@ private:
// Any member function of FGATCMgr is permitted to leave this iterator pointing // Any member function of FGATCMgr is permitted to leave this iterator pointing
// at any point in or at the end of the list. // 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. // Hence any new access must explicitly first check for atc_list.end() before dereferencing.
// A map of airport-IDs that have taxiway network files against bucket number
typedef map < int, string > ai_apt_map_type;
typedef ai_apt_map_type::iterator ai_apt_map_iterator;
ai_apt_map_type airports;
// Position of the Users Aircraft // Position of the Users Aircraft
// (This may be needed to calculate the distance from the user when deciding which 3D model to render) // (This may be needed to calculate the distance from the user when deciding which 3D model to render)

View file

@ -22,6 +22,7 @@
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include <Airports/simple.hxx>
#include "ATCmgr.hxx" #include "ATCmgr.hxx"
#include "commlist.hxx" #include "commlist.hxx"
@ -31,6 +32,7 @@
//#include "approachlist.hxx" //#include "approachlist.hxx"
#include "ATCdisplay.hxx" #include "ATCdisplay.hxx"
#include "ATCDialog.hxx" #include "ATCDialog.hxx"
#include "ATCutils.hxx"
/* /*
// periodic radio station search wrapper // periodic radio station search wrapper
@ -50,6 +52,7 @@ AirportATC::AirportATC() :
ground_freq(0.0), ground_freq(0.0),
ground_active(false), ground_active(false),
set_by_AI(false), set_by_AI(false),
numAI(0),
set_by_comm_search(false) { set_by_comm_search(false) {
} }
@ -83,6 +86,7 @@ void FGATCMgr::init() {
lat_node = fgGetNode("/position/latitude-deg", true); lat_node = fgGetNode("/position/latitude-deg", true);
elev_node = fgGetNode("/position/altitude-ft", true); elev_node = fgGetNode("/position/altitude-ft", true);
atc_list_itr = atc_list.begin(); atc_list_itr = atc_list.begin();
// Search for connected ATC stations once per 0.8 seconds or so // Search for connected ATC stations once per 0.8 seconds or so
// global_events.Register( "fgATCSearch()", fgATCSearch, // global_events.Register( "fgATCSearch()", fgATCSearch,
// fgEVENT::FG_EVENT_READY, 800); // fgEVENT::FG_EVENT_READY, 800);
@ -92,23 +96,6 @@ void FGATCMgr::init() {
current_commlist = new FGCommList; current_commlist = new FGCommList;
SGPath p_comm( globals->get_fg_root() ); SGPath p_comm( globals->get_fg_root() );
current_commlist->init( p_comm ); current_commlist->init( p_comm );
// Initialise the airport_atc_map - we'll cheat for now and just hardcode KEMT and any others that may be needed for development
AirportATC *a = new AirportATC;
a->lon = -118.034719;
a->lat = 34.086114;
a->elev = 296.0;
a->atis_freq = 118.75;
a->atis_active = false;
a->tower_freq = 121.2;
a->tower_active = false;
a->ground_freq = 125.9;
a->ground_active = false;
//a->set_by_AI = true;
//a->set_by_comm_search = false;
airport_atc_map[(string)"KEMT"] = a;
#ifdef ENABLE_AUDIO_SUPPORT #ifdef ENABLE_AUDIO_SUPPORT
// Load all available voices. // Load all available voices.
@ -191,6 +178,53 @@ void FGATCMgr::update(double dt) {
//cout << "comm1 type = " << comm_type[0] << '\n'; //cout << "comm1 type = " << comm_type[0] << '\n';
} }
// Returns frequency in KHz - should I alter this to return in MHz?
unsigned short int FGATCMgr::GetFrequency(string ident, atc_type tp) {
ATCData test;
bool ok = current_commlist->FindByCode(ident, test, tp);
return(ok ? test.freq : 0);
}
// Register the fact that the AI system wants to activate an airport
// Might need more sophistication in this in the future - eg registration by aircraft call-sign.
bool FGATCMgr::AIRegisterAirport(string ident) {
if(airport_atc_map.find(ident) != airport_atc_map.end()) {
airport_atc_map[ident]->set_by_AI = true;
return(true);
} else {
FGAirport ap;
if(dclFindAirportID(ident, &ap)) {
AirportATC *a = new AirportATC;
// I'm not entirely sure that this AirportATC structure business is actually needed - it just duplicates what we can find out anyway!
a->lon = ap.longitude;
a->lat = ap.latitude;
a->elev = ap.elevation;
a->atis_freq = GetFrequency(ident, ATIS);
a->atis_active = false;
a->tower_freq = GetFrequency(ident, TOWER);
a->tower_active = false;
a->ground_freq = GetFrequency(ident, GROUND);
a->ground_active = false;
// TODO - some airports will have a tower/ground frequency but be inactive overnight.
a->set_by_AI = true;
a->numAI++;
airport_atc_map[ident] = a;
return(true);
}
}
return(false);
}
// Register the fact that the comm radio is tuned to an airport
bool FGATCMgr::CommRegisterAirport(string ident) { // Later we'll differentiate between comm 1 and comm2
// TODO - implement me!
return(false);
}
// Remove from list only if not needed by the AI system or the other comm channel // Remove from list only if not needed by the AI system or the other comm channel
// TODO - implement me!! // TODO - implement me!!
void FGATCMgr::CommRemoveFromList(const char* id, atc_type tp, int chan) { void FGATCMgr::CommRemoveFromList(const char* id, atc_type tp, int chan) {
@ -263,10 +297,11 @@ bool FGATCMgr::GetAirportATCDetails(string icao, AirportATC* a) {
// Return a pointer to a given sort of ATC at a given airport and activate if necessary // Return a pointer to a given sort of ATC at a given airport and activate if necessary
// ONLY CALL THIS FUNCTION AFTER FIRST CHECKING THE SERVICE EXISTS BY CALLING GetAirportATCDetails // Returns NULL if service doesn't exist - calling function should check for this.
// FIXME - we really ought to take out the necessity for two function calls by simply returning
// a NULL pointer if the service doesn't exist and requiring the caller to check for it (NULL).
FGATC* FGATCMgr::GetATCPointer(string icao, atc_type type) { FGATC* FGATCMgr::GetATCPointer(string icao, atc_type type) {
if(airport_atc_map.find(icao) == airport_atc_map.end()) {
return NULL;
}
AirportATC *a = airport_atc_map[icao]; AirportATC *a = airport_atc_map[icao];
//cout << "a->lon = " << a->lon << '\n'; //cout << "a->lon = " << a->lon << '\n';
//cout << "a->elev = " << a->elev << '\n'; //cout << "a->elev = " << a->elev << '\n';
@ -275,28 +310,45 @@ FGATC* FGATCMgr::GetATCPointer(string icao, atc_type type) {
case TOWER: case TOWER:
if(a->tower_active) { if(a->tower_active) {
// Get the pointer from the list // Get the pointer from the list
return(FindInList(icao.c_str(), type)); // DCL - this untested so far. return(FindInList(icao.c_str(), type));
} else { } else {
FGTower* t = new FGTower;
ATCData data; ATCData data;
if(current_commlist->FindByFreq(a->lon, a->lat, a->elev, a->tower_freq, &data, TOWER)) { if(current_commlist->FindByFreq(a->lon, a->lat, a->elev, a->tower_freq, &data, TOWER)) {
FGTower* t = new FGTower;
t->SetData(&data); t->SetData(&data);
atc_list.push_back(t); atc_list.push_back(t);
a->tower_active = true; a->tower_active = true;
airport_atc_map[icao] = a; airport_atc_map[icao] = a;
t->Init();
return(t); return(t);
} else { } else {
cout << "ERROR - tower that should exist in FGATCMgr::GetATCPointer for airport " << icao << " not found\n"; cout << "ERROR - tower that should exist in FGATCMgr::GetATCPointer for airport " << icao << " not found\n";
} }
} }
break; break;
// Lets add the rest to get rid of the compiler warnings even though we don't need them yet.
case APPROACH: case APPROACH:
break; break;
case ATIS: case ATIS:
SG_LOG(SG_GENERAL, SG_ALERT, "ERROR - ATIS station should not be requested from FGATCMgr::GetATCPointer"); SG_LOG(SG_GENERAL, SG_ALERT, "ERROR - ATIS station should not be requested from FGATCMgr::GetATCPointer");
break; break;
case GROUND: case GROUND:
if(a->ground_active) {
// Get the pointer from the list
return(FindInList(icao.c_str(), type));
} else {
ATCData data;
if(current_commlist->FindByFreq(a->lon, a->lat, a->elev, a->ground_freq, &data, GROUND)) {
FGGround* g = new FGGround;
g->SetData(&data);
atc_list.push_back(g);
a->ground_active = true;
airport_atc_map[icao] = a;
g->Init();
return(g);
} else {
cout << "ERROR - ground control that should exist in FGATCMgr::GetATCPointer for airport " << icao << " not found\n";
}
}
break; break;
case INVALID: case INVALID:
break; break;

View file

@ -62,10 +62,13 @@ struct AirportATC {
//bool approach_active; //bool approach_active;
//float departure_freq; //float departure_freq;
//bool departure_active; //bool departure_active;
// NOTE - the *_active flags determine whether the service is active in atc_list,
// *NOT* whether the tower etc is closed or not!!!!
// Flags to ensure the stations don't get wrongly deactivated // Flags to ensure the stations don't get wrongly deactivated
bool set_by_AI; // true when the AI manager has activated this station bool set_by_AI; // true when the AI manager has activated this station
// Do we need to ref-count the number of AI planes setting this? unsigned int numAI; // Ref count of the number of AI planes registered
bool set_by_comm_search; // true when the comm_search has activated this station bool set_by_comm_search; // true when the comm_search has activated this station
// Do we need to distingiush comm1 and comm2? // Do we need to distingiush comm1 and comm2?
}; };
@ -159,6 +162,7 @@ public:
bool GetAirportATCDetails(string icao, AirportATC* a); bool GetAirportATCDetails(string icao, AirportATC* a);
// Return a pointer to a given sort of ATC at a given airport and activate if necessary // Return a pointer to a given sort of ATC at a given airport and activate if necessary
// Returns NULL if service doesn't exist - calling function should check for this.
FGATC* GetATCPointer(string icao, atc_type type); FGATC* GetATCPointer(string icao, atc_type type);
// Display a dialog box with options relevant to the currently tuned ATC service. // Display a dialog box with options relevant to the currently tuned ATC service.
@ -178,6 +182,16 @@ public:
atc_type GetComm2ATCType() { return(comm_type[1]); } atc_type GetComm2ATCType() { return(comm_type[1]); }
FGATC* GetComm2ATCPointer() { return(comm_atc_ptr[1]); } FGATC* GetComm2ATCPointer() { return(comm_atc_ptr[1]); }
// Get the frequency of a given service at a given airport
// Returns zero if not found
unsigned short int GetFrequency(string ident, atc_type tp);
// Register the fact that the AI system wants to activate an airport
bool AIRegisterAirport(string ident);
// Register the fact that the comm radio is tuned to an airport
bool CommRegisterAirport(string ident); // Later we'll differentiate between comm 1 and comm2
private: private:
// Remove a class from the atc_list and delete it from memory // Remove a class from the atc_list and delete it from memory

View file

@ -120,7 +120,14 @@ bool FGCommList::FindByFreq( double lon, double lat, double elev, double freq,
lon *= SGD_DEGREES_TO_RADIANS; lon *= SGD_DEGREES_TO_RADIANS;
lat *= SGD_DEGREES_TO_RADIANS; lat *= SGD_DEGREES_TO_RADIANS;
comm_list_type stations = commlist_freq[(int)(freq*100.0 + 0.5)]; // HACK - if freq > 1000 assume it's in KHz, otherwise assume MHz.
// A bit ugly but it works for now!!!!
comm_list_type stations;
if(freq > 1000.0) {
stations = commlist_freq[(int)freq];
} else {
stations = commlist_freq[(int)(freq*100.0 + 0.5)];
}
comm_list_iterator current = stations.begin(); comm_list_iterator current = stations.begin();
comm_list_iterator last = stations.end(); comm_list_iterator last = stations.end();

View file

@ -53,6 +53,12 @@ FGGround::FGGround() {
networkLoadOK = false; networkLoadOK = false;
} }
FGGround::FGGround(string id) {
display = false;
networkLoadOK = false;
ident = id;
}
FGGround::~FGGround() { FGGround::~FGGround() {
} }

View file

@ -208,6 +208,7 @@ class FGGround : public FGATC {
public: public:
FGGround(); FGGround();
FGGround(string id);
~FGGround(); ~FGGround();
void Init(); void Init();