]> git.mxchange.org Git - flightgear.git/commitdiff
Start roughing in interactive tower control. AI planes now get the ground control...
authordaveluff <daveluff>
Mon, 10 Mar 2003 13:41:37 +0000 (13:41 +0000)
committerdaveluff <daveluff>
Mon, 10 Mar 2003 13:41:37 +0000 (13:41 +0000)
src/ATC/AILocalTraffic.cxx
src/ATC/tower.cxx
src/ATC/tower.hxx

index 8404f32373f529c11553e539fd7e1fda334f3956..fe52749c9fd648e17f20a6479432a53b5267caf1 100644 (file)
@@ -169,25 +169,14 @@ bool FGAILocalTraffic::Init(string ICAO, OperatingState initialState, PatternLeg
                                return(false);
                        }
                        freq = (double)tower->get_freq() / 100.0;
-               } else {
-                       // Check CTAF, unicom etc
-               }
-               if(a.ground_freq) {             // Ground control
-                       ground = (FGGround*)ATC->GetATCPointer((string)airportID, GROUND);      // Maybe need some error checking here
+                       ground = tower->GetGroundPtr();
                        if(ground == NULL) {
                                // 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);
                        }
-                       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();
+                       // Check CTAF, unicom etc
                }
        } else {
                //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 
        // might fall down with very slopey airports.
 
-       //cout << "In Init(), initialState = " << initialState << '\n';
+       //cout << "In Init(), initialState = " << initialState << endl;
        operatingState = initialState;
        switch(operatingState) {
        case PARKED:
index 5f6920f70bfeac57475aec240f24e91a20a2a1b9..ee78286149a18211a9094508f93fd6883f40705b 100644 (file)
@@ -76,13 +76,55 @@ finalAcknowledged(false)
 // FGTower
 
 FGTower::FGTower() {
+       ATCmgr = globals->get_ATC_mgr();
 }
 
 FGTower::~FGTower() {
+       if(!separateGround) {
+               delete ground;
+       }
 }
 
 void FGTower::Init() {
     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() {
@@ -94,14 +136,58 @@ void FGTower::Update() {
     // We need to check for planes not under our control coming within our 
     // control area and address if necessary.
 
-    // Hardwired for testing
-    static int play = 0;
-    if(play == 200) {
-       //cout << "Registering message in tower.cxx ****************************\n";
-       //globals->get_ATC_display()->RegisterSingleMessage((string)"Cessna eight-two-zero Cleared for takeoff", 2);
-    }
-    ++play;
+       // TODO - a lot of the below probably doesn't need to be called every frame and should be staggered.
+       
+       // Sort the arriving planes
+
+       // 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();
+               }
+               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) {
        cout << "Request Landing Clearance called...\n";
index cd4b1e46a3f2f8ad92ba47a0a843d2ffc1b1b686..430604e8f5cfec5aac035c85efc618df404de13e 100644 (file)
@@ -40,6 +40,14 @@ SG_USING_STD(ios);
 //DCL - a complete guess for now.
 #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.
 // Not fixed yet - may include more stuff later.
 class TowerPlaneRec {
@@ -64,8 +72,12 @@ class TowerPlaneRec {
        bool finalAcknowledged;
        bool onRwy;
        // 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 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;
@@ -73,7 +85,7 @@ typedef tower_plane_rec_list_type::const_iterator tower_plane_rec_list_const_ite
 
 class FGTower : public FGATC {
 
-       public:
+public:
        
        FGTower();
        ~FGTower();
@@ -92,20 +104,27 @@ class FGTower : public FGATC {
        void ReportGoingAround(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 SetNoDisplay() {display = false;}
        
        inline string get_trans_ident() { return trans_ident; }
        inline atc_type GetType() { return TOWER; }
        
-       // Make a request of tower control
-       //void Request(tower_request request);
+       inline FGGround* GetGroundPtr() {return ground; }
+
+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();
        
-       private:
+       void doCommunication();
        
        void IssueLandingClearance(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 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
        // or possibly another data structure with the positions of the inactive planes.
        // Need a data structure to hold outstanding communications from aircraft.
-       
+/*     
        // Linked-list of planes on approach ordered with nearest first (timewise).
        // Includes planes that have landed but not yet vacated runway.
        // 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
        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.
        // 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.
        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