1
0
Fork 0

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:
durk 2006-10-06 17:36:31 +00:00
parent 8be61d7813
commit 666910a793
18 changed files with 631 additions and 681 deletions

View file

@ -43,6 +43,7 @@
SG_USING_STD(string);
#include "AIAircraft.hxx"
//#include <Airports/trafficcontroller.hxx>
static string tempReg;
//
// accel, decel, climb_rate, descent_rate, takeoff_speed, climb_speed,
@ -93,6 +94,8 @@ FGAIAircraft::FGAIAircraft(FGAISchedule *ref) :
FGAIAircraft::~FGAIAircraft() {
//delete fp;
if (controller)
controller->signOff(getID());
}
@ -180,15 +183,29 @@ void FGAIAircraft::Run(double dt) {
if (now < fp->getStartTime()) {
// Do execute Ground elev for inactive aircraft, so they
// 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) {
Transform(); // make sure aip is initialized.
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);
if (trafficRef) {
double userLatitude = fgGetDouble("/position/latitude-deg");
double userLongitude = fgGetDouble("/position/longitude-deg");
double course, distance;
SGWayPoint current(pos.getLongitudeDeg(), pos.getLatitudeDeg(), 0);
SGWayPoint user (userLongitude, userLatitude, 0);
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;
}
@ -229,10 +246,7 @@ void FGAIAircraft::Run(double dt) {
hdg,
speed,
altitude_ft, dt);
//if (controller->hasInstruction(getID()))
// {
processATC(controller->getInstruction(getID()));
// }
processATC(controller->getInstruction(getID()));
}
double turn_radius_ft;
@ -972,29 +986,34 @@ void FGAIAircraft::announcePositionToController()
int leg = fp->getLeg();
// For starters, I'll only do this for departure and arrival taxi. The mechanism
// could be extended to include any controller however.
//int node, currentTaxiSegment;
//if (taxiRoute->next(&node, &currentTaxiSegment)) {
if (fp->getCurrentWaypoint()->routeIndex != 0) {
//if (fp->getCurrentWaypoint()->routeIndex != 0) {
//char buffer[10];
//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) {
case 3:
//cerr << trafficRef->getRegistration()
// << " taxiing to runway at segment "
// << fp->getCurrentWaypoint()->routeIndex
// << endl;
//cerr << "Match check between taxisegment and taxiroute : " << node << " "
// << fp->getCurrentWaypoint()->name << endl;
case 3: // Taxiing to runway
if (trafficRef->getDepartureAirport()->getDynamics()->getGroundNetwork()->exists())
controller = trafficRef->getDepartureAirport()->getDynamics()->getGroundNetwork();
break;
case 9:
//cerr << trafficRef->getRegistration()
// << " taxiing to parking at segment "
// << fp->getCurrentWaypoint()->routeIndex
// << endl;
case 4: //Take off tower controller
if (trafficRef->getDepartureAirport()->getDynamics())
{
controller = trafficRef->getDepartureAirport()->getDynamics()->getTowerController();
//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())
controller = trafficRef->getArrivalAirport()->getDynamics()->getGroundNetwork();
break;
@ -1002,20 +1021,27 @@ void FGAIAircraft::announcePositionToController()
controller = 0;
break;
}
} else {
//fp->deleteTaxiRoute();
controller = 0;
}
if ((controller != prevController) && (prevController != 0)) {
prevController->signOff(getID());
//cerr << trafficRef->getRegistration()
// << " signing off " << endl;
string callsign = trafficRef->getCallSign();
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;
if (controller) {
controller->announcePosition(getID(), fp, fp->getCurrentWaypoint()->routeIndex,
_getLatitude(), _getLongitude(), hdg, speed, altitude_ft,
trafficRef->getRadius());
_getLatitude(), _getLongitude(), hdg, speed, altitude_ft,
trafficRef->getRadius(), leg);
}
}
}

View file

