//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifndef _FG_TOWER_HXX
#define _FG_TOWER_HXX
#include <simgear/compiler.h>
#include <simgear/math/point3d.hxx>
#include <simgear/misc/sgstream.hxx>
-//#include <simgear/math/sg_geodesy.hxx>
#include <plib/sg.h>
-//#include <Airports/runways.hxx>
#include STL_IOSTREAM
#include STL_STRING
SG_USING_STD(ios);
#include "ATC.hxx"
-//#include "ATCmgr.hxx"
-#include "ground.hxx"
#include "ATCProjection.hxx"
#include "AIPlane.hxx"
+class FGATCMgr;
+class FGGround;
+
//DCL - a complete guess for now.
#define FG_TOWER_DEFAULT_RANGE 30
USER_REPORT_3_MILE_FINAL = 5,
USER_REPORT_DOWNWIND = 6,
USER_REPORT_RWY_VACATED = 7,
- USER_REPORT_GOING_AROUND = 8
+ USER_REPORT_GOING_AROUND = 8,
+ USER_REQUEST_TAKE_OFF = 9
};
// TODO - need some differentiation of IFR and VFR traffic in order to give the former priority.
public:
TowerPlaneRec();
- TowerPlaneRec(PlaneRec p);
- TowerPlaneRec(Point3D pt);
- TowerPlaneRec(PlaneRec p, Point3D pt);
+ TowerPlaneRec(const PlaneRec& p);
+ TowerPlaneRec(const Point3D& pt);
+ TowerPlaneRec(const PlaneRec& p, const Point3D& pt);
FGAIPlane* planePtr; // This might move to the planeRec eventually
PlaneRec plane;
bool clearedToTakeOff;
// ought to add time cleared to depart so we can nag if necessary
bool holdShortReported;
+ bool lineUpReported;
bool downwindReported;
bool longFinalReported;
bool longFinalAcknowledged;
bool finalAcknowledged;
bool rwyVacatedReported;
bool rwyVacatedAcknowledged;
- bool instructedToGoAround; // set true if told by tower to go around
+ bool goAroundReported; // set true if plane informs tower that it's going around.
+ bool instructedToGoAround; // set true if plane told by tower to go around.
bool onRwy; // is physically on the runway
bool nextOnRwy; // currently projected by tower to be the next on the runway
+ bool gearWasUp; // Tell to ATC about gear
+ bool gearUpReported; // Tell to pilot about landing gear
bool vfrArrivalReported;
bool vfrArrivalAcknowledged;
PatternLeg leg;
LandingType landingType;
-
bool isUser; // true if this plane is the user
};
// Contact tower for VFR approach
// eg "Cessna Charlie Foxtrot Golf Foxtrot Sierra eight miles South of the airport for full stop with Bravo"
// This function probably only called via user interaction - AI planes will have an overloaded function taking a planerec.
- void VFRArrivalContact(string ID, LandingType opt = AIP_LT_UNKNOWN);
+ void VFRArrivalContact(const string& ID, const LandingType& opt = AIP_LT_UNKNOWN);
// For the AI planes...
- void VFRArrivalContact(PlaneRec plane, FGAIPlane* requestee, LandingType lt = AIP_LT_UNKNOWN);
-
- void RequestDepartureClearance(string ID);
- void ReportFinal(string ID);
- void ReportLongFinal(string ID);
- void ReportOuterMarker(string ID);
- void ReportMiddleMarker(string ID);
- void ReportInnerMarker(string ID);
- void ReportGoingAround(string ID);
- void ReportRunwayVacated(string ID);
- void ReportReadyForDeparture(string ID);
- void ReportDownwind(string ID);
+ void VFRArrivalContact(const PlaneRec& plane, FGAIPlane* requestee, const LandingType& lt = AIP_LT_UNKNOWN);
+
+ void RequestDepartureClearance(const string& ID);
+ void RequestTakeOffClearance(const string& ID);
+ void ReportFinal(const string& ID);
+ void ReportLongFinal(const string& ID);
+ void ReportOuterMarker(const string& ID);
+ void ReportMiddleMarker(const string& ID);
+ void ReportInnerMarker(const string& ID);
+ void ReportRunwayVacated(const string& ID);
+ void ReportReadyForDeparture(const string& ID);
+ void ReportDownwind(const string& ID);
+ void ReportGoingAround(const string& ID);
// Contact tower when at a hold short for departure - for now we'll assume plane - maybe vehicles might want to cross runway eventually?
- void ContactAtHoldShort(PlaneRec plane, FGAIPlane* requestee, tower_traffic_type operation);
+ void ContactAtHoldShort(const PlaneRec& plane, FGAIPlane* requestee, tower_traffic_type operation);
// Register the presence of an AI plane at a point where contact would already have been made in real life
// CAUTION - currently it is assumed that this plane's callsign is unique - it is up to AIMgr to generate unique callsigns.
- void RegisterAIPlane(PlaneRec plane, FGAIPlane* ai, tower_traffic_type op, PatternLeg lg = LEG_UNKNOWN);
+ void RegisterAIPlane(const PlaneRec& plane, FGAIPlane* ai, const tower_traffic_type& op, const PatternLeg& lg = LEG_UNKNOWN);
// Deregister and remove an AI plane.
- void DeregisterAIPlane(string id);
+ void DeregisterAIPlane(const string& id);
// Public interface to the active runway - this will get more complex
// in the future and consider multi-runway use, airplane weight etc.
- inline string GetActiveRunway() { return activeRwy; }
- inline RunwayDetails GetActiveRunwayDetails() { return rwy; }
+ inline const string& GetActiveRunway() const { return activeRwy; }
+ inline const RunwayDetails& GetActiveRunwayDetails() const { return rwy; }
// 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 int GetPatternDirection() const { return rwy.patternDirection; }
- inline string get_trans_ident() { return trans_ident; }
+ inline const string& get_trans_ident() const { return trans_ident; }
- inline FGGround* GetGroundPtr() { return ground; }
+ inline FGGround* const GetGroundPtr() const { return ground; }
// Returns true if positions of crosswind/downwind/base leg turns should be constrained by previous traffic
// plus the constraint position as a rwy orientated orthopos (meters)
bool GetBaseConstraint(double& bpos);
string GenText(const string& m, int c);
+ string GetWeather();
+ string GetATISID();
private:
- FGATCMgr* ATCmgr;
+ FGATCMgr* ATCmgr;
// This is purely for synactic convienience to avoid writing globals->get_ATC_mgr()-> all through the code!
// Respond to a transmission
void Respond();
void ProcessRunwayVacatedReport(TowerPlaneRec* t);
+ void ProcessDownwindReport(TowerPlaneRec* t);
// Remove all options from the user dialog choice
void RemoveAllUserDialogOptions();
void ClearHoldingPlane(TowerPlaneRec* t);
// Find a pointer to plane of callsign ID within the internal data structures
- TowerPlaneRec* FindPlane(string ID);
+ TowerPlaneRec* FindPlane(const string& ID);
// Remove and delete all instances of a plane with a given ID
- void RemovePlane(string ID);
+ void RemovePlane(const string& ID);
// Figure out if a given position lies on the active runway
// Might have to change when we consider more than one active rwy.
- bool OnActiveRunway(Point3D pt);
+ bool OnActiveRunway(const Point3D& pt);
// Figure out if a given position lies on a runway or not
- bool OnAnyRunway(Point3D pt);
+ bool OnAnyRunway(const Point3D& pt, bool onGround);
// Calculate the eta of a plane to the threshold.
// For ground traffic this is the fastest they can get there.
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.
// environment - need to make sure we're getting the surface winds and not winds aloft.
- SGPropertyNode* wind_from_hdg; //degrees
- SGPropertyNode* wind_speed_knots; //knots
+ SGPropertyNode_ptr wind_from_hdg; //degrees
+ SGPropertyNode_ptr wind_speed_knots; //knots
double aptElev; // Airport elevation
string activeRwy; // Active runway number - For now we'll disregard multiple / alternate runway operation.
RunwayDetails rwy; // Assumed to be the active one for now.
bool rwyOccupied; // Active runway occupied flag. For now we'll disregard land-and-hold-short operations.
FGATCAlignedProjection ortho; // Orthogonal mapping of the local area with the active runway threshold at the origin
+ FGATCAlignedProjection ortho_temp; // Ortho for any runway (needed to get plane position in airport)
// Figure out which runways are active.
// For now we'll just be simple and do one active runway - eventually this will get much more complex
tower_plane_rec_list_iterator vacatedListItr;
// Returns true if successful
- bool RemoveFromTrafficList(string id);
- bool RemoveFromAppList(string id);
- bool RemoveFromRwyList(string id);
+ bool RemoveFromTrafficList(const string& id);
+ bool RemoveFromAppList(const string& id);
+ bool RemoveFromRwyList(const string& id);
// Return the ETA of plane no. list_pos (1-based) in the traffic list.
// i.e. list_pos = 1 implies next to use runway.
bool AddToTrafficList(TowerPlaneRec* t, bool holding = false);
bool AddToCircuitList(TowerPlaneRec* t);
+
+ // Add to vacated list only if not already present
+ void AddToVacatedList(TowerPlaneRec* t);
+
+ void AddToHoldingList(TowerPlaneRec* t);
// 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
bool tower_failed; // tower failed?
// Pointers to current users position and orientation
- SGPropertyNode* user_lon_node;
- SGPropertyNode* user_lat_node;
- SGPropertyNode* user_elev_node;
- SGPropertyNode* user_hdg_node;
+ SGPropertyNode_ptr user_lon_node;
+ SGPropertyNode_ptr user_lat_node;
+ SGPropertyNode_ptr user_elev_node;
+ SGPropertyNode_ptr user_hdg_node;
// Details of the general traffic flow etc in the circuit
double crosswind_leg_pos; // Distance from threshold crosswind leg is being turned to in meters (actual operation - *not* ideal circuit)