// groundnet.hxx - A number of classes to handle taxiway // assignments by the AI code // // Written by Durk Talsma, started June 2005. // // Copyright (C) 2004 Durk Talsma. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // // 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // // $Id$ #ifndef _GROUNDNETWORK_HXX_ #define _GROUNDNETWORK_HXX_ #include #include #include STL_STRING #include SG_USING_STD(string); SG_USING_STD(vector); #include "gnnode.hxx" #include "parking.hxx" #include class FGTaxiSegment; // forward reference class FGAIFlightPlan; // forward reference class FGAirport; // forward reference typedef vector FGTaxiSegmentVector; typedef vector::iterator FGTaxiSegmentVectorIterator; //typedef vector FGTaxiSegmentPointerVector; //typedef vector::iterator FGTaxiSegmentPointerVectorIterator; /*************************************************************************************** * class FGTaxiSegment **************************************************************************************/ class FGTaxiSegment { private: int startNode; int endNode; double length; double course; double headingDiff; bool isActive; bool isPushBackRoute; FGTaxiNode *start; FGTaxiNode *end; int index; FGTaxiSegment *oppositeDirection; public: FGTaxiSegment() : startNode(0), endNode(0), length(0), course(0), headingDiff(0), isActive(0), isPushBackRoute(0), start(0), end(0), index(0), oppositeDirection(0) { }; FGTaxiSegment (const FGTaxiSegment &other) : startNode (other.startNode), endNode (other.endNode), length (other.length), course (other.course), headingDiff (other.headingDiff), isActive (other.isActive), isPushBackRoute (other.isPushBackRoute), 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; course = other.course; headingDiff = other.headingDiff; isActive = other.isActive; isPushBackRoute = other.isPushBackRoute; start = other.start; end = other.end; index = other.index; oppositeDirection = other.oppositeDirection; return *this; }; 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 setTrackDistance(); FGTaxiNode * getEnd() { return end;}; FGTaxiNode * getStart() { return start; }; double getLength() { return length; }; int getIndex() { return index; }; bool isPushBack() { return isPushBackRoute; }; 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 intVec; typedef vector::iterator intVecIterator; /*************************************************************************************** * class FGTaxiRoute **************************************************************************************/ class FGTaxiRoute { private: intVec nodes; intVec routes; double distance; int depth; intVecIterator currNode; intVecIterator currRoute; public: FGTaxiRoute() { distance = 0; currNode = nodes.begin(); currRoute = routes.begin();}; FGTaxiRoute(intVec nds, intVec rts, double dist, int dpth) { nodes = nds; routes = rts; distance = dist; currNode = nodes.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; }; FGTaxiRoute(const FGTaxiRoute& copy) : nodes(copy.nodes), routes(copy.routes), distance(copy.distance), depth(copy.depth), currNode(nodes.begin()), currRoute(routes.begin()) {}; bool operator< (const FGTaxiRoute &other) const {return distance < other.distance; }; bool empty () { return nodes.begin() == nodes.end(); }; bool next(int *nde); bool next(int *nde, int *rte); void rewind(int legNr); void first() { currNode = nodes.begin(); currRoute = routes.begin(); }; int size() { return nodes.size(); }; int getDepth() { return depth; }; }; typedef vector TaxiRouteVector; typedef vector::iterator TaxiRouteVectorIterator; /************************************************************************************** * class FGGroundNetWork *************************************************************************************/ class FGGroundNetwork : public FGATCController { private: bool hasNetwork; //int maxDepth; int count; FGTaxiNodeVector nodes; FGTaxiNodeVector pushBackNodes; FGTaxiSegmentVector segments; //intVec route; //intVec nodesStack; //intVec routesStack; TaxiRouteVector routes; TrafficVector activeTraffic; TrafficVectorIterator currTraffic; SGWayPoint destination; bool foundRoute; double totalDistance, maxDistance; FGTowerController *towerController; FGAirport *parent; //void printRoutingError(string); void checkSpeedAdjustment(int id, double lat, double lon, double heading, double speed, double alt); void checkHoldPosition(int id, double lat, double lon, double heading, double speed, double alt); public: FGGroundNetwork(); ~FGGroundNetwork(); void addNode (const FGTaxiNode& node); void addNodes (FGParkingVec *parkings); void addSegment(const FGTaxiSegment& seg); void init(); bool exists() { return hasNetwork; }; void setTowerController(FGTowerController *twrCtrlr) { towerController = twrCtrlr; }; int findNearestNode(double lat, double lon); FGTaxiNode *findNode(int idx); FGTaxiSegment *findSegment(int idx); FGTaxiRoute findShortestRoute(int start, int end, bool fullSearch=true); //void trace(FGTaxiNode *, int, int, double dist); int getNrOfNodes() { return nodes.size(); }; void setParent(FGAirport *par) { parent = par; }; 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 checkForCircularWaits(int id); }; #endif