@ -176,6 +176,7 @@ ssgBranch * FGAIBase::load3DModel(const string& fg_root,
personality_branch->addKid( model );
return personality_branch;
//return model;
}
bool FGAIBase::isa( object_type otype ) {

View file

@ -98,6 +98,7 @@ public:
int getRouteIndex(int i); // returns the AI related index of this current routes.
FGTaxiRoute *getTaxiRoute() { return taxiRoute; };
void deleteTaxiRoute();
string getRunway() { return activeRunway; };
private:

View file

@ -598,6 +598,7 @@ void FGAIFlightPlan::createTakeOff(bool firstFlight, FGAirport *apt, double spee
exit(1);
}
}
// Acceleration point, 105 meters into the runway,
heading = rwy._heading;
double azimuth = heading + 180.0;
while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
@ -622,13 +623,34 @@ void FGAIFlightPlan::createTakeOff(bool firstFlight, FGAirport *apt, double spee
lon = lon2;
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,
2560 * SG_FEET_TO_METER,
&lat2, &lon2, &az2 );
wpt = new waypoint;
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->longitude = lon2;
wpt->altitude = apt->getElevation()+3000;
@ -640,6 +662,46 @@ void FGAIFlightPlan::createTakeOff(bool firstFlight, FGAirport *apt, double spee
wpt->on_ground = false;
wpt->routeIndex = 0;
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);
}
/*******************************************************************

View file

@ -259,10 +259,30 @@ FGAIManager::loadScenarioFile(const std::string& filename)
// 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
// 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())
{
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)
return i->getModelId();

View file

@ -49,10 +49,11 @@ public:
FGModelID(const string& pth, ssgBranch * mdl) { path =pth; model=mdl;};
ssgBranch * const getModelId() const { return model;};
const string & getPath() const { return path;};
int getNumRefs() const { return model.getNumRefs(); };
};
typedef vector<FGModelID> ModelVec;
typedef vector<FGModelID>::const_iterator ModelVecIterator;
typedef vector<FGModelID>::iterator ModelVecIterator;
class FGAIThermal;
@ -99,7 +100,7 @@ public:
void processScenario( const string &filename );
ssgBranch * getModel(const string& path) const;
ssgBranch * getModel(const string& path);
void setModel(const string& path, ssgBranch *model);
static SGPropertyNode_ptr loadScenarioFile(const std::string& filename);

View file

@ -9,7 +9,8 @@ libAirports_a_SOURCES = \
runwayprefs.cxx runwayprefs.hxx \
parking.cxx parking.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_LDADD = -lsgmath -lsgdebug -lsgmisc -lz $(base_LIBS)

View file

@ -91,7 +91,6 @@ FGAirportDynamics::FGAirportDynamics(const FGAirportDynamics& other)
// Destructor
FGAirportDynamics::~FGAirportDynamics()
{
}
@ -109,6 +108,7 @@ void FGAirportDynamics::init()
// add the gate positions to the ground network.
groundNetwork.addNodes(&parkings);
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)

View file

@ -32,6 +32,7 @@
#include "parking.hxx"
#include "groundnetwork.hxx"
#include "runwayprefs.hxx"
#include "trafficcontrol.hxx"
class FGAirportDynamics : public XMLVisitor {
@ -42,9 +43,10 @@ private:
double _elevation; // ft
string _id;
FGParkingVec parkings;
FGParkingVec parkings;
FGRunwayPreference rwyPrefs;
FGGroundNetwork groundNetwork;
FGGroundNetwork groundNetwork;
FGTowerController towerController;
time_t lastUpdate;
string prevTrafficType;
@ -86,7 +88,8 @@ public:
//const string &getName() const { return _name;};
// Returns degrees
FGGroundNetwork* getGroundNetwork() { return &groundNetwork; };
FGGroundNetwork *getGroundNetwork() { return &groundNetwork; };
FGTowerController *getTowerController() { return &towerController; };
void setRwyUse(const FGRunwayPreference& ref);

File diff suppressed because it is too large Load diff

View file

@ -35,17 +35,18 @@ SG_USING_STD(vector);
#include "parking.hxx"
//#include <AIModel/AIBase.hxx>
#include "trafficcontrol.hxx"
class FGTaxiSegment; // forward reference
class FGAIFlightPlan; // forward reference
typedef vector<FGTaxiSegment> FGTaxiSegmentVector;
typedef vector<FGTaxiSegment*> FGTaxiSegmentPointerVector;
typedef vector<FGTaxiSegment>::iterator FGTaxiSegmentVectorIterator;
typedef vector<FGTaxiSegment*>::iterator FGTaxiSegmentPointerVectorIterator;
typedef vector<FGTaxiSegment*> FGTaxiSegmentVector;
typedef vector<FGTaxiSegment*>::iterator FGTaxiSegmentVectorIterator;
//typedef vector<FGTaxiSegment*> FGTaxiSegmentPointerVector;
//typedef vector<FGTaxiSegment*>::iterator FGTaxiSegmentPointerVectorIterator;
/**************************************************************************************
* class FGTaxiNode
@ -56,7 +57,7 @@ private:
double lat;
double lon;
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:
FGTaxiNode();
@ -74,13 +75,13 @@ public:
int getIndex() { return index; };
FGTaxiNode *getAddress() { return this;};
FGTaxiSegmentPointerVectorIterator getBeginRoute() { return next.begin(); };
FGTaxiSegmentPointerVectorIterator getEndRoute() { return next.end(); };
FGTaxiSegmentVectorIterator getBeginRoute() { return next.begin(); };
FGTaxiSegmentVectorIterator getEndRoute() { return next.end(); };
bool operator<(const FGTaxiNode &other) const { return index < other.index; };
};
typedef vector<FGTaxiNode> FGTaxiNodeVector;
typedef vector<FGTaxiNode>::iterator FGTaxiNodeVectorIterator;
typedef vector<FGTaxiNode*> FGTaxiNodeVector;
typedef vector<FGTaxiNode*>::iterator FGTaxiNodeVectorIterator;
/***************************************************************************************
* class FGTaxiSegment
@ -160,133 +161,6 @@ public:
typedef vector<FGTaxiRoute> TaxiRouteVector;
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;
double totalDistance, maxDistance;
FGTowerController *towerController;
void printRoutingError(string);
@ -318,6 +193,7 @@ private:
public:
FGGroundNetwork();
~FGGroundNetwork();
void addNode (const FGTaxiNode& node);
void addNodes (FGParkingVec *parkings);
@ -325,6 +201,7 @@ public:
void init();
bool exists() { return hasNetwork; };
void setTowerController(FGTowerController *twrCtrlr) { towerController = twrCtrlr; };
int findNearestNode(double lat, double lon);
FGTaxiNode *findNode(int idx);
FGTaxiSegment *findSegment(int idx);
@ -332,7 +209,7 @@ public:
void trace(FGTaxiNode *, int, int, double dist);
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 update(int id, double lat, double lon, double heading, double speed, double alt, double dt);
virtual bool hasInstruction(int id);

View file

@ -90,7 +90,7 @@ FGAirportDynamics * FGAirport::getDynamics()
return dynamics;
} else {
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);
SGPath parkpath( globals->get_fg_root() );

View file

@ -280,3 +280,9 @@ bool FGScheduledFlight::initializeAirports()
initialized = true;
return true;
}
bool compareScheduledFlights(FGScheduledFlight *a, FGScheduledFlight *b)
{
return (*a) < (*b);
};

View file

@ -95,13 +95,16 @@ public:
{
return (departureTime < other.departureTime);
};
string& getFlightRules() { return fltRules; };
time_t processTimeString(const string& time);
const string& getCallSign() {return callsign; };
};
typedef vector<FGScheduledFlight> FGScheduledFlightVec;
typedef vector<FGScheduledFlight>::iterator FGScheduledFlightVecIterator;
typedef vector<FGScheduledFlight*> FGScheduledFlightVec;
typedef vector<FGScheduledFlight*>::iterator FGScheduledFlightVecIterator;
bool compareScheduledFlights(FGScheduledFlight *a, FGScheduledFlight *b);
#endif

View file

@ -106,7 +106,7 @@ FGAISchedule::FGAISchedule(string mdl,
for (FGScheduledFlightVecIterator i = flt.begin();
i != flt.end();
i++)
flights.push_back(FGScheduledFlight((*i)));
flights.push_back(new FGScheduledFlight((*(*i))));
AIManagerRef = 0;
score = scre;
firstRun = true;
@ -136,7 +136,11 @@ FGAISchedule::FGAISchedule(const FGAISchedule &other)
FGAISchedule::~FGAISchedule()
{
for (FGScheduledFlightVecIterator flt = flights.begin(); flt != flights.end(); flt++)
{
delete (*flt);
}
flights.clear();
}
bool FGAISchedule::init()
@ -154,7 +158,7 @@ bool FGAISchedule::init()
i++)
{
//i->adjustTime(now);
if (!(i->initializeAirports()))
if (!((*i)->initializeAirports()))
return false;
}
//sort(flights.begin(), flights.end());
@ -216,19 +220,20 @@ bool FGAISchedule::update(time_t now)
i != flights.end();
i++)
{
i->adjustTime(now);
(*i)->adjustTime(now);
}
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;
}
// Sort all the scheduled flights according to scheduled departure time.
// Because this is done at every update, we only need to check the status
// of the first listed flight.
sort(flights.begin(), flights.end());
sort(flights.begin(), flights.end(), compareScheduledFlights);
if (!deptime)
deptime = flights.begin()->getDepartureTime();
deptime = (*flights.begin())->getDepartureTime();
FGScheduledFlightVecIterator i = flights.begin();
if (AIManagerRef)
{
@ -246,9 +251,9 @@ bool FGAISchedule::update(time_t now)
//cerr << "Estimated minimum distance to user: " << distanceToUser << endl;
// This flight entry is entirely in the past, do we need to
// 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;
}
@ -260,10 +265,10 @@ bool FGAISchedule::update(time_t now)
// Part of this flight is in the future.
if (i->getArrivalTime() > now)
if ((*i)->getArrivalTime() > now)
{
dep = i->getDepartureAirport();
arr = i->getArrivalAirport ();
dep = (*i)->getDepartureAirport();
arr = (*i)->getArrivalAirport ();
if (!(dep && arr))
return false;
@ -295,13 +300,13 @@ bool FGAISchedule::update(time_t now)
// position of the aircraft by calculating the ratio between
// total time enroute and elapsed time enroute.
totalTimeEnroute = i->getArrivalTime() - i->getDepartureTime();
if (now > i->getDepartureTime())
totalTimeEnroute = (*i)->getArrivalTime() - (*i)->getDepartureTime();
if (now > (*i)->getDepartureTime())
{
//err << "Lat = " << lat << ", lon = " << lon << endl;
//cerr << "Time diff: " << now-i->getDepartureTime() << endl;
elapsedTimeEnroute = now - i->getDepartureTime();
remainingTimeEnroute = i->getArrivalTime() - now;
elapsedTimeEnroute = now - (*i)->getDepartureTime();
remainingTimeEnroute = (*i)->getArrivalTime() - now;
}
else
{
@ -327,7 +332,7 @@ bool FGAISchedule::update(time_t now)
}
temp = sgCartToPolar3d(Point3D(newPos[0], newPos[1],newPos[2]));
if (now > i->getDepartureTime())
if (now > (*i)->getDepartureTime())
{
//cerr << "Lat = " << lat << ", lon = " << lon << endl;
//cerr << "Time diff: " << now-i->getDepartureTime() << endl;
@ -343,13 +348,13 @@ bool FGAISchedule::update(time_t now)
SGWayPoint current (lon,
lat,
i->getCruiseAlt());
(*i)->getCruiseAlt());
SGWayPoint user ( userLongitude,
userLatitude,
i->getCruiseAlt());
(*i)->getCruiseAlt());
SGWayPoint dest ( arr->getLongitude(),
arr->getLatitude(),
i->getCruiseAlt());
(*i)->getCruiseAlt());
// We really only need distance to user
// and course to destination
user.CourseAndDistance(current, &courseToUser, &distanceToUser);
@ -392,12 +397,12 @@ bool FGAISchedule::update(time_t now)
//aircraft->setFlightPlan(flightPlanName);
aircraft->setLatitude(lat);
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->setBank(0);
aircraft->SetFlightPlan(new FGAIFlightPlan(flightPlanName, courseToDest, deptime,
dep, arr,true, radius,
i->getCruiseAlt()*100,
(*i)->getCruiseAlt()*100,
lat, lon, speed, flightType, acType,
airline));
aimgr->attach(aircraft);
@ -425,9 +430,9 @@ bool FGAISchedule::update(time_t now)
// Currently this status is mostly ignored, but in future
// versions, code should go here that -if within user range-
// 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;
}
}
@ -445,8 +450,8 @@ bool FGAISchedule::update(time_t now)
void FGAISchedule::next()
{
flights.begin()->update();
sort(flights.begin(), flights.end());
(*flights.begin())->update();
sort(flights.begin(), flights.end(), compareScheduledFlights);
}
double FGAISchedule::getSpeed()
@ -457,24 +462,29 @@ double FGAISchedule::getSpeed()
FGAirport *dep, *arr;
FGScheduledFlightVecIterator i = flights.begin();
dep = i->getDepartureAirport();
arr = i->getArrivalAirport ();
dep = (*i)->getDepartureAirport();
arr = (*i)->getArrivalAirport ();
if (!(dep && arr))
return 0;
SGWayPoint dest ( dep->getLongitude(),
dep->getLatitude(),
i->getCruiseAlt());
(*i)->getCruiseAlt());
SGWayPoint curr ( arr->getLongitude(),
arr->getLatitude(),
i->getCruiseAlt());
remainingTimeEnroute = i->getArrivalTime() - i->getDepartureTime();
(*i)->getCruiseAlt());
remainingTimeEnroute = (*i)->getArrivalTime() - (*i)->getDepartureTime();
dest.CourseAndDistance(curr, &courseToDest, &distanceToDest);
speed = (distanceToDest*SG_METER_TO_NM) /
((double) remainingTimeEnroute/3600.0);
return speed;
}
bool compareSchedules(FGAISchedule*a, FGAISchedule*b)
{
return (*a) < (*b);
}
// void FGAISchedule::setClosestDistanceToUser()
// {
@ -520,3 +530,4 @@ double FGAISchedule::getSpeed()
// }
// //return distToUser;
// }

View file

@ -71,29 +71,31 @@ class FGAISchedule
//void setClosestDistanceToUser();
void next(); // forces the schedule to move on to the next flight.
time_t getDepartureTime () { return flights.begin()->getDepartureTime (); };
FGAirport * getDepartureAirport () { return flights.begin()->getDepartureAirport(); };
FGAirport * getArrivalAirport () { return flights.begin()->getArrivalAirport (); };
int getCruiseAlt () { return flights.begin()->getCruiseAlt (); };
time_t getDepartureTime () { return (*flights.begin())->getDepartureTime (); };
FGAirport * getDepartureAirport () { return (*flights.begin())->getDepartureAirport(); };
FGAirport * getArrivalAirport () { return (*flights.begin())->getArrivalAirport (); };
int getCruiseAlt () { return (*flights.begin())->getCruiseAlt (); };
double getRadius () { return radius; };
double getGroundOffset () { return groundOffset;};
const string& getFlightType () { return flightType;};
const string& getAirline () { return airline; };
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& getFlightRules () { return (*flights.begin())->getFlightRules (); };
bool getHeavy () { return heavy; };
// 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.
bool operator< (const FGAISchedule &other) const { return (score > other.score); };
//void * getAiRef () { return AIManagerRef; };
//FGAISchedule* getAddress () { return this;};
// More member functions follow later
};
typedef vector<FGAISchedule > ScheduleVector;
typedef vector<FGAISchedule >::iterator ScheduleVectorIterator;
typedef vector<FGAISchedule*> ScheduleVector;
typedef vector<FGAISchedule*>::iterator ScheduleVectorIterator;
bool compareSchedules(FGAISchedule*a, FGAISchedule*b);
#endif

View file

@ -79,6 +79,20 @@ FGTrafficManager::FGTrafficManager()
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()
{
@ -97,8 +111,9 @@ void FGTrafficManager::init()
// currAircraft++;
// }
// }
//cerr << "Sorting by distance " << endl;
sort(scheduledAircraft.begin(), scheduledAircraft.end());
// Sort by points: Aircraft with frequent visits to the
// startup airport will be processed first
sort(scheduledAircraft.begin(), scheduledAircraft.end(), compareSchedules);
currAircraft = scheduledAircraft.begin();
currAircraftClosest = scheduledAircraft.begin();
//cerr << "Done initializing schedules" << endl;
@ -114,7 +129,7 @@ void FGTrafficManager::update(double something)
//cerr << "resetting schedule " << endl;
currAircraft = scheduledAircraft.begin();
}
if (!(currAircraft->update(now)))
if (!((*currAircraft)->update(now)))
{
// after proper initialization, we shouldnt get here.
// But let's make sure
@ -232,7 +247,7 @@ void FGTrafficManager::endElement (const char * name) {
string apt = fgGetString("/sim/presets/airport-id");
//cerr << "Airport information: " << apt << " " << departurePort << " " << arrivalPort << endl;
if (departurePort == apt) score++;
flights.push_back(FGScheduledFlight(callsign,
flights.push_back(new FGScheduledFlight(callsign,
fltrules,
departurePort,
arrivalPort,
@ -244,7 +259,7 @@ void FGTrafficManager::endElement (const char * name) {
else if (element == string("aircraft"))
{
//cerr << "Pushing back aircraft " << registration << endl;
scheduledAircraft.push_back(FGAISchedule(mdl,
scheduledAircraft.push_back(new FGAISchedule(mdl,
livery,
registration,
heavy,
@ -256,8 +271,14 @@ void FGTrafficManager::endElement (const char * name) {
offset,
score,
flights));
while(flights.begin() != flights.end())
flights.pop_back();
// while(flights.begin() != flights.end()) {
// flights.pop_back();
// }
for (FGScheduledFlightVecIterator flt = flights.begin(); flt != flights.end(); flt++)
{
delete (*flt);
}
flights.clear();
SG_LOG( SG_GENERAL, SG_BULK, "Reading aircraft : "
<< registration
<< " with prioritization score "

View file

@ -59,7 +59,7 @@ private:
public:
FGTrafficManager();
~FGTrafficManager();
void init();
void update(double time);
void release(int ref);