FlightGear next
trafficcontrol.hxx
Go to the documentation of this file.
1// trafficcontrol.hxx - classes to manage AIModels based air traffic control
2// Written by Durk Talsma, started September 2006.
3//
4// This program is free software; you can redistribute it and/or
5// modify it under the terms of the GNU General Public License as
6// published by the Free Software Foundation; either version 2 of the
7// License, or (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful, but
10// WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program; if not, write to the Free Software
16// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17//
18// $Id$
19
20
21#ifndef _TRAFFIC_CONTROL_HXX_
22#define _TRAFFIC_CONTROL_HXX_
23
25
26#include <osg/Geode>
27#include <osg/Geometry>
28#include <osg/MatrixTransform>
29#include <osg/Shape>
30
31#include <simgear/compiler.h>
32// There is probably a better include than sg_geodesy to get the SG_NM_TO_METER...
33#include <simgear/math/sg_geodesy.hxx>
34#include <simgear/debug/logstream.hxx>
35#include <simgear/structure/SGReferenced.hxx>
36#include <simgear/structure/SGSharedPtr.hxx>
37
39
40class FGAIAircraft;
41typedef std::vector<FGAIAircraft*> AircraftVec;
42typedef std::vector<FGAIAircraft*>::iterator AircraftVecIterator;
43
44class FGAIFlightPlan;
45typedef std::vector<FGAIFlightPlan*> FlightPlanVec;
46typedef std::vector<FGAIFlightPlan*>::iterator FlightPlanVecIterator;
47typedef std::map<std::string, FlightPlanVec> FlightPlanVecMap;
48
49class FGTrafficRecord;
50typedef std::list<SGSharedPtr<FGTrafficRecord>> TrafficVector;
51typedef std::list<SGSharedPtr<FGTrafficRecord>>::const_iterator TrafficVectorIterator;
52
54typedef std::vector<ActiveRunwayQueue> ActiveRunwayVec;
55typedef std::vector<ActiveRunwayQueue>::iterator ActiveRunwayVecIterator;
56
57typedef std::vector<int> intVec;
58typedef std::vector<int>::iterator intVecIterator;
59
60/**************************************************************************************
61 * class FGATCInstruction
62 * like class FGATC Controller, this class definition should go into its own file
63 * and or directory... For now, just testing this stuff out though...
64 *************************************************************************************/
66{
67private:
68 bool holdPattern = false;
69 int requestedArrivalTime{0};
70 bool holdPosition = false;
71 bool requestHoldPosition = false;
72 bool resumeTaxi = false;
73 bool changeSpeed = false;
74 bool changeHeading = false;
75 bool changeAltitude = false;
76 bool resolveCircularWait = false;
77 int waitsForId;
78 int waitingSince;
79
80 double speed = std::numeric_limits<double>::max();
81 double heading;
82 double alt;
83
84
85public:
87
88 bool hasInstruction () const;
89 bool getHoldPattern () const {
90 return holdPattern;
91 };
92 void setRunwaySlot (int val) {
93 requestedArrivalTime = val;
94 };
95 int getRunwaySlot () const {
96 return requestedArrivalTime;
97 };
98 bool getHoldPosition () const {
99 return holdPosition;
100 };
102 return requestHoldPosition;
103 };
104 bool getResumeTaxi() const {
105 return resumeTaxi;
106 };
107
108 bool getChangeSpeed () const {
109 return changeSpeed;
110 };
111 bool getChangeHeading () const {
112 return changeHeading;
113 };
114 bool getChangeAltitude() const {
115 return changeAltitude;
116 };
118 return resolveCircularWait;
119 };
120
121 double getSpeed () const {
122 return speed;
123 };
124 double getHeading () const {
125 return heading;
126 };
127 double getAlt () const {
128 return alt;
129 };
130
131 int getWaitsForId () const {
132 return waitsForId;
133 };
134 int getWaitingSince () const {
135 return waitingSince;
136 };
137
138 void setHoldPattern (bool val) {
139 holdPattern = val;
140 };
141 void setHoldPosition (bool val) {
142 holdPosition = val;
143 };
144 void setRequestHoldPosition (bool val) {
145 requestHoldPosition = val;
146 };
147 void setResumeTaxi (bool val) {
148 resumeTaxi = val;
149 };
150 void setChangeSpeed (bool val) {
151 changeSpeed = val;
152 };
153 void setChangeHeading (bool val) {
154 changeHeading = val;
155 };
156 void setChangeAltitude(bool val) {
157 changeAltitude = val;
158 };
159 void setResolveCircularWait (bool val) {
160 resolveCircularWait = val;
161 };
162
163 void setSpeed (double val) {
164 speed = val;
165 };
166 void setHeading (double val) {
167 heading = val;
168 };
169 void setAlt (double val) {
170 alt = val;
171 };
172
173 void setWaitsForId(int id) {
174 waitsForId = id;
175 };
176 void setWaitingSince(int t) {
177 waitingSince = t;
178 };
179
180};
181
182
183/**************************************************************************************
184 * class FGTrafficRecord
185 * Represents the interaction of an AI Aircraft and ATC
186 *************************************************************************************/
187class FGTrafficRecord : public SGReferenced
188{
189private:
190 int id;
191 int currentPos;
192 int leg;
193 int frequencyId;
194 int state;
195 bool allowTransmission;
196 bool allowPushback;
197 int priority;
198 int plannedArrivalTime{0};
199 time_t timer;
200 intVec intentions;
201 FGATCInstruction instruction;
202 SGGeod pos;
203 double heading;
204 double headingDiff;
205 double speed;
206 double altitude;
207 double radius;
208 int takeOffStatus = AITakeOffStatus::NONE; // 1 = joined departure queue; 2 = Passed DepartureHold waypoint; handover control to tower; 0 = any other state.
209 time_t takeOffTimeSlot{0};
210 std::string callsign;
211 std::string runway;
212 SGSharedPtr<FGAIAircraft> aircraft;
213
214
215public:
217 virtual ~FGTrafficRecord();
218
219 void setId(int val) {
220 id = val;
221 };
222 void setRadius(double rad) {
223 radius = rad;
224 };
225 void setPositionAndIntentions(int pos, FGAIFlightPlan *route);
226 void setRunway(const std::string& rwy) {
227 runway = rwy;
228 };
229 void setLeg(int lg) {
230 leg = lg;
231 };
232 int getId() const {
233 return id;
234 };
235
238 int getState() const {
239 return state;
240 };
241
244 void setState(int s) {
245 state = s;
246 }
248 return instruction;
249 };
250 bool hasInstruction() const {
251 return instruction.hasInstruction();
252 };
253 void resetTakeOffStatus() { takeOffStatus = AITakeOffStatus::NONE; };
254 void setTakeOffStatus(int status) { takeOffStatus = status; };
255 int getTakeOffStatus() { return takeOffStatus; };
256 void setTakeOffSlot(time_t timeSlot) { takeOffTimeSlot = timeSlot; };
257 time_t getTakeOffSlot() { return takeOffTimeSlot; };
258
259 void setPositionAndHeading(double lat, double lon, double hdg, double spd, double alt, int leg);
262 bool isOpposing (FGGroundNetwork *, FGTrafficRecord &other, int node);
263
264 bool isActive(int margin) const;
265 bool isDead() const;
266 void clearATCController() const;
267
269
270 bool getSpeedAdjustment() const {
271 return instruction.getChangeSpeed();
272 };
273 void setPlannedArrivalTime (int val) {
274 plannedArrivalTime = val;
275 };
276
278 return plannedArrivalTime;
279 };
280 void setRunwaySlot( int val ) {
281 if (plannedArrivalTime) {
282 SG_LOG(SG_ATC, SG_BULK, callsign << "(" << id << ") Runwayslot timedelta " << (val-plannedArrivalTime));
283 }
284 instruction.setRunwaySlot(val);
285 };
286
288 return instruction.getRunwaySlot();
289 };
290 SGGeod getPos() {
291 return pos;
292 }
293 double getHeading () const {
294 return heading ;
295 };
296
297 double getHeadingDiff () const {
298 return headingDiff ;
299 };
300 double getSpeed () const {
301 return speed ;
302 };
303 double getFAltitude () const {
304 return altitude ;
305 };
306 double getRadius () const {
307 return radius ;
308 };
309
310 int getWaitsForId () const {
311 return instruction.getWaitsForId();
312 };
313 int getWaitingSince () const {
314 return instruction.getWaitingSince();
315 };
316
317 void setSpeedAdjustment(double spd);
318 void setHeadingAdjustment(double heading);
320 instruction.setChangeSpeed (false);
321 };
323 instruction.setChangeHeading(false);
324 };
325
326 bool hasHeadingAdjustment() const {
327 return instruction.getChangeHeading();
328 };
329 bool hasHoldPosition() const {
330 return instruction.getHoldPosition();
331 };
333 return instruction.getRequestHoldPosition();
334 };
335 bool getResumeTaxi() const {
336 return instruction.getResumeTaxi();
337 };
338 void setHoldPosition (bool inst) {
339 instruction.setHoldPosition(inst);
340 };
341 void setRequestHoldPosition (bool inst) {
342 instruction.setRequestHoldPosition(inst);
343 };
344 void setResumeTaxi (bool inst) {
345 instruction.setResumeTaxi(inst);
346 };
348 return instruction.getWaitsForId();
349 }
350 void setWaitsForId(int id) {
351 instruction.setWaitsForId(id);
352 };
353 void setWaitingSince(int id) {
354 instruction.setWaitingSince(id);
355 };
356
357
359 instruction.setResolveCircularWait(true);
360 };
362 instruction.setResolveCircularWait(false);
363 };
364
365 void setCallsign(const std::string& clsgn) { callsign = clsgn; };
366 const std::string& getCallsign() const {
367 return callsign;
368 };
369
370 const std::string& getRunway() const {
371 return runway;
372 };
373
374 void setAircraft(FGAIAircraft *ref);
375
376 void updateState() {
377 state++;
378 allowTransmission=true;
379 };
380
381 FGAIAircraft *getAircraft() const;
382
383 int getTime() const {
384 return timer;
385 };
386 int getLeg() const {
387 return leg;
388 };
389 void setTime(time_t time) {
390 timer = time;
391 };
392
393 bool pushBackAllowed() const;
394 bool allowTransmissions() const {
395 return allowTransmission;
396 };
397 void allowPushBack() { allowPushback =true;};
398 void denyPushBack () { allowPushback = false;};
400 allowTransmission=false;
401 };
403 allowTransmission=true;
404 };
406 frequencyId++;
407 };
408 int getNextFrequency() const {
409 return frequencyId;
410 };
412 return intentions;
413 };
414 int getCurrentPosition() const {
415 return currentPos;
416 };
417 void setPriority(int p) { priority = p; };
418 int getPriority() const { return priority; };
419};
420
421/***********************************************************************
422 * Active runway, a utility class to keep track of which aircraft has
423 * clearance for a given runway.
424 **********************************************************************/
426{
427public:
429 const time_t SEPARATION = 120;
430
431private:
432 const std::string icao;
433 const std::string rwy;
434 int currentlyCleared;
435 double distanceToFinal;
436 using AircraftRefVec = std::vector<SGSharedPtr<FGTrafficRecord>>;
437 AircraftRefVec runwayQueue;
438
439public:
440 ActiveRunwayQueue(const std::string& apt, const std::string& r, int cc);
441
442 const std::string& getRunwayName() const
443 {
444 return rwy;
445 };
446
447 int getCleared() const
448 {
449 return currentlyCleared;
450 };
451
452 double getApproachDistance() const
453 {
454 return distanceToFinal;
455 };
456
457 //time_t getEstApproachTime() { return estimatedArrival; };
458
459 //void setEstApproachTime(time_t time) { estimatedArrival = time; };
460 void addToQueue(SGSharedPtr<FGTrafficRecord> ac);
461
462 void setCleared(int number) {
463 currentlyCleared = number;
464 };
465 void requestTimeSlot(SGSharedPtr<FGTrafficRecord> eta);
466 void updateFirst(SGSharedPtr<FGTrafficRecord> eta, time_t newETA);
467 //time_t requestTimeSlot(time_t eta, std::string wakeCategory);
469 return runwayQueue.size();
470 };
471
472 const SGSharedPtr<FGTrafficRecord> getFirstAircraftInDepartureQueue() const;
473
474 const SGSharedPtr<FGTrafficRecord> getFirstOfStatus(int stat) const;
475
476 const SGSharedPtr<FGTrafficRecord> get(int id) const;
477
478 void removeFromQueue(int id);
479
481
482 void printRunwayQueue() const;
483
484 private:
485 void resort()
486 {
487 std::sort(runwayQueue.begin(), runwayQueue.end(),
488 [](const SGSharedPtr<FGTrafficRecord> a, const SGSharedPtr<FGTrafficRecord> b) {
489 return a->getRunwaySlot() < b->getRunwaySlot();
490 });
491 };
492};
493
494
495#endif // _TRAFFIC_CONTROL_HXX
#define p(x)
const SGSharedPtr< FGTrafficRecord > get(int id) const
Fetch the first aircraft in the departure queue with a certain status.
double getApproachDistance() const
void setCleared(int number)
ActiveRunwayQueue(const std::string &apt, const std::string &r, int cc)
const time_t SEPARATION
Separation between aircraft in seconds.
void updateFirst(SGSharedPtr< FGTrafficRecord > eta, time_t newETA)
Update the first and move all records backwards.
void requestTimeSlot(SGSharedPtr< FGTrafficRecord > eta)
Fetch next slot for the active runway.
const std::string & getRunwayName() const
const SGSharedPtr< FGTrafficRecord > getFirstAircraftInDepartureQueue() const
int getCleared() const
Get id of cleared AI Aircraft.
void printRunwayQueue() const
Output the contents of the departure queue vector nicely formatted.
const SGSharedPtr< FGTrafficRecord > getFirstOfStatus(int stat) const
Fetch the first aircraft in the departure queue with a certain status.
void removeFromQueue(int id)
void addToQueue(SGSharedPtr< FGTrafficRecord > ac)
void setHoldPattern(bool val)
void setResolveCircularWait(bool val)
bool getChangeHeading() const
bool getChangeAltitude() const
bool getHoldPosition() const
void setChangeHeading(bool val)
void setRunwaySlot(int val)
double getSpeed() const
int getWaitsForId() const
void setAlt(double val)
bool getChangeSpeed() const
void setWaitsForId(int id)
void setResumeTaxi(bool val)
double getHeading() const
void setSpeed(double val)
void setChangeSpeed(bool val)
int getWaitingSince() const
void setHeading(double val)
bool hasInstruction() const
bool getCheckForCircularWait() const
void setHoldPosition(bool val)
int getRunwaySlot() const
void setChangeAltitude(bool val)
void setRequestHoldPosition(bool val)
double getAlt() const
void setWaitingSince(int t)
bool getResumeTaxi() const
bool getHoldPattern() const
bool getRequestHoldPosition() const
void setRequestHoldPosition(bool inst)
double getRadius() const
void setHeadingAdjustment(double heading)
bool checkPositionAndIntentions(FGTrafficRecord &other)
Check if another aircraft is ahead of the current one, and on the same taxiway.
int getCurrentPosition() const
void setPlannedArrivalTime(int val)
void setWaitingSince(int id)
void setPositionAndHeading(double lat, double lon, double hdg, double spd, double alt, int leg)
void setSpeedAdjustment(double spd)
bool isActive(int margin) const
bool hasHoldPosition() const
bool getRequestHoldPosition() const
void setPositionAndIntentions(int pos, FGAIFlightPlan *route)
bool allowTransmissions() const
bool pushBackAllowed() const
bool getSpeedAdjustment() const
void setState(int s)
Set the current ATC State of type.
double getHeadingDiff() const
The last diff of heading when turning.
void setRadius(double rad)
void allowRepeatedTransmissions()
double getSpeed() const
bool isOpposing(FGGroundNetwork *, FGTrafficRecord &other, int node)
bool hasHeadingAdjustment() const
intVec & getIntentions()
double getFAltitude() const
int getState() const
Return the current ATC State of type.
int crosses(FGGroundNetwork *, FGTrafficRecord &other)
void setPriority(int p)
void suppressRepeatedTransmissions()
int getPlannedArrivalTime() const
Arrival time planned by aircraft.
const std::string & getRunway() const
FGAIAircraft * getAircraft() const
void setCallsign(const std::string &clsgn)
int getPriority() const
int getWaitingSince() const
void setTakeOffSlot(time_t timeSlot)
FGATCInstruction getInstruction() const
void setLeg(int lg)
void setHoldPosition(bool inst)
void setTakeOffStatus(int status)
void setId(int val)
double getHeading() const
void setRunwaySlot(int val)
const std::string & getCallsign() const
int getNextFrequency() const
virtual ~FGTrafficRecord()
bool isDead() const
void setResumeTaxi(bool inst)
void setWaitsForId(int id)
int getRunwaySlot()
Arrival time requested by ATC.
void setAircraft(FGAIAircraft *ref)
bool hasInstruction() const
int getWaitsForId() const
void setTime(time_t time)
void clearATCController() const
bool getResumeTaxi() const
bool onRoute(FGGroundNetwork *, FGTrafficRecord &other)
void clearResolveCircularWait()
void setRunway(const std::string &rwy)
static int status
std::vector< int > intVec
std::vector< int >::iterator intVecIterator
std::vector< int > intVec
std::vector< FGAIFlightPlan * >::iterator FlightPlanVecIterator
std::list< SGSharedPtr< FGTrafficRecord > >::const_iterator TrafficVectorIterator
std::vector< FGAIAircraft * > AircraftVec
std::map< std::string, FlightPlanVec > FlightPlanVecMap
std::vector< FGAIAircraft * >::iterator AircraftVecIterator
std::vector< ActiveRunwayQueue > ActiveRunwayVec
std::vector< ActiveRunwayQueue >::iterator ActiveRunwayVecIterator
std::vector< FGAIFlightPlan * > FlightPlanVec
std::list< SGSharedPtr< FGTrafficRecord > > TrafficVector