]> git.mxchange.org Git - flightgear.git/blobdiff - src/ATC/trafficcontrol.hxx
Autopilot: fix configuration to prevent false warnings.
[flightgear.git] / src / ATC / trafficcontrol.hxx
index 7e83a72b476097808a23c9745046a93eab2d1a64..bdedf0e1e902b57d6c45f95ac5794835512ba07c 100644 (file)
 #ifndef _TRAFFIC_CONTROL_HXX_
 #define _TRAFFIC_CONTROL_HXX_
 
+#include <Airports/airports_fwd.hxx>
 
-#ifndef __cplusplus
-# error This library requires C++
-#endif
-
+#include <osg/Geode>
+#include <osg/Geometry>
+#include <osg/MatrixTransform>
+#include <osg/Shape>
 
 #include <simgear/compiler.h>
 // There is probably a better include than sg_geodesy to get the SG_NM_TO_METER...
 #include <simgear/math/sg_geodesy.hxx>
 #include <simgear/debug/logstream.hxx>
+#include <simgear/structure/SGReferenced.hxx>
+#include <simgear/structure/SGSharedPtr.hxx>
 
+class FGAIAircraft;
+typedef std::vector<FGAIAircraft*> AircraftVec;
+typedef std::vector<FGAIAircraft*>::iterator AircraftVecIterator;
 
+class FGAIFlightPlan;
+typedef std::vector<FGAIFlightPlan*>           FlightPlanVec;
+typedef std::vector<FGAIFlightPlan*>::iterator FlightPlanVecIterator;
+typedef std::map<std::string, FlightPlanVec>   FlightPlanVecMap;
 
-#include <string>
-#include <vector>
-
-using std::string;
-using std::vector;
-
-
-typedef vector<int> intVec;
-typedef vector<int>::iterator intVecIterator;
+class FGTrafficRecord;
+typedef std::list<FGTrafficRecord> TrafficVector;
+typedef std::list<FGTrafficRecord>::iterator TrafficVectorIterator;
 
+class ActiveRunway;
+typedef std::vector<ActiveRunway> ActiveRunwayVec;
+typedef std::vector<ActiveRunway>::iterator ActiveRunwayVecIterator;
 
