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>
48 typedef vector<int> intVec;
49 typedef vector<int>::iterator intVecIterator;
52 class FGAIFlightPlan; // forward reference
53 class FGGroundNetwork; // forward reference
54 class FGAIAircraft; // forward reference
55 class FGAirportDynamics;
57 /**************************************************************************************
58 * class FGATCInstruction
59 * like class FGATC Controller, this class definition should go into its own file
60 * and or directory... For now, just testing this stuff out though...
61 *************************************************************************************/
62 class FGATCInstruction
70 bool resolveCircularWait;
78 bool hasInstruction ();
79 bool getHoldPattern () { return holdPattern; };
80 bool getHoldPosition () { return holdPosition; };
81 bool getChangeSpeed () { return changeSpeed; };
82 bool getChangeHeading () { return changeHeading; };
83 bool getChangeAltitude() { return changeAltitude; };
85 double getSpeed () { return speed; };
86 double getHeading () { return heading; };
87 double getAlt () { return alt; };
89 bool getCheckForCircularWait() { return resolveCircularWait; };
91 void setHoldPattern (bool val) { holdPattern = val; };
92 void setHoldPosition (bool val) { holdPosition = val; };
93 void setChangeSpeed (bool val) { changeSpeed = val; };
94 void setChangeHeading (bool val) { changeHeading = val; };
95 void setChangeAltitude(bool val) { changeAltitude = val; };
97 void setResolveCircularWait (bool val) { resolveCircularWait = val; };
99 void setSpeed (double val) { speed = val; };
100 void setHeading (double val) { heading = val; };
101 void setAlt (double val) { alt = val; };
108 /**************************************************************************************
109 * class FGTrafficRecord
110 *************************************************************************************/
111 class FGTrafficRecord
119 bool allowTransmission;
122 FGATCInstruction instruction;
123 double latitude, longitude, heading, speed, altitude, radius;
125 //FGAISchedule *trafficRef;
126 FGAIAircraft *aircraft;
132 void setId(int val) { id = val; };
133 void setRadius(double rad) { radius = rad;};
134 void setPositionAndIntentions(int pos, FGAIFlightPlan *route);
135 void setRunway(string rwy) { runway = rwy;};
136 void setLeg(int lg) { leg = lg;};
137 int getId() { return id;};
138 int getState() { return state;};
139 void setState(int s) { state = s;}
140 FGATCInstruction getInstruction() { return instruction;};
141 bool hasInstruction() { return instruction.hasInstruction(); };
142 void setPositionAndHeading(double lat, double lon, double hdg, double spd, double alt);
143 bool checkPositionAndIntentions(FGTrafficRecord &other);
144 int crosses (FGGroundNetwork *, FGTrafficRecord &other);
145 bool isOpposing (FGGroundNetwork *, FGTrafficRecord &other, int node);
147 bool onRoute(FGGroundNetwork *, FGTrafficRecord &other);
149 bool getSpeedAdjustment() { return instruction.getChangeSpeed(); };
151 double getLatitude () { return latitude ; };
152 double getLongitude() { return longitude; };
153 double getHeading () { return heading ; };
154 double getSpeed () { return speed ; };
155 double getAltitude () { return altitude ; };
156 double getRadius () { return radius ; };
158 int getWaitsForId () { return waitsForId; };
160 void setSpeedAdjustment(double spd);
161 void setHeadingAdjustment(double heading);
162 void clearSpeedAdjustment () { instruction.setChangeSpeed (false); };
163 void clearHeadingAdjustment() { instruction.setChangeHeading(false); };
165 bool hasHeadingAdjustment() { return instruction.getChangeHeading(); };
166 bool hasHoldPosition() { return instruction.getHoldPosition(); };
167 void setHoldPosition (bool inst) { instruction.setHoldPosition(inst); };
169 void setWaitsForId(int id) { waitsForId = id; };
171 void setResolveCircularWait() { instruction.setResolveCircularWait(true); };
172 void clearResolveCircularWait() { instruction.setResolveCircularWait(false); };
174 string getRunway() { return runway; };
175 //void setCallSign(string clsgn) { callsign = clsgn; };
176 void setAircraft(FGAIAircraft *ref) { aircraft = ref;};
177 void updateState() { state++; allowTransmission=true; };
178 //string getCallSign() { return callsign; };
179 FGAIAircraft *getAircraft() { return aircraft;};
180 int getTime() { return timer; };
181 int getLeg() { return leg; };
182 void setTime(time_t time) { timer = time; };
184 bool pushBackAllowed();
185 bool allowTransmissions() { return allowTransmission; };
186 void suppressRepeatedTransmissions () { allowTransmission=false; };
187 void allowRepeatedTransmissions () { allowTransmission=true; };
188 void nextFrequency() { frequencyId++; };
189 int getNextFrequency() { return frequencyId; };
190 intVec& getIntentions() { return intentions; };
191 int getCurrentPosition() { return currentPos; };
194 typedef vector<FGTrafficRecord> TrafficVector;
195 typedef vector<FGTrafficRecord>::iterator TrafficVectorIterator;
197 typedef vector<time_t> TimeVector;
198 typedef vector<time_t>::iterator TimeVectorIterator;
200 typedef vector<FGAIAircraft*> AircraftVec;
201 typedef vector<FGAIAircraft*>::iterator AircraftVecIterator;
203 /***********************************************************************
204 * Active runway, a utility class to keep track of which aircraft has
205 * clearance for a given runway.
206 **********************************************************************/
211 int currentlyCleared;
212 double distanceToFinal;
213 TimeVector estimatedArrivalTimes;
214 AircraftVec departureCue;
217 ActiveRunway(string r, int cc) { rwy = r; currentlyCleared = cc; distanceToFinal = 6.0 * SG_NM_TO_METER; };
219 string getRunwayName() { return rwy; };
220 int getCleared () { return currentlyCleared; };
221 double getApproachDistance() { return distanceToFinal; };
222 //time_t getEstApproachTime() { return estimatedArrival; };
224 //void setEstApproachTime(time_t time) { estimatedArrival = time; };
225 void addToDepartureCue(FGAIAircraft *ac) { departureCue.push_back(ac); };
226 void setCleared(int number) { currentlyCleared = number; };
227 time_t requestTimeSlot(time_t eta);
229 int getDepartureCueSize() { return departureCue.size(); };
230 FGAIAircraft* getFirstAircraftInDepartureCue() { return departureCue.size() ? *(departureCue.begin()) : NULL; };
231 void updateDepartureCue() { departureCue.erase(departureCue.begin()); }
234 typedef vector<ActiveRunway> ActiveRunwayVec;
235 typedef vector<ActiveRunway>::iterator ActiveRunwayVecIterator;
238 * class FGATCController
239 * NOTE: this class serves as an abstraction layer for all sorts of ATC controllers.
240 *************************************************************************************/
241 class FGATCController
249 time_t lastTransmission;
254 string formatATCFrequency3_2(int );
255 string genTransponderCode(string fltRules);
256 bool isUserAircraft(FGAIAircraft*);
260 MSG_ANNOUNCE_ENGINE_START,
261 MSG_REQUEST_ENGINE_START,
262 MSG_PERMIT_ENGINE_START,
263 MSG_DENY_ENGINE_START,
264 MSG_ACKNOWLEDGE_ENGINE_START,
265 MSG_REQUEST_PUSHBACK_CLEARANCE,
266 MSG_PERMIT_PUSHBACK_CLEARANCE,
267 MSG_HOLD_PUSHBACK_CLEARANCE,
268 MSG_ACKNOWLEDGE_SWITCH_GROUND_FREQUENCY,
269 MSG_INITIATE_CONTACT,
270 MSG_ACKNOWLEDGE_INITIATE_CONTACT,
271 MSG_REQUEST_TAXI_CLEARANCE,
272 MSG_ISSUE_TAXI_CLEARANCE,
273 MSG_ACKNOWLEDGE_TAXI_CLEARANCE,
275 MSG_ACKNOWLEDGE_HOLD_POSITION,
277 MSG_ACKNOWLEDGE_RESUME_TAXI,
278 MSG_REPORT_RUNWAY_HOLD_SHORT,
279 MSG_ACKNOWLEDGE_REPORT_RUNWAY_HOLD_SHORT,
280 MSG_SWITCH_TOWER_FREQUENCY,
281 MSG_ACKNOWLEDGE_SWITCH_TOWER_FREQUENCY
286 ATC_GROUND_TO_AIR } AtcMsgDir;
288 virtual ~FGATCController();
291 virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
292 double lat, double lon,
293 double hdg, double spd, double alt, double radius, int leg,
294 FGAIAircraft *aircraft) = 0;
295 virtual void signOff(int id) = 0;
296 virtual void updateAircraftInformation(int id, double lat, double lon,
297 double heading, double speed, double alt, double dt) = 0;
298 virtual bool hasInstruction(int id) = 0;
299 virtual FGATCInstruction getInstruction(int id) = 0;
301 double getDt() { return dt_count; };
302 void setDt(double dt) { dt_count = dt;};
303 void transmit(FGTrafficRecord *rec, FGAirportDynamics *parent, AtcMsgId msgId, AtcMsgDir msgDir, bool audible);
304 string getGateName(FGAIAircraft *aircraft);
305 virtual void render(bool) = 0;
306 virtual string getName() = 0;
307 double calculate_attenuation(FGTrafficRecord * rec, FGAirportDynamics *parent, int ground_to_air);
311 AtcMsgDir lastTransmissionDirection;
314 /******************************************************************************
315 * class FGTowerControl
316 *****************************************************************************/
317 class FGTowerController : public FGATCController
320 TrafficVector activeTraffic;
321 ActiveRunwayVec activeRunways;
322 FGAirportDynamics *parent;
325 FGTowerController(FGAirportDynamics *parent);
326 virtual ~FGTowerController() {};
327 virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
328 double lat, double lon,
329 double hdg, double spd, double alt, double radius, int leg,
330 FGAIAircraft *aircraft);
331 virtual void signOff(int id);
332 virtual void updateAircraftInformation(int id, double lat, double lon,
333 double heading, double speed, double alt, double dt);
334 virtual bool hasInstruction(int id);
335 virtual FGATCInstruction getInstruction(int id);
337 virtual void render(bool);
338 virtual string getName();
339 bool hasActiveTraffic() { return activeTraffic.size() != 0; };
340 TrafficVector &getActiveTraffic() { return activeTraffic; };
343 /******************************************************************************
344 * class FGStartupController
346 *****************************************************************************/
348 class FGStartupController : public FGATCController
351 TrafficVector activeTraffic;
352 //ActiveRunwayVec activeRunways;
353 FGAirportDynamics *parent;
356 FGStartupController(FGAirportDynamics *parent);
357 virtual ~FGStartupController() {};
358 virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
359 double lat, double lon,
360 double hdg, double spd, double alt, double radius, int leg,
361 FGAIAircraft *aircraft);
362 virtual void signOff(int id);
363 virtual void updateAircraftInformation(int id, double lat, double lon,
364 double heading, double speed, double alt, double dt);
365 virtual bool hasInstruction(int id);
366 virtual FGATCInstruction getInstruction(int id);
368 virtual void render(bool);
369 virtual string getName();
371 bool hasActiveTraffic() { return activeTraffic.size() != 0; };
372 TrafficVector &getActiveTraffic() { return activeTraffic; };
374 // 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.
375 bool checkTransmissionState(int st, time_t now, time_t startTime, TrafficVectorIterator i, AtcMsgId msgId,
380 /******************************************************************************
381 * class FGTowerControl
382 *****************************************************************************/
383 class FGApproachController : public FGATCController
386 TrafficVector activeTraffic;
387 ActiveRunwayVec activeRunways;
388 FGAirportDynamics *parent;
391 FGApproachController(FGAirportDynamics * parent);
392 virtual ~FGApproachController() { };
393 virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
394 double lat, double lon,
395 double hdg, double spd, double alt, double radius, int leg,
396 FGAIAircraft *aircraft);
397 virtual void signOff(int id);
398 virtual void updateAircraftInformation(int id, double lat, double lon,
399 double heading, double speed, double alt, double dt);
400 virtual bool hasInstruction(int id);
401 virtual FGATCInstruction getInstruction(int id);
403 virtual void render(bool);
404 virtual string getName();
406 ActiveRunway* getRunway(string name);
408 bool hasActiveTraffic() { return activeTraffic.size() != 0; };
409 TrafficVector &getActiveTraffic() { return activeTraffic; };
413 #endif // _TRAFFIC_CONTROL_HXX