1
0
Fork 0

Clean up dynamics/parking handing code.

Refactor some parking / airport-dynamics APIs, in preparation for caching the ground cache data in the nav-cache.
This commit is contained in:
James Turner 2012-09-23 21:42:40 +01:00
parent 01be5529ba
commit b1854459b3
12 changed files with 273 additions and 455 deletions

View file

@ -129,7 +129,7 @@ public:
bool create(FGAIAircraft *, FGAirport *dep, FGAirport *arr, int leg, double alt, double speed, double lat, double lon, bool create(FGAIAircraft *, FGAirport *dep, FGAirport *arr, int leg, double alt, double speed, double lat, double lon,
bool firstLeg, double radius, const std::string& fltType, const std::string& aircraftType, const std::string& airline, double distance); bool firstLeg, double radius, const std::string& fltType, const std::string& aircraftType, const std::string& airline, double distance);
bool createPushBack(FGAIAircraft *, bool, FGAirport*, double, double, double, const std::string&, const std::string&, const std::string&); bool createPushBack(FGAIAircraft *, bool, FGAirport*, double radius, const std::string&, const std::string&, const std::string&);
bool createTakeOff(FGAIAircraft *, bool, FGAirport *, double, const std::string&); bool createTakeOff(FGAIAircraft *, bool, FGAirport *, double, const std::string&);
void setLeg(int val) { leg = val;} void setLeg(int val) { leg = val;}
@ -189,7 +189,7 @@ private:
std::string name; std::string name;
bool isValid; bool isValid;
void createPushBackFallBack(FGAIAircraft *, bool, FGAirport*, double, double, double, const std::string&, const std::string&, const std::string&); void createPushBackFallBack(FGAIAircraft *, bool, FGAirport*, double radius, const std::string&, const std::string&, const std::string&);
bool createClimb(FGAIAircraft *, bool, FGAirport *, double, double, const std::string&); bool createClimb(FGAIAircraft *, bool, FGAirport *, double, double, const std::string&);
bool createCruise(FGAIAircraft *, bool, FGAirport*, FGAirport*, double, double, double, double, const std::string&); bool createCruise(FGAIAircraft *, bool, FGAirport*, FGAirport*, double, double, double, double, const std::string&);
bool createDescent(FGAIAircraft *, FGAirport *, double latitude, double longitude, double speed, double alt,const std::string&, double distance); bool createDescent(FGAIAircraft *, FGAirport *, double latitude, double longitude, double speed, double alt,const std::string&, double distance);

View file

