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:
parent
1154a0dae2
commit
96970dcbaf
9 changed files with 232 additions and 40 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -49,6 +53,11 @@ private:
|
||||||
// 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)
|
||||||
double current_lon;
|
double current_lon;
|
||||||
|
|
|
@ -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);
|
||||||
|
@ -93,23 +97,6 @@ void FGATCMgr::init() {
|
||||||
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.
|
||||||
// For now we'll do one hardwired one
|
// For now we'll do one hardwired one
|
||||||
|
@ -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;
|
||||||
|
|
|
@ -63,9 +63,12 @@ struct AirportATC {
|
||||||
//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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,12 @@ FGGround::FGGround() {
|
||||||
networkLoadOK = false;
|
networkLoadOK = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FGGround::FGGround(string id) {
|
||||||
|
display = false;
|
||||||
|
networkLoadOK = false;
|
||||||
|
ident = id;
|
||||||
|
}
|
||||||
|
|
||||||
FGGround::~FGGround() {
|
FGGround::~FGGround() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -208,6 +208,7 @@ class FGGround : public FGATC {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FGGround();
|
FGGround();
|
||||||
|
FGGround(string id);
|
||||||
~FGGround();
|
~FGGround();
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue