]> git.mxchange.org Git - flightgear.git/blob - src/ATC/trafficcontrol.hxx
Merge branch 'next' of gitorious.org:fg/flightgear into next
[flightgear.git] / src / ATC / trafficcontrol.hxx
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
24
25 #ifndef __cplusplus
26 # error This library requires C++
27 #endif
28
29 #include <osg/Geode>
30 #include <osg/Geometry>
31 #include <osg/MatrixTransform>
32 #include <osg/Shape>
33
34 #include <simgear/compiler.h>
35 // There is probably a better include than sg_geodesy to get the SG_NM_TO_METER...
36 #include <simgear/math/sg_geodesy.hxx>
37 #include <simgear/debug/logstream.hxx>
38 #include <simgear/structure/SGReferenced.hxx>
39 #include <simgear/structure/SGSharedPtr.hxx>
40
41
42 #include <string>
43 #include <vector>
44 #include <list>
45
46 using std::string;
47 using std::vector;
48 using std::list;
49
50
51 typedef vector<int> intVec;
52 typedef vector<int>::iterator intVecIterator;
53
54
55 class FGAIFlightPlan;  // forward reference
56 class FGGroundNetwork; // forward reference
57 class FGAIAircraft;    // forward reference
58 class FGAirportDynamics;
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  *************************************************************************************/
65 class FGATCInstruction
66 {
67 private:
68     bool holdPattern;
69     bool holdPosition;
70     bool changeSpeed;
71     bool changeHeading;
72     bool changeAltitude;
73     bool resolveCircularWait;
74
75     double speed;
76     double heading;
77     double alt;
78 public:
79
80     FGATCInstruction();
81     bool hasInstruction   ();
82     bool getHoldPattern   () {
83         return holdPattern;
84     };
85     bool getHoldPosition  () {
86         return holdPosition;
87     };
88     bool getChangeSpeed   () {
89         return changeSpeed;
90     };
91     bool getChangeHeading () {
92         return changeHeading;
93     };
94     bool getChangeAltitude() {
95         return changeAltitude;
96     };
97
98     double getSpeed       () {
99         return speed;
100     };
101     double getHeading     () {
102         return heading;
103     };
104     double getAlt         () {
105         return alt;
106     };
107
108     bool getCheckForCircularWait() {
109         return resolveCircularWait;
110     };
111
112     void setHoldPattern   (bool val) {
113         holdPattern    = val;
114     };
115     void setHoldPosition  (bool val) {
116         holdPosition   = val;
117     };
118     void setChangeSpeed   (bool val) {
119         changeSpeed    = val;
120     };
121     void setChangeHeading (bool val) {
122         changeHeading  = val;
123     };
124     void setChangeAltitude(bool val) {
125         changeAltitude = val;
126     };
127
128     void setResolveCircularWait (bool val) {
129         resolveCircularWait = val;
130     };
131
132     void setSpeed       (double val) {
133         speed   = val;
134     };
135     void setHeading     (double val) {
136         heading = val;
137     };
138     void setAlt         (double val) {
139         alt     = val;
140     };
141 };
142
143
144
145
146
147 /**************************************************************************************
148  * class FGTrafficRecord
149  *************************************************************************************/
150 class FGTrafficRecord
151 {
152 private:
153     int id, waitsForId;
154     int currentPos;
155     int leg;
156     int frequencyId;
157     int state;
158     bool allowTransmission;
159     bool allowPushback;
160     int priority;
161     time_t timer;
162     intVec intentions;
163     FGATCInstruction instruction;
164     double latitude, longitude, heading, speed, altitude, radius;
165     string runway;
166     //FGAISchedule *trafficRef;
167     FGAIAircraft *aircraft;
168
169
170 public:
171     FGTrafficRecord();
172
173     void setId(int val)  {
174         id = val;
175     };
176     void setRadius(double rad) {
177         radius = rad;
178     };
179     void setPositionAndIntentions(int pos, FGAIFlightPlan *route);
180     void setRunway(string rwy) {
181         runway = rwy;
182     };
183     void setLeg(int lg) {
184         leg = lg;
185     };
186     int getId() {
187         return id;
188     };
189     int getState() {
190         return state;
191     };
192     void setState(int s) {
193         state = s;
194     }
195     FGATCInstruction getInstruction() {
196         return instruction;
197     };
198     bool hasInstruction() {
199         return instruction.hasInstruction();
200     };
201     void setPositionAndHeading(double lat, double lon, double hdg, double spd, double alt);
202     bool checkPositionAndIntentions(FGTrafficRecord &other);
203     int  crosses                   (FGGroundNetwork *, FGTrafficRecord &other);
204     bool isOpposing                (FGGroundNetwork *, FGTrafficRecord &other, int node);
205     
206     bool isActive(int margin);
207
208     bool onRoute(FGGroundNetwork *, FGTrafficRecord &other);
209
210     bool getSpeedAdjustment() {
211         return instruction.getChangeSpeed();
212     };
213
214     double getLatitude () {
215         return latitude ;
216     };
217     double getLongitude() {
218         return longitude;
219     };
220     double getHeading  () {
221         return heading  ;
222     };
223     double getSpeed    () {
224         return speed    ;
225     };
226     double getAltitude () {
227         return altitude ;
228     };
229     double getRadius   () {
230         return radius   ;
231     };
232
233     int getWaitsForId  () {
234         return waitsForId;
235     };
236
237     void setSpeedAdjustment(double spd);
238     void setHeadingAdjustment(double heading);
239     void clearSpeedAdjustment  () {
240         instruction.setChangeSpeed  (false);
241     };
242     void clearHeadingAdjustment() {
243         instruction.setChangeHeading(false);
244     };
245
246     bool hasHeadingAdjustment() {
247         return instruction.getChangeHeading();
248     };
249     bool hasHoldPosition() {
250         return instruction.getHoldPosition();
251     };
252     void setHoldPosition (bool inst) {
253         instruction.setHoldPosition(inst);
254     };
255
256     void setWaitsForId(int id) {
257         waitsForId = id;
258     };
259
260     void setResolveCircularWait()   {
261         instruction.setResolveCircularWait(true);
262     };
263     void clearResolveCircularWait() {
264         instruction.setResolveCircularWait(false);
265     };
266
267     string getRunway() {
268         return runway;
269     };
270     //void setCallSign(string clsgn) { callsign = clsgn; };
271     void setAircraft(FGAIAircraft *ref) {
272         aircraft = ref;
273     };
274     void updateState() {
275         state++;
276         allowTransmission=true;
277     };
278     //string getCallSign() { return callsign; };
279     FGAIAircraft *getAircraft() {
280         return aircraft;
281     };
282     int getTime() {
283         return timer;
284     };
285     int getLeg() {
286         return leg;
287     };
288     void setTime(time_t time) {
289         timer = time;
290     };
291
292     bool pushBackAllowed();
293     bool allowTransmissions() {
294         return allowTransmission;
295     };
296     void allowPushBack() { allowPushback =true;};
297     void denyPushBack () { allowPushback = false;};
298     void suppressRepeatedTransmissions () {
299         allowTransmission=false;
300     };
301     void allowRepeatedTransmissions () {
302         allowTransmission=true;
303     };
304     void nextFrequency() {
305         frequencyId++;
306     };
307     int  getNextFrequency() {
308         return frequencyId;
309     };
310     intVec& getIntentions() {
311         return intentions;
312     };
313     int getCurrentPosition() {
314         return currentPos;
315     };
316     void setPriority(int p) { priority = p; };
317     int getPriority()       { return priority; };
318 };
319
320 typedef list<FGTrafficRecord> TrafficVector;
321 typedef list<FGTrafficRecord>::iterator TrafficVectorIterator;
322
323 typedef vector<time_t> TimeVector;
324 typedef vector<time_t>::iterator TimeVectorIterator;
325
326 typedef vector<FGAIAircraft*> AircraftVec;
327 typedef vector<FGAIAircraft*>::iterator AircraftVecIterator;
328
329 /***********************************************************************
330  * Active runway, a utility class to keep track of which aircraft has
331  * clearance for a given runway.
332  **********************************************************************/
333 class ActiveRunway
334 {
335 private:
336     string rwy;
337     int currentlyCleared;
338     double distanceToFinal;
339     TimeVector estimatedArrivalTimes;
340     AircraftVec departureCue;
341
342 public:
343     ActiveRunway(string r, int cc) {
344         rwy = r;
345         currentlyCleared = cc;
346         distanceToFinal = 6.0 * SG_NM_TO_METER;
347     };
348
349     string getRunwayName() {
350         return rwy;
351     };
352     int    getCleared   () {
353         return currentlyCleared;
354     };
355     double getApproachDistance() {
356         return distanceToFinal;
357     };
358     //time_t getEstApproachTime() { return estimatedArrival; };
359
360     //void setEstApproachTime(time_t time) { estimatedArrival = time; };
361     void addToDepartureCue(FGAIAircraft *ac) {
362         departureCue.push_back(ac);
363     };
364     void setCleared(int number) {
365         currentlyCleared = number;
366     };
367     time_t requestTimeSlot(time_t eta);
368
369     int getDepartureCueSize() {
370         return departureCue.size();
371     };
372     FGAIAircraft* getFirstAircraftInDepartureCue() {
373         return departureCue.size() ? *(departureCue.begin()) : NULL;
374     };
375     void updateDepartureCue() {
376         departureCue.erase(departureCue.begin());
377     }
378 };
379
380 typedef vector<ActiveRunway> ActiveRunwayVec;
381 typedef vector<ActiveRunway>::iterator ActiveRunwayVecIterator;
382
383 /**
384  * class FGATCController
385  * NOTE: this class serves as an abstraction layer for all sorts of ATC controllers.
386  *************************************************************************************/
387 class FGATCController
388 {
389 private:
390
391
392 protected:
393     bool initialized;
394     bool available;
395     time_t lastTransmission;
396
397     double dt_count;
398     osg::Group* group;
399
400     string formatATCFrequency3_2(int );
401     string genTransponderCode(string fltRules);
402     bool isUserAircraft(FGAIAircraft*);
403
404 public:
405     typedef enum {
406         MSG_ANNOUNCE_ENGINE_START,
407         MSG_REQUEST_ENGINE_START,
408         MSG_PERMIT_ENGINE_START,
409         MSG_DENY_ENGINE_START,
410         MSG_ACKNOWLEDGE_ENGINE_START,
411         MSG_REQUEST_PUSHBACK_CLEARANCE,
412         MSG_PERMIT_PUSHBACK_CLEARANCE,
413         MSG_HOLD_PUSHBACK_CLEARANCE,
414         MSG_ACKNOWLEDGE_SWITCH_GROUND_FREQUENCY,
415         MSG_INITIATE_CONTACT,
416         MSG_ACKNOWLEDGE_INITIATE_CONTACT,
417         MSG_REQUEST_TAXI_CLEARANCE,
418         MSG_ISSUE_TAXI_CLEARANCE,
419         MSG_ACKNOWLEDGE_TAXI_CLEARANCE,
420         MSG_HOLD_POSITION,
421         MSG_ACKNOWLEDGE_HOLD_POSITION,
422         MSG_RESUME_TAXI,
423         MSG_ACKNOWLEDGE_RESUME_TAXI,
424         MSG_REPORT_RUNWAY_HOLD_SHORT,
425         MSG_ACKNOWLEDGE_REPORT_RUNWAY_HOLD_SHORT,
426         MSG_SWITCH_TOWER_FREQUENCY,
427         MSG_ACKNOWLEDGE_SWITCH_TOWER_FREQUENCY
428     } AtcMsgId;
429
430     typedef enum {
431         ATC_AIR_TO_GROUND,
432         ATC_GROUND_TO_AIR
433     } AtcMsgDir;
434     FGATCController();
435     virtual ~FGATCController();
436     void init();
437
438     virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
439                                   double lat, double lon,
440                                   double hdg, double spd, double alt, double radius, int leg,
441                                   FGAIAircraft *aircraft) = 0;
442     virtual void             signOff(int id) = 0;
443     virtual void             updateAircraftInformation(int id, double lat, double lon,
444             double heading, double speed, double alt, double dt) = 0;
445     virtual bool             hasInstruction(int id) = 0;
446     virtual FGATCInstruction getInstruction(int id) = 0;
447
448     double getDt() {
449         return dt_count;
450     };
451     void   setDt(double dt) {
452         dt_count = dt;
453     };
454     void transmit(FGTrafficRecord *rec, AtcMsgId msgId, AtcMsgDir msgDir, bool audible);
455     string getGateName(FGAIAircraft *aircraft);
456     virtual void render(bool) = 0;
457     virtual string getName()  = 0;
458
459     virtual void update(double) = 0;
460
461
462 private:
463
464     AtcMsgDir lastTransmissionDirection;
465 };
466
467 /******************************************************************************
468  * class FGTowerControl
469  *****************************************************************************/
470 class FGTowerController : public FGATCController
471 {
472 private:
473     TrafficVector activeTraffic;
474     ActiveRunwayVec activeRunways;
475     FGAirportDynamics *parent;
476
477 public:
478     FGTowerController(FGAirportDynamics *parent);
479     virtual ~FGTowerController() {};
480     virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
481                                   double lat, double lon,
482                                   double hdg, double spd, double alt, double radius, int leg,
483                                   FGAIAircraft *aircraft);
484     virtual void             signOff(int id);
485     virtual void             updateAircraftInformation(int id, double lat, double lon,
486             double heading, double speed, double alt, double dt);
487     virtual bool             hasInstruction(int id);
488     virtual FGATCInstruction getInstruction(int id);
489
490     virtual void render(bool);
491     virtual string getName();
492     virtual void update(double dt);
493     bool hasActiveTraffic() {
494         return activeTraffic.size() != 0;
495     };
496     TrafficVector &getActiveTraffic() {
497         return activeTraffic;
498     };
499 };
500
501 /******************************************************************************
502  * class FGStartupController
503  * handle
504  *****************************************************************************/
505
506 class FGStartupController : public FGATCController
507 {
508 private:
509     TrafficVector activeTraffic;
510     //ActiveRunwayVec activeRunways;
511     FGAirportDynamics *parent;
512
513 public:
514     FGStartupController(FGAirportDynamics *parent);
515     virtual ~FGStartupController() {};
516     virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
517                                   double lat, double lon,
518                                   double hdg, double spd, double alt, double radius, int leg,
519                                   FGAIAircraft *aircraft);
520     virtual void             signOff(int id);
521     virtual void             updateAircraftInformation(int id, double lat, double lon,
522             double heading, double speed, double alt, double dt);
523     virtual bool             hasInstruction(int id);
524     virtual FGATCInstruction getInstruction(int id);
525
526     virtual void render(bool);
527     virtual string getName();
528     virtual void update(double dt);
529
530     bool hasActiveTraffic() {
531         return activeTraffic.size() != 0;
532     };
533     TrafficVector &getActiveTraffic() {
534         return activeTraffic;
535     };
536
537     // Hpoefully, we can move this function to the base class, but I need to verify what is needed for the other controllers before doing so.
538     bool checkTransmissionState(int st, time_t now, time_t startTime, TrafficVectorIterator i, AtcMsgId msgId,
539                                 AtcMsgDir msgDir);
540
541 };
542
543 /******************************************************************************
544  * class FGTowerControl
545  *****************************************************************************/
546 class FGApproachController : public FGATCController
547 {
548 private:
549     TrafficVector activeTraffic;
550     ActiveRunwayVec activeRunways;
551     FGAirportDynamics *parent;
552
553 public:
554     FGApproachController(FGAirportDynamics * parent);
555     virtual ~FGApproachController() { };
556     virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
557                                   double lat, double lon,
558                                   double hdg, double spd, double alt, double radius, int leg,
559                                   FGAIAircraft *aircraft);
560     virtual void             signOff(int id);
561     virtual void             updateAircraftInformation(int id, double lat, double lon,
562             double heading, double speed, double alt, double dt);
563     virtual bool             hasInstruction(int id);
564     virtual FGATCInstruction getInstruction(int id);
565
566     virtual void render(bool);
567     virtual string getName();
568     virtual void update(double dt);
569
570     ActiveRunway* getRunway(string name);
571
572     bool hasActiveTraffic() {
573         return activeTraffic.size() != 0;
574     };
575     TrafficVector &getActiveTraffic() {
576         return activeTraffic;
577     };
578 };
579
580
581 #endif // _TRAFFIC_CONTROL_HXX