#ifndef _GROUNDNETWORK_HXX_
#define _GROUNDNETWORK_HXX_
-#include <osg/Geode>
-#include <osg/Geometry>
-#include <osg/MatrixTransform>
-#include <osg/Shape>
-
-
#include <simgear/compiler.h>
-#include <simgear/route/waypoint.hxx>
#include <string>
-#include <vector>
-
-using std::string;
-using std::vector;
#include "gnnode.hxx"
#include "parking.hxx"
-#include <ATC/trafficcontrol.hxx>
+class FGAirportDynamicsXMLLoader;
-class FGTaxiSegment; // forward reference
-class FGAIFlightPlan; // forward reference
-class FGAirport; // forward reference
+typedef std::vector<int> intVec;
+typedef std::vector<int>::iterator intVecIterator;
-typedef vector<FGTaxiSegment*> FGTaxiSegmentVector;
-typedef vector<FGTaxiSegment*>::iterator FGTaxiSegmentVectorIterator;
-
-//typedef vector<FGTaxiSegment*> FGTaxiSegmentPointerVector;
-//typedef vector<FGTaxiSegment*>::iterator FGTaxiSegmentPointerVectorIterator;
+class Block
+{
+private:
+ int id;
+ time_t blocktime;
+ time_t touch;
+public:
+ Block(int i, time_t bt, time_t curr) { id = i; blocktime= bt; touch = curr; };
+ ~Block() {};
+ int getId() { return id; };
+ void updateTimeStamps(time_t bt, time_t now) { blocktime = (bt < blocktime) ? bt : blocktime; touch = now; };
+ const time_t getBlockTime() const { return blocktime; };
+ time_t getTimeStamp() { return touch; };
+ bool operator< (const Block &other) const { return blocktime < other.blocktime; };
+};
/***************************************************************************************
* class FGTaxiSegment
class FGTaxiSegment
{
private:
- int startNode;
- int endNode;
- double length;
- double heading;
- SGGeod center;
+ // weak (non-owning) pointers deliberately here:
+ // the ground-network owns the nodes
+ const FGTaxiNode* startNode;
+ const FGTaxiNode* endNode;
+
bool isActive;
- bool isPushBackRoute;
- bool isBlocked;
- FGTaxiNode *start;
- FGTaxiNode *end;
- int index;
- FGTaxiSegment *oppositeDirection;
-
+ BlockList blockTimes;
+ int index;
+ FGTaxiSegment *oppositeDirection; // also deliberatley weak
+ friend class FGGroundNetwork;
public:
- FGTaxiSegment() :
- startNode(0),
- endNode(0),
- length(0),
- heading(0),
- isActive(0),
- isPushBackRoute(0),
- isBlocked(0),
- start(0),
- end(0),
- index(0),
- oppositeDirection(0)
- {
- };
-
- FGTaxiSegment (const FGTaxiSegment &other) :
- startNode (other.startNode),
- endNode (other.endNode),
- length (other.length),
- heading (other.heading),
- center (other.center),
- isActive (other.isActive),
- isPushBackRoute (other.isPushBackRoute),
- isBlocked (other.isBlocked),
- start (other.start),
- end (other.end),
- index (other.index),
- oppositeDirection (other.oppositeDirection)
- {
- };
-
- FGTaxiSegment& operator=(const FGTaxiSegment &other)
- {
- startNode = other.startNode;
- endNode = other.endNode;
- length = other.length;
- heading = other.heading;
- center = other.center;
- isActive = other.isActive;
- isPushBackRoute = other.isPushBackRoute;
- isBlocked = other.isBlocked;
- start = other.start;
- end = other.end;
- index = other.index;
- oppositeDirection = other.oppositeDirection;
- return *this;
- };
-
+ FGTaxiSegment(FGTaxiNode* start, FGTaxiNode* end);
+
void setIndex (int val) {
index = val;
};
- void setStartNodeRef (int val) {
- startNode = val;
- };
- void setEndNodeRef (int val) {
- endNode = val;
- };
-
- void setOpposite(FGTaxiSegment *opp) {
- oppositeDirection = opp;
- };
-
- void setStart(FGTaxiNodeVector *nodes);
- void setEnd (FGTaxiNodeVector *nodes);
- void setPushBackType(bool val) {
- isPushBackRoute = val;
- };
+
void setDimensions(double elevation);
- void block() {
- isBlocked = true;
- }
- void unblock() {
- isBlocked = false;
- };
- bool hasBlock() {
- return isBlocked;
- };
-
- FGTaxiNode * getEnd() {
- return end;
- };
- FGTaxiNode * getStart() {
- return start;
- };
- double getLength() {
- return length;
- };
+ void block(int id, time_t blockTime, time_t now);
+ void unblock(time_t now);
+ bool hasBlock(time_t now);
+
+ FGTaxiNodeRef getEnd() const;
+ FGTaxiNodeRef getStart() const;
+
+ double getLength() const;
+
+ // compute the center of the arc
+ SGGeod getCenter() const;
+
+ double getHeading() const;
+
int getIndex() {
- return index;
- };
- double getLatitude() {
- return center.getLatitudeDeg();
- };
- double getLongitude() {
- return center.getLongitudeDeg();
- };
- double getHeading() {
- return heading;
- };
- bool isPushBack() {
- return isPushBackRoute;
+ return index;
};
int getPenalty(int nGates);
- FGTaxiSegment *getAddress() {
- return this;
- };
-
bool operator<(const FGTaxiSegment &other) const {
return index < other.index;
};
- //bool hasSmallerHeadingDiff (const FGTaxiSegment &other) const { return headingDiff < other.headingDiff; };
+
FGTaxiSegment *opposite() {
return oppositeDirection;
};
- void setCourseDiff(double crse);
-
-
-
-
};
-
-
-
-typedef vector<int> intVec;
-typedef vector<int>::iterator intVecIterator;
-
-
-
/***************************************************************************************
* class FGTaxiRoute
**************************************************************************************/
class FGTaxiRoute
{
private:
- intVec nodes;
+ FGTaxiNodeVector nodes;
intVec routes;
double distance;
-// int depth;
- intVecIterator currNode;
- intVecIterator currRoute;
+ FGTaxiNodeVector::iterator currNode;
+ intVec::iterator currRoute;
public:
FGTaxiRoute() {
currNode = nodes.begin();
currRoute = routes.begin();
};
- FGTaxiRoute(intVec nds, intVec rts, double dist, int dpth) {
+
+ FGTaxiRoute(const FGTaxiNodeVector& nds, intVec rts, double dist, int dpth) {
nodes = nds;
routes = rts;
distance = dist;
currNode = nodes.begin();
currRoute = routes.begin();
-// depth = dpth;
};
FGTaxiRoute& operator= (const FGTaxiRoute &other) {
nodes = other.nodes;
routes = other.routes;
distance = other.distance;
-// depth = other.depth;
currNode = nodes.begin();
currRoute = routes.begin();
return *this;
nodes(copy.nodes),
routes(copy.routes),
distance(copy.distance),
-// depth(copy.depth),
currNode(nodes.begin()),
currRoute(routes.begin())
{};
return distance < other.distance;
};
bool empty () {
- return nodes.begin() == nodes.end();
+ return nodes.empty();
};
- bool next(int *nde);
- bool next(int *nde, int *rte);
- void rewind(int legNr);
-
+ bool next(FGTaxiNodeRef& nde, int *rte);
+
void first() {
currNode = nodes.begin();
currRoute = routes.begin();
int nodesLeft() {
return nodes.end() - currNode;
};
-
-// int getDepth() { return depth; };
};
-typedef vector<FGTaxiRoute> TaxiRouteVector;
-typedef vector<FGTaxiRoute>::iterator TaxiRouteVectorIterator;
-
/**************************************************************************************
* class FGGroundNetWork
*************************************************************************************/
-class FGGroundNetwork : public FGATCController
+class FGGroundNetwork
{
private:
+ friend class FGAirportDynamicsXMLLoader;
+
+ FGAirportDynamics* dynamics; // weak back-pointer to our owner
bool hasNetwork;
bool networkInitialized;
- time_t nextSave;
- //int maxDepth;
- int count;
+
int version;
- FGTaxiNodeVector nodes;
- FGTaxiNodeVector pushBackNodes;
+
FGTaxiSegmentVector segments;
- //intVec route;
- //intVec nodesStack;
- //intVec routesStack;
- TaxiRouteVector routes;
- TrafficVector activeTraffic;
- TrafficVectorIterator currTraffic;
-
- bool foundRoute;
- double totalDistance, maxDistance;
- FGTowerController *towerController;
+
FGAirport *parent;
+ FGParkingList m_parkings;
+ FGTaxiNodeVector m_nodes;
+
+ FGTaxiNodeRef findNodeByIndex(int index) const;
//void printRoutingError(string);
double heading, double speed, double alt);
+ void addSegment(const FGTaxiNodeRef& from, const FGTaxiNodeRef& to);
+ void addParking(const FGParkingRef& park);
+
+ FGTaxiNodeVector segmentsFrom(const FGTaxiNodeRef& from) const;
public:
FGGroundNetwork();
~FGGroundNetwork();
-
- void addNode (const FGTaxiNode& node);
- void addNodes (FGParkingVec *parkings);
- void addSegment(const FGTaxiSegment& seg);
- void setVersion (int v) { version = v;};
+ void setVersion (int v) { version = v;};
int getVersion() { return version; };
- void init();
+ void init(FGAirportDynamics* pr);
bool exists() {
return hasNetwork;
};
- void setTowerController(FGTowerController *twrCtrlr) {
- towerController = twrCtrlr;
- };
- int findNearestNode(double lat, double lon);
- int findNearestNode(const SGGeod& aGeod);
- int findNearestNodeOnRunway(const SGGeod& aGeod);
+ FGTaxiNodeRef findNearestNode(const SGGeod& aGeod) const;
+ FGTaxiNodeRef findNearestNodeOnRunway(const SGGeod& aGeod, FGRunway* aRunway = NULL) const;
- FGTaxiNode *findNode(unsigned idx);
- FGTaxiSegment *findSegment(unsigned idx);
- FGTaxiRoute findShortestRoute(int start, int end, bool fullSearch=true);
- //void trace(FGTaxiNode *, int, int, double dist);
+ FGTaxiSegment *findSegment(unsigned int idx) const;
- int getNrOfNodes() {
- return nodes.size();
- };
+ FGTaxiSegment* findOppositeSegment(unsigned int index) const;
- void setParent(FGAirport *par) {
- parent = par;
- };
+ const FGParkingList& allParkings() const;
+
+ /**
+ * Find the taxiway segment joining two (ground-net) nodes. Returns
+ * NULL if no such segment exists.
+ * It is permitted to pass HULL for the 'to' indicating that any
+ * segment originating at 'from' is acceptable.
+ */
+ FGTaxiSegment *findSegment(const FGTaxiNode* from, const FGTaxiNode* to) const;
+
+ FGTaxiRoute findShortestRoute(FGTaxiNode* start, FGTaxiNode* end, bool fullSearch=true);
+
+
+ void blockSegmentsEndingAt(FGTaxiSegment* seg, int blockId,
+ time_t blockTime, time_t now);
- 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);
-
- bool checkTransmissionState(int minState, int MaxState, TrafficVectorIterator i, time_t now, AtcMsgId msgId,
- AtcMsgDir msgDir);
- bool checkForCircularWaits(int id);
- virtual void render(bool);
- virtual string getName();
- virtual void update(double dt);
-
- void saveElevationCache();
void addVersion(int v) {version = v; };
+ void unblockAllSegments(time_t now);
};