1 // trafficcontrol.hxx - classes to manage AIModels based air traffic control
2 // Written by Durk Talsma, started September 2006.
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.
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.
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.
21 #ifndef _TRAFFIC_CONTROL_HXX_
22 #define _TRAFFIC_CONTROL_HXX_
26 # error This library requires C++
30 #include <osg/Geometry>
31 #include <osg/MatrixTransform>
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>
51 typedef vector<int> intVec;
52 typedef vector<int>::iterator intVecIterator;
55 class FGAIFlightPlan; // forward reference
56 class FGGroundNetwork; // forward reference
57 class FGAIAircraft; // forward reference
58 class FGAirportDynamics;
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
73 bool resolveCircularWait;
81 bool hasInstruction ();
82 bool getHoldPattern () {
85 bool getHoldPosition () {
88 bool getChangeSpeed () {
91 bool getChangeHeading () {
94 bool getChangeAltitude() {
95 return changeAltitude;
101 double getHeading () {
108 bool getCheckForCircularWait() {
109 return resolveCircularWait;
112 void setHoldPattern (bool val) {
115 void setHoldPosition (bool val) {
118 void setChangeSpeed (bool val) {
121 void setChangeHeading (bool val) {
124 void setChangeAltitude(bool val) {
125 changeAltitude = val;
128 void setResolveCircularWait (bool val) {
129 resolveCircularWait = val;
132 void setSpeed (double val) {
135 void setHeading (double val) {
138 void setAlt (double val) {
147 /**************************************************************************************
148 * class FGTrafficRecord
149 *************************************************************************************/
150 class FGTrafficRecord
158 bool allowTransmission;
163 FGATCInstruction instruction;
164 double latitude, longitude, heading, speed, altitude, radius;
166 //FGAISchedule *trafficRef;
167 FGAIAircraft *aircraft;
173 void setId(int val) {
176 void setRadius(double rad) {
179 void setPositionAndIntentions(int pos, FGAIFlightPlan *route);
180 void setRunway(string rwy) {
183 void setLeg(int lg) {
192 void setState(int s) {
195 FGATCInstruction getInstruction() {
198 bool hasInstruction() {
199 return instruction.hasInstruction();
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);
206 bool isActive(int margin);
208 bool onRoute(FGGroundNetwork *, FGTrafficRecord &other);
210 bool getSpeedAdjustment() {
211 return instruction.getChangeSpeed();
214 double getLatitude () {
217 double getLongitude() {
220 double getHeading () {
226 double getAltitude () {
229 double getRadius () {
233 int getWaitsForId () {
237 void setSpeedAdjustment(double spd);
238 void setHeadingAdjustment(double heading);
239 void clearSpeedAdjustment () {
240 instruction.setChangeSpeed (false);
242 void clearHeadingAdjustment() {
243 instruction.setChangeHeading(false);
246 bool hasHeadingAdjustment() {
247 return instruction.getChangeHeading();
249 bool hasHoldPosition() {
250 return instruction.getHoldPosition();
252 void setHoldPosition (bool inst) {
253 instruction.setHoldPosition(inst);
256 void setWaitsForId(int id) {
260 void setResolveCircularWait() {
261 instruction.setResolveCircularWait(true);
263 void clearResolveCircularWait() {
264 instruction.setResolveCircularWait(false);
270 //void setCallSign(string clsgn) { callsign = clsgn; };
271 void setAircraft(FGAIAircraft *ref) {
276 allowTransmission=true;
278 //string getCallSign() { return callsign; };
279 FGAIAircraft *getAircraft() {
288 void setTime(time_t time) {
292 bool pushBackAllowed();
293 bool allowTransmissions() {
294 return allowTransmission;
296 void allowPushBack() { allowPushback =true;};
297 void denyPushBack () { allowPushback = false;};
298 void suppressRepeatedTransmissions () {
299 allowTransmission=false;
301 void allowRepeatedTransmissions () {
302 allowTransmission=true;
304 void nextFrequency() {
307 int getNextFrequency() {
310 intVec& getIntentions() {
313 int getCurrentPosition() {
316 void setPriority(int p) { priority = p; };
317 int getPriority() { return priority; };
320 typedef list<FGTrafficRecord> TrafficVector;
321 typedef list<FGTrafficRecord>::iterator TrafficVectorIterator;
323 typedef vector<time_t> TimeVector;
324 typedef vector<time_t>::iterator TimeVectorIterator;
326 typedef vector<FGAIAircraft*> AircraftVec;
327 typedef vector<FGAIAircraft*>::iterator AircraftVecIterator;
329 /***********************************************************************
330 * Active runway, a utility class to keep track of which aircraft has
331 * clearance for a given runway.
332 **********************************************************************/
337 int currentlyCleared;
338 double distanceToFinal;
339 TimeVector estimatedArrivalTimes;
340 AircraftVec departureCue;
343 ActiveRunway(string r, int cc) {
345 currentlyCleared = cc;
346 distanceToFinal = 6.0 * SG_NM_TO_METER;
349 string getRunwayName() {
353 return currentlyCleared;
355 double getApproachDistance() {
356 return distanceToFinal;
358 //time_t getEstApproachTime() { return estimatedArrival; };
360 //void setEstApproachTime(time_t time) { estimatedArrival = time; };
361 void addToDepartureCue(FGAIAircraft *ac) {
362 departureCue.push_back(ac);
364 void setCleared(int number) {
365 currentlyCleared = number;
367 time_t requestTimeSlot(time_t eta);
369 int getDepartureCueSize() {
370 return departureCue.size();
372 FGAIAircraft* getFirstAircraftInDepartureCue() {
373 return departureCue.size() ? *(departureCue.begin()) : NULL;
375 FGAIAircraft* getFirstOfStatus(int stat);
376 void updateDepartureCue() {
377 departureCue.erase(departureCue.begin());
379 void printDepartureCue();
382 typedef vector<ActiveRunway> ActiveRunwayVec;
383 typedef vector<ActiveRunway>::iterator ActiveRunwayVecIterator;
386 * class FGATCController
387 * NOTE: this class serves as an abstraction layer for all sorts of ATC controllers.
388 *************************************************************************************/
389 class FGATCController
397 time_t lastTransmission;
402 string formatATCFrequency3_2(int );
403 string genTransponderCode(string fltRules);
404 bool isUserAircraft(FGAIAircraft*);
408 MSG_ANNOUNCE_ENGINE_START,
409 MSG_REQUEST_ENGINE_START,
410 MSG_PERMIT_ENGINE_START,
411 MSG_DENY_ENGINE_START,
412 MSG_ACKNOWLEDGE_ENGINE_START,
413 MSG_REQUEST_PUSHBACK_CLEARANCE,
414 MSG_PERMIT_PUSHBACK_CLEARANCE,
415 MSG_HOLD_PUSHBACK_CLEARANCE,
416 MSG_ACKNOWLEDGE_SWITCH_GROUND_FREQUENCY,
417 MSG_INITIATE_CONTACT,
418 MSG_ACKNOWLEDGE_INITIATE_CONTACT,
419 MSG_REQUEST_TAXI_CLEARANCE,
420 MSG_ISSUE_TAXI_CLEARANCE,
421 MSG_ACKNOWLEDGE_TAXI_CLEARANCE,
423 MSG_ACKNOWLEDGE_HOLD_POSITION,
425 MSG_ACKNOWLEDGE_RESUME_TAXI,
426 MSG_REPORT_RUNWAY_HOLD_SHORT,
427 MSG_ACKNOWLEDGE_REPORT_RUNWAY_HOLD_SHORT,
428 MSG_SWITCH_TOWER_FREQUENCY,
429 MSG_ACKNOWLEDGE_SWITCH_TOWER_FREQUENCY
437 virtual ~FGATCController();
440 virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
441 double lat, double lon,
442 double hdg, double spd, double alt, double radius, int leg,
443 FGAIAircraft *aircraft) = 0;
444 virtual void signOff(int id) = 0;
445 virtual void updateAircraftInformation(int id, double lat, double lon,
446 double heading, double speed, double alt, double dt) = 0;
447 virtual bool hasInstruction(int id) = 0;
448 virtual FGATCInstruction getInstruction(int id) = 0;
453 void setDt(double dt) {
456 void transmit(FGTrafficRecord *rec, FGAirportDynamics *parent, AtcMsgId msgId, AtcMsgDir msgDir, bool audible);
457 string getGateName(FGAIAircraft *aircraft);
458 virtual void render(bool) = 0;
459 virtual string getName() = 0;
461 virtual void update(double) = 0;
466 AtcMsgDir lastTransmissionDirection;
469 /******************************************************************************
470 * class FGTowerControl
471 *****************************************************************************/
472 class FGTowerController : public FGATCController
475 TrafficVector activeTraffic;
476 ActiveRunwayVec activeRunways;
477 FGAirportDynamics *parent;
480 FGTowerController(FGAirportDynamics *parent);
481 virtual ~FGTowerController() {};
482 virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
483 double lat, double lon,
484 double hdg, double spd, double alt, double radius, int leg,
485 FGAIAircraft *aircraft);
486 virtual void signOff(int id);
487 virtual void updateAircraftInformation(int id, double lat, double lon,
488 double heading, double speed, double alt, double dt);
489 virtual bool hasInstruction(int id);
490 virtual FGATCInstruction getInstruction(int id);
492 virtual void render(bool);
493 virtual string getName();
494 virtual void update(double dt);
495 bool hasActiveTraffic() {
496 return activeTraffic.size() != 0;
498 TrafficVector &getActiveTraffic() {
499 return activeTraffic;
503 /******************************************************************************
504 * class FGStartupController
506 *****************************************************************************/
508 class FGStartupController : public FGATCController
511 TrafficVector activeTraffic;
512 //ActiveRunwayVec activeRunways;
513 FGAirportDynamics *parent;
516 FGStartupController(FGAirportDynamics *parent);
517 virtual ~FGStartupController() {};
518 virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
519 double lat, double lon,
520 double hdg, double spd, double alt, double radius, int leg,
521 FGAIAircraft *aircraft);
522 virtual void signOff(int id);
523 virtual void updateAircraftInformation(int id, double lat, double lon,
524 double heading, double speed, double alt, double dt);
525 virtual bool hasInstruction(int id);
526 virtual FGATCInstruction getInstruction(int id);
528 virtual void render(bool);
529 virtual string getName();
530 virtual void update(double dt);
532 bool hasActiveTraffic() {
533 return activeTraffic.size() != 0;
535 TrafficVector &getActiveTraffic() {
536 return activeTraffic;
539 // 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.
540 bool checkTransmissionState(int st, time_t now, time_t startTime, TrafficVectorIterator i, AtcMsgId msgId,
545 /******************************************************************************
546 * class FGTowerControl
547 *****************************************************************************/
548 class FGApproachController : public FGATCController
551 TrafficVector activeTraffic;
552 ActiveRunwayVec activeRunways;
553 FGAirportDynamics *parent;
556 FGApproachController(FGAirportDynamics * parent);
557 virtual ~FGApproachController() { };
558 virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
559 double lat, double lon,
560 double hdg, double spd, double alt, double radius, int leg,
561 FGAIAircraft *aircraft);
562 virtual void signOff(int id);
563 virtual void updateAircraftInformation(int id, double lat, double lon,
564 double heading, double speed, double alt, double dt);
565 virtual bool hasInstruction(int id);
566 virtual FGATCInstruction getInstruction(int id);
568 virtual void render(bool);
569 virtual string getName();
570 virtual void update(double dt);
572 ActiveRunway* getRunway(string name);
574 bool hasActiveTraffic() {
575 return activeTraffic.size() != 0;
577 TrafficVector &getActiveTraffic() {
578 return activeTraffic;
583 #endif // _TRAFFIC_CONTROL_HXX