#ifndef _FG_GROUND_HXX
#define _FG_GROUND_HXX
+#include STL_IOSTREAM
+#include STL_STRING
+
+SG_USING_STD(string);
+SG_USING_STD(ios);
+
+#include <map>
#include <vector>
#include <list>
-//#include <map>
+#include <simgear/math/point3d.hxx>
+#include <simgear/misc/sgstream.hxx>
+#include <simgear/math/sg_geodesy.hxx>
+#include "ATC.hxx"
+//#include "ATCmgr.hxx"
+#include "ATCProjection.hxx"
+#include "AIEntity.hxx"
+//#include "AILocalTraffic.hxx" // RunwayDetails - this is a temporary hack
+
+SG_USING_STD(map);
SG_USING_STD(vector);
SG_USING_STD(list);
-//SG_USING_STD(map);
//////////////////////////////////////////////////////
// Types for the logical network data structure
-typedef enum arc_type {
- RUNWAY,
- TAXIWAY
+enum arc_type {
+ RUNWAY,
+ TAXIWAY
};
-typedef enum node_type {
- GATE,
- APRON,
- HOLD
+enum node_type {
+ GATE,
+ APRON,
+ HOLD,
+ JUNCTION,
+ TJUNCTION
};
-typedef struct arc {
- int distance;
- char* name;
- arc_type type;
+enum GateType {
+ TRANSPORT_PASSENGER,
+ TRANSPORT_PASSENGER_NARROWBODY,
+ TRANSPORT_PASSENGER_WIDEBODY,
+ TRANSPORT_CARGO,
+ GA_LOCAL,
+ GA_LOCAL_SINGLE,
+ GA_LOCAL_TWIN,
+ GA_TRANSIENT,
+ GA_TRANSIENT_SINGLE,
+ GA_TRANSIENT_TWIN,
+ OTHER // ie. anything goes!!
};
-typedef list<arc> arc_list_type;
-typedef arc_list_type::iterator arc_list_itr;
-typedef arc_list_type::const_iterator arc_list_const_itr;
+enum network_element_type {
+ NODE,
+ ARC
+};
-typedef struct node {
- point pos;
- char* name;
- node_type node;
- arc_list arcs;
+struct ground_network_element {
+ network_element_type struct_type;
};
-typedef vector<node> node_array_type;
-typedef node_array_type::iterator node_array_itr;
-typedef node_array_type::const_iterator node_array_const_itr;
+struct arc : public ground_network_element {
+ int distance;
+ string name;
+ arc_type type;
+ bool directed; //false if 2-way, true if 1-way.
+ //This is a can of worms since arcs might be one way in different directions under different circumstances
+ unsigned int n1; // The nodeID of the first node
+ unsigned int n2; // The nodeID of the second node
+ // If the arc is directed then flow is normally from n1 to n2. See the above can of worms comment though.
+};
+
+typedef vector <arc*> arc_array_type; // This was and may become again a list instead of vector
+typedef arc_array_type::iterator arc_array_iterator;
+typedef arc_array_type::const_iterator arc_array_const_iterator;
+
+struct node : public ground_network_element {
+ node();
+ ~node();
+
+ unsigned int nodeID; //each node in an airport needs a unique ID number - this is ZERO-BASED to match array position
+ Point3D pos;
+ Point3D orthoPos;
+ string name;
+ node_type type;
+ arc_array_type arcs;
+ double max_turn_radius;
+};
+
+typedef vector <node*> node_array_type;
+typedef node_array_type::iterator node_array_iterator;
+typedef node_array_type::const_iterator node_array_const_iterator;
+
+struct Gate : public node {
+ GateType gateType;
+ int max_weight; //units??
+ //airline_code airline; //For the future - we don't have any airline codes ATM
+ int id; // The gate number in the logical scheme of things
+ string name; // The real-world gate letter/number
+ //node* pNode;
+ bool used;
+ double heading; // The direction the parked-up plane should point in degrees
+};
+
+typedef vector < Gate* > gate_vec_type;
+typedef gate_vec_type::iterator gate_vec_iterator;
+typedef gate_vec_type::const_iterator gate_vec_const_iterator;
+
+// A map of gate vs. the logical (internal FGFS) gate ID
+typedef map < int, Gate* > gate_map_type;
+typedef gate_map_type::iterator gate_map_iterator;
+typedef gate_map_type::const_iterator gate_map_const_iterator;
+
+// Runways - all the runway stuff is likely to change in the future
+struct Rwy {
+ int id; //note this is a very simplified scheme for now - R & L are not differentiated
+ //It should work for simple one rwy airports
+ node_array_type exits; //Array of available exits from runway
+ // should probably add an FGRunway structure here as well eventually
+ // Eventually we will also want some encoding of real-life preferred runways
+ // This will get us up and running for single runway airports though.
+};
+
+typedef vector < Rwy > runway_array_type;
+typedef runway_array_type::iterator runway_array_iterator;
+typedef runway_array_type::const_iterator runway_array_const_iterator;
+
// end logical network types
///////////////////////////////////////////////////////
-// somewhere in the ATC/AI system we are going to have defined something like
-// typedef struct plane_rec
-// list <PlaneRec> plane_rec_list_type
+///////////////////////////////////////////////////////
+// Structures to use the network
+
+// A path through the network
+typedef vector < ground_network_element* > ground_network_path_type;
+typedef ground_network_path_type::iterator ground_network_path_iterator;
+typedef ground_network_path_type::const_iterator ground_network_path_const_iterator;
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////
+//
+// Stuff for the shortest-path algorithms
+struct a_path {
+ a_path();
+
+ ground_network_path_type path;
+ int cost;
+};
+
+// Paths mapped by nodeID reached so-far
+typedef map < unsigned int, a_path* > shortest_path_map_type;
+typedef shortest_path_map_type::iterator shortest_path_map_iterator;
+
+// Nodes mapped by their ID
+//typedef map < unsigned int, node* > node_map_type;
+//typedef node_map_type::iterator node_map_iterator;
+////////////////////////////////////////////////
+
+// Planes active within the ground network.
// A more specialist plane rec to include ground information
-typedef struct ground_rec {
- plane_rec plane;
- point current_pos;
- node destination;
- node last_clearance;
+struct GroundRec {
+ FGAIEntity* planePtr; // This might move to the planeRec eventually
+
+ PlaneRec plane;
+ Point3D current_pos;
+ node* destination;
+ node* last_clearance;
+ bool taxiRequestOutstanding; // Plane has requested taxi and we haven't responded yet
+ double clearanceCounter; // Hack for communication timing - counter since clearance requested in seconds
+
bool cleared; // set true when the plane has been cleared to somewhere
bool incoming; //true for arrivals, false for departures
// status?
// Almost certainly need to add more here
};
-typedef list<ground_rec*> ground_rec_list;
+typedef list < GroundRec* > ground_rec_list;
typedef ground_rec_list::iterator ground_rec_list_itr;
typedef ground_rec_list::const_iterator ground_rec_list_const_itr;
+//////////////////////////////////////////////////////////////////////////////////////////
+
+// Hack
+// perhaps we could use an FGRunway instead of this
+struct GRunwayDetails {
+ Point3D threshold_pos;
+ Point3D end1ortho; // ortho projection end1 (the threshold ATM)
+ Point3D end2ortho; // ortho projection end2 (the take off end in the current hardwired scheme)
+ double hdg; // true runway heading
+ double length; // In *METERS*
+ string rwyID;
+};
+
///////////////////////////////////////////////////////////////////////////////
//
// FGGround
///////////////////////////////////////////////////////////////////////////////
class FGGround : public FGATC {
-private:
-
- // Need a data structure to hold details of the various active planes
- // Need a data structure to hold details of the logical network
- // including which gates are filled - or possibly another data structure
- // with the positions of the inactive planes.
- // Need a data structure to hold outstanding communications from aircraft.
- // Possibly need a data structure to hold outstanding communications to aircraft.
-
- // logical network
- node_array_type network;
-
- // Planes currently active
- ground_rec_list ground_traffic;
-
public:
-
+ FGGround();
+ FGGround(string id);
+ ~FGGround();
void Init();
- void Update();
-
+ void Update(double dt);
+
+ inline string get_trans_ident() { return trans_ident; }
+ inline atc_type GetType() { return GROUND; }
inline void SetDisplay() {display = true;}
inline void SetNoDisplay() {display = false;}
- // Its possible that NewArrival and NewDeparture should simply be rolled into Request.
-
// Contact ground control on arrival, assumed to request any gate
- void NewArrival(plane_rec plane);
+ //void NewArrival(plane_rec plane);
// Contact ground control on departure, assumed to request currently active runway.
- void NewDeparture(plane_rec plane);
+ void RequestDeparture(PlaneRec plane, FGAIEntity* requestee);
// Contact ground control when the calling routine doesn't know if arrival
// or departure is appropriate.
- void NewContact(plane_rec plane);
+ //void NewContact(plane_rec plane);
// Make a request of ground control.
- void Request(ground_request request);
+ //void Request(ground_request request);
+
+ // Randomly fill some of the available gates and GA parking spots with planes
+ void PopulateGates();
+
+ // Return a suitable gate (maybe this should be a list of suitable gates so the plane or controller can choose the closest one)
+ void ReturnGate(Gate &gate, GateType type);
+
+ // Return a pointer to an unused gate
+ Gate* GetGateNode();
+
+ // Runway stuff - this might change in the future.
+ // Get a list of exits from a given runway
+ // It is up to the calling function to check for non-zero size of returned array before use
+ node_array_type GetExits(string rwyID);
+
+ // Get a path from one node to another
+ ground_network_path_type GetPath(node* A, node* B);
+
+ // Get a path from a node to a runway threshold
+ ground_network_path_type GetPath(node* A, string rwyID);
+
+ // Get a path from a node to a runway hold short point
+ // Bit of a hack this at the moment!
+ ground_network_path_type GetPathToHoldShort(node* A, string rwyID);
private:
+ FGATCMgr* ATCmgr;
+ // This is purely for synactic convienience to avoid writing globals->get_ATC_mgr()-> all through the code!
+
+ // Need a data structure to hold details of the various active planes
+ // Need a data structure to hold details of the logical network
+ // including which gates are filled - or possibly another data structure
+ // with the positions of the inactive planes.
+ // Need a data structure to hold outstanding communications from aircraft.
+ // Possibly need a data structure to hold outstanding communications to aircraft.
- // Find the shortest route through the logical network between two points.
- FindShortestRoute(point a, point b);
+ // The logical network
+ // NODES WILL BE STORED IN THE NETWORK IN ORDER OF nodeID NUMBER
+ // ie. NODE 5 WILL BE AT network[5]
+ node_array_type network;
+
+ // A map of all the gates indexed against internal (FGFS) ID
+ gate_map_type gates;
+ gate_map_iterator gatesItr;
+
+ FGATCAlignedProjection ortho;
+
+ // Planes currently active
+ //ground_rec_list ground_traffic;
- // Project a point in WGS84 lat/lon onto the local gnomonic.
- ConvertWGS84ToXY(sgVec3 wgs84, point xy);
+ // Find the shortest route through the logical network between two points.
+ //FindShortestRoute(point a, point b);
// Assign a gate or parking location to a new arrival
- AssignGate(ground_rec &g);
+ //AssignGate(ground_rec &g);
// Generate the next clearance for an airplane
- NextClearance(ground_rec &g);
-
+ //NextClearance(ground_rec &g);
+
+ // 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
+
+ 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?
+ bool networkLoadOK; // Indicates whether LoadNetwork returned true or false at last attempt
+
+ // Tower control
+ bool untowered; // True if this is an untowered airport (we still need the ground class for shortest path implementation etc
+ //FGATC* tower; // Pointer to the tower control
+
+ // Logical runway details - this might change in the future.
+ //runway_array_type runways; // STL way
+ Rwy runways[36]; // quick hack!
+
+ // Physical runway details
+ 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.// 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
+ // Copied from FGTower - TODO - it would be better to implement this just once, and have ground call tower
+ // for runway operation details, but at the moment we can't guarantee that tower control at a given airport
+ // will be initialised before ground so we can't do that.
+ void DoRwyDetails();
+
+ // Load the logical ground network for this airport from file.
+ // Return true if successfull.
+ bool LoadNetwork();
+
+ // Parse a runway exit string and push the supplied node pointer onto the runway exit list
+ void ParseRwyExits(node* np, char* es);
+
+ // Return a random gate ID of an unused gate.
+ // Two error values may be returned and must be checked for by the calling function:
+ // -2 signifies that no gates exist at this airport.
+ // -1 signifies that all gates are currently full.
+ // TODO - modify to return a suitable gate based on aircraft size/weight.
+ int GetRandomGateID();
+
+ // Return a pointer to the node at a runway threshold
+ // Returns NULL if unsuccessful.
+ node* GetThresholdNode(string rwyID);
+
+ // A shortest path algorithm from memory (I can't find the bl&*dy book again!)
+ ground_network_path_type GetShortestPath(node* A, node* B);
+
+ // Planes
+ ground_rec_list ground_traffic;
+ ground_rec_list_itr ground_traffic_itr;
};
-#endif //_FG_GROUND_HXX
\ No newline at end of file
+#endif // _FG_GROUND_HXX
+