Major update of traffic manager and AI related airport facilities.
- Moved AIModels/Traffic Manager related AI functions to a new file - Rewrote the traffic manager so that the containers use pointers to objects instead of the objects themselves, which will allow for a more flexible memory management. - Rewrote parts of the airport groundnetwork code, also because the stl containers now contain object pointers instead of the objects themselves. - Fixed an uninitialized iterator in the AI distance tracking code - Fixed flawed logic in some of the traffic controller's while loops - Added a tower controller, which paces take-off behavior of AITraffic in a more realistic way. - Various other minor fixes and fine tuning.
This commit is contained in:
parent
8be61d7813
commit
666910a793
18 changed files with 631 additions and 681 deletions
|
@ -43,6 +43,7 @@
|
||||||
SG_USING_STD(string);
|
SG_USING_STD(string);
|
||||||
|
|
||||||
#include "AIAircraft.hxx"
|
#include "AIAircraft.hxx"
|
||||||
|
//#include <Airports/trafficcontroller.hxx>
|
||||||
static string tempReg;
|
static string tempReg;
|
||||||
//
|
//
|
||||||
// accel, decel, climb_rate, descent_rate, takeoff_speed, climb_speed,
|
// accel, decel, climb_rate, descent_rate, takeoff_speed, climb_speed,
|
||||||
|
@ -93,6 +94,8 @@ FGAIAircraft::FGAIAircraft(FGAISchedule *ref) :
|
||||||
|
|
||||||
FGAIAircraft::~FGAIAircraft() {
|
FGAIAircraft::~FGAIAircraft() {
|
||||||
//delete fp;
|
//delete fp;
|
||||||
|
if (controller)
|
||||||
|
controller->signOff(getID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -180,15 +183,29 @@ void FGAIAircraft::Run(double dt) {
|
||||||
if (now < fp->getStartTime()) {
|
if (now < fp->getStartTime()) {
|
||||||
// Do execute Ground elev for inactive aircraft, so they
|
// Do execute Ground elev for inactive aircraft, so they
|
||||||
// Are repositioned to the correct ground altitude when the user flies within visibility range.
|
// Are repositioned to the correct ground altitude when the user flies within visibility range.
|
||||||
|
// In addition, check whether we are out of user range, so this aircraft
|
||||||
|
// can be deleted.
|
||||||
if (no_roll) {
|
if (no_roll) {
|
||||||
Transform(); // make sure aip is initialized.
|
Transform(); // make sure aip is initialized.
|
||||||
getGroundElev(dt); // make sure it's exectuted first time around, so force a large dt value
|
if (trafficRef) {
|
||||||
//getGroundElev(dt); // Need to do this twice.
|
double userLatitude = fgGetDouble("/position/latitude-deg");
|
||||||
//cerr << trafficRef->getRegistration() << " Setting altitude to " << tgt_altitude;
|
double userLongitude = fgGetDouble("/position/longitude-deg");
|
||||||
doGroundAltitude();
|
double course, distance;
|
||||||
//cerr << " Actual altitude " << altitude << endl;
|
SGWayPoint current(pos.getLongitudeDeg(), pos.getLatitudeDeg(), 0);
|
||||||
// Transform();
|
SGWayPoint user (userLongitude, userLatitude, 0);
|
||||||
pos.setElevationFt(altitude_ft);
|
user.CourseAndDistance(current, &course, &distance);
|
||||||
|
if ((distance * SG_METER_TO_NM) > TRAFFICTOAIDIST) {
|
||||||
|
setDie(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
getGroundElev(dt); // make sure it's exectuted first time around, so force a large dt value
|
||||||
|
//getGroundElev(dt); // Need to do this twice.
|
||||||
|
//cerr << trafficRef->getRegistration() << " Setting altitude to " << tgt_altitude;
|
||||||
|
doGroundAltitude();
|
||||||
|
//cerr << " Actual altitude " << altitude << endl;
|
||||||
|
// Transform();
|
||||||
|
pos.setElevationFt(altitude_ft);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -229,10 +246,7 @@ void FGAIAircraft::Run(double dt) {
|
||||||
hdg,
|
hdg,
|
||||||
speed,
|
speed,
|
||||||
altitude_ft, dt);
|
altitude_ft, dt);
|
||||||
//if (controller->hasInstruction(getID()))
|
processATC(controller->getInstruction(getID()));
|
||||||
// {
|
|
||||||
processATC(controller->getInstruction(getID()));
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double turn_radius_ft;
|
double turn_radius_ft;
|
||||||
|
@ -972,29 +986,34 @@ void FGAIAircraft::announcePositionToController()
|
||||||
|
|
||||||
int leg = fp->getLeg();
|
int leg = fp->getLeg();
|
||||||
|
|
||||||
// For starters, I'll only do this for departure and arrival taxi. The mechanism
|
//if (fp->getCurrentWaypoint()->routeIndex != 0) {
|
||||||
// could be extended to include any controller however.
|
|
||||||
//int node, currentTaxiSegment;
|
|
||||||
//if (taxiRoute->next(&node, ¤tTaxiSegment)) {
|
|
||||||
if (fp->getCurrentWaypoint()->routeIndex != 0) {
|
|
||||||
//char buffer[10];
|
//char buffer[10];
|
||||||
//snprintf (buffer, 10, "%d", node);
|
//snprintf (buffer, 10, "%d", node);
|
||||||
|
// Note that leg was been incremented after creating the current leg, so we should use
|
||||||
|
// leg numbers here that are one higher than the number that is used to create the leg
|
||||||
|
//
|
||||||
switch (leg) {
|
switch (leg) {
|
||||||
case 3:
|
case 3: // Taxiing to runway
|
||||||
//cerr << trafficRef->getRegistration()
|
|
||||||
// << " taxiing to runway at segment "
|
|
||||||
// << fp->getCurrentWaypoint()->routeIndex
|
|
||||||
// << endl;
|
|
||||||
//cerr << "Match check between taxisegment and taxiroute : " << node << " "
|
|
||||||
// << fp->getCurrentWaypoint()->name << endl;
|
|
||||||
if (trafficRef->getDepartureAirport()->getDynamics()->getGroundNetwork()->exists())
|
if (trafficRef->getDepartureAirport()->getDynamics()->getGroundNetwork()->exists())
|
||||||
controller = trafficRef->getDepartureAirport()->getDynamics()->getGroundNetwork();
|
controller = trafficRef->getDepartureAirport()->getDynamics()->getGroundNetwork();
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 4: //Take off tower controller
|
||||||
//cerr << trafficRef->getRegistration()
|
if (trafficRef->getDepartureAirport()->getDynamics())
|
||||||
// << " taxiing to parking at segment "
|
{
|
||||||
// << fp->getCurrentWaypoint()->routeIndex
|
controller = trafficRef->getDepartureAirport()->getDynamics()->getTowerController();
|
||||||
// << endl;
|
//if (trafficRef->getDepartureAirport()->getId() == "EHAM") {
|
||||||
|
//cerr << trafficRef->getCallSign() << " at runway " << fp->getRunway() << "Ready for departure "
|
||||||
|
// << trafficRef->getFlightType() << " to " << trafficRef->getArrivalAirport()->getId() << endl;
|
||||||
|
// if (controller == 0) {
|
||||||
|
//cerr << "Error in assigning controller at " << trafficRef->getDepartureAirport()->getId() << endl;
|
||||||
|
//}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cerr << "Error: Could not find Dynamics at airport : " << trafficRef->getDepartureAirport()->getId() << endl;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 9: // Taxiing for parking
|
||||||
if (trafficRef->getArrivalAirport()->getDynamics()->getGroundNetwork()->exists())
|
if (trafficRef->getArrivalAirport()->getDynamics()->getGroundNetwork()->exists())
|
||||||
controller = trafficRef->getArrivalAirport()->getDynamics()->getGroundNetwork();
|
controller = trafficRef->getArrivalAirport()->getDynamics()->getGroundNetwork();
|
||||||
break;
|
break;
|
||||||
|
@ -1002,20 +1021,27 @@ void FGAIAircraft::announcePositionToController()
|
||||||
controller = 0;
|
controller = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
//fp->deleteTaxiRoute();
|
|
||||||
controller = 0;
|
|
||||||
}
|
|
||||||
if ((controller != prevController) && (prevController != 0)) {
|
if ((controller != prevController) && (prevController != 0)) {
|
||||||
prevController->signOff(getID());
|
prevController->signOff(getID());
|
||||||
//cerr << trafficRef->getRegistration()
|
string callsign = trafficRef->getCallSign();
|
||||||
// << " signing off " << endl;
|
if ( trafficRef->getHeavy())
|
||||||
|
callsign += "Heavy";
|
||||||
|
switch (leg) {
|
||||||
|
case 3:
|
||||||
|
cerr << callsign << " ready to taxi to runway " << fp->getRunway() << endl;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
cerr << callsign << " at runway " << fp->getRunway() << "Ready for take-off. "
|
||||||
|
<< trafficRef->getFlightRules() << " to " << trafficRef->getArrivalAirport()->getId()
|
||||||
|
<< "(" << trafficRef->getArrivalAirport()->getName() << ")."<< endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
prevController = controller;
|
prevController = controller;
|
||||||
if (controller) {
|
if (controller) {
|
||||||
controller->announcePosition(getID(), fp, fp->getCurrentWaypoint()->routeIndex,
|
controller->announcePosition(getID(), fp, fp->getCurrentWaypoint()->routeIndex,
|
||||||
_getLatitude(), _getLongitude(), hdg, speed, altitude_ft,
|
_getLatitude(), _getLongitude(), hdg, speed, altitude_ft,
|
||||||
trafficRef->getRadius());
|
trafficRef->getRadius(), leg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,6 +176,7 @@ ssgBranch * FGAIBase::load3DModel(const string& fg_root,
|
||||||
personality_branch->addKid( model );
|
personality_branch->addKid( model );
|
||||||
|
|
||||||
return personality_branch;
|
return personality_branch;
|
||||||
|
//return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FGAIBase::isa( object_type otype ) {
|
bool FGAIBase::isa( object_type otype ) {
|
||||||
|
|
|
@ -98,6 +98,7 @@ public:
|
||||||
int getRouteIndex(int i); // returns the AI related index of this current routes.
|
int getRouteIndex(int i); // returns the AI related index of this current routes.
|
||||||
FGTaxiRoute *getTaxiRoute() { return taxiRoute; };
|
FGTaxiRoute *getTaxiRoute() { return taxiRoute; };
|
||||||
void deleteTaxiRoute();
|
void deleteTaxiRoute();
|
||||||
|
string getRunway() { return activeRunway; };
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -598,6 +598,7 @@ void FGAIFlightPlan::createTakeOff(bool firstFlight, FGAirport *apt, double spee
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Acceleration point, 105 meters into the runway,
|
||||||
heading = rwy._heading;
|
heading = rwy._heading;
|
||||||
double azimuth = heading + 180.0;
|
double azimuth = heading + 180.0;
|
||||||
while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
|
while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
|
||||||
|
@ -622,13 +623,34 @@ void FGAIFlightPlan::createTakeOff(bool firstFlight, FGAirport *apt, double spee
|
||||||
lon = lon2;
|
lon = lon2;
|
||||||
az = az2;
|
az = az2;
|
||||||
|
|
||||||
//Next: the Start of Climb
|
//Start Climbing to 3000 ft. Let's do this
|
||||||
|
// at the center of the runway for now:
|
||||||
|
//
|
||||||
geo_direct_wgs_84 ( 0, lat, lon, heading,
|
geo_direct_wgs_84 ( 0, lat, lon, heading,
|
||||||
2560 * SG_FEET_TO_METER,
|
2560 * SG_FEET_TO_METER,
|
||||||
&lat2, &lon2, &az2 );
|
&lat2, &lon2, &az2 );
|
||||||
|
|
||||||
wpt = new waypoint;
|
wpt = new waypoint;
|
||||||
wpt->name = "SOC";
|
wpt->name = "SOC";
|
||||||
|
wpt->latitude = rwy._lat;
|
||||||
|
wpt->longitude = rwy._lon;
|
||||||
|
wpt->altitude = apt->getElevation()+1000;
|
||||||
|
wpt->speed = speed;
|
||||||
|
wpt->crossat = -10000;
|
||||||
|
wpt->gear_down = true;
|
||||||
|
wpt->flaps_down= true;
|
||||||
|
wpt->finished = false;
|
||||||
|
wpt->on_ground = false;
|
||||||
|
wpt->routeIndex = 0;
|
||||||
|
waypoints.push_back(wpt);
|
||||||
|
|
||||||
|
|
||||||
|
geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, heading,
|
||||||
|
rwy._length * SG_FEET_TO_METER,
|
||||||
|
&lat2, &lon2, &az2 );
|
||||||
|
|
||||||
|
wpt = new waypoint;
|
||||||
|
wpt->name = "3000 ft";
|
||||||
wpt->latitude = lat2;
|
wpt->latitude = lat2;
|
||||||
wpt->longitude = lon2;
|
wpt->longitude = lon2;
|
||||||
wpt->altitude = apt->getElevation()+3000;
|
wpt->altitude = apt->getElevation()+3000;
|
||||||
|
@ -640,6 +662,46 @@ void FGAIFlightPlan::createTakeOff(bool firstFlight, FGAirport *apt, double spee
|
||||||
wpt->on_ground = false;
|
wpt->on_ground = false;
|
||||||
wpt->routeIndex = 0;
|
wpt->routeIndex = 0;
|
||||||
waypoints.push_back(wpt);
|
waypoints.push_back(wpt);
|
||||||
|
|
||||||
|
// Finally, add two more waypoints, so that aircraft will remain under
|
||||||
|
// Tower control until they have reached the 3000 ft climb point
|
||||||
|
|
||||||
|
|
||||||
|
geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, heading,
|
||||||
|
5000,
|
||||||
|
&lat2, &lon2, &az2 );
|
||||||
|
|
||||||
|
|
||||||
|
wpt = new waypoint;
|
||||||
|
wpt->name = "5000 ft";
|
||||||
|
wpt->latitude = lat2;
|
||||||
|
wpt->longitude = lon2;
|
||||||
|
wpt->altitude = apt->getElevation()+5000;
|
||||||
|
wpt->speed = speed;
|
||||||
|
wpt->crossat = -10000;
|
||||||
|
wpt->gear_down = true;
|
||||||
|
wpt->flaps_down= true;
|
||||||
|
wpt->finished = false;
|
||||||
|
wpt->on_ground = false;
|
||||||
|
wpt->routeIndex = 0;
|
||||||
|
waypoints.push_back(wpt);
|
||||||
|
|
||||||
|
// geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, heading,
|
||||||
|
// 100000,
|
||||||
|
// &lat2, &lon2, &az2 );
|
||||||
|
// wpt = new waypoint;
|
||||||
|
// wpt->name = "5100 ft";
|
||||||
|
// wpt->latitude = lat2;
|
||||||
|
// wpt->longitude = lon2;
|
||||||
|
// wpt->altitude = apt->getElevation()+5100;
|
||||||
|
// wpt->speed = speed;
|
||||||
|
// wpt->crossat = -10000;
|
||||||
|
// wpt->gear_down = true;
|
||||||
|
// wpt->flaps_down= true;
|
||||||
|
// wpt->finished = false;
|
||||||
|
// wpt->on_ground = false;
|
||||||
|
// wpt->routeIndex = 0;
|
||||||
|
// waypoints.push_back(wpt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
|
|
|
@ -259,10 +259,30 @@ FGAIManager::loadScenarioFile(const std::string& filename)
|
||||||
// This code keeps track of models that have already been loaded
|
// This code keeps track of models that have already been loaded
|
||||||
// Eventually we'd prbably need to find a way to keep track of models
|
// Eventually we'd prbably need to find a way to keep track of models
|
||||||
// that are unloaded again
|
// that are unloaded again
|
||||||
ssgBranch * FGAIManager::getModel(const string& path) const
|
ssgBranch * FGAIManager::getModel(const string& path)
|
||||||
{
|
{
|
||||||
ModelVecIterator i = loadedModels.begin();
|
ModelVecIterator i = loadedModels.begin();
|
||||||
|
cerr << "Reference count summary " << endl;
|
||||||
|
int count = 0;
|
||||||
while (i != loadedModels.end())
|
while (i != loadedModels.end())
|
||||||
|
{
|
||||||
|
count += i->getNumRefs() -1;
|
||||||
|
cerr << "Model " << i->getPath() << " has reference count of " << i->getNumRefs() << " ";
|
||||||
|
if (i->getNumRefs() == 1)
|
||||||
|
{
|
||||||
|
i = loadedModels.erase(i);
|
||||||
|
cerr << "[ Deleted ]" << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
cerr << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cerr << "Reference summary end : " << count << "models allocated" << endl;
|
||||||
|
i = loadedModels.begin();
|
||||||
|
|
||||||
|
while (i != loadedModels.end())
|
||||||
{
|
{
|
||||||
if (i->getPath() == path)
|
if (i->getPath() == path)
|
||||||
return i->getModelId();
|
return i->getModelId();
|
||||||
|
|
|
@ -49,10 +49,11 @@ public:
|
||||||
FGModelID(const string& pth, ssgBranch * mdl) { path =pth; model=mdl;};
|
FGModelID(const string& pth, ssgBranch * mdl) { path =pth; model=mdl;};
|
||||||
ssgBranch * const getModelId() const { return model;};
|
ssgBranch * const getModelId() const { return model;};
|
||||||
const string & getPath() const { return path;};
|
const string & getPath() const { return path;};
|
||||||
|
int getNumRefs() const { return model.getNumRefs(); };
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef vector<FGModelID> ModelVec;
|
typedef vector<FGModelID> ModelVec;
|
||||||
typedef vector<FGModelID>::const_iterator ModelVecIterator;
|
typedef vector<FGModelID>::iterator ModelVecIterator;
|
||||||
|
|
||||||
class FGAIThermal;
|
class FGAIThermal;
|
||||||
|
|
||||||
|
@ -99,7 +100,7 @@ public:
|
||||||
|
|
||||||
void processScenario( const string &filename );
|
void processScenario( const string &filename );
|
||||||
|
|
||||||
ssgBranch * getModel(const string& path) const;
|
ssgBranch * getModel(const string& path);
|
||||||
void setModel(const string& path, ssgBranch *model);
|
void setModel(const string& path, ssgBranch *model);
|
||||||
|
|
||||||
static SGPropertyNode_ptr loadScenarioFile(const std::string& filename);
|
static SGPropertyNode_ptr loadScenarioFile(const std::string& filename);
|
||||||
|
|
|
@ -9,7 +9,8 @@ libAirports_a_SOURCES = \
|
||||||
runwayprefs.cxx runwayprefs.hxx \
|
runwayprefs.cxx runwayprefs.hxx \
|
||||||
parking.cxx parking.hxx \
|
parking.cxx parking.hxx \
|
||||||
groundnetwork.cxx groundnetwork.hxx \
|
groundnetwork.cxx groundnetwork.hxx \
|
||||||
dynamics.cxx dynamics.hxx
|
dynamics.cxx dynamics.hxx \
|
||||||
|
trafficcontrol.hxx trafficcontrol.cxx
|
||||||
|
|
||||||
calc_loc_SOURCES = calc_loc.cxx
|
calc_loc_SOURCES = calc_loc.cxx
|
||||||
calc_loc_LDADD = -lsgmath -lsgdebug -lsgmisc -lz $(base_LIBS)
|
calc_loc_LDADD = -lsgmath -lsgdebug -lsgmisc -lz $(base_LIBS)
|
||||||
|
|
|
@ -91,7 +91,6 @@ FGAirportDynamics::FGAirportDynamics(const FGAirportDynamics& other)
|
||||||
// Destructor
|
// Destructor
|
||||||
FGAirportDynamics::~FGAirportDynamics()
|
FGAirportDynamics::~FGAirportDynamics()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -109,6 +108,7 @@ void FGAirportDynamics::init()
|
||||||
// add the gate positions to the ground network.
|
// add the gate positions to the ground network.
|
||||||
groundNetwork.addNodes(&parkings);
|
groundNetwork.addNodes(&parkings);
|
||||||
groundNetwork.init();
|
groundNetwork.init();
|
||||||
|
groundNetwork .setTowerController(&towerController);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FGAirportDynamics::getAvailableParking(double *lat, double *lon, double *heading, int *gateId, double rad, const string &flType, const string &acType, const string &airline)
|
bool FGAirportDynamics::getAvailableParking(double *lat, double *lon, double *heading, int *gateId, double rad, const string &flType, const string &acType, const string &airline)
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "parking.hxx"
|
#include "parking.hxx"
|
||||||
#include "groundnetwork.hxx"
|
#include "groundnetwork.hxx"
|
||||||
#include "runwayprefs.hxx"
|
#include "runwayprefs.hxx"
|
||||||
|
#include "trafficcontrol.hxx"
|
||||||
|
|
||||||
|
|
||||||
class FGAirportDynamics : public XMLVisitor {
|
class FGAirportDynamics : public XMLVisitor {
|
||||||
|
@ -42,9 +43,10 @@ private:
|
||||||
double _elevation; // ft
|
double _elevation; // ft
|
||||||
string _id;
|
string _id;
|
||||||
|
|
||||||
FGParkingVec parkings;
|
FGParkingVec parkings;
|
||||||
FGRunwayPreference rwyPrefs;
|
FGRunwayPreference rwyPrefs;
|
||||||
FGGroundNetwork groundNetwork;
|
FGGroundNetwork groundNetwork;
|
||||||
|
FGTowerController towerController;
|
||||||
|
|
||||||
time_t lastUpdate;
|
time_t lastUpdate;
|
||||||
string prevTrafficType;
|
string prevTrafficType;
|
||||||
|
@ -86,7 +88,8 @@ public:
|
||||||
//const string &getName() const { return _name;};
|
//const string &getName() const { return _name;};
|
||||||
// Returns degrees
|
// Returns degrees
|
||||||
|
|
||||||
FGGroundNetwork* getGroundNetwork() { return &groundNetwork; };
|
FGGroundNetwork *getGroundNetwork() { return &groundNetwork; };
|
||||||
|
FGTowerController *getTowerController() { return &towerController; };
|
||||||
|
|
||||||
|
|
||||||
void setRwyUse(const FGRunwayPreference& ref);
|
void setRwyUse(const FGRunwayPreference& ref);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -35,17 +35,18 @@ SG_USING_STD(vector);
|
||||||
|
|
||||||
|
|
||||||
#include "parking.hxx"
|
#include "parking.hxx"
|
||||||
//#include <AIModel/AIBase.hxx>
|
#include "trafficcontrol.hxx"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class FGTaxiSegment; // forward reference
|
class FGTaxiSegment; // forward reference
|
||||||
class FGAIFlightPlan; // forward reference
|
class FGAIFlightPlan; // forward reference
|
||||||
|
|
||||||
typedef vector<FGTaxiSegment> FGTaxiSegmentVector;
|
typedef vector<FGTaxiSegment*> FGTaxiSegmentVector;
|
||||||
typedef vector<FGTaxiSegment*> FGTaxiSegmentPointerVector;
|
typedef vector<FGTaxiSegment*>::iterator FGTaxiSegmentVectorIterator;
|
||||||
typedef vector<FGTaxiSegment>::iterator FGTaxiSegmentVectorIterator;
|
|
||||||
typedef vector<FGTaxiSegment*>::iterator FGTaxiSegmentPointerVectorIterator;
|
//typedef vector<FGTaxiSegment*> FGTaxiSegmentPointerVector;
|
||||||
|
//typedef vector<FGTaxiSegment*>::iterator FGTaxiSegmentPointerVectorIterator;
|
||||||
|
|
||||||
/**************************************************************************************
|
/**************************************************************************************
|
||||||
* class FGTaxiNode
|
* class FGTaxiNode
|
||||||
|
@ -56,7 +57,7 @@ private:
|
||||||
double lat;
|
double lat;
|
||||||
double lon;
|
double lon;
|
||||||
int index;
|
int index;
|
||||||
FGTaxiSegmentPointerVector next; // a vector to all the segments leaving from this node
|
FGTaxiSegmentVector next; // a vector of pointers to all the segments leaving from this node
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FGTaxiNode();
|
FGTaxiNode();
|
||||||
|
@ -74,13 +75,13 @@ public:
|
||||||
|
|
||||||
int getIndex() { return index; };
|
int getIndex() { return index; };
|
||||||
FGTaxiNode *getAddress() { return this;};
|
FGTaxiNode *getAddress() { return this;};
|
||||||
FGTaxiSegmentPointerVectorIterator getBeginRoute() { return next.begin(); };
|
FGTaxiSegmentVectorIterator getBeginRoute() { return next.begin(); };
|
||||||
FGTaxiSegmentPointerVectorIterator getEndRoute() { return next.end(); };
|
FGTaxiSegmentVectorIterator getEndRoute() { return next.end(); };
|
||||||
bool operator<(const FGTaxiNode &other) const { return index < other.index; };
|
bool operator<(const FGTaxiNode &other) const { return index < other.index; };
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef vector<FGTaxiNode> FGTaxiNodeVector;
|
typedef vector<FGTaxiNode*> FGTaxiNodeVector;
|
||||||
typedef vector<FGTaxiNode>::iterator FGTaxiNodeVectorIterator;
|
typedef vector<FGTaxiNode*>::iterator FGTaxiNodeVectorIterator;
|
||||||
|
|
||||||
/***************************************************************************************
|
/***************************************************************************************
|
||||||
* class FGTaxiSegment
|
* class FGTaxiSegment
|
||||||
|
@ -160,133 +161,6 @@ public:
|
||||||
typedef vector<FGTaxiRoute> TaxiRouteVector;
|
typedef vector<FGTaxiRoute> TaxiRouteVector;
|
||||||
typedef vector<FGTaxiRoute>::iterator TaxiRouteVectorIterator;
|
typedef vector<FGTaxiRoute>::iterator TaxiRouteVectorIterator;
|
||||||
|
|
||||||
/**************************************************************************************
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
double speed;
|
|
||||||
double heading;
|
|
||||||
double alt;
|
|
||||||
public:
|
|
||||||
|
|
||||||
FGATCInstruction();
|
|
||||||
bool hasInstruction ();
|
|
||||||
bool getHoldPattern () { return holdPattern; };
|
|
||||||
bool getHoldPosition () { return holdPosition; };
|
|
||||||
bool getChangeSpeed () { return changeSpeed; };
|
|
||||||
bool getChangeHeading () { return changeHeading; };
|
|
||||||
bool getChangeAltitude() { return changeAltitude; };
|
|
||||||
|
|
||||||
double getSpeed () { return speed; };
|
|
||||||
double getHeading () { return heading; };
|
|
||||||
double getAlt () { return alt; };
|
|
||||||
|
|
||||||
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 setSpeed (double val) { speed = val; };
|
|
||||||
void setHeading (double val) { heading = val; };
|
|
||||||
void setAlt (double val) { alt = val; };
|
|
||||||
};
|
|
||||||
|
|
||||||
class FGGroundNetwork;
|
|
||||||
|
|
||||||
/**************************************************************************************
|
|
||||||
* class FGTrafficRecord
|
|
||||||
*************************************************************************************/
|
|
||||||
class FGTrafficRecord
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
int id, waitsForId;
|
|
||||||
int currentPos;
|
|
||||||
intVec intentions;
|
|
||||||
FGATCInstruction instruction;
|
|
||||||
double latitude, longitude, heading, speed, altitude, radius;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
FGTrafficRecord() {};
|
|
||||||
|
|
||||||
void setId(int val) { id = val; };
|
|
||||||
void setRadius(double rad) { radius = rad;};
|
|
||||||
void setPositionAndIntentions(int pos, FGAIFlightPlan *route);
|
|
||||||
int getId() { return id;};
|
|
||||||
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 getSpeedAdjustment() { return instruction.getChangeSpeed(); };
|
|
||||||
|
|
||||||
double getLatitude () { return latitude ; };
|
|
||||||
double getLongitude() { return longitude; };
|
|
||||||
double getHeading () { return heading ; };
|
|
||||||
double getSpeed () { return speed ; };
|
|
||||||
double getAltitude () { return altitude ; };
|
|
||||||
double getRadius () { return radius ; };
|
|
||||||
|
|
||||||
int getWaitsForId () { return waitsForId; };
|
|
||||||
|
|
||||||
void setSpeedAdjustment(double spd) { instruction.setChangeSpeed(true);
|
|
||||||
instruction.setSpeed(spd); };
|
|
||||||
void setHeadingAdjustment(double heading) { instruction.setChangeHeading(true);
|
|
||||||
instruction.setHeading(heading); };
|
|
||||||
void clearSpeedAdjustment () { instruction.setChangeSpeed (false); };
|
|
||||||
void clearHeadingAdjustment() { instruction.setChangeHeading(false); };
|
|
||||||
|
|
||||||
bool hasHeadingAdjustment() { return instruction.getChangeHeading(); };
|
|
||||||
bool hasHoldPosition() { return instruction.getHoldPosition(); };
|
|
||||||
void setHoldPosition (bool inst) { instruction.setHoldPosition(inst); };
|
|
||||||
|
|
||||||
void setWaitsForId(int id) { waitsForId = id; };
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef vector<FGTrafficRecord> TrafficVector;
|
|
||||||
typedef vector<FGTrafficRecord>::iterator TrafficVectorIterator;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************************
|
|
||||||
* class FGATCController
|
|
||||||
* NOTE: this class serves as an abstraction layer for all sorts of ATC controller,
|
|
||||||
* Ground and air, so eventually it should move to its own file / directory.
|
|
||||||
*************************************************************************************/
|
|
||||||
class FGATCController
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
double dt_count;
|
|
||||||
public:
|
|
||||||
FGATCController() { dt_count = 0;};
|
|
||||||
virtual ~FGATCController() {};
|
|
||||||
virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
|
|
||||||
double lat, double lon,
|
|
||||||
double hdg, double spd, double alt, double radius) = 0;
|
|
||||||
virtual void signOff(int id) = 0;
|
|
||||||
virtual void update(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;};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -308,6 +182,7 @@ private:
|
||||||
|
|
||||||
bool foundRoute;
|
bool foundRoute;
|
||||||
double totalDistance, maxDistance;
|
double totalDistance, maxDistance;
|
||||||
|
FGTowerController *towerController;
|
||||||
|
|
||||||
void printRoutingError(string);
|
void printRoutingError(string);
|
||||||
|
|
||||||
|
@ -318,6 +193,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FGGroundNetwork();
|
FGGroundNetwork();
|
||||||
|
~FGGroundNetwork();
|
||||||
|
|
||||||
void addNode (const FGTaxiNode& node);
|
void addNode (const FGTaxiNode& node);
|
||||||
void addNodes (FGParkingVec *parkings);
|
void addNodes (FGParkingVec *parkings);
|
||||||
|
@ -325,6 +201,7 @@ public:
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
bool exists() { return hasNetwork; };
|
bool exists() { return hasNetwork; };
|
||||||
|
void setTowerController(FGTowerController *twrCtrlr) { towerController = twrCtrlr; };
|
||||||
int findNearestNode(double lat, double lon);
|
int findNearestNode(double lat, double lon);
|
||||||
FGTaxiNode *findNode(int idx);
|
FGTaxiNode *findNode(int idx);
|
||||||
FGTaxiSegment *findSegment(int idx);
|
FGTaxiSegment *findSegment(int idx);
|
||||||
|
@ -332,7 +209,7 @@ public:
|
||||||
void trace(FGTaxiNode *, int, int, double dist);
|
void trace(FGTaxiNode *, int, int, double dist);
|
||||||
|
|
||||||
virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
|
virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
|
||||||
double lat, double lon, double hdg, double spd, double alt, double radius);
|
double lat, double lon, double hdg, double spd, double alt, double radius, int leg);
|
||||||
virtual void signOff(int id);
|
virtual void signOff(int id);
|
||||||
virtual void update(int id, double lat, double lon, double heading, double speed, double alt, double dt);
|
virtual void update(int id, double lat, double lon, double heading, double speed, double alt, double dt);
|
||||||
virtual bool hasInstruction(int id);
|
virtual bool hasInstruction(int id);
|
||||||
|
|
|
@ -90,7 +90,7 @@ FGAirportDynamics * FGAirport::getDynamics()
|
||||||
return dynamics;
|
return dynamics;
|
||||||
} else {
|
} else {
|
||||||
FGRunwayPreference rwyPrefs;
|
FGRunwayPreference rwyPrefs;
|
||||||
//cerr << "Trying to load dynamics for " << _id << endl;
|
cerr << "Trying to load dynamics for " << _id << endl;
|
||||||
dynamics = new FGAirportDynamics(_latitude, _longitude, _elevation, _id);
|
dynamics = new FGAirportDynamics(_latitude, _longitude, _elevation, _id);
|
||||||
|
|
||||||
SGPath parkpath( globals->get_fg_root() );
|
SGPath parkpath( globals->get_fg_root() );
|
||||||
|
|
|
@ -280,3 +280,9 @@ bool FGScheduledFlight::initializeAirports()
|
||||||
initialized = true;
|
initialized = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool compareScheduledFlights(FGScheduledFlight *a, FGScheduledFlight *b)
|
||||||
|
{
|
||||||
|
return (*a) < (*b);
|
||||||
|
};
|
||||||
|
|
|
@ -95,13 +95,16 @@ public:
|
||||||
{
|
{
|
||||||
return (departureTime < other.departureTime);
|
return (departureTime < other.departureTime);
|
||||||
};
|
};
|
||||||
|
string& getFlightRules() { return fltRules; };
|
||||||
|
|
||||||
time_t processTimeString(const string& time);
|
time_t processTimeString(const string& time);
|
||||||
const string& getCallSign() {return callsign; };
|
const string& getCallSign() {return callsign; };
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef vector<FGScheduledFlight> FGScheduledFlightVec;
|
typedef vector<FGScheduledFlight*> FGScheduledFlightVec;
|
||||||
typedef vector<FGScheduledFlight>::iterator FGScheduledFlightVecIterator;
|
typedef vector<FGScheduledFlight*>::iterator FGScheduledFlightVecIterator;
|
||||||
|
|
||||||
|
bool compareScheduledFlights(FGScheduledFlight *a, FGScheduledFlight *b);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -106,7 +106,7 @@ FGAISchedule::FGAISchedule(string mdl,
|
||||||
for (FGScheduledFlightVecIterator i = flt.begin();
|
for (FGScheduledFlightVecIterator i = flt.begin();
|
||||||
i != flt.end();
|
i != flt.end();
|
||||||
i++)
|
i++)
|
||||||
flights.push_back(FGScheduledFlight((*i)));
|
flights.push_back(new FGScheduledFlight((*(*i))));
|
||||||
AIManagerRef = 0;
|
AIManagerRef = 0;
|
||||||
score = scre;
|
score = scre;
|
||||||
firstRun = true;
|
firstRun = true;
|
||||||
|
@ -136,7 +136,11 @@ FGAISchedule::FGAISchedule(const FGAISchedule &other)
|
||||||
|
|
||||||
FGAISchedule::~FGAISchedule()
|
FGAISchedule::~FGAISchedule()
|
||||||
{
|
{
|
||||||
|
for (FGScheduledFlightVecIterator flt = flights.begin(); flt != flights.end(); flt++)
|
||||||
|
{
|
||||||
|
delete (*flt);
|
||||||
|
}
|
||||||
|
flights.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FGAISchedule::init()
|
bool FGAISchedule::init()
|
||||||
|
@ -154,7 +158,7 @@ bool FGAISchedule::init()
|
||||||
i++)
|
i++)
|
||||||
{
|
{
|
||||||
//i->adjustTime(now);
|
//i->adjustTime(now);
|
||||||
if (!(i->initializeAirports()))
|
if (!((*i)->initializeAirports()))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//sort(flights.begin(), flights.end());
|
//sort(flights.begin(), flights.end());
|
||||||
|
@ -216,19 +220,20 @@ bool FGAISchedule::update(time_t now)
|
||||||
i != flights.end();
|
i != flights.end();
|
||||||
i++)
|
i++)
|
||||||
{
|
{
|
||||||
i->adjustTime(now);
|
(*i)->adjustTime(now);
|
||||||
}
|
}
|
||||||
if (fgGetBool("/sim/traffic-manager/instantaneous-action") == true)
|
if (fgGetBool("/sim/traffic-manager/instantaneous-action") == true)
|
||||||
deptime = now;
|
deptime = now + rand() % 300; // Wait up to 5 minutes until traffic starts moving to prevent too many aircraft
|
||||||
|
// from cluttering the gate areas.
|
||||||
firstRun = false;
|
firstRun = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort all the scheduled flights according to scheduled departure time.
|
// Sort all the scheduled flights according to scheduled departure time.
|
||||||
// Because this is done at every update, we only need to check the status
|
// Because this is done at every update, we only need to check the status
|
||||||
// of the first listed flight.
|
// of the first listed flight.
|
||||||
sort(flights.begin(), flights.end());
|
sort(flights.begin(), flights.end(), compareScheduledFlights);
|
||||||
if (!deptime)
|
if (!deptime)
|
||||||
deptime = flights.begin()->getDepartureTime();
|
deptime = (*flights.begin())->getDepartureTime();
|
||||||
FGScheduledFlightVecIterator i = flights.begin();
|
FGScheduledFlightVecIterator i = flights.begin();
|
||||||
if (AIManagerRef)
|
if (AIManagerRef)
|
||||||
{
|
{
|
||||||
|
@ -246,9 +251,9 @@ bool FGAISchedule::update(time_t now)
|
||||||
//cerr << "Estimated minimum distance to user: " << distanceToUser << endl;
|
//cerr << "Estimated minimum distance to user: " << distanceToUser << endl;
|
||||||
// This flight entry is entirely in the past, do we need to
|
// This flight entry is entirely in the past, do we need to
|
||||||
// push it forward in time to the next scheduled departure.
|
// push it forward in time to the next scheduled departure.
|
||||||
if ((i->getDepartureTime() < now) && (i->getArrivalTime() < now))
|
if (((*i)->getDepartureTime() < now) && ((*i)->getArrivalTime() < now))
|
||||||
{
|
{
|
||||||
i->update();
|
(*i)->update();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,10 +265,10 @@ bool FGAISchedule::update(time_t now)
|
||||||
|
|
||||||
|
|
||||||
// Part of this flight is in the future.
|
// Part of this flight is in the future.
|
||||||
if (i->getArrivalTime() > now)
|
if ((*i)->getArrivalTime() > now)
|
||||||
{
|
{
|
||||||
dep = i->getDepartureAirport();
|
dep = (*i)->getDepartureAirport();
|
||||||
arr = i->getArrivalAirport ();
|
arr = (*i)->getArrivalAirport ();
|
||||||
if (!(dep && arr))
|
if (!(dep && arr))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -295,13 +300,13 @@ bool FGAISchedule::update(time_t now)
|
||||||
// position of the aircraft by calculating the ratio between
|
// position of the aircraft by calculating the ratio between
|
||||||
// total time enroute and elapsed time enroute.
|
// total time enroute and elapsed time enroute.
|
||||||
|
|
||||||
totalTimeEnroute = i->getArrivalTime() - i->getDepartureTime();
|
totalTimeEnroute = (*i)->getArrivalTime() - (*i)->getDepartureTime();
|
||||||
if (now > i->getDepartureTime())
|
if (now > (*i)->getDepartureTime())
|
||||||
{
|
{
|
||||||
//err << "Lat = " << lat << ", lon = " << lon << endl;
|
//err << "Lat = " << lat << ", lon = " << lon << endl;
|
||||||
//cerr << "Time diff: " << now-i->getDepartureTime() << endl;
|
//cerr << "Time diff: " << now-i->getDepartureTime() << endl;
|
||||||
elapsedTimeEnroute = now - i->getDepartureTime();
|
elapsedTimeEnroute = now - (*i)->getDepartureTime();
|
||||||
remainingTimeEnroute = i->getArrivalTime() - now;
|
remainingTimeEnroute = (*i)->getArrivalTime() - now;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -327,7 +332,7 @@ bool FGAISchedule::update(time_t now)
|
||||||
}
|
}
|
||||||
|
|
||||||
temp = sgCartToPolar3d(Point3D(newPos[0], newPos[1],newPos[2]));
|
temp = sgCartToPolar3d(Point3D(newPos[0], newPos[1],newPos[2]));
|
||||||
if (now > i->getDepartureTime())
|
if (now > (*i)->getDepartureTime())
|
||||||
{
|
{
|
||||||
//cerr << "Lat = " << lat << ", lon = " << lon << endl;
|
//cerr << "Lat = " << lat << ", lon = " << lon << endl;
|
||||||
//cerr << "Time diff: " << now-i->getDepartureTime() << endl;
|
//cerr << "Time diff: " << now-i->getDepartureTime() << endl;
|
||||||
|
@ -343,13 +348,13 @@ bool FGAISchedule::update(time_t now)
|
||||||
|
|
||||||
SGWayPoint current (lon,
|
SGWayPoint current (lon,
|
||||||
lat,
|
lat,
|
||||||
i->getCruiseAlt());
|
(*i)->getCruiseAlt());
|
||||||
SGWayPoint user ( userLongitude,
|
SGWayPoint user ( userLongitude,
|
||||||
userLatitude,
|
userLatitude,
|
||||||
i->getCruiseAlt());
|
(*i)->getCruiseAlt());
|
||||||
SGWayPoint dest ( arr->getLongitude(),
|
SGWayPoint dest ( arr->getLongitude(),
|
||||||
arr->getLatitude(),
|
arr->getLatitude(),
|
||||||
i->getCruiseAlt());
|
(*i)->getCruiseAlt());
|
||||||
// We really only need distance to user
|
// We really only need distance to user
|
||||||
// and course to destination
|
// and course to destination
|
||||||
user.CourseAndDistance(current, &courseToUser, &distanceToUser);
|
user.CourseAndDistance(current, &courseToUser, &distanceToUser);
|
||||||
|
@ -392,12 +397,12 @@ bool FGAISchedule::update(time_t now)
|
||||||
//aircraft->setFlightPlan(flightPlanName);
|
//aircraft->setFlightPlan(flightPlanName);
|
||||||
aircraft->setLatitude(lat);
|
aircraft->setLatitude(lat);
|
||||||
aircraft->setLongitude(lon);
|
aircraft->setLongitude(lon);
|
||||||
aircraft->setAltitude(i->getCruiseAlt()*100); // convert from FL to feet
|
aircraft->setAltitude((*i)->getCruiseAlt()*100); // convert from FL to feet
|
||||||
aircraft->setSpeed(speed);
|
aircraft->setSpeed(speed);
|
||||||
aircraft->setBank(0);
|
aircraft->setBank(0);
|
||||||
aircraft->SetFlightPlan(new FGAIFlightPlan(flightPlanName, courseToDest, deptime,
|
aircraft->SetFlightPlan(new FGAIFlightPlan(flightPlanName, courseToDest, deptime,
|
||||||
dep, arr,true, radius,
|
dep, arr,true, radius,
|
||||||
i->getCruiseAlt()*100,
|
(*i)->getCruiseAlt()*100,
|
||||||
lat, lon, speed, flightType, acType,
|
lat, lon, speed, flightType, acType,
|
||||||
airline));
|
airline));
|
||||||
aimgr->attach(aircraft);
|
aimgr->attach(aircraft);
|
||||||
|
@ -425,9 +430,9 @@ bool FGAISchedule::update(time_t now)
|
||||||
// Currently this status is mostly ignored, but in future
|
// Currently this status is mostly ignored, but in future
|
||||||
// versions, code should go here that -if within user range-
|
// versions, code should go here that -if within user range-
|
||||||
// positions these aircraft at parking locations at the airport.
|
// positions these aircraft at parking locations at the airport.
|
||||||
if ((i->getDepartureTime() > now) && (i->getArrivalTime() > now))
|
if (((*i)->getDepartureTime() > now) && ((*i)->getArrivalTime() > now))
|
||||||
{
|
{
|
||||||
dep = i->getDepartureAirport();
|
dep = (*i)->getDepartureAirport();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -445,8 +450,8 @@ bool FGAISchedule::update(time_t now)
|
||||||
|
|
||||||
void FGAISchedule::next()
|
void FGAISchedule::next()
|
||||||
{
|
{
|
||||||
flights.begin()->update();
|
(*flights.begin())->update();
|
||||||
sort(flights.begin(), flights.end());
|
sort(flights.begin(), flights.end(), compareScheduledFlights);
|
||||||
}
|
}
|
||||||
|
|
||||||
double FGAISchedule::getSpeed()
|
double FGAISchedule::getSpeed()
|
||||||
|
@ -457,24 +462,29 @@ double FGAISchedule::getSpeed()
|
||||||
FGAirport *dep, *arr;
|
FGAirport *dep, *arr;
|
||||||
|
|
||||||
FGScheduledFlightVecIterator i = flights.begin();
|
FGScheduledFlightVecIterator i = flights.begin();
|
||||||
dep = i->getDepartureAirport();
|
dep = (*i)->getDepartureAirport();
|
||||||
arr = i->getArrivalAirport ();
|
arr = (*i)->getArrivalAirport ();
|
||||||
if (!(dep && arr))
|
if (!(dep && arr))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
SGWayPoint dest ( dep->getLongitude(),
|
SGWayPoint dest ( dep->getLongitude(),
|
||||||
dep->getLatitude(),
|
dep->getLatitude(),
|
||||||
i->getCruiseAlt());
|
(*i)->getCruiseAlt());
|
||||||
SGWayPoint curr ( arr->getLongitude(),
|
SGWayPoint curr ( arr->getLongitude(),
|
||||||
arr->getLatitude(),
|
arr->getLatitude(),
|
||||||
i->getCruiseAlt());
|
(*i)->getCruiseAlt());
|
||||||
remainingTimeEnroute = i->getArrivalTime() - i->getDepartureTime();
|
remainingTimeEnroute = (*i)->getArrivalTime() - (*i)->getDepartureTime();
|
||||||
dest.CourseAndDistance(curr, &courseToDest, &distanceToDest);
|
dest.CourseAndDistance(curr, &courseToDest, &distanceToDest);
|
||||||
speed = (distanceToDest*SG_METER_TO_NM) /
|
speed = (distanceToDest*SG_METER_TO_NM) /
|
||||||
((double) remainingTimeEnroute/3600.0);
|
((double) remainingTimeEnroute/3600.0);
|
||||||
return speed;
|
return speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool compareSchedules(FGAISchedule*a, FGAISchedule*b)
|
||||||
|
{
|
||||||
|
return (*a) < (*b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// void FGAISchedule::setClosestDistanceToUser()
|
// void FGAISchedule::setClosestDistanceToUser()
|
||||||
// {
|
// {
|
||||||
|
@ -520,3 +530,4 @@ double FGAISchedule::getSpeed()
|
||||||
// }
|
// }
|
||||||
// //return distToUser;
|
// //return distToUser;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
|
@ -71,29 +71,31 @@ class FGAISchedule
|
||||||
//void setClosestDistanceToUser();
|
//void setClosestDistanceToUser();
|
||||||
void next(); // forces the schedule to move on to the next flight.
|
void next(); // forces the schedule to move on to the next flight.
|
||||||
|
|
||||||
time_t getDepartureTime () { return flights.begin()->getDepartureTime (); };
|
time_t getDepartureTime () { return (*flights.begin())->getDepartureTime (); };
|
||||||
FGAirport * getDepartureAirport () { return flights.begin()->getDepartureAirport(); };
|
FGAirport * getDepartureAirport () { return (*flights.begin())->getDepartureAirport(); };
|
||||||
FGAirport * getArrivalAirport () { return flights.begin()->getArrivalAirport (); };
|
FGAirport * getArrivalAirport () { return (*flights.begin())->getArrivalAirport (); };
|
||||||
int getCruiseAlt () { return flights.begin()->getCruiseAlt (); };
|
int getCruiseAlt () { return (*flights.begin())->getCruiseAlt (); };
|
||||||
double getRadius () { return radius; };
|
double getRadius () { return radius; };
|
||||||
double getGroundOffset () { return groundOffset;};
|
double getGroundOffset () { return groundOffset;};
|
||||||
const string& getFlightType () { return flightType;};
|
const string& getFlightType () { return flightType;};
|
||||||
const string& getAirline () { return airline; };
|
const string& getAirline () { return airline; };
|
||||||
const string& getAircraft () { return acType; };
|
const string& getAircraft () { return acType; };
|
||||||
const string& getCallSign () { return flights.begin()->getCallSign (); };
|
const string& getCallSign () { return (*flights.begin())->getCallSign (); };
|
||||||
const string& getRegistration () { return registration;};
|
const string& getRegistration () { return registration;};
|
||||||
|
const string& getFlightRules () { return (*flights.begin())->getFlightRules (); };
|
||||||
bool getHeavy () { return heavy; };
|
bool getHeavy () { return heavy; };
|
||||||
// used to sort in decending order of score: I've probably found a better way to
|
// used to sort in decending order of score: I've probably found a better way to
|
||||||
// decending order sorting, but still need to test that.
|
// decending order sorting, but still need to test that.
|
||||||
bool operator< (const FGAISchedule &other) const { return (score > other.score); };
|
bool operator< (const FGAISchedule &other) const { return (score > other.score); };
|
||||||
//void * getAiRef () { return AIManagerRef; };
|
//void * getAiRef () { return AIManagerRef; };
|
||||||
//FGAISchedule* getAddress () { return this;};
|
//FGAISchedule* getAddress () { return this;};
|
||||||
// More member functions follow later
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef vector<FGAISchedule > ScheduleVector;
|
typedef vector<FGAISchedule*> ScheduleVector;
|
||||||
typedef vector<FGAISchedule >::iterator ScheduleVectorIterator;
|
typedef vector<FGAISchedule*>::iterator ScheduleVectorIterator;
|
||||||
|
|
||||||
|
bool compareSchedules(FGAISchedule*a, FGAISchedule*b);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,20 @@ FGTrafficManager::FGTrafficManager()
|
||||||
score = 0;
|
score = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FGTrafficManager:: ~FGTrafficManager()
|
||||||
|
{
|
||||||
|
for (ScheduleVectorIterator sched = scheduledAircraft.begin(); sched != scheduledAircraft.end(); sched++)
|
||||||
|
{
|
||||||
|
delete (*sched);
|
||||||
|
}
|
||||||
|
scheduledAircraft.clear();
|
||||||
|
// for (FGScheduledFlightVecIterator flt = flights.begin(); flt != flights.end(); flt++)
|
||||||
|
// {
|
||||||
|
// delete (*flt);
|
||||||
|
// }
|
||||||
|
// flights.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void FGTrafficManager::init()
|
void FGTrafficManager::init()
|
||||||
{
|
{
|
||||||
|
@ -97,8 +111,9 @@ void FGTrafficManager::init()
|
||||||
// currAircraft++;
|
// currAircraft++;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//cerr << "Sorting by distance " << endl;
|
// Sort by points: Aircraft with frequent visits to the
|
||||||
sort(scheduledAircraft.begin(), scheduledAircraft.end());
|
// startup airport will be processed first
|
||||||
|
sort(scheduledAircraft.begin(), scheduledAircraft.end(), compareSchedules);
|
||||||
currAircraft = scheduledAircraft.begin();
|
currAircraft = scheduledAircraft.begin();
|
||||||
currAircraftClosest = scheduledAircraft.begin();
|
currAircraftClosest = scheduledAircraft.begin();
|
||||||
//cerr << "Done initializing schedules" << endl;
|
//cerr << "Done initializing schedules" << endl;
|
||||||
|
@ -114,7 +129,7 @@ void FGTrafficManager::update(double something)
|
||||||
//cerr << "resetting schedule " << endl;
|
//cerr << "resetting schedule " << endl;
|
||||||
currAircraft = scheduledAircraft.begin();
|
currAircraft = scheduledAircraft.begin();
|
||||||
}
|
}
|
||||||
if (!(currAircraft->update(now)))
|
if (!((*currAircraft)->update(now)))
|
||||||
{
|
{
|
||||||
// after proper initialization, we shouldnt get here.
|
// after proper initialization, we shouldnt get here.
|
||||||
// But let's make sure
|
// But let's make sure
|
||||||
|
@ -232,7 +247,7 @@ void FGTrafficManager::endElement (const char * name) {
|
||||||
string apt = fgGetString("/sim/presets/airport-id");
|
string apt = fgGetString("/sim/presets/airport-id");
|
||||||
//cerr << "Airport information: " << apt << " " << departurePort << " " << arrivalPort << endl;
|
//cerr << "Airport information: " << apt << " " << departurePort << " " << arrivalPort << endl;
|
||||||
if (departurePort == apt) score++;
|
if (departurePort == apt) score++;
|
||||||
flights.push_back(FGScheduledFlight(callsign,
|
flights.push_back(new FGScheduledFlight(callsign,
|
||||||
fltrules,
|
fltrules,
|
||||||
departurePort,
|
departurePort,
|
||||||
arrivalPort,
|
arrivalPort,
|
||||||
|
@ -244,7 +259,7 @@ void FGTrafficManager::endElement (const char * name) {
|
||||||
else if (element == string("aircraft"))
|
else if (element == string("aircraft"))
|
||||||
{
|
{
|
||||||
//cerr << "Pushing back aircraft " << registration << endl;
|
//cerr << "Pushing back aircraft " << registration << endl;
|
||||||
scheduledAircraft.push_back(FGAISchedule(mdl,
|
scheduledAircraft.push_back(new FGAISchedule(mdl,
|
||||||
livery,
|
livery,
|
||||||
registration,
|
registration,
|
||||||
heavy,
|
heavy,
|
||||||
|
@ -256,8 +271,14 @@ void FGTrafficManager::endElement (const char * name) {
|
||||||
offset,
|
offset,
|
||||||
score,
|
score,
|
||||||
flights));
|
flights));
|
||||||
while(flights.begin() != flights.end())
|
// while(flights.begin() != flights.end()) {
|
||||||
flights.pop_back();
|
// flights.pop_back();
|
||||||
|
// }
|
||||||
|
for (FGScheduledFlightVecIterator flt = flights.begin(); flt != flights.end(); flt++)
|
||||||
|
{
|
||||||
|
delete (*flt);
|
||||||
|
}
|
||||||
|
flights.clear();
|
||||||
SG_LOG( SG_GENERAL, SG_BULK, "Reading aircraft : "
|
SG_LOG( SG_GENERAL, SG_BULK, "Reading aircraft : "
|
||||||
<< registration
|
<< registration
|
||||||
<< " with prioritization score "
|
<< " with prioritization score "
|
||||||
|
|
|
@ -59,7 +59,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FGTrafficManager();
|
FGTrafficManager();
|
||||||
|
~FGTrafficManager();
|
||||||
void init();
|
void init();
|
||||||
void update(double time);
|
void update(double time);
|
||||||
void release(int ref);
|
void release(int ref);
|
||||||
|
|
Loading…
Add table
Reference in a new issue