FlightGear next
groundnetwork.hxx
Go to the documentation of this file.
1/*
2 * SPDX-FileName: groundnet.hxx
3 * SPDX-FileComment: A number of classes to handle taxiway assignments by the AI code
4 * SPDX-FileCopyrightText: Copyright (C) 2004 Durk Talsma
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
8#pragma once
9
10#include <string>
11#include <unordered_map>
12
13#include <simgear/compiler.h>
14
15#include "gnnode.hxx"
16#include "parking.hxx"
17
18
19class FGAirportDynamicsXMLLoader;
20
21typedef std::vector<int> intVec;
22typedef std::vector<int>::iterator intVecIterator;
23
24class Block
25{
26private:
27 int id;
28 time_t blocktime;
29 time_t touch;
30
31public:
32 Block(int i, time_t bt, time_t curr) : blocktime{bt}, touch{curr}
33 {
34 id = i;
35 }
36
37 ~Block() {}
38
39 int getId() { return id; }
40
41 void updateTimeStamps(time_t bt, time_t now)
42 {
43 blocktime = (bt < blocktime) ? bt : blocktime;
44 touch = now;
45 }
46
47 time_t getBlockTime() const { return blocktime; }
48 time_t getTimeStamp() { return touch; }
49 bool operator<(const Block& other) const { return blocktime < other.blocktime; }
50};
51
52/***************************************************************************************
53 * class FGTaxiSegment
54 **************************************************************************************/
56{
57private:
58 // weak (non-owning) pointers deliberately here:
59 // the ground-network owns the nodes
60 const FGTaxiNode* startNode;
61 const FGTaxiNode* endNode;
62
63 bool isActive;
64 BlockList blockTimes;
65
66 int index;
67 FGTaxiSegment* oppositeDirection; // also deliberately weak
68
69 friend class FGGroundNetwork;
70
71public:
73
74 void setIndex(int val)
75 {
76 index = val;
77 }
78
79 void setDimensions(double elevation);
80 void block(int id, time_t blockTime, time_t now);
81 void unblock(time_t now);
82 bool hasBlock(time_t now);
83
84 FGTaxiNodeRef getEnd() const;
85 FGTaxiNodeRef getStart() const;
86
87 double getLength() const;
88
89 // compute the center of the arc
90 SGGeod getCenter() const;
91
92 double getHeading() const;
93
94 int getIndex() const
95 {
96 return index;
97 }
98
99 int getPenalty(int nGates);
100
101 bool operator<(const FGTaxiSegment& other) const
102 {
103 return index < other.index;
104 }
105
107 {
108 return oppositeDirection;
109 }
110};
111
112/***************************************************************************************
113 * class FGTaxiRoute
114 **************************************************************************************/
116{
117private:
118 FGTaxiNodeVector nodes;
119 intVec routes;
120 double distance;
121 FGTaxiNodeVector::iterator currNode;
122 intVec::iterator currRoute;
123
124public:
126 {
127 distance = 0;
128 currNode = nodes.begin();
129 currRoute = routes.begin();
130 }
131
132 FGTaxiRoute(const FGTaxiNodeVector& nds, const intVec& rts, double dist, int dpth);
133
134
136 {
137 nodes = other.nodes;
138 routes = other.routes;
139 distance = other.distance;
140 currNode = nodes.begin();
141 currRoute = routes.begin();
142 return *this;
143 }
144
145 FGTaxiRoute(const FGTaxiRoute& copy) : nodes(copy.nodes),
146 routes(copy.routes),
147 distance(copy.distance),
148 currNode(nodes.begin()),
149 currRoute(routes.begin()) {}
150
151 bool operator<(const FGTaxiRoute& other) const
152 {
153 return distance < other.distance;
154 }
155 bool empty()
156 {
157 return nodes.empty();
158 }
159 bool next(FGTaxiNodeRef& nde, int* rte);
160
161 void first()
162 {
163 currNode = nodes.begin();
164 currRoute = routes.begin();
165 }
166 int size()
167 {
168 return nodes.size();
169 }
171 {
172 return nodes.end() - currNode;
173 }
174};
175
176/**************************************************************************************
177 * class FGGroundNetWork
178 *************************************************************************************/
180{
181private:
183
184 bool hasNetwork;
185 bool networkInitialized;
186
187 int version;
188
189 FGTaxiSegmentVector segments;
190
191 FGAirport* parent;
192
193 FGParkingList m_parkings;
194 FGTaxiNodeVector m_nodes;
195
196 FGTaxiNodeRef findNodeByIndex(int index) const;
197
198 void addSegment(const FGTaxiNodeRef& from, const FGTaxiNodeRef& to);
199 void addParking(const FGParkingRef& park);
200
201 void addAwosFreq(int val)
202 {
203 freqAwos.push_back(val);
204 }
205 void addUnicomFreq(int val)
206 {
207 freqUnicom.push_back(val);
208 }
209 void addClearanceFreq(int val)
210 {
211 freqClearance.push_back(val);
212 }
213 void addGroundFreq(int val)
214 {
215 freqGround.push_back(val);
216 }
217 void addTowerFreq(int val)
218 {
219 freqTower.push_back(val);
220 }
221 void addApproachFreq(int val)
222 {
223 freqApproach.push_back(val);
224 }
225
226 intVec freqAwos; // </AWOS>
227 intVec freqUnicom; // </UNICOM>
228 intVec freqClearance; // </CLEARANCE>
229 intVec freqGround; // </GROUND>
230 intVec freqTower; // </TOWER>
231 intVec freqApproach; // </APPROACH>
232
233 using NodeFromSegmentMap = std::unordered_multimap<FGTaxiNode*, FGTaxiSegment*>;
234
236 NodeFromSegmentMap m_segmentsEndingAtNodeMap;
237
238public:
239 explicit FGGroundNetwork(FGAirport* pr);
240 virtual ~FGGroundNetwork();
241
242 void setVersion(int v) { version = v; }
243 int getVersion() { return version; }
244
245 void init();
246 bool exists()
247 {
248 return hasNetwork;
249 }
250
252 {
253 return parent;
254 }
255
256 FGTaxiNodeRef findNearestNode(const SGGeod& aGeod) const;
257 FGTaxiNodeRef findNearestNodeOnRunwayEntry(const SGGeod& aGeod) const;
258 FGTaxiNodeRef findNearestNodeOnRunwayExit(const SGGeod& aGeod, FGRunway* aRunway = NULL) const;
259
260 FGTaxiNodeRef findNearestNodeOffRunway(const SGGeod& aGeod, FGRunway* aRunway, double distanceM) const;
261
262 FGTaxiSegment* findOppositeSegment(unsigned int index) const;
263
264 const FGParkingList& allParkings() const;
265
266 FGParkingRef getParkingByIndex(unsigned int index) const;
267
268 FGParkingRef findParkingByName(const std::string& name) const;
269
276 FGTaxiSegment* findSegment(const FGTaxiNode* from, const FGTaxiNode* to) const;
278 FGTaxiSegment* findSegmentByHeading(const FGTaxiNode* from, const double heading) const;
279 FGTaxiSegment* findSegment(unsigned int idx) const;
284
285
286 FGTaxiRoute findShortestRoute(FGTaxiNode* start, FGTaxiNode* end, bool fullSearch = true);
287
288
289 void blockSegmentsEndingAt(const FGTaxiSegment* seg, int blockId, time_t blockTime, time_t now);
290
291 void addVersion(int v) { version = v; };
292 void unblockAllSegments(time_t now);
293
294 const intVec& getApproachFrequencies() const;
295 const intVec& getTowerFrequencies() const;
296 const intVec& getGroundFrequencies() const;
297};
#define i(x)
SGSharedPtr< FGTaxiNode > FGTaxiNodeRef
std::vector< FGTaxiSegment * > FGTaxiSegmentVector
std::vector< FGParkingRef > FGParkingList
std::vector< Block > BlockList
std::vector< FGTaxiNodeRef > FGTaxiNodeVector
SGSharedPtr< FGParking > FGParkingRef
bool operator<(const Block &other) const
Block(int i, time_t bt, time_t curr)
time_t getTimeStamp()
time_t getBlockTime() const
int getId()
void updateTimeStamps(time_t bt, time_t now)
void addVersion(int v)
FGTaxiNodeRef findNearestNodeOffRunway(const SGGeod &aGeod, FGRunway *aRunway, double distanceM) const
FGGroundNetwork(FGAirport *pr)
FGTaxiNodeRef findNearestNodeOnRunwayExit(const SGGeod &aGeod, FGRunway *aRunway=NULL) const
Returns the nearest node in that is in direction of runway heading.
FGTaxiNodeVector findSegmentsFrom(const FGTaxiNodeRef &from) const
Find the segments connected to the node.
FGTaxiSegment * findSegmentByHeading(const FGTaxiNode *from, const double heading) const
Find the taxiway segment best matching the heading.
FGAirport * airport() const
FGParkingRef findParkingByName(const std::string &name) const
const intVec & getApproachFrequencies() const
FGTaxiNodeRef findNearestNodeOnRunwayEntry(const SGGeod &aGeod) const
const intVec & getGroundFrequencies() const
FGParkingRef getParkingByIndex(unsigned int index) const
void unblockAllSegments(time_t now)
FGTaxiSegment * findSegment(const FGTaxiNode *from, const FGTaxiNode *to) const
Find the taxiway segment joining two (ground-net) nodes.
FGTaxiSegment * findSegment(unsigned int idx) const
FGTaxiNodeRef findNearestNode(const SGGeod &aGeod) const
friend class FGGroundNetXMLLoader
virtual ~FGGroundNetwork()
FGTaxiSegment * findOppositeSegment(unsigned int index) const
FGTaxiRoute findShortestRoute(FGTaxiNode *start, FGTaxiNode *end, bool fullSearch=true)
void blockSegmentsEndingAt(const FGTaxiSegment *seg, int blockId, time_t blockTime, time_t now)
const intVec & getTowerFrequencies() const
const FGParkingList & allParkings() const
void setVersion(int v)
bool operator<(const FGTaxiRoute &other) const
FGTaxiRoute & operator=(const FGTaxiRoute &other)
bool next(FGTaxiNodeRef &nde, int *rte)
FGTaxiRoute(const FGTaxiRoute &copy)
FGTaxiSegment(FGTaxiNode *start, FGTaxiNode *end)
void setDimensions(double elevation)
FGTaxiNodeRef getEnd() const
double getLength() const
int getPenalty(int nGates)
bool hasBlock(time_t now)
FGTaxiSegment * opposite()
void unblock(time_t now)
bool operator<(const FGTaxiSegment &other) const
int getIndex() const
FGTaxiNodeRef getStart() const
void block(int id, time_t blockTime, time_t now)
double getHeading() const
void setIndex(int val)
SGGeod getCenter() const
friend class FGGroundNetwork
const char * name
std::vector< int > intVec
std::vector< int >::iterator intVecIterator