1
0
Fork 0
flightgear/src/ATC/trafficcontrol.hxx
Tom Paoletti 81cd33e2fa Performance optimization: empty() instead of size()>0
empty() is guaranteed to be constant complexity for both vectors and lists, while size() has linear complexity for lists.
2013-08-19 09:01:59 +01:00

569 lines
16 KiB
C++

// trafficcontrol.hxx - classes to manage AIModels based air traffic control
// Written by Durk Talsma, started September 2006.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
#ifndef _TRAFFIC_CONTROL_HXX_
#define _TRAFFIC_CONTROL_HXX_
#include <Airports/airports_fwd.hxx>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/MatrixTransform>
#include <osg/Shape>
#include <simgear/compiler.h>
// There is probably a better include than sg_geodesy to get the SG_NM_TO_METER...
#include <simgear/math/sg_geodesy.hxx>
#include <simgear/debug/logstream.hxx>
#include <simgear/structure/SGReferenced.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
class FGAIAircraft;
typedef std::vector<FGAIAircraft*> AircraftVec;
typedef std::vector<FGAIAircraft*>::iterator AircraftVecIterator;
class FGAIFlightPlan;
typedef std::vector<FGAIFlightPlan*> FlightPlanVec;
typedef std::vector<FGAIFlightPlan*>::iterator FlightPlanVecIterator;
typedef std::map<std::string, FlightPlanVec> FlightPlanVecMap;
class FGTrafficRecord;
typedef std::list<FGTrafficRecord> TrafficVector;
typedef std::list<FGTrafficRecord>::iterator TrafficVectorIterator;
class ActiveRunway;
typedef std::vector<ActiveRunway> ActiveRunwayVec;
typedef std::vector<ActiveRunway>::iterator ActiveRunwayVecIterator;
typedef std::vector<int> intVec;
typedef std::vector<int>::iterator intVecIterator;
/**************************************************************************************
* class FGATCInstruction
* like class FGATC Controller, this class definition should go into its own file
* and or directory... For now, just testing this stuff out though...
*************************************************************************************/
class FGATCInstruction
{
private:
bool holdPattern;
bool holdPosition;
bool changeSpeed;
bool changeHeading;
bool changeAltitude;
bool resolveCircularWait;
double speed;
double heading;
double alt;
public:
FGATCInstruction();
bool hasInstruction () const;
bool getHoldPattern () const {
return holdPattern;
};
bool getHoldPosition () const {
return holdPosition;
};
bool getChangeSpeed () const {
return changeSpeed;
};
bool getChangeHeading () const {
return changeHeading;
};
bool getChangeAltitude() const {
return changeAltitude;
};
double getSpeed () const {
return speed;
};
double getHeading () const {
return heading;
};
double getAlt () const {
return alt;
};
bool getCheckForCircularWait() const {
return resolveCircularWait;
};
void setHoldPattern (bool val) {
holdPattern = val;
};
void setHoldPosition (bool val) {
holdPosition = val;
};
void setChangeSpeed (bool val) {
changeSpeed = val;
};
void setChangeHeading (bool val) {
changeHeading = val;
};
void setChangeAltitude(bool val) {
changeAltitude = val;
};
void setResolveCircularWait (bool val) {
resolveCircularWait = val;
};
void setSpeed (double val) {
speed = val;
};
void setHeading (double val) {
heading = val;
};
void setAlt (double val) {
alt = val;
};
};
/**************************************************************************************
* class FGTrafficRecord
*************************************************************************************/
class FGTrafficRecord
{
private:
int id, waitsForId;
int currentPos;
int leg;
int frequencyId;
int state;
bool allowTransmission;
bool allowPushback;
int priority;
time_t timer;
intVec intentions;
FGATCInstruction instruction;
double latitude, longitude, heading, speed, altitude, radius;
std::string runway;
//FGAISchedule *trafficRef;
FGAIAircraft *aircraft;
public:
FGTrafficRecord();
void setId(int val) {
id = val;
};
void setRadius(double rad) {
radius = rad;
};
void setPositionAndIntentions(int pos, FGAIFlightPlan *route);
void setRunway(const std::string& rwy) {
runway = rwy;
};
void setLeg(int lg) {
leg = lg;
};
int getId() {
return id;
};
int getState() {
return state;
};
void setState(int s) {
state = s;
}
FGATCInstruction getInstruction() {
return instruction;
};
bool hasInstruction() {
return instruction.hasInstruction();
};
void setPositionAndHeading(double lat, double lon, double hdg, double spd, double alt);
bool checkPositionAndIntentions(FGTrafficRecord &other);
int crosses (FGGroundNetwork *, FGTrafficRecord &other);
bool isOpposing (FGGroundNetwork *, FGTrafficRecord &other, int node);
bool isActive(int margin) const;
bool onRoute(FGGroundNetwork *, FGTrafficRecord &other);
bool getSpeedAdjustment() const {
return instruction.getChangeSpeed();
};
double getLatitude () const {
return latitude ;
};
double getLongitude() const {
return longitude;
};
double getHeading () const {
return heading ;
};
double getSpeed () const {
return speed ;
};
double getAltitude () const {
return altitude ;
};
double getRadius () const {
return radius ;
};
int getWaitsForId () const {
return waitsForId;
};
void setSpeedAdjustment(double spd);
void setHeadingAdjustment(double heading);
void clearSpeedAdjustment () {
instruction.setChangeSpeed (false);
};
void clearHeadingAdjustment() {
instruction.setChangeHeading(false);
};
bool hasHeadingAdjustment() const {
return instruction.getChangeHeading();
};
bool hasHoldPosition() const {
return instruction.getHoldPosition();
};
void setHoldPosition (bool inst) {
instruction.setHoldPosition(inst);
};
void setWaitsForId(int id) {
waitsForId = id;
};
void setResolveCircularWait() {
instruction.setResolveCircularWait(true);
};
void clearResolveCircularWait() {
instruction.setResolveCircularWait(false);
};
const std::string& getRunway() const {
return runway;
};
//void setCallSign(string clsgn) { callsign = clsgn; };
void setAircraft(FGAIAircraft *ref) {
aircraft = ref;
};
void updateState() {
state++;
allowTransmission=true;
};
//string getCallSign() { return callsign; };
FGAIAircraft *getAircraft() const {
return aircraft;
};
int getTime() const {
return timer;
};
int getLeg() const {
return leg;
};
void setTime(time_t time) {
timer = time;
};
bool pushBackAllowed() const;
bool allowTransmissions() const {
return allowTransmission;
};
void allowPushBack() { allowPushback =true;};
void denyPushBack () { allowPushback = false;};
void suppressRepeatedTransmissions () {
allowTransmission=false;
};
void allowRepeatedTransmissions () {
allowTransmission=true;
};
void nextFrequency() {
frequencyId++;
};
int getNextFrequency() const {
return frequencyId;
};
intVec& getIntentions() {
return intentions;
};
int getCurrentPosition() const {
return currentPos;
};
void setPriority(int p) { priority = p; };
int getPriority() const { return priority; };
};
/***********************************************************************
* Active runway, a utility class to keep track of which aircraft has
* clearance for a given runway.
**********************************************************************/
class ActiveRunway
{
private:
std::string rwy;
int currentlyCleared;
double distanceToFinal;
TimeVector estimatedArrivalTimes;
AircraftVec departureCue;
public:
ActiveRunway(const std::string& r, int cc) {
rwy = r;
currentlyCleared = cc;
distanceToFinal = 6.0 * SG_NM_TO_METER;
};
std::string getRunwayName() {
return rwy;
};
int getCleared () {
return currentlyCleared;
};
double getApproachDistance() {
return distanceToFinal;
};
//time_t getEstApproachTime() { return estimatedArrival; };
//void setEstApproachTime(time_t time) { estimatedArrival = time; };
void addToDepartureCue(FGAIAircraft *ac) {
departureCue.push_back(ac);
};
void setCleared(int number) {
currentlyCleared = number;
};
time_t requestTimeSlot(time_t eta);
int getDepartureCueSize() {
return departureCue.size();
};
FGAIAircraft* getFirstAircraftInDepartureCue() {
return departureCue.size() ? *(departureCue.begin()) : NULL;
};
FGAIAircraft* getFirstOfStatus(int stat);
void updateDepartureCue() {
departureCue.erase(departureCue.begin());
}
void printDepartureCue();
};
/**
* class FGATCController
* NOTE: this class serves as an abstraction layer for all sorts of ATC controllers.
*************************************************************************************/
class FGATCController
{
private:
protected:
bool initialized;
bool available;
time_t lastTransmission;
double dt_count;
osg::Group* group;
std::string formatATCFrequency3_2(int );
std::string genTransponderCode(const std::string& fltRules);
bool isUserAircraft(FGAIAircraft*);
public:
typedef enum {
MSG_ANNOUNCE_ENGINE_START,
MSG_REQUEST_ENGINE_START,
MSG_PERMIT_ENGINE_START,
MSG_DENY_ENGINE_START,
MSG_ACKNOWLEDGE_ENGINE_START,
MSG_REQUEST_PUSHBACK_CLEARANCE,
MSG_PERMIT_PUSHBACK_CLEARANCE,
MSG_HOLD_PUSHBACK_CLEARANCE,
MSG_ACKNOWLEDGE_SWITCH_GROUND_FREQUENCY,
MSG_INITIATE_CONTACT,
MSG_ACKNOWLEDGE_INITIATE_CONTACT,
MSG_REQUEST_TAXI_CLEARANCE,
MSG_ISSUE_TAXI_CLEARANCE,
MSG_ACKNOWLEDGE_TAXI_CLEARANCE,
MSG_HOLD_POSITION,
MSG_ACKNOWLEDGE_HOLD_POSITION,
MSG_RESUME_TAXI,
MSG_ACKNOWLEDGE_RESUME_TAXI,
MSG_REPORT_RUNWAY_HOLD_SHORT,
MSG_ACKNOWLEDGE_REPORT_RUNWAY_HOLD_SHORT,
MSG_SWITCH_TOWER_FREQUENCY,
MSG_ACKNOWLEDGE_SWITCH_TOWER_FREQUENCY
} AtcMsgId;
typedef enum {
ATC_AIR_TO_GROUND,
ATC_GROUND_TO_AIR
} AtcMsgDir;
FGATCController();
virtual ~FGATCController();
void init();
virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
double lat, double lon,
double hdg, double spd, double alt, double radius, int leg,
FGAIAircraft *aircraft) = 0;
virtual void signOff(int id) = 0;
virtual void updateAircraftInformation(int id, double lat, double lon,
double heading, double speed, double alt, double dt) = 0;
virtual bool hasInstruction(int id) = 0;
virtual FGATCInstruction getInstruction(int id) = 0;
double getDt() {
return dt_count;
};
void setDt(double dt) {
dt_count = dt;
};
void transmit(FGTrafficRecord *rec, FGAirportDynamics *parent, AtcMsgId msgId, AtcMsgDir msgDir, bool audible);
std::string getGateName(FGAIAircraft *aircraft);
virtual void render(bool) = 0;
virtual std::string getName() = 0;
virtual void update(double) = 0;
private:
AtcMsgDir lastTransmissionDirection;
};
/******************************************************************************
* class FGTowerControl
*****************************************************************************/
class FGTowerController : public FGATCController
{
private:
TrafficVector activeTraffic;
ActiveRunwayVec activeRunways;
FGAirportDynamics *parent;
public:
FGTowerController(FGAirportDynamics *parent);
virtual ~FGTowerController() {};
virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
double lat, double lon,
double hdg, double spd, double alt, double radius, int leg,
FGAIAircraft *aircraft);
virtual void signOff(int id);
virtual void updateAircraftInformation(int id, double lat, double lon,
double heading, double speed, double alt, double dt);
virtual bool hasInstruction(int id);
virtual FGATCInstruction getInstruction(int id);
virtual void render(bool);
virtual std::string getName();
virtual void update(double dt);
bool hasActiveTraffic() {
return ! activeTraffic.empty();
};
TrafficVector &getActiveTraffic() {
return activeTraffic;
};
};
/******************************************************************************
* class FGStartupController
* handle
*****************************************************************************/
class FGStartupController : public FGATCController
{
private:
TrafficVector activeTraffic;
//ActiveRunwayVec activeRunways;
FGAirportDynamics *parent;
public:
FGStartupController(FGAirportDynamics *parent);
virtual ~FGStartupController() {};
virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
double lat, double lon,
double hdg, double spd, double alt, double radius, int leg,
FGAIAircraft *aircraft);
virtual void signOff(int id);
virtual void updateAircraftInformation(int id, double lat, double lon,
double heading, double speed, double alt, double dt);
virtual bool hasInstruction(int id);
virtual FGATCInstruction getInstruction(int id);
virtual void render(bool);
virtual std::string getName();
virtual void update(double dt);
bool hasActiveTraffic() {
return ! activeTraffic.empty();
};
TrafficVector &getActiveTraffic() {
return activeTraffic;
};
// 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.
bool checkTransmissionState(int st, time_t now, time_t startTime, TrafficVectorIterator i, AtcMsgId msgId,
AtcMsgDir msgDir);
};
/******************************************************************************
* class FGTowerControl
*****************************************************************************/
class FGApproachController : public FGATCController
{
private:
TrafficVector activeTraffic;
ActiveRunwayVec activeRunways;
FGAirportDynamics *parent;
public:
FGApproachController(FGAirportDynamics * parent);
virtual ~FGApproachController() { };
virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
double lat, double lon,
double hdg, double spd, double alt, double radius, int leg,
FGAIAircraft *aircraft);
virtual void signOff(int id);
virtual void updateAircraftInformation(int id, double lat, double lon,
double heading, double speed, double alt, double dt);
virtual bool hasInstruction(int id);
virtual FGATCInstruction getInstruction(int id);
virtual void render(bool);
virtual std::string getName();
virtual void update(double dt);
ActiveRunway* getRunway(const std::string& name);
bool hasActiveTraffic() {
return ! activeTraffic.empty();
};
TrafficVector &getActiveTraffic() {
return activeTraffic;
};
};
#endif // _TRAFFIC_CONTROL_HXX