-class FGAIFlightPlan;  // forward reference
-class FGGroundNetwork; // forward reference
-class FGAIAircraft;    // forward reference
+typedef std::vector<int> intVec;
+typedef std::vector<int>::iterator intVecIterator;
 
 /**************************************************************************************
  * class FGATCInstruction
@@ -57,43 +63,79 @@ class FGAIAircraft;    // forward reference
 class FGATCInstruction
 {
 private:
-  bool holdPattern;
-  bool holdPosition;
-  bool changeSpeed;
-  bool changeHeading;
-  bool changeAltitude;
-  bool resolveCircularWait;
-
-  double speed;
-  double heading;
-  double alt;
+    bool holdPattern;
+    bool holdPosition;
+    bool changeSpeed;
+    bool changeHeading;
+    bool changeAltitude;
+    bool resolveCircularWait;
+
+    double speed;
+    double heading;
+    double alt;
 public:
 
-  FGATCInstruction();
-  bool hasInstruction   ();
-  bool getHoldPattern   () { return holdPattern;    };
-  bool getHoldPosition  () { return holdPosition;   };
-  bool getChangeSpeed   () { return changeSpeed;    };
-  bool getChangeHeading () { return changeHeading;  };
-  bool getChangeAltitude() { return changeAltitude; };
-
-  double getSpeed       () { return speed; };
-  double getHeading     () { return heading; };
-  double getAlt         () { return alt; };
-
-  bool getCheckForCircularWait() { return resolveCircularWait; };
-
-  void setHoldPattern   (bool val) { holdPattern    = val; };
-  void setHoldPosition  (bool val) { holdPosition   = val; };
-  void setChangeSpeed   (bool val) { changeSpeed    = val; };
-  void setChangeHeading (bool val) { changeHeading  = val; };
-  void setChangeAltitude(bool val) { changeAltitude = val; };
-
-  void setResolveCircularWait (bool val) { resolveCircularWait = val; }; 
-
-  void setSpeed       (double val) { speed   = val; };
-  void setHeading     (double val) { heading = val; };
-  void setAlt         (double val) { alt     = val; };
+    FGATCInstruction();
+    bool hasInstruction   () const;
+    bool getHoldPattern   () const {
+        return holdPattern;
+    };
+    bool getHoldPosition  () const {
+        return holdPosition;
+    };
+    bool getChangeSpeed   () const {
+        return changeSpeed;
+    };
+    bool getChangeHeading () const {
+        return changeHeading;
+    };
+    bool getChangeAltitude() const {
+        return changeAltitude;
+    };
+
+    double getSpeed       () const {
+        return speed;
+    };
+    double getHeading     () const {
+        return heading;
+    };
+    double getAlt         () const {
+        return alt;
+    };
+
+    bool getCheckForCircularWait() const {
+        return resolveCircularWait;
+    };
+
+    void setHoldPattern   (bool val) {
+        holdPattern    = val;
+    };
+    void setHoldPosition  (bool val) {
+        holdPosition   = val;
+    };
+    void setChangeSpeed   (bool val) {
+        changeSpeed    = val;
+    };
+    void setChangeHeading (bool val) {
+        changeHeading  = val;
+    };
+    void setChangeAltitude(bool val) {
+        changeAltitude = val;
+    };
+
+    void setResolveCircularWait (bool val) {
+        resolveCircularWait = val;
+    };
+
+    void setSpeed       (double val) {
+        speed   = val;
+    };
+    void setHeading     (double val) {
+        heading = val;
+    };
+    void setAlt         (double val) {
+        alt     = val;
+    };
 };
 
 
@@ -106,90 +148,172 @@ public:
 class FGTrafficRecord
 {
 private:
-  int id, waitsForId;
-  int currentPos;
-  int leg;
-  int frequencyId;
-  int state;
-  bool allowTransmission;
-  time_t timer;
-  intVec intentions;
-  FGATCInstruction instruction;
-  double latitude, longitude, heading, speed, altitude, radius;
-  string runway;
-  //FGAISchedule *trafficRef;
-  FGAIAircraft *aircraft;
-  
-  
-public:
-  FGTrafficRecord();
-  
-  void setId(int val)  { id = val; };
-  void setRadius(double rad) { radius = rad;};
-  void setPositionAndIntentions(int pos, FGAIFlightPlan *route);
-  void setRunway(string rwy) { runway = rwy;};
-  void setLeg(int lg) { leg = lg;};
-  int getId() { return id;};
-  int getState() { return state;};
-  void setState(int s) { state = s;}
-  FGATCInstruction getInstruction() { return instruction;};
-  bool hasInstruction() { return instruction.hasInstruction(); };
-  void setPositionAndHeading(double lat, double lon, double hdg, double spd, double alt);
-  bool checkPositionAndIntentions(FGTrafficRecord &other);
-  int  crosses                   (FGGroundNetwork *, FGTrafficRecord &other); 
-  bool isOpposing                (FGGroundNetwork *, FGTrafficRecord &other, int node);
-
-  bool onRoute(FGGroundNetwork *, FGTrafficRecord &other);
-
-  bool getSpeedAdjustment() { return instruction.getChangeSpeed(); };
-  
-  double getLatitude () { return latitude ; };
-  double getLongitude() { return longitude; };
-  double getHeading  () { return heading  ; };
-  double getSpeed    () { return speed    ; };
-  double getAltitude () { return altitude ; };
-  double getRadius   () { return radius   ; };
-
-  int getWaitsForId  () { return waitsForId; };
-
-  void setSpeedAdjustment(double spd);
-  void setHeadingAdjustment(double heading);
-  void clearSpeedAdjustment  () { instruction.setChangeSpeed  (false); };
-  void clearHeadingAdjustment() { instruction.setChangeHeading(false); };
-
-  bool hasHeadingAdjustment() { return instruction.getChangeHeading(); };
-  bool hasHoldPosition() { return instruction.getHoldPosition(); };
-  void setHoldPosition (bool inst) { instruction.setHoldPosition(inst); };
-
-  void setWaitsForId(int id) { waitsForId = id; };
-
-  void setResolveCircularWait()   { instruction.setResolveCircularWait(true);  };
-  void clearResolveCircularWait() { instruction.setResolveCircularWait(false); };
-
-  string getRunway() { return runway; };
-  //void setCallSign(string clsgn) { callsign = clsgn; };
-  void setAircraft(FGAIAircraft *ref) { aircraft = ref;};
-  void updateState() { state++; allowTransmission=true; };
-  //string getCallSign() { return callsign; };
-  FGAIAircraft *getAircraft() { return aircraft;};
-  int getTime() { return timer; };
-  int getLeg() { return leg; };
-  void setTime(time_t time) { timer = time; };
-
-  bool pushBackAllowed();
-  bool allowTransmissions() { return allowTransmission; };
-  void suppressRepeatedTransmissions () { allowTransmission=false; };
-  void allowRepeatedTransmissions () { allowTransmission=true; };
-  void nextFrequency() { frequencyId++; };
-  int  getNextFrequency() { return frequencyId; };
-};
-
-typedef vector<FGTrafficRecord> TrafficVector;
-typedef vector<FGTrafficRecord>::iterator TrafficVectorIterator;
+    int id, waitsForId;
+    int currentPos;
+    int leg;
+    int frequencyId;
+    int state;
+    bool allowTransmission;
+    bool allowPushback;
+    int priority;
+    time_t timer;
+    intVec intentions;
+    FGATCInstruction instruction;
+    double latitude, longitude, heading, speed, altitude, radius;
+    std::string runway;
+    //FGAISchedule *trafficRef;
+    FGAIAircraft *aircraft;
 
-typedef vector<time_t> TimeVector;
-typedef vector<time_t>::iterator TimeVectorIterator;
 
+public:
+    FGTrafficRecord();
+
+    void setId(int val)  {
+        id = val;
+    };
+    void setRadius(double rad) {
+        radius = rad;
+    };
+    void setPositionAndIntentions(int pos, FGAIFlightPlan *route);
+    void setRunway(const std::string& rwy) {
+        runway = rwy;
+    };
+    void setLeg(int lg) {
+        leg = lg;
+    };
+    int getId() {
+        return id;
+    };
+    int getState() {
+        return state;
+    };
+    void setState(int s) {
+        state = s;
+    }
+    FGATCInstruction getInstruction() {
+        return instruction;
+    };
+    bool hasInstruction() {
+        return instruction.hasInstruction();
+    };
+    void setPositionAndHeading(double lat, double lon, double hdg, double spd, double alt);
+    bool checkPositionAndIntentions(FGTrafficRecord &other);
+    int  crosses                   (FGGroundNetwork *, FGTrafficRecord &other);
+    bool isOpposing                (FGGroundNetwork *, FGTrafficRecord &other, int node);
+    
+    bool isActive(int margin) const;
+
+    bool onRoute(FGGroundNetwork *, FGTrafficRecord &other);
+
+    bool getSpeedAdjustment() const {
+        return instruction.getChangeSpeed();
+    };
+
+    double getLatitude () const {
+        return latitude ;
+    };
+    double getLongitude() const {
+        return longitude;
+    };
+    double getHeading  () const {
+        return heading  ;
+    };
+    double getSpeed    () const {
+        return speed    ;
+    };
+    double getAltitude () const {
+        return altitude ;
+    };
+    double getRadius   () const {
+        return radius   ;
+    };
+
+    int getWaitsForId  () const {
+        return waitsForId;
+    };
+
+    void setSpeedAdjustment(double spd);
+    void setHeadingAdjustment(double heading);
+    void clearSpeedAdjustment  () {
+        instruction.setChangeSpeed  (false);
+    };
+    void clearHeadingAdjustment() {
+        instruction.setChangeHeading(false);
+    };
+
+    bool hasHeadingAdjustment() const {
+        return instruction.getChangeHeading();
+    };
+    bool hasHoldPosition() const {
+        return instruction.getHoldPosition();
+    };
+    void setHoldPosition (bool inst) {
+        instruction.setHoldPosition(inst);
+    };
+
+    void setWaitsForId(int id) {
+        waitsForId = id;
+    };
+
+    void setResolveCircularWait()   {
+        instruction.setResolveCircularWait(true);
+    };
+    void clearResolveCircularWait() {
+        instruction.setResolveCircularWait(false);
+    };
+
+    const std::string& getRunway() const {
+        return runway;
+    };
+    //void setCallSign(string clsgn) { callsign = clsgn; };
+    void setAircraft(FGAIAircraft *ref) {
+        aircraft = ref;
+    };
+    void updateState() {
+        state++;
+        allowTransmission=true;
+    };
+    //string getCallSign() { return callsign; };
+    FGAIAircraft *getAircraft() const {
+        return aircraft;
+    };
+    int getTime() const {
+        return timer;
+    };
+    int getLeg() const {
+        return leg;
+    };
+    void setTime(time_t time) {
+        timer = time;
+    };
+
+    bool pushBackAllowed() const;
+    bool allowTransmissions() const {
+        return allowTransmission;
+    };
+    void allowPushBack() { allowPushback =true;};
+    void denyPushBack () { allowPushback = false;};
+    void suppressRepeatedTransmissions () {
+        allowTransmission=false;
+    };
+    void allowRepeatedTransmissions () {
+        allowTransmission=true;
+    };
+    void nextFrequency() {
+        frequencyId++;
+    };
+    int  getNextFrequency() const {
+        return frequencyId;
+    };
+    intVec& getIntentions() {
+        return intentions;
+    };
+    int getCurrentPosition() const {
+        return currentPos;
+    };
+    void setPriority(int p) { priority = p; };
+    int getPriority() const { return priority; };
+};
 
 /***********************************************************************
  * Active runway, a utility class to keep track of which aircraft has
@@ -198,80 +322,134 @@ typedef vector<time_t>::iterator TimeVectorIterator;
 class ActiveRunway
 {
 private:
-  string rwy;
-  int currentlyCleared;
-  double distanceToFinal;
-  TimeVector estimatedArrivalTimes;
+    std::string rwy;
+    int currentlyCleared;
+    double distanceToFinal;
+    TimeVector estimatedArrivalTimes;
+    AircraftVec departureCue;
+
 public:
-  ActiveRunway(string r, int cc) { rwy = r; currentlyCleared = cc; distanceToFinal = 6.0 * SG_NM_TO_METER; };
-  
-  string getRunwayName() { return rwy; };
-  int    getCleared   () { return currentlyCleared; };
-  double getApproachDistance() { return distanceToFinal; };
-  //time_t getEstApproachTime() { return estimatedArrival; };
-
-  //void setEstApproachTime(time_t time) { estimatedArrival = time; };
-  time_t requestTimeSlot(time_t eta);
+    ActiveRunway(const std::string& r, int cc) {
+        rwy = r;
+        currentlyCleared = cc;
+        distanceToFinal = 6.0 * SG_NM_TO_METER;
+    };
+
+    std::string getRunwayName() {
+        return rwy;
+    };
+    int    getCleared   () {
+        return currentlyCleared;
+    };
+    double getApproachDistance() {
+        return distanceToFinal;
+    };
+    //time_t getEstApproachTime() { return estimatedArrival; };
+
+    //void setEstApproachTime(time_t time) { estimatedArrival = time; };
+    void addToDepartureCue(FGAIAircraft *ac) {
+        departureCue.push_back(ac);
+    };
+    void setCleared(int number) {
+        currentlyCleared = number;
+    };
+    time_t requestTimeSlot(time_t eta);
+
+    int getDepartureCueSize() {
+        return departureCue.size();
+    };
+    FGAIAircraft* getFirstAircraftInDepartureCue() {
+        return departureCue.size() ? *(departureCue.begin()) : NULL;
+    };
+    FGAIAircraft* getFirstOfStatus(int stat);
+    void updateDepartureCue() {
+        departureCue.erase(departureCue.begin());
+    }
+    void printDepartureCue();
 };
 
-typedef vector<ActiveRunway> ActiveRunwayVec;
-typedef vector<ActiveRunway>::iterator ActiveRunwayVecIterator;
-
 /**
  * class FGATCController
- * NOTE: this class serves as an abstraction layer for all sorts of ATC controllers. 
+ * NOTE: this class serves as an abstraction layer for all sorts of ATC controllers.
  *************************************************************************************/
 class FGATCController
 {
-protected:
-  bool available;
-  time_t lastTransmission;
+private:
 
-  double dt_count;
 
+protected:
+    bool initialized;
+    bool available;
+    time_t lastTransmission;
 
-  string formatATCFrequency3_2(int );
-  string genTransponderCode(string fltRules);
+    double dt_count;
+    osg::Group* group;
+
+    std::string formatATCFrequency3_2(int );
+    std::string genTransponderCode(const std::string& fltRules);
+    bool isUserAircraft(FGAIAircraft*);
 
 public:
-  typedef enum {
-      MSG_ANNOUNCE_ENGINE_START,
-      MSG_REQUEST_ENGINE_START,
-      MSG_PERMIT_ENGINE_START,
-      MSG_DENY_ENGINE_START,
-      MSG_ACKNOWLEDGE_ENGINE_START,
-      MSG_REQUEST_PUSHBACK_CLEARANCE,
-      MSG_PERMIT_PUSHBACK_CLEARANCE,
-      MSG_HOLD_PUSHBACK_CLEARANCE,
-      MSG_ACKNOWLEDGE_SWITCH_GROUND_FREQUENCY,
-      MSG_INITIATE_CONTACT,
-      MSG_ACKNOWLEDGE_INITIATE_CONTACT,
-      MSG_REQUEST_TAXI_CLEARANCE,
-      MSG_ISSUE_TAXI_CLEARANCE,
-      MSG_ACKNOWLEDGE_TAXI_CLEARANCE,
-      MSG_HOLD_POSITION,
-      MSG_ACKNOWLEDGE_HOLD_POSITION,
-      MSG_RESUME_TAXI,
-      MSG_ACKNOWLEDGE_RESUME_TAXI } AtcMsgId;
-  typedef enum {
-      ATC_AIR_TO_GROUND,
-      ATC_GROUND_TO_AIR } AtcMsgDir;
-  FGATCController();
-  virtual ~FGATCController() {};
-  virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
-                               double lat, double lon,
-                               double hdg, double spd, double alt, double radius, int leg,
-                               FGAIAircraft *aircraft) = 0;
-  virtual void             signOff(int id) = 0;
-  virtual void             update(int id, double lat, double lon, 
-                                 double heading, double speed, double alt, double dt) = 0;
-  virtual bool             hasInstruction(int id) = 0;
-  virtual FGATCInstruction getInstruction(int id) = 0;
-
-  double getDt() { return dt_count; };
-  void   setDt(double dt) { dt_count = dt;};
-  void transmit(FGTrafficRecord *rec, AtcMsgId msgId, AtcMsgDir msgDir);
-  string getGateName(FGAIAircraft *aircraft);
+    typedef enum {
+        MSG_ANNOUNCE_ENGINE_START,
+        MSG_REQUEST_ENGINE_START,
+        MSG_PERMIT_ENGINE_START,
+        MSG_DENY_ENGINE_START,
+        MSG_ACKNOWLEDGE_ENGINE_START,
+        MSG_REQUEST_PUSHBACK_CLEARANCE,
+        MSG_PERMIT_PUSHBACK_CLEARANCE,
+        MSG_HOLD_PUSHBACK_CLEARANCE,
+        MSG_ACKNOWLEDGE_SWITCH_GROUND_FREQUENCY,
+        MSG_INITIATE_CONTACT,
+        MSG_ACKNOWLEDGE_INITIATE_CONTACT,
+        MSG_REQUEST_TAXI_CLEARANCE,
+        MSG_ISSUE_TAXI_CLEARANCE,
+        MSG_ACKNOWLEDGE_TAXI_CLEARANCE,
+        MSG_HOLD_POSITION,
+        MSG_ACKNOWLEDGE_HOLD_POSITION,
+        MSG_RESUME_TAXI,
+        MSG_ACKNOWLEDGE_RESUME_TAXI,
+        MSG_REPORT_RUNWAY_HOLD_SHORT,
+        MSG_ACKNOWLEDGE_REPORT_RUNWAY_HOLD_SHORT,
+        MSG_SWITCH_TOWER_FREQUENCY,
+        MSG_ACKNOWLEDGE_SWITCH_TOWER_FREQUENCY
+    } AtcMsgId;
+
+    typedef enum {
+        ATC_AIR_TO_GROUND,
+        ATC_GROUND_TO_AIR
+    } AtcMsgDir;
+    FGATCController();
+    virtual ~FGATCController();
+    void init();
+
+    virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
+                                  double lat, double lon,
+                                  double hdg, double spd, double alt, double radius, int leg,
+                                  FGAIAircraft *aircraft) = 0;
+    virtual void             signOff(int id) = 0;
+    virtual void             updateAircraftInformation(int id, double lat, double lon,
+            double heading, double speed, double alt, double dt) = 0;
+    virtual bool             hasInstruction(int id) = 0;
+    virtual FGATCInstruction getInstruction(int id) = 0;
+
+    double getDt() {
+        return dt_count;
+    };
+    void   setDt(double dt) {
+        dt_count = dt;
+    };
+    void transmit(FGTrafficRecord *rec, FGAirportDynamics *parent, AtcMsgId msgId, AtcMsgDir msgDir, bool audible);
+    std::string getGateName(FGAIAircraft *aircraft);
+    virtual void render(bool) = 0;
+    virtual std::string getName()  = 0;
+
+    virtual void update(double) = 0;
+
+
+private:
+
+    AtcMsgDir lastTransmissionDirection;
 };
 
 /******************************************************************************
@@ -280,54 +458,75 @@ public:
 class FGTowerController : public FGATCController
 {
 private:
-  TrafficVector activeTraffic;
-  ActiveRunwayVec activeRunways;
-  
+    TrafficVector activeTraffic;
+    ActiveRunwayVec activeRunways;
+    FGAirportDynamics *parent;
+
 public:
-  FGTowerController();
-  virtual ~FGTowerController() {};
-  virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
-                               double lat, double lon,
-                               double hdg, double spd, double alt, double radius, int leg,
-                               FGAIAircraft *aircraft);
-  virtual void             signOff(int id);
-  virtual void             update(int id, double lat, double lon, 
-                                 double heading, double speed, double alt, double dt);
-  virtual bool             hasInstruction(int id);
-  virtual FGATCInstruction getInstruction(int id);
-
-  bool hasActiveTraffic() { return activeTraffic.size() != 0; };
-  TrafficVector &getActiveTraffic() { return activeTraffic; };
+    FGTowerController(FGAirportDynamics *parent);
+    virtual ~FGTowerController() {};
+    virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
+                                  double lat, double lon,
+                                  double hdg, double spd, double alt, double radius, int leg,
+                                  FGAIAircraft *aircraft);
+    virtual void             signOff(int id);
+    virtual void             updateAircraftInformation(int id, double lat, double lon,
+            double heading, double speed, double alt, double dt);
+    virtual bool             hasInstruction(int id);
+    virtual FGATCInstruction getInstruction(int id);
+
+    virtual void render(bool);
+    virtual std::string getName();
+    virtual void update(double dt);
+    bool hasActiveTraffic() {
+        return ! activeTraffic.empty();
+    };
+    TrafficVector &getActiveTraffic() {
+        return activeTraffic;
+    };
 };
 
 /******************************************************************************
  * class FGStartupController
- * handle 
+ * handle
  *****************************************************************************/
 
 class FGStartupController : public FGATCController
 {
 private:
-  TrafficVector activeTraffic;
-  //ActiveRunwayVec activeRunways;
-  
+    TrafficVector activeTraffic;
+    //ActiveRunwayVec activeRunways;
+    FGAirportDynamics *parent;
+
 public:
-  FGStartupController();
-  virtual ~FGStartupController() {};
-  virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
-                               double lat, double lon,
-                               double hdg, double spd, double alt, double radius, int leg,
-                               FGAIAircraft *aircraft);
-  virtual void             signOff(int id);
-  virtual void             update(int id, double lat, double lon, 
-                                 double heading, double speed, double alt, double dt);
-  virtual bool             hasInstruction(int id);
-  virtual FGATCInstruction getInstruction(int id);
-
-  bool hasActiveTraffic() { return activeTraffic.size() != 0; };
-  TrafficVector &getActiveTraffic() { return activeTraffic; };
-
-}; 
+    FGStartupController(FGAirportDynamics *parent);
+    virtual ~FGStartupController() {};
+    virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
+                                  double lat, double lon,
+                                  double hdg, double spd, double alt, double radius, int leg,
+                                  FGAIAircraft *aircraft);
+    virtual void             signOff(int id);
+    virtual void             updateAircraftInformation(int id, double lat, double lon,
+            double heading, double speed, double alt, double dt);
+    virtual bool             hasInstruction(int id);
+    virtual FGATCInstruction getInstruction(int id);
+
+    virtual void render(bool);
+    virtual std::string getName();
+    virtual void update(double dt);
+
+    bool hasActiveTraffic() {
+        return ! activeTraffic.empty();
+    };
+    TrafficVector &getActiveTraffic() {
+        return activeTraffic;
+    };
+
+    // Hpoefully, we can move this function to the base class, but I need to verify what is needed for the other controllers before doing so.
+    bool checkTransmissionState(int st, time_t now, time_t startTime, TrafficVectorIterator i, AtcMsgId msgId,
+                                AtcMsgDir msgDir);
+
+};
 
 /******************************************************************************
  * class FGTowerControl
@@ -335,26 +534,35 @@ public:
 class FGApproachController : public FGATCController
 {
 private:
-  TrafficVector activeTraffic;
-  ActiveRunwayVec activeRunways;
-  
+    TrafficVector activeTraffic;
+    ActiveRunwayVec activeRunways;
+    FGAirportDynamics *parent;
+
 public:
-  FGApproachController();
-  virtual ~FGApproachController() {};
-  virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
-                               double lat, double lon,
-                               double hdg, double spd, double alt, double radius, int leg,
-                               FGAIAircraft *aircraft);
-  virtual void             signOff(int id);
-  virtual void             update(int id, double lat, double lon, 
-                                 double heading, double speed, double alt, double dt);
-  virtual bool             hasInstruction(int id);
-  virtual FGATCInstruction getInstruction(int id);
-
-  ActiveRunway* getRunway(string name);
-
-  bool hasActiveTraffic() { return activeTraffic.size() != 0; };
-  TrafficVector &getActiveTraffic() { return activeTraffic; };
+    FGApproachController(FGAirportDynamics * parent);
+    virtual ~FGApproachController() { };
+    virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
+                                  double lat, double lon,
+                                  double hdg, double spd, double alt, double radius, int leg,
+                                  FGAIAircraft *aircraft);
+    virtual void             signOff(int id);
+    virtual void             updateAircraftInformation(int id, double lat, double lon,
+            double heading, double speed, double alt, double dt);
+    virtual bool             hasInstruction(int id);
+    virtual FGATCInstruction getInstruction(int id);
+
+    virtual void render(bool);
+    virtual std::string getName();
+    virtual void update(double dt);
+
+    ActiveRunway* getRunway(const std::string& name);
+
+    bool hasActiveTraffic() {
+        return ! activeTraffic.empty();
+    };
+    TrafficVector &getActiveTraffic() {
+        return activeTraffic;
+    };
 };