]> git.mxchange.org Git - flightgear.git/commitdiff
Start adding a better framework for ATC-initiated communication. There should be...
authordaveluff <daveluff>
Wed, 10 Mar 2004 16:01:17 +0000 (16:01 +0000)
committerdaveluff <daveluff>
Wed, 10 Mar 2004 16:01:17 +0000 (16:01 +0000)
src/ATC/ATC.cxx
src/ATC/ATC.hxx
src/ATC/approach.cxx
src/ATC/approach.hxx
src/ATC/atis.cxx
src/ATC/atis.hxx
src/ATC/ground.cxx
src/ATC/ground.hxx
src/ATC/tower.cxx
src/ATC/tower.hxx

index 085d84166b7523e8fb14c99575a91cdc43e9b351..d76ba74cf2ca9294508904708331653c847f9068 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <simgear/sound/soundmgr.hxx>
 
+#include <Main/globals.hxx>
 #include <Main/fg_props.hxx>
 
 #include "ATC.hxx"
@@ -38,6 +39,18 @@ FGATC::FGATC() {
        responseID = "";
        responseReqd = false;
        _type = INVALID;
+       _display = false;
+       _displaying = false;
+       
+       // Transmission timing stuff
+       pending_transmission = "";
+       _timeout = 0;
+       _pending = false;
+       _callback_code = 0;
+       _transmit = false;
+       _transmitting = false;
+       _counter = 0.0;
+       _max_count = 5.0;
 }
 
 FGATC::~FGATC() {
@@ -64,6 +77,54 @@ void FGATC::Update(double dt) {
                        _releaseCounter += dt;
                }
        }
+       
+       // Transmission stuff cribbed from AIPlane.cxx
+       if(_pending) {
+               if(GetFreqClear()) {
+                       //cout << "TUNED STATION FREQ CLEAR\n";
+                       SetFreqInUse();
+                       _pending = false;
+                       _transmit = true;
+                       _transmitting = false;
+               } else {
+                       if(_timeout > 0.0) {    // allows count down to be avoided by initially setting it to zero
+                               _timeout -= dt;
+                               if(_timeout <= 0.0) {
+                                       _timeout = 0.0;
+                                       _pending = false;
+                                       // timed out - don't render.
+                               }
+                       }
+               }
+       }
+
+       if(_transmit) {
+               _counter = 0.0;
+               _max_count = 5.0;               // FIXME - hardwired length of message - need to calculate it!
+               
+               //cout << "Transmission = " << pending_transmission << '\n';
+               if(_display) {
+                       //Render(pending_transmission, ident, false);
+                       // At the moment Render only works for ATIS
+                       globals->get_ATC_display()->RegisterSingleMessage(pending_transmission);
+               }
+               // Run the callback regardless of whether on same freq as user or not.
+               //cout << "_callback_code = " << _callback_code << '\n';
+               if(_callback_code) {
+                       ProcessCallback(_callback_code);
+               }
+               _transmit = false;
+               _transmitting = true;
+       } else if(_transmitting) {
+               if(_counter >= _max_count) {
+                       //NoRender(plane.callsign);  commented out since at the moment NoRender is designed just to stop repeating messages,
+                       // and this will be primarily used on single messages.
+                       _transmitting = false;
+                       //if(tuned_station) tuned_station->NotifyTransmissionFinished(plane.callsign);
+                       // TODO - need to let the plane the transmission is aimed at that it's finished.
+               }
+               _counter += dt;
+       }
 }
 
 void FGATC::ReceiveUserCallback(int code) {
@@ -96,17 +157,41 @@ void FGATC::NotifyTransmissionFinished(string rid) {
        }
 }
 
-void FGATC::AddPlane(string pid) {
+void FGATC::Transmit(int callback_code) {
+       SG_LOG(SG_ATC, SG_INFO, "Transmit called by " << ident << " " << _type << ", msg = " << pending_transmission);
+       _pending = true;
+       _callback_code = callback_code;
+       _timeout = 0.0;
 }
 
-int FGATC::RemovePlane() {
-       return 0;
+void FGATC::ConditionalTransmit(double timeout, int callback_code) {
+       SG_LOG(SG_ATC, SG_INFO, "Timed transmit called by " << ident << " " << _type << ", msg = " << pending_transmission);
+       _pending = true;
+       _callback_code = callback_code;
+       _timeout = timeout;
+}
+
+void FGATC::ImmediateTransmit(int callback_code) {
+       SG_LOG(SG_ATC, SG_INFO, "Immediate transmit called by " << ident << " " << _type << ", msg = " << pending_transmission);
+       if(_display) {
+               //Render(pending_transmission, ident, false);
+               // At the moment Render doesn't work except for ATIS
+               globals->get_ATC_display()->RegisterSingleMessage(pending_transmission);
+       }
+       if(callback_code) {
+               ProcessCallback(callback_code);
+       }
 }
 
-void FGATC::SetDisplay() {
+// Derived classes should override this.
+void FGATC::ProcessCallback(int code) {
 }
 
-void FGATC::SetNoDisplay() {
+void FGATC::AddPlane(string pid) {
+}
+
+int FGATC::RemovePlane() {
+       return 0;
 }
 
 void FGATC::SetData(ATCData* d) {
index 0a06761a0c36968f211c87ee00af9109673b772f..1bbbd846e37d89b44050d55c3f2eda16e48bebd0 100644 (file)
@@ -123,10 +123,10 @@ public:
        virtual int RemovePlane();
        
        // Indicate that this instance should output to the display if appropriate 
-       virtual void SetDisplay();
+       inline void SetDisplay() { _display = true; }
        
        // Indicate that this instance should not output to the display
-       virtual void SetNoDisplay();
+       inline void SetNoDisplay() { _display = false; }
        
        // Generate the text of a message from its parameters and the current context.
        virtual string GenText(const string& m, int c);
@@ -186,6 +186,17 @@ protected:
        // Requires the sound manager refname if audio, else "".
        void NoRender(string refname);
        
+       // Transmit a message when channel becomes free of other dialog
+    void Transmit(int callback_code = 0);
+       
+       // Transmit a message if channel becomes free within timeout (seconds). timeout of zero implies no limit
+       void ConditionalTransmit(double timeout, int callback_code = 0);
+       
+       // Transmit regardless of other dialog on the channel eg emergency
+       void ImmediateTransmit(int callback_code = 0);
+       
+       virtual void ProcessCallback(int code);
+       
        double lon, lat, elev;
        double x, y, z;
        int freq;
@@ -199,7 +210,8 @@ protected:
        bool playing;           // Indicates a message in progress      
        bool voiceOK;           // Flag - true if at least one voice has loaded OK
        FGATCVoice* vPtr;
-       
+
+       string pending_transmission;    // derived classes set this string before calling Transmit(...) 
        bool freqClear;         // Flag to indicate if the frequency is clear of ongoing dialog
        bool receiving;         // Flag to indicate we are receiving a transmission
        bool responseReqd;      // Flag to indicate we should be responding to a request/report 
@@ -213,6 +225,20 @@ protected:
        bool _runReleaseCounter;        // A timer for releasing the frequency after giving the message enough time to display
        double _releaseTime;
        double _releaseCounter;
+       
+       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.
+       
+private:
+       // Transmission timing stuff.
+       bool _pending;
+       double _timeout;
+       int _callback_code;     // A callback code to be notified and processed by the derived classes
+                                               // A value of zero indicates no callback required
+       bool _transmit;         // we are to transmit
+       bool _transmitting;     // we are transmitting
+       double _counter;
+       double _max_count;
 };
 
 inline istream&
index 6d7a5a869ceeb90c81611964ae405eec65b336e3..c036a28274f7d33114860858bb990cfbd5d88f2e 100644 (file)
@@ -77,7 +77,6 @@ FGApproach::~FGApproach(){
 }
 
 void FGApproach::Init() {
-  display = false;
 }
 
 
index fb2d319244dd79599603042db4d52d3dca22ffdb..29d349060ab8c5da40a9ec63a71e56b19be8f690 100644 (file)
@@ -117,8 +117,6 @@ class FGApproach : public FGATC {
   double active_rw_lat;
   double active_rw_len;
 
-  bool     display;            // Flag to indicate whether we should be outputting to the display.
-  bool     displaying;         // Flag to indicate whether we are outputting to the display.
   int      num_planes;          // number of planes on the stack
   PlaneApp planes[max_planes];  // Array of planes
   string   transmission;
@@ -160,12 +158,6 @@ public:
   // Remove plane from stack if out of range
   int RemovePlane();
   
-  //Indicate that this instance should be outputting to the ATC display
-  inline void SetDisplay(void) {display = true;}
-  
-  //Indicate that this instance should not be outputting to the ATC display
-  inline void SetNoDisplay(void) {display = false;}
-  
   inline double get_bucket() const { return bucket; }
   inline int get_pnum() const { return num_planes; }
   inline string get_trans_ident() { return trans_ident; }
index 35bb25a2eec98c01872d4b82016f726416033803..ff0da5767891b196127945c178c05e77cad32625 100644 (file)
@@ -54,8 +54,6 @@ SG_USING_STD(cout);
 #include "ATCmgr.hxx"
 
 FGATIS::FGATIS() :
-       display(false),
-       displaying(false),
        transmission(""),
        trans_ident(""),
        atis_failed(false),
@@ -72,8 +70,8 @@ FGATIS::~FGATIS() {
 
 // Main update function - checks whether we are displaying or not the correct message.
 void FGATIS::Update(double dt) {
-       if(display) {
-               if(displaying) {
+       if(_display) {
+               if(_displaying) {
                        // Check if we need to update the message
                        // - basically every hour and if the weather changes significantly at the station
                        //globals->get_ATC_display()->ChangeRepeatingMessage(transmission);
@@ -82,14 +80,14 @@ void FGATIS::Update(double dt) {
                        UpdateTransmission();
                        //cout << "ATIS.CXX - calling ATCMgr to render transmission..." << endl;
                        Render(transmission, refname, true);
-                       displaying = true;
+                       _displaying = true;
                }
        } else {
                // We shouldn't be displaying
-               if(displaying) {
+               if(_displaying) {
                        //cout << "ATIS.CXX - calling NoRender()..." << endl;
                        NoRender(refname);
-                       displaying = false;
+                       _displaying = false;
                }
        }
 }
index 0d22b3efa229b59762e8a04e6daf901bac42f662..741e9943dd63c5950d0935887eab59b4ba0c04fb 100644 (file)
@@ -53,8 +53,6 @@ SG_USING_STD(string);
 class FGATIS : public FGATC {
        
        //atc_type type;
-       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.
        string transmission;    // The actual ATIS transmission
        // This is not stored in default.atis but is generated
        // from the prevailing conditions when required.
@@ -80,12 +78,6 @@ class FGATIS : public FGATC {
        //run the ATIS instance
        void Update(double dt);
        
-       //Indicate that this instance should be outputting to the ATC display
-       inline void SetDisplay(void) {display = true;}
-       
-       //Indicate that this instance should not be outputting to the ATC display
-       inline void SetNoDisplay(void) {display = false;}
-       
        //inline void set_type(const atc_type tp) {type = tp;}
        inline string get_trans_ident() { return trans_ident; }
        inline void set_refname(string r) { refname = r; } 
index 4685600354def2c440dbf55c2ee11ce2dd2f13b4..3e2e0f68b95268f04942e872575189f7d27bf943 100644 (file)
@@ -54,7 +54,6 @@ a_path::a_path() {
 FGGround::FGGround() {
        ATCmgr = globals->get_ATC_mgr();
        _type = GROUND;
-       display = false;
        networkLoadOK = false;
        ground_traffic.erase(ground_traffic.begin(), ground_traffic.end());
        ground_traffic_itr = ground_traffic.begin();
@@ -69,7 +68,6 @@ FGGround::FGGround() {
 
 FGGround::FGGround(string id) {
        ATCmgr = globals->get_ATC_mgr();
-       display = false;
        networkLoadOK = false;
        ground_traffic.erase(ground_traffic.begin(), ground_traffic.end());
        ground_traffic_itr = ground_traffic.begin();
@@ -274,7 +272,6 @@ bool FGGround::LoadNetwork() {
 }
 
 void FGGround::Init() {
-       display = false;
        untowered = false;
        
        // Figure out which is the active runway - TODO - it would be better to have ground call tower
@@ -318,7 +315,7 @@ void FGGround::Update(double dt) {
                                trns += " taxi holding point runway ";  // TODO - add the holding point name
                                // eg " taxi holding point G2 runway "
                                trns += ConvertRwyNumToSpokenString(activeRwy);
-                               if(display) {
+                               if(_display) {
                                        globals->get_ATC_display()->RegisterSingleMessage(trns, 0);
                                }
                                g->planePtr->RegisterTransmission(1);   // cleared to taxi
@@ -336,7 +333,7 @@ void FGGround::Update(double dt) {
                        char buf[10];
                        sprintf(buf, "%.2f", f);
                        trns += buf;
-                       if(display) {
+                       if(_display) {
                                globals->get_ATC_display()->RegisterSingleMessage(trns, 0);
                        }
                        g->planePtr->RegisterTransmission(2);   // contact tower
index b0cf1f3d86fbe0fc89eaf5b8af1d4548a54cd675..ffc668c4ab400ac8282734009775ed3a22bc6320 100644 (file)
@@ -232,8 +232,6 @@ public:
     void Update(double dt);
        
        inline string get_trans_ident() { return trans_ident; }
-    inline void SetDisplay() {display = true;}
-    inline void SetNoDisplay() {display = false;}
 
     // Contact ground control on arrival, assumed to request any gate
     //void NewArrival(plane_rec plane);
@@ -313,8 +311,6 @@ private:
        SGPropertyNode* wind_from_hdg;  //degrees
        SGPropertyNode* wind_speed_knots;               //knots
        
-       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.
        // for failure modeling
        string trans_ident;             // transmitted ident
        bool ground_failed;             // ground failed?
index c10d631436a67417445e37617874d0e05f88116e..b77670e0c56beca28ec67f095d8b3b287c7fb806 100644 (file)
@@ -231,7 +231,6 @@ FGTower::~FGTower() {
 
 void FGTower::Init() {
        //cout << "Initialising tower " << ident << '\n';
-    display = false;
        
        // Pointers to user's position
        user_lon_node = fgGetNode("/position/longitude-deg", true);
@@ -256,7 +255,7 @@ void FGTower::Init() {
                                ground = new FGGround(ident);
                                separateGround = false;
                                ground->Init();
-                               if(display) {
+                               if(_display) {
                                        ground->SetDisplay();
                                } else {
                                        ground->SetNoDisplay();
@@ -268,7 +267,7 @@ void FGTower::Init() {
                        ground = new FGGround(ident);
                        separateGround = false;
                        ground->Init();
-                       if(display) {
+                       if(_display) {
                                ground->SetDisplay();
                        } else {
                                ground->SetNoDisplay();
@@ -280,7 +279,7 @@ void FGTower::Init() {
                ground = new FGGround(ident);
                separateGround = false;
                ground->Init();
-               if(display) {
+               if(_display) {
                        ground->SetDisplay();
                } else {
                        ground->SetNoDisplay();
@@ -407,7 +406,8 @@ void FGTower::Update(double dt) {
                // 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) {
+               // We could also get rid of this by overloading FGATC's Set(No)Display() functions.
+               if(_display) {
                        ground->SetDisplay();
                } else {
                        ground->SetNoDisplay();
@@ -503,7 +503,7 @@ void FGTower::Respond() {
                                }
                        }
                        trns += ConvertRwyNumToSpokenString(activeRwy);
-                       if(display) {
+                       if(_display) {
                                globals->get_ATC_display()->RegisterSingleMessage(trns, 0);
                        } else {
                                //cout << "Not displaying, trns was " << trns << '\n';
@@ -526,7 +526,7 @@ void FGTower::Respond() {
                                t->clearedToLand = true;
                                if(!t->isUser) t->planePtr->RegisterTransmission(7);
                        }
-                       if(display) {
+                       if(_display) {
                                globals->get_ATC_display()->RegisterSingleMessage(trns);
                        }
                        if(t->isUser) {
@@ -562,7 +562,7 @@ void FGTower::Respond() {
                                // Not currently sure under which circumstances we do or don't bother transmitting this.
                                string trns = t->plane.callsign;
                                trns += " hold position";
-                               if(display) {
+                               if(_display) {
                                        globals->get_ATC_display()->RegisterSingleMessage(trns, 0);
                                }
                                // TODO - add some idea of what traffic is blocking him.
@@ -600,7 +600,7 @@ void FGTower::Respond() {
                                trns += " continue approach";
                                t->clearedToLand = false;
                        }
-                       if(display && disp) {
+                       if(_display && disp) {
                                globals->get_ATC_display()->RegisterSingleMessage(trns);
                        }
                        t->finalAcknowledged = true;
@@ -634,7 +634,7 @@ void FGTower::ProcessRunwayVacatedReport(TowerPlaneRec* t) {
                if(!t->isUser) t->planePtr->RegisterTransmission(6);    // TODO - this is a mega-hack!!
        }
        //cout << "trns = " << trns << '\n';
-       if(display) {
+       if(_display) {
                globals->get_ATC_display()->RegisterSingleMessage(trns);
        }
        // Maybe we should check that the plane really *has* vacated the runway!
@@ -741,7 +741,7 @@ void FGTower::ClearHoldingPlane(TowerPlaneRec* t) {
                departed = false;
                timeSinceLastDeparture = 0.0;
        }
-       if(display) {
+       if(_display) {
                globals->get_ATC_display()->RegisterSingleMessage(trns, 0);
        }
        //cout << "Done ClearHoldingPlane " << endl;
@@ -961,9 +961,8 @@ void FGTower::CheckCircuitList(double dt) {
                                        // For now this should stop the AI plane landing on top of the user.
                                        string trns = t->plane.callsign;
                                        trns += " GO AROUND TRAFFIC ON RUNWAY I REPEAT GO AROUND";
-                                       if(display) {
-                                               globals->get_ATC_display()->RegisterSingleMessage(trns, 0);
-                                       }
+                                       pending_transmission = trns;
+                                       ImmediateTransmit();
                                        t->instructedToGoAround = true;
                                        t->clearedToLand = false;
                                        // Assume it complies!!!
@@ -1082,9 +1081,8 @@ void FGTower::CheckApproachList(double dt) {
                        // For now this should stop the AI plane landing on top of the user.
                        string trns = t->plane.callsign;
                        trns += " GO AROUND TRAFFIC ON RUNWAY I REPEAT GO AROUND";
-                       if(display) {
-                               globals->get_ATC_display()->RegisterSingleMessage(trns, 0);
-                       }
+                       pending_transmission = trns;
+                       ImmediateTransmit();
                        t->instructedToGoAround = true;
                        t->clearedToLand = false;
                        t->nextOnRwy = false;   // But note this is recalculated so don't rely on it
@@ -1159,9 +1157,8 @@ void FGTower::CheckDepartureList(double dt) {
                if(distout > 10000) {
                        string trns = t->plane.callsign;
                        trns += " You are now clear of my airspace, good day";
-                       if(display) {
-                               globals->get_ATC_display()->RegisterSingleMessage(trns, 0);
-                       }
+                       pending_transmission = trns;
+                       Transmit();
                        if(t->isUser) {
                                // Change the communication options
                                RemoveAllUserDialogOptions();
index 9d0a557342c5544b219908f7344bfffa7440aa45..1fd3d65ed2eaa8d69feab408a8a4857019bf8ef7 100644 (file)
@@ -168,9 +168,6 @@ public:
        // Get the pattern direction of the active rwy.
        inline int GetPatternDirection() { return rwy.patternDirection; }
        
-       inline void SetDisplay() { display = true; }
-       inline void SetNoDisplay() { display = false; }
-       
        inline string get_trans_ident() { return trans_ident; }
        
        inline FGGround* GetGroundPtr() { return ground; }
@@ -247,9 +244,6 @@ private:
        unsigned int update_count;      // Convienince counter for speading computational load over several updates
        unsigned int update_count_max;  // ditto.
        
-       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.
-       
        double timeSinceLastDeparture;  // Time in seconds since last departure from active rwy.
        bool departed;  // set true when the above needs incrementing with time, false when it doesn't.