@ -62,7 +62,7 @@ bool FGAIFlightPlan::create(FGAIAircraft * ac, FGAirport * dep,
int currWpt = wpt_iterator - waypoints.begin(); int currWpt = wpt_iterator - waypoints.begin();
switch (legNr) { switch (legNr) {
case 1: case 1:
retVal = createPushBack(ac, firstFlight, dep, latitude, longitude, retVal = createPushBack(ac, firstFlight, dep,
radius, fltType, aircraftType, airline); radius, fltType, aircraftType, airline);
// Pregenerate the taxi leg. // Pregenerate the taxi leg.
//if (retVal) { //if (retVal) {
@ -206,22 +206,21 @@ bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight,
const string & acType, const string & acType,
const string & airline) const string & airline)
{ {
double heading, lat, lon;
// If this function is called during initialization, // If this function is called during initialization,
// make sure we obtain a valid gate ID first // make sure we obtain a valid gate ID first
// and place the model at the location of the gate. // and place the model at the location of the gate.
if (firstFlight) { if (firstFlight)
if (!(apt->getDynamics()->getAvailableParking(&lat, &lon, {
&heading, &gateId, gateId = apt->getDynamics()->getAvailableParking(radius, fltType,
radius, fltType, acType, airline);
acType, airline))) { if (gateId < 0) {
SG_LOG(SG_AI, SG_WARN, "Could not find parking for a " << SG_LOG(SG_AI, SG_WARN, "Could not find parking for a " <<
acType << acType <<
" of flight type " << fltType << " of flight type " << fltType <<
" of airline " << airline << " of airline " << airline <<
" at airport " << apt->getId()); " at airport " << apt->getId());
} }
} }
string rwyClass = getRunwayClassFromTrafficType(fltType); string rwyClass = getRunwayClassFromTrafficType(fltType);
@ -355,11 +354,9 @@ void FGAIFlightPlan::createDefaultLandingTaxi(FGAIAircraft * ac,
ac->getPerformance()->vTaxi()); ac->getPerformance()->vTaxi());
pushBackWaypoint(wpt); pushBackWaypoint(wpt);
double heading, lat, lon; FGParking* parkPos = aAirport->getDynamics()->getParking(gateId);
aAirport->getDynamics()->getParking(gateId, &lat, &lon, &heading); wpt = createOnGround(ac, "ENDtaxi", parkPos->getGeod(), airportElev,
wpt = ac->getPerformance()->vTaxi());
createOnGround(ac, "ENDtaxi", SGGeod::fromDeg(lon, lat), airportElev,
ac->getPerformance()->vTaxi());
pushBackWaypoint(wpt); pushBackWaypoint(wpt);
} }
@ -369,9 +366,7 @@ bool FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac, FGAirport * apt,
const string & acType, const string & acType,
const string & airline) const string & airline)
{ {
double heading, lat, lon; gateId = apt->getDynamics()->getAvailableParking(radius, fltType,
apt->getDynamics()->getAvailableParking(&lat, &lon, &heading,
&gateId, radius, fltType,
acType, airline); acType, airline);
SGGeod lastWptPos = SGGeod lastWptPos =
@ -1012,34 +1007,25 @@ bool FGAIFlightPlan::createParking(FGAIAircraft * ac, FGAirport * apt,
{ {
FGAIWaypoint *wpt; FGAIWaypoint *wpt;
double aptElev = apt->getElevation(); double aptElev = apt->getElevation();
double lat = 0.0, lat2 = 0.0;
double lon = 0.0, lon2 = 0.0;
double az2 = 0.0;
double heading = 0.0;
double vTaxi = ac->getPerformance()->vTaxi(); double vTaxi = ac->getPerformance()->vTaxi();
double vTaxiReduced = vTaxi * (2.0 / 3.0); double vTaxiReduced = vTaxi * (2.0 / 3.0);
apt->getDynamics()->getParking(gateId, &lat, &lon, &heading); FGParking* parking = apt->getDynamics()->getParking(gateId);
heading += 180.0; double heading = SGMiscd::normalizePeriodic(0, 360, parking->getHeading() + 180.0);
if (heading > 360) double az; // unused
heading -= 360; SGGeod pos;
geo_direct_wgs_84(0, lat, lon, heading,
2.2 * radius, &lat2, &lon2, &az2); SGGeodesy::direct(parking->getGeod(), heading, 2.2 * parking->getRadius(),
wpt = pos, az);
createOnGround(ac, "taxiStart", SGGeod::fromDeg(lon2, lat2),
aptElev, vTaxiReduced); wpt = createOnGround(ac, "taxiStart", pos, aptElev, vTaxiReduced);
pushBackWaypoint(wpt); pushBackWaypoint(wpt);
geo_direct_wgs_84(0, lat, lon, heading, SGGeodesy::direct(parking->getGeod(), heading, 0.1 * parking->getRadius(),
0.1 * radius, &lat2, &lon2, &az2); pos, az);
wpt = createOnGround(ac, "taxiStart2", pos, aptElev, vTaxiReduced);
wpt =
createOnGround(ac, "taxiStart2", SGGeod::fromDeg(lon2, lat2),
aptElev, vTaxiReduced);
pushBackWaypoint(wpt); pushBackWaypoint(wpt);
wpt = wpt = createOnGround(ac, "END-Parking", parking->getGeod(), aptElev,
createOnGround(ac, "END-Parking", SGGeod::fromDeg(lon, lat), aptElev,
vTaxiReduced); vTaxiReduced);
pushBackWaypoint(wpt); pushBackWaypoint(wpt);
return true; return true;

View file

@ -41,14 +41,11 @@
// TODO: Use James Turner's createOnGround functions. // TODO: Use James Turner's createOnGround functions.
bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac, bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
bool firstFlight, FGAirport *dep, bool firstFlight, FGAirport *dep,
double latitude,
double longitude,
double radius, double radius,
const string& fltType, const string& fltType,
const string& aircraftType, const string& aircraftType,
const string& airline) const string& airline)
{ {
double lat, lon, heading;
double vTaxi = ac->getPerformance()->vTaxi(); double vTaxi = ac->getPerformance()->vTaxi();
double vTaxiBackward = vTaxi * (-2.0/3.0); double vTaxiBackward = vTaxi * (-2.0/3.0);
double vTaxiReduced = vTaxi * (2.0/3.0); double vTaxiReduced = vTaxi * (2.0/3.0);
@ -59,132 +56,111 @@ bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
if (!(dep->getDynamics()->getGroundNetwork()->exists())) { if (!(dep->getDynamics()->getGroundNetwork()->exists())) {
//cerr << "Push Back fallback" << endl; //cerr << "Push Back fallback" << endl;
createPushBackFallBack(ac, firstFlight, dep, latitude, longitude, createPushBackFallBack(ac, firstFlight, dep,
radius, fltType, aircraftType, airline); radius, fltType, aircraftType, airline);
return true;
}
// establish the parking position / gate if required
if (firstFlight) {
gateId = dep->getDynamics()->getAvailableParking(radius, fltType,
aircraftType, airline);
if (gateId < 0) {
SG_LOG(SG_AI, SG_WARN, "Warning: Could not find parking for a " <<
aircraftType <<
" of flight type " << fltType <<
" of airline " << airline <<
" at airport " << dep->getId());
return false;
}
} else { } else {
if (firstFlight) { dep->getDynamics()->getParking(gateId);
}
if (gateId < 0) {
createPushBackFallBack(ac, firstFlight, dep,
radius, fltType, aircraftType, airline);
return true;
if (!(dep->getDynamics()->getAvailableParking(&lat, &lon, }
&heading, &gateId,
radius, fltType,
aircraftType, airline))) {
SG_LOG(SG_AI, SG_WARN, "Warning: Could not find parking for a " <<
aircraftType <<
" of flight type " << fltType <<
" of airline " << airline <<
" at airport " << dep->getId());
return false;
char buffer[10];
snprintf (buffer, 10, "%d", gateId);
SGGeod coord = coord.fromDeg(lon, lat);
//FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(node);
FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiBackward);
wpt->setRouteIndex(-1);
pushBackWaypoint(wpt);
}
//cerr << "Success : GateId = " << gateId << endl;
SG_LOG(SG_AI, SG_WARN, "Warning: Successfully found a parking for a " <<
aircraftType <<
" of flight type " << fltType <<
" of airline " << airline <<
" at airport " << dep->getId());
} else {
//cerr << "Push Back follow-up Flight" << endl;
dep->getDynamics()->getParking(gateId, &lat, &lon, &heading);
}
if (gateId < 0) {
createPushBackFallBack(ac, firstFlight, dep, latitude, longitude,
radius, fltType, aircraftType, airline);
return true;
} FGParking *parking = dep->getDynamics()->getParking(gateId);
//cerr << "getting parking " << gateId; int pushBackNode = parking->getPushBackPoint();
//cerr << " for a " <<
// aircraftType << pushBackRoute = parking->getPushBackRoute();
// " of flight type " << fltType << if ((pushBackNode > 0) && (pushBackRoute == 0)) { // Load the already established route for this gate
// " of airline " << airline << int node, rte;
// " at airport " << dep->getId() << endl; FGTaxiRoute route;
FGParking *parking = dep->getDynamics()->getParking(gateId); //cerr << "Creating push-back for " << gateId << " (" << parking->getName() << ") using push-back point " << pushBackNode << endl;
int pushBackNode = parking->getPushBackPoint(); route = dep->getDynamics()->getGroundNetwork()->findShortestRoute(gateId, pushBackNode, false);
parking->setPushBackRoute(new FGTaxiRoute(route));
pushBackRoute = parking->getPushBackRoute(); pushBackRoute = parking->getPushBackRoute();
if ((pushBackNode > 0) && (pushBackRoute == 0)) { // Load the already established route for this gate int size = pushBackRoute->size();
int node, rte; if (size < 2) {
FGTaxiRoute route; SG_LOG(SG_AI, SG_ALERT, "Push back route from gate " << gateId << " has only " << size << " nodes.");
//cerr << "Creating push-back for " << gateId << " (" << parking->getName() << ") using push-back point " << pushBackNode << endl; SG_LOG(SG_AI, SG_ALERT, "Using " << pushBackNode);
route = dep->getDynamics()->getGroundNetwork()->findShortestRoute(gateId, pushBackNode, false);
parking->setPushBackRoute(new FGTaxiRoute(route));
pushBackRoute = parking->getPushBackRoute();
int size = pushBackRoute->size();
if (size < 2) {
SG_LOG(SG_AI, SG_ALERT, "Push back route from gate " << gateId << " has only " << size << " nodes.");
SG_LOG(SG_AI, SG_ALERT, "Using " << pushBackNode);
}
pushBackRoute->first();
while (pushBackRoute->next(&node, &rte))
{
//FGTaxiNode *tn = apt->getDynamics()->getGroundNetwork()->findSegment(node)->getEnd();
char buffer[10];
snprintf (buffer, 10, "%d", node);
FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(node);
//ids.pop_back();
//wpt = new waypoint;
SGGeod coord = coord.fromDeg(tn->getLongitude(), tn->getLatitude());
FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiBackward);
wpt->setRouteIndex(rte);
pushBackWaypoint(wpt);
}
// some special considerations for the last point:
waypoints.back()->setName(string("PushBackPoint"));
waypoints.back()->setSpeed(vTaxi);
ac->setTaxiClearanceRequest(true);
} else { // In case of a push forward departure...
ac->setTaxiClearanceRequest(false);
double lat2 = 0.0, lon2 = 0.0, az2 = 0.0;
//cerr << "Creating final push forward point for gate " << gateId << endl;
FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(gateId);
FGTaxiSegmentVectorIterator ts = tn->getBeginRoute();
FGTaxiSegmentVectorIterator te = tn->getEndRoute();
// if the starting node equals the ending node, then there aren't any routes for this parking.
// in cases like these we should flag the gate as being inoperative and return false
if (ts == te) {
SG_LOG(SG_AI, SG_ALERT, "Gate " << gateId << "doesn't seem to have routes associated with it.");
parking->setAvailable(false);
return false;
}
tn = (*ts)->getEnd();
lastNodeVisited = tn->getIndex();
if (tn == NULL) {
SG_LOG(SG_AI, SG_ALERT, "No valid taxinode found");
exit(1);
}
double distance = (*ts)->getLength();
//cerr << "Length of push forward route = " << distance << " and heading is " << heading << endl;
lat2 = tn->getLatitude();
lon2 = tn->getLongitude();
for (int i = 1; i < 10; i++) {
geo_direct_wgs_84 ( 0, lat, lon, heading,
((i / 10.0) * distance), &lat2, &lon2, &az2 );
char buffer[16];
snprintf(buffer, 16, "pushback-%02d", i);
SGGeod coord = coord.fromDeg(lon2, lat2);
//cerr << i << endl;
FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiReduced);
wpt->setRouteIndex((*ts)->getIndex());
pushBackWaypoint(wpt);
}
// cerr << "Done " << endl;
waypoints.back()->setName(string("PushBackPoint"));
// cerr << "Done assinging new name" << endl;
} }
pushBackRoute->first();
while (pushBackRoute->next(&node, &rte))
{
//FGTaxiNode *tn = apt->getDynamics()->getGroundNetwork()->findSegment(node)->getEnd();
char buffer[10];
snprintf (buffer, 10, "%d", node);
FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(node);
//ids.pop_back();
//wpt = new waypoint;
FGAIWaypoint *wpt = createOnGround(ac, string(buffer), tn->getGeod(), dep->getElevation(), vTaxiBackward);
wpt->setRouteIndex(rte);
pushBackWaypoint(wpt);
}
// some special considerations for the last point:
waypoints.back()->setName(string("PushBackPoint"));
waypoints.back()->setSpeed(vTaxi);
ac->setTaxiClearanceRequest(true);
} else { // In case of a push forward departure...
ac->setTaxiClearanceRequest(false);
double az2 = 0.0;
//cerr << "Creating final push forward point for gate " << gateId << endl;
FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(gateId);
FGTaxiSegmentVectorIterator ts = tn->getBeginRoute();
FGTaxiSegmentVectorIterator te = tn->getEndRoute();
// if the starting node equals the ending node, then there aren't any routes for this parking.
// in cases like these we should flag the gate as being inoperative and return false
if (ts == te) {
SG_LOG(SG_AI, SG_ALERT, "Gate " << gateId << "doesn't seem to have routes associated with it.");
parking->setAvailable(false);
return false;
}
tn = (*ts)->getEnd();
lastNodeVisited = tn->getIndex();
if (tn == NULL) {
SG_LOG(SG_AI, SG_ALERT, "No valid taxinode found");
exit(1);
}
double distance = (*ts)->getLength();
double parkingHeading = parking->getHeading();
for (int i = 1; i < 10; i++) {
SGGeod pushForwardPt;
SGGeodesy::direct(parking->getGeod(), parkingHeading,
((i / 10.0) * distance), pushForwardPt, az2);
char buffer[16];
snprintf(buffer, 16, "pushback-%02d", i);
FGAIWaypoint *wpt = createOnGround(ac, string(buffer), pushForwardPt, dep->getElevation(), vTaxiReduced);
wpt->setRouteIndex((*ts)->getIndex());
pushBackWaypoint(wpt);
}
// cerr << "Done " << endl;
waypoints.back()->setName(string("PushBackPoint"));
// cerr << "Done assinging new name" << endl;
} }
return true; return true;
} }
/******************************************************************* /*******************************************************************
@ -193,49 +169,29 @@ bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
* network yet. * network yet.
******************************************************************/ ******************************************************************/
void FGAIFlightPlan::createPushBackFallBack(FGAIAircraft *ac, bool firstFlight, FGAirport *dep, void FGAIFlightPlan::createPushBackFallBack(FGAIAircraft *ac, bool firstFlight, FGAirport *dep,
double latitude,
double longitude,
double radius, double radius,
const string& fltType, const string& fltType,
const string& aircraftType, const string& aircraftType,
const string& airline) const string& airline)
{ {
double heading;
double lat;
double lon;
double lat2 = 0.0;
double lon2 = 0.0;
double az2 = 0.0; double az2 = 0.0;
double vTaxi = ac->getPerformance()->vTaxi(); double vTaxi = ac->getPerformance()->vTaxi();
double vTaxiBackward = vTaxi * (-2.0/3.0); double vTaxiBackward = vTaxi * (-2.0/3.0);
double vTaxiReduced = vTaxi * (2.0/3.0); double vTaxiReduced = vTaxi * (2.0/3.0);
double heading = 180.0; // this is a completely arbitrary heading!
FGAIWaypoint *wpt = createOnGround(ac, string("park"), dep->geod(), dep->getElevation(), vTaxiBackward);
dep->getDynamics()->getParking(-1, &lat, &lon, &heading);
heading += 180.0;
if (heading > 360)
heading -= 360;
SGGeod coord = coord.fromDeg(lon, lat);
FGAIWaypoint *wpt = createOnGround(ac, string("park"), coord, dep->getElevation(), vTaxiBackward);
pushBackWaypoint(wpt); pushBackWaypoint(wpt);
geo_direct_wgs_84 ( 0, lat, lon, heading, SGGeod coord;
10, SGGeodesy::direct(dep->geod(), heading, 10, coord, az2);
&lat2, &lon2, &az2 );
coord = coord.fromDeg(lon2, lat2);
wpt = createOnGround(ac, string("park2"), coord, dep->getElevation(), vTaxiBackward); wpt = createOnGround(ac, string("park2"), coord, dep->getElevation(), vTaxiBackward);
pushBackWaypoint(wpt); pushBackWaypoint(wpt);
geo_direct_wgs_84 ( 0, lat, lon, heading, SGGeodesy::direct(dep->geod(), heading, 2.2 * radius, coord, az2);
2.2*radius,
&lat2, &lon2, &az2 );
coord = coord.fromDeg(lon2, lat2);
wpt = createOnGround(ac, string("taxiStart"), coord, dep->getElevation(), vTaxiReduced); wpt = createOnGround(ac, string("taxiStart"), coord, dep->getElevation(), vTaxiReduced);
pushBackWaypoint(wpt); pushBackWaypoint(wpt);

View file

@ -143,8 +143,6 @@ void FGATCManager::init() {
if (!(fp->createPushBack(&ai_ac, if (!(fp->createPushBack(&ai_ac,
false, false,
apt, apt,
latitude,
longitude,
aircraftRadius, aircraftRadius,
fltType, fltType,
aircraftType, aircraftType,

View file

@ -589,8 +589,7 @@ void FGATCController::transmit(FGTrafficRecord * rec, FGAirportDynamics *parent,
getDynamics()->getActiveRunway(rwyClass, 1, activeRunway, getDynamics()->getActiveRunway(rwyClass, 1, activeRunway,
heading); heading);
rec->getAircraft()->GetFlightPlan()->setRunway(activeRunway); rec->getAircraft()->GetFlightPlan()->setRunway(activeRunway);
fp = rec->getAircraft()->getTrafficRef()->getDepartureAirport()-> fp = NULL;
getDynamics()->getSID(activeRunway, heading);
rec->getAircraft()->GetFlightPlan()->setSID(fp); rec->getAircraft()->GetFlightPlan()->setSID(fp);
if (fp) { if (fp) {
SID = fp->getName() + " departure"; SID = fp->getName() + " departure";
@ -737,11 +736,8 @@ void FGATCController::transmit(FGTrafficRecord * rec, FGAirportDynamics *parent,
SGGeod sender_pos; SGGeod sender_pos;
double sender_alt_ft, sender_alt; double sender_alt_ft, sender_alt;
if(ground_to_air) { if(ground_to_air) {
sender_alt_ft = parent->getElevation(); sender_pos = parent->parent()->geod();
sender_alt = sender_alt_ft * SG_FEET_TO_METER; }
sender_pos= SGGeod::fromDegM( parent->getLongitude(),
parent->getLatitude(), sender_alt );
}
else { else {
sender_alt_ft = rec->getAltitude(); sender_alt_ft = rec->getAltitude();
sender_alt = sender_alt_ft * SG_FEET_TO_METER; sender_alt = sender_alt_ft * SG_FEET_TO_METER;

View file

@ -23,6 +23,10 @@
#endif #endif
#include <algorithm> #include <algorithm>
#include <string>
#include <vector>
#include <boost/foreach.hpp>
#include <simgear/compiler.h> #include <simgear/compiler.h>
@ -37,20 +41,17 @@
#include <Airports/runways.hxx> #include <Airports/runways.hxx>
#include <ATCDCL/ATCutils.hxx> #include <ATCDCL/ATCutils.hxx>
#include <string> #include "simple.hxx"
#include <vector> #include "dynamics.hxx"
using std::string; using std::string;
using std::vector; using std::vector;
using std::sort; using std::sort;
using std::random_shuffle; using std::random_shuffle;
#include "simple.hxx"
#include "dynamics.hxx"
FGAirportDynamics::FGAirportDynamics(FGAirport * ap): FGAirportDynamics::FGAirportDynamics(FGAirport * ap):
_ap(ap), rwyPrefs(ap), SIDs(ap), _ap(ap), rwyPrefs(ap),
startupController (this), startupController (this),
towerController (this), towerController (this),
approachController (this), approachController (this),
atisSequenceIndex(-1), atisSequenceIndex(-1),
@ -85,159 +86,67 @@ void FGAirportDynamics::init()
} }
bool FGAirportDynamics::getAvailableParking(double *lat, double *lon, int FGAirportDynamics::innerGetAvailableParking(double radius, const string & flType,
double *heading, int *gateId, const string & acType,
double rad, const string & airline,
const string & flType, bool skipEmptyAirlineCode)
{
FGParkingVecIterator i;
for (i = parkings.begin(); i != parkings.end(); i++) {
// Taken by another aircraft, or no airline codes
if (!i->isAvailable()) {
continue;
}
if (skipEmptyAirlineCode && i->getCodes().empty()) {
continue;
}
// check airline codes match
if (!airline.empty() && !i->getCodes().empty()) {
if (i->getCodes().find(airline, 0) == string::npos) {
continue;
}
}
// Type doesn't match
if (i->getType() != flType) {
continue;
}
// too small
if (i->getRadius() < radius) {
continue;
}
i->setAvailable(false);
return i->getIndex();
}
return -1;
}
int FGAirportDynamics::getAvailableParking(double radius, const string & flType,
const string & acType, const string & acType,
const string & airline) const string & airline)
{ {
bool found = false; if (parkings.empty()) {
bool available = false; return -1;
FGParkingVecIterator i;
if (parkings.begin() == parkings.end()) {
//cerr << "Could not find parking spot at " << _ap->getId() << endl;
*lat = _ap->getLatitude();
*lon = _ap->getLongitude();
* gateId = -1;
*heading = 0;
found = true;
} else {
// First try finding a parking with a designated airline code
for (i = parkings.begin(); !(i == parkings.end() || found); i++) {
available = true;
// Taken by another aircraft
if (!(i->isAvailable())) {
available = false;
continue;
}
// No airline codes, so skip
if (i->getCodes().empty()) {
available = false;
continue;
} else { // Airline code doesn't match
//cerr << "Code = " << airline << ": Codes " << i->getCodes();
if (i->getCodes().find(airline, 0) == string::npos) {
available = false;
//cerr << "Unavailable" << endl;
continue;
} else {
//cerr << "Available" << endl;
}
}
// Type doesn't match
if (i->getType() != flType) {
available = false;
continue;
}
// too small
if (i->getRadius() < rad) {
available = false;
continue;
}
if (available) {
*lat = i->getLatitude();
*lon = i->getLongitude();
*heading = i->getHeading();
*gateId = i->getIndex();
i->setAvailable(false);
found = true;
}
}
// then try again for those without codes.
for (i = parkings.begin(); !(i == parkings.end() || found); i++) {
available = true;
if (!(i->isAvailable())) {
available = false;
continue;
}
if (!(i->getCodes().empty())) {
if ((i->getCodes().find(airline, 0) == string::npos)) {
available = false;
continue;
}
}
if (i->getType() != flType) {
available = false;
continue;
}
if (i->getRadius() < rad) {
available = false;
continue;
}
if (available) {
*lat = i->getLatitude();
*lon = i->getLongitude();
*heading = i->getHeading();
*gateId = i->getIndex();
i->setAvailable(false);
found = true;
}
}
// And finally once more if that didn't work. Now ignore the airline codes, as a last resort
for (i = parkings.begin(); !(i == parkings.end() || found); i++) {
available = true;
if (!(i->isAvailable())) {
available = false;
continue;
}
if (i->getType() != flType) {
available = false;
continue;
}
if (i->getRadius() < rad) {
available = false;
continue;
}
if (available) {
*lat = i->getLatitude();
*lon = i->getLongitude();
*heading = i->getHeading();
*gateId = i->getIndex();
i->setAvailable(false);
found = true;
}
}
} }
if (!found) {
//cerr << "Traffic overflow at" << _ap->getId() // most exact seach - airline codes must be present and match
// << ". flType = " << flType int result = innerGetAvailableParking(radius, flType, acType, airline, true);
// << ". airline = " << airline if (result >= 0) {
// << " Radius = " <<rad return result;
// << endl; }
*lat = _ap->getLatitude();
*lon = _ap->getLongitude(); // more tolerant - gates with empty airline codes are permitted
*heading = 0; result = innerGetAvailableParking(radius, flType, acType, airline, false);
*gateId = -1; if (result >= 0) {
//exit(1); return result;
} }
return found;
}
void FGAirportDynamics::getParking(int id, double *lat, double *lon, // fallback - ignore the airline code entirely
double *heading) return innerGetAvailableParking(radius, flType, acType, string(), false);
{
if (id < 0) {
*lat = _ap->getLatitude();
*lon = _ap->getLongitude();
*heading = 0;
} else {
FGParkingVecIterator i = parkings.begin();
for (i = parkings.begin(); i != parkings.end(); i++) {
if (id == i->getIndex()) {
*lat = i->getLatitude();
*lon = i->getLongitude();
*heading = i->getHeading();
}
}
}
} }
FGParking *FGAirportDynamics::getParking(int id) FGParking *FGAirportDynamics::getParking(int id)
@ -263,6 +172,18 @@ string FGAirportDynamics::getParkingName(int id)
return string("overflow"); return string("overflow");
} }
int FGAirportDynamics::findParkingByName(const std::string& name) const
{
FGParkingVec::const_iterator i = parkings.begin();
for (i = parkings.begin(); i != parkings.end(); i++) {
if (i->getName() == name) {
return i->getIndex();
}
}
return -1;
}
void FGAirportDynamics::releaseParking(int id) void FGAirportDynamics::releaseParking(int id)
{ {
if (id >= 0) { if (id >= 0) {
@ -279,8 +200,6 @@ void FGAirportDynamics::releaseParking(int id)
void FGAirportDynamics::setRwyUse(const FGRunwayPreference & ref) void FGAirportDynamics::setRwyUse(const FGRunwayPreference & ref)
{ {
rwyPrefs = ref; rwyPrefs = ref;
//cerr << "Exiting due to not implemented yet" << endl;
//exit(1);
} }
bool FGAirportDynamics::innerGetActiveRunway(const string & trafficType, bool FGAirportDynamics::innerGetActiveRunway(const string & trafficType,
@ -466,22 +385,12 @@ void FGAirportDynamics::addParking(FGParking & park)
parkings.push_back(park); parkings.push_back(park);
} }
double FGAirportDynamics::getLatitude() const
{
return _ap->getLatitude();
}
double FGAirportDynamics::getLongitude() const
{
return _ap->getLongitude();
}
double FGAirportDynamics::getElevation() const double FGAirportDynamics::getElevation() const
{ {
return _ap->getElevation(); return _ap->getElevation();
} }
const string & FGAirportDynamics::getId() const const string FGAirportDynamics::getId() const
{ {
return _ap->getId(); return _ap->getId();
} }
@ -543,13 +452,6 @@ int FGAirportDynamics::getTowerFrequency(unsigned nr)
return towerFreq; return towerFreq;
} }
FGAIFlightPlan *FGAirportDynamics::getSID(string activeRunway,
double heading)
{
return SIDs.getBest(activeRunway, heading);
}
const std::string FGAirportDynamics::getAtisSequence() const std::string FGAirportDynamics::getAtisSequence()
{ {
if (atisSequenceIndex == -1) { if (atisSequenceIndex == -1) {

View file

@ -26,7 +26,6 @@
#include "parking.hxx" #include "parking.hxx"
#include "groundnetwork.hxx" #include "groundnetwork.hxx"
#include "runwayprefs.hxx" #include "runwayprefs.hxx"
#include "sidstar.hxx"
// forward decls // forward decls
class FGAirport; class FGAirport;
@ -39,7 +38,6 @@ private:
FGParkingVec parkings; FGParkingVec parkings;
FGRunwayPreference rwyPrefs; FGRunwayPreference rwyPrefs;
FGSidStar SIDs;
FGStartupController startupController; FGStartupController startupController;
FGGroundNetwork groundNetwork; FGGroundNetwork groundNetwork;
FGTowerController towerController; FGTowerController towerController;
@ -65,8 +63,9 @@ private:
bool innerGetActiveRunway(const std::string &trafficType, int action, std::string &runway, double heading); bool innerGetActiveRunway(const std::string &trafficType, int action, std::string &runway, double heading);
std::string chooseRwyByHeading(stringVec rwys, double heading); std::string chooseRwyByHeading(stringVec rwys, double heading);
double elevation; int innerGetAvailableParking(double radius, const std::string & flType,
const std::string & acType, const std::string & airline,
bool skipEmptyAirlineCode);
public: public:
FGAirportDynamics(FGAirport* ap); FGAirportDynamics(FGAirport* ap);
~FGAirportDynamics(); ~FGAirportDynamics();
@ -91,36 +90,36 @@ public:
}; };
void init(); void init();
double getLongitude() const;
// Returns degrees
double getLatitude() const;
// Returns ft
double getElevation() const; double getElevation() const;
const string& getId() const; const std::string getId() const;
FGAirport* parent() const
{ return _ap; }
void getActiveRunway(const string& trafficType, int action, string& runway, double heading); void getActiveRunway(const string& trafficType, int action, string& runway, double heading);
void addParking(FGParking& park); void addParking(FGParking& park);
bool getAvailableParking(double *lat, double *lon,
double *heading, int *gate, double rad, const string& fltype, /**
const string& acType, const string& airline); * retrieve an available parking by GateID, or -1 if no suitable
void getParking (int id, double *lat, double* lon, double *heading); * parking location could be found.
*/
int getAvailableParking(double radius, const std::string& fltype,
const std::string& acType, const std::string& airline);
FGParking *getParking(int i); FGParking *getParking(int i);
void releaseParking(int id); void releaseParking(int id);
string getParkingName(int i); std::string getParkingName(int i);
int getNrOfParkings() { int getNrOfParkings() {
return parkings.size(); return parkings.size();
}; };
//FGAirport *getAddress() { return this; };
//const string &getName() const { return _name;};
// Returns degrees
// Departure / Arrival procedures
FGSidStar * getSIDs() {
return &SIDs;
};
FGAIFlightPlan * getSID(string activeRunway, double heading);
/**
* Find a parking gate index by name. Note names are often not unique
* in our data, so will return the first match.
*/
int findParkingByName(const std::string& name) const;
// ATC related functions. // ATC related functions.
FGStartupController *getStartupController() { FGStartupController *getStartupController() {

View file

@ -31,7 +31,7 @@ bool sortByLength (FGTaxiSegment *a, FGTaxiSegment *b);
class FGTaxiNode class FGTaxiNode
{ {
private: protected:
SGGeod geod; SGGeod geod;
int index; int index;
@ -106,9 +106,9 @@ FGTaxiNode &operator =(const FGTaxiNode &other)
const SGGeod& getGeod() const { return geod; } const SGGeod& getGeod() const { return geod; }
int getIndex() { return index; }; int getIndex() const { return index; };
int getHoldPointType() { return holdType; }; int getHoldPointType() const { return holdType; };
bool getIsOnRunway() { return isOnRunway; }; bool getIsOnRunway() const { return isOnRunway; };
FGTaxiNode *getAddress() { return this;}; FGTaxiNode *getAddress() { return this;};
FGTaxiSegmentVectorIterator getBeginRoute() { return next.begin(); }; FGTaxiSegmentVectorIterator getBeginRoute() { return next.begin(); };

View file

@ -36,9 +36,6 @@
#include "gnnode.hxx" #include "gnnode.hxx"
using std::string;
using std::vector;
class FGTaxiRoute; class FGTaxiRoute;
@ -46,9 +43,9 @@ class FGParking : public FGTaxiNode {
private: private:
double heading; double heading;
double radius; double radius;
string parkingName; std::string parkingName;
string type; std::string type;
string airlineCodes; std::string airlineCodes;
bool available; bool available;
int pushBackPoint; int pushBackPoint;
@ -92,34 +89,26 @@ public:
return *this; return *this;
}; };
~FGParking(); ~FGParking();
// FGParking(double lat,
// double lon,
// double hdg,
// double rad,
// int idx,
// const string& name,
// const string& tpe,
// const string& codes);
void setHeading (double hdg) { heading = hdg; }; void setHeading (double hdg) { heading = hdg; };
void setRadius (double rad) { radius = rad; }; void setRadius (double rad) { radius = rad; };
void setName (const string& name) { parkingName = name; }; void setName (const std::string& name) { parkingName = name; };
void setType (const string& tpe) { type = tpe; }; void setType (const std::string& tpe) { type = tpe; };
void setCodes (const string& codes){ airlineCodes= codes;}; void setCodes (const std::string& codes){ airlineCodes= codes;};
void setPushBackRoute(FGTaxiRoute *val) { pushBackRoute = val; }; void setPushBackRoute(FGTaxiRoute *val) { pushBackRoute = val; };
void setPushBackPoint(int val) { pushBackPoint = val; }; void setPushBackPoint(int val) { pushBackPoint = val; };
bool isAvailable () { return available;}; bool isAvailable () const { return available;};
void setAvailable(bool val) { available = val; }; void setAvailable(bool val) { available = val; };
double getHeading () { return heading; }; double getHeading () const { return heading; };
double getRadius () { return radius; }; double getRadius () const { return radius; };
string getType () { return type; }; std::string getType () const { return type; };
string getCodes () { return airlineCodes;}; std::string getCodes () const { return airlineCodes;};
string getName () { return parkingName; }; std::string getName () const { return parkingName; };
FGTaxiRoute * getPushBackRoute () { return pushBackRoute; }; FGTaxiRoute * getPushBackRoute () { return pushBackRoute; };
@ -129,8 +118,8 @@ public:
return radius < other.radius; }; return radius < other.radius; };
}; };
typedef vector<FGParking> FGParkingVec; typedef std::vector<FGParking> FGParkingVec;
typedef vector<FGParking>::iterator FGParkingVecIterator; typedef std::vector<FGParking>::iterator FGParkingVecIterator;
typedef vector<FGParking>::const_iterator FGParkingVecConstIterator; typedef std::vector<FGParking>::const_iterator FGParkingVecConstIterator;
#endif #endif

View file

@ -38,6 +38,7 @@
#include <simgear/props/props_io.hxx> #include <simgear/props/props_io.hxx>
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include <simgear/sg_inlines.h> #include <simgear/sg_inlines.h>
#include <simgear/structure/exception.hxx>
#include <Environment/environment_mgr.hxx> #include <Environment/environment_mgr.hxx>
#include <Environment/environment.hxx> #include <Environment/environment.hxx>
@ -115,7 +116,6 @@ FGAirportDynamics * FGAirport::getDynamics()
FGRunwayPreference rwyPrefs(this); FGRunwayPreference rwyPrefs(this);
XMLLoader::load(&rwyPrefs); XMLLoader::load(&rwyPrefs);
_dynamics->setRwyUse(rwyPrefs); _dynamics->setRwyUse(rwyPrefs);
XMLLoader::load(_dynamics->getSIDs());
return _dynamics; return _dynamics;
} }

View file

@ -29,6 +29,7 @@
#include "runwayprefloader.hxx" #include "runwayprefloader.hxx"
#include "dynamics.hxx" #include "dynamics.hxx"
#include "simple.hxx"
#include "runwayprefs.hxx" #include "runwayprefs.hxx"
using std::string; using std::string;
@ -36,9 +37,10 @@ using std::string;
XMLLoader::XMLLoader() {} XMLLoader::XMLLoader() {}
XMLLoader::~XMLLoader() {} XMLLoader::~XMLLoader() {}
void XMLLoader::load(FGAirportDynamics* d) { void XMLLoader::load(FGAirportDynamics* d)
{
FGAirportDynamicsXMLLoader visitor(d); FGAirportDynamicsXMLLoader visitor(d);
if(loadAirportXMLDataIntoVisitor(d->getId(), "groundnet", visitor)) { if(loadAirportXMLDataIntoVisitor(d->parent()->ident(), "groundnet", visitor)) {
d->init(); d->init();
} }
} }
@ -48,13 +50,6 @@ void XMLLoader::load(FGRunwayPreference* p) {
loadAirportXMLDataIntoVisitor(p->getId(), "rwyuse", visitor); loadAirportXMLDataIntoVisitor(p->getId(), "rwyuse", visitor);
} }
void XMLLoader::load(FGSidStar* p) {
SGPath path;
if (findAirportData(p->getId(), "SID", path)) {
p->load(path);
}
}
bool XMLLoader::findAirportData(const std::string& aICAO, bool XMLLoader::findAirportData(const std::string& aICAO,
const std::string& aFileName, SGPath& aPath) const std::string& aFileName, SGPath& aPath)
{ {

View file

@ -24,6 +24,7 @@
// simgear // simgear
#include <simgear/props/props_io.hxx> #include <simgear/props/props_io.hxx>
#include <simgear/structure/exception.hxx>
#include "globals.hxx" #include "globals.hxx"
#include "fg_props.hxx" #include "fg_props.hxx"
@ -150,7 +151,8 @@ bool setPosFromAirportIDandHdg( const string& id, double tgt_hdg ) {
} }
// Set current_options lon/lat given an airport id and parkig position name // Set current_options lon/lat given an airport id and parkig position name
static bool fgSetPosFromAirportIDandParkpos( const string& id, const string& parkpos ) { static bool fgSetPosFromAirportIDandParkpos( const string& id, const string& parkpos )
{
if ( id.empty() ) if ( id.empty() )
return false; return false;
@ -167,11 +169,9 @@ static bool fgSetPosFromAirportIDandParkpos( const string& id, const string& par
return false; return false;
} }
int park_index = dcs->getNrOfParkings() - 1; int gateID;
bool succes;
double radius = fgGetDouble("/sim/dimensions/radius-m"); double radius = fgGetDouble("/sim/dimensions/radius-m");
if ((parkpos == string("AVAILABLE")) && (radius > 0)) { if ((parkpos == string("AVAILABLE")) && (radius > 0)) {
double lat, lon, heading;
string fltType; string fltType;
string acOperator; string acOperator;
SGPath acData; SGPath acData;
@ -203,30 +203,27 @@ static bool fgSetPosFromAirportIDandParkpos( const string& id, const string& par
} }
string acType; // Currently not used by findAvailable parking, so safe to leave empty. string acType; // Currently not used by findAvailable parking, so safe to leave empty.
succes = dcs->getAvailableParking(&lat, &lon, &heading, &park_index, radius, fltType, acType, acOperator); gateID = dcs->getAvailableParking(radius, fltType, acType, acOperator);
if (succes) { if (gateID >=0 ) {
fgGetString("/sim/presets/parkpos"); fgGetString("/sim/presets/parkpos");
fgSetString("/sim/presets/parkpos", dcs->getParking(park_index)->getName()); fgSetString("/sim/presets/parkpos", dcs->getParking(gateID)->getName());
} else { } else {
SG_LOG( SG_GENERAL, SG_ALERT, SG_LOG( SG_GENERAL, SG_ALERT,
"Failed to find a suitable parking at airport " << id ); "Failed to find a suitable parking at airport " << id );
return false; return false;
} }
} else { } else {
//cerr << "We shouldn't get here when AVAILABLE" << endl; gateID = dcs->findParkingByName(parkpos);
while (park_index >= 0 && dcs->getParkingName(park_index) != parkpos) park_index--; if (gateID < 0) {
if (park_index < 0) {
SG_LOG( SG_GENERAL, SG_ALERT, SG_LOG( SG_GENERAL, SG_ALERT,
"Failed to find parking position " << parkpos << "Failed to find a parking at airport " << id << ":" << parkpos);
" at airport " << id );
return false; return false;
} }
} }
FGParking* parking = dcs->getParking(park_index);
FGParking* parking = dcs->getParking(gateID);
parking->setAvailable(false); parking->setAvailable(false);
fgApplyStartOffset( fgApplyStartOffset(parking->getGeod(), parking->getHeading());
SGGeod::fromDeg(parking->getLongitude(), parking->getLatitude()),
parking->getHeading());
return true; return true;
} }