1
0
Fork 0

Start roughing in interactive tower control. AI planes now get the ground control pointer through tower control, which then handles the difference between larger airports with separate ground and smaller ones where tower handles it

This commit is contained in:
daveluff 2003-03-10 13:41:37 +00:00
parent 3a2495e47a
commit aabe4da5ca
3 changed files with 132 additions and 32 deletions

View file

@ -169,25 +169,14 @@ bool FGAILocalTraffic::Init(string ICAO, OperatingState initialState, PatternLeg
return(false); return(false);
} }
freq = (double)tower->get_freq() / 100.0; freq = (double)tower->get_freq() / 100.0;
} else { ground = tower->GetGroundPtr();
// 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) { if(ground == NULL) {
// Something has gone wrong :-( // Something has gone wrong :-(
cout << "ERROR - ground has frequency but can't get ground pointer :-(\n"; cout << "ERROR - can't get a ground pointer from tower control in FGAILocalTraffic::Init() :-(\n";
return(false); return(false);
} }
freq = (double)tower->get_freq() / 100.0;
} else { } else {
// Initialise ground anyway to do the shortest path stuff! // Check CTAF, unicom etc
// 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";
@ -199,7 +188,7 @@ bool FGAILocalTraffic::Init(string ICAO, OperatingState initialState, PatternLeg
// WARNING - we use this elev for the whole airport - some assumptions in the code // WARNING - we use this elev for the whole airport - some assumptions in the code
// might fall down with very slopey airports. // might fall down with very slopey airports.
//cout << "In Init(), initialState = " << initialState << '\n'; //cout << "In Init(), initialState = " << initialState << endl;
operatingState = initialState; operatingState = initialState;
switch(operatingState) { switch(operatingState) {
case PARKED: case PARKED:

View file

@ -76,13 +76,55 @@ finalAcknowledged(false)
// FGTower // FGTower
FGTower::FGTower() { FGTower::FGTower() {
ATCmgr = globals->get_ATC_mgr();
} }
FGTower::~FGTower() { FGTower::~FGTower() {
if(!separateGround) {
delete ground;
}
} }
void FGTower::Init() { void FGTower::Init() {
display = false; display = false;
// Need some way to initialise rwyOccupied flag correctly if the user is on the runway and to know its the user.
// I'll punt the startup issue for now though!!!
rwyOccupied = false;
// Setup the ground control at this airport
AirportATC a;
if(ATCmgr->GetAirportATCDetails(ident, &a)) {
if(a.ground_freq) { // Ground control
ground = (FGGround*)ATCmgr->GetATCPointer(ident, GROUND);
separateGround = true;
if(ground == NULL) {
// Something has gone wrong :-(
cout << "ERROR - ground has frequency but can't get ground pointer :-(\n";
ground = new FGGround(ident);
separateGround = false;
ground->Init();
if(display) {
ground->SetDisplay();
} else {
ground->SetNoDisplay();
}
}
} else {
// Initialise ground anyway to do the shortest path stuff!
// Note that we're now responsible for updating and deleting this - NOT the ATCMgr.
ground = new FGGround(ident);
separateGround = false;
ground->Init();
if(display) {
ground->SetDisplay();
} else {
ground->SetNoDisplay();
}
}
} else {
//cout << "Unable to find airport details in FGTower::Init()\n";
}
} }
void FGTower::Update() { void FGTower::Update() {
@ -94,14 +136,58 @@ void FGTower::Update() {
// We need to check for planes not under our control coming within our // We need to check for planes not under our control coming within our
// control area and address if necessary. // control area and address if necessary.
// Hardwired for testing // TODO - a lot of the below probably doesn't need to be called every frame and should be staggered.
static int play = 0;
if(play == 200) { // Sort the arriving planes
//cout << "Registering message in tower.cxx ****************************\n";
//globals->get_ATC_display()->RegisterSingleMessage((string)"Cessna eight-two-zero Cleared for takeoff", 2); // Calculate the eta of each plane to the threshold.
// For ground traffic this is the fastest they can get there.
// For air traffic this is the middle approximation.
doThresholdETACalc();
// Order the list of traffic as per expected threshold use and flag any conflicts
bool conflicts = doThresholdUseOrder();
// sortConficts() !!!
doCommunication();
if(!separateGround) {
// The display stuff might have to get more clever than this when not separate
// since the tower and ground might try communicating simultaneously even though
// they're mean't to be the same contoller/frequency!!
if(display) {
ground->SetDisplay();
} else {
ground->SetNoDisplay();
} }
++play; ground->Update();
} }
}
// Calculate the eta of each plane to the threshold.
// For ground traffic this is the fastest they can get there.
// For air traffic this is the middle approximation.
void FGTower::doThresholdETACalc() {
// For now we'll be very crude and hardwire expected speeds to C172-like values
double app_ias = 100.0; // Speed during straight-in approach
double circuit_ias = 80.0; // Speed around circuit
double final_ias = 70.0; // Speed during final approach
tower_plane_rec_list_iterator twrItr;
for(twrItr = trafficList.begin(); twrItr != trafficList.end(); twrItr++) {
}
}
bool FGTower::doThresholdUseOrder() {
return(true);
}
void FGTower::doCommunication() {
}
void FGTower::RequestLandingClearance(string ID) { void FGTower::RequestLandingClearance(string ID) {
cout << "Request Landing Clearance called...\n"; cout << "Request Landing Clearance called...\n";

View file

@ -40,6 +40,14 @@ SG_USING_STD(ios);
//DCL - a complete guess for now. //DCL - a complete guess for now.
#define FG_TOWER_DEFAULT_RANGE 30 #define FG_TOWER_DEFAULT_RANGE 30
enum tower_traffic_type {
CIRCUIT,
INBOUND,
OUTBOUND,
STRAIGHT_IN
// Umm - what's the difference between INBOUND and STRAIGHT_IN ?
};
// Structure for holding details of a plane under tower control. // Structure for holding details of a plane under tower control.
// Not fixed yet - may include more stuff later. // Not fixed yet - may include more stuff later.
class TowerPlaneRec { class TowerPlaneRec {
@ -64,8 +72,12 @@ class TowerPlaneRec {
bool finalAcknowledged; bool finalAcknowledged;
bool onRwy; bool onRwy;
// enum type - light, medium, heavy etc - we need someway of approximating the aircraft type and performance. // enum type - light, medium, heavy etc - we need someway of approximating the aircraft type and performance.
// Type of operation the plane is doing
tower_traffic_type opType;
}; };
typedef list < TowerPlaneRec* > tower_plane_rec_list_type; typedef list < TowerPlaneRec* > tower_plane_rec_list_type;
typedef tower_plane_rec_list_type::iterator tower_plane_rec_list_iterator; typedef tower_plane_rec_list_type::iterator tower_plane_rec_list_iterator;
typedef tower_plane_rec_list_type::const_iterator tower_plane_rec_list_const_iterator; typedef tower_plane_rec_list_type::const_iterator tower_plane_rec_list_const_iterator;
@ -92,20 +104,27 @@ class FGTower : public FGATC {
void ReportGoingAround(string ID); void ReportGoingAround(string ID);
void ReportRunwayVacated(string ID); void ReportRunwayVacated(string ID);
// Parse a literal message to decide which of above it represents.
// (a long term project that eventually will hopefully receive the output from voice recognition software.)
void LiteralTransmission(string trns, string ID);
inline void SetDisplay() {display = true;} inline void SetDisplay() {display = true;}
inline void SetNoDisplay() {display = false;} inline void SetNoDisplay() {display = false;}
inline string get_trans_ident() { return trans_ident; } inline string get_trans_ident() { return trans_ident; }
inline atc_type GetType() { return TOWER; } inline atc_type GetType() { return TOWER; }
// Make a request of tower control inline FGGround* GetGroundPtr() {return ground; }
//void Request(tower_request request);
private: private:
FGATCMgr* ATCmgr;
// This is purely for synactic convienience to avoid writing globals->get_ATC_mgr()-> all through the code!
// Calculate the eta of each plane to the threshold.
// For ground traffic this is the fastest they can get there.
// For air traffic this is the middle approximation.
void doThresholdETACalc();
// Order the list of traffic as per expected threshold use and flag any conflicts
bool doThresholdUseOrder();
void doCommunication();
void IssueLandingClearance(TowerPlaneRec* tpr); void IssueLandingClearance(TowerPlaneRec* tpr);
void IssueGoAround(TowerPlaneRec* tpr); void IssueGoAround(TowerPlaneRec* tpr);
@ -114,10 +133,12 @@ class FGTower : public FGATC {
bool display; // Flag to indicate whether we should be outputting to the ATC display. bool display; // Flag to indicate whether we should be outputting to the ATC display.
bool displaying; // Flag to indicate whether we are outputting to the ATC display. bool displaying; // Flag to indicate whether we are outputting to the ATC display.
bool rwyOccupied; // Active runway occupied flag. For now we'll disregard multiple runway and land-and-hold-short operations
// Need a data structure to hold details of the various active planes // Need a data structure to hold details of the various active planes
// or possibly another data structure with the positions of the inactive planes. // or possibly another data structure with the positions of the inactive planes.
// Need a data structure to hold outstanding communications from aircraft. // Need a data structure to hold outstanding communications from aircraft.
/*
// Linked-list of planes on approach ordered with nearest first (timewise). // Linked-list of planes on approach ordered with nearest first (timewise).
// Includes planes that have landed but not yet vacated runway. // Includes planes that have landed but not yet vacated runway.
// Somewhat analagous to the paper strips used (used to be used?) in real life. // Somewhat analagous to the paper strips used (used to be used?) in real life.
@ -131,12 +152,16 @@ class FGTower : public FGATC {
// List of planes on rwy // List of planes on rwy
tower_plane_rec_list_type rwyList; tower_plane_rec_list_type rwyList;
*/
// Linked list of all planes due to use a given rwy arranged in projected order of rwy use
tower_plane_rec_list_type trafficList; // TODO - needs to be expandable to more than one rwy
// Ground can be separate or handled by tower in real life. // Ground can be separate or handled by tower in real life.
// In the program we will always use a separate FGGround class, but we need to know // In the program we will always use a separate FGGround class, but we need to know
// whether it is supposed to be separate or not to give the correct instructions. // whether it is supposed to be separate or not to give the correct instructions.
bool separateGround; // true if ground control is separate bool separateGround; // true if ground control is separate
FGGround* groundPtr; // The ground control associated with this airport. FGGround* ground; // The ground control associated with this airport.
// for failure modeling // for failure modeling