Refactor some parking / airport-dynamics APIs, in preparation for caching the ground cache data in the nav-cache.
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 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&);
void setLeg(int val) { leg = val;}
std::string name;
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 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);
int currWpt = wpt_iterator - waypoints.begin();
switch (legNr) {
case 1:
- retVal = createPushBack(ac, firstFlight, dep, latitude, longitude,
+ retVal = createPushBack(ac, firstFlight, dep,
radius, fltType, aircraftType, airline);
// Pregenerate the taxi leg.
//if (retVal) {
const string & acType,
const string & airline)
{
- double heading, lat, lon;
// If this function is called during initialization,
// make sure we obtain a valid gate ID first
// and place the model at the location of the gate.
- if (firstFlight) {
- if (!(apt->getDynamics()->getAvailableParking(&lat, &lon,
- &heading, &gateId,
- radius, fltType,
- acType, airline))) {
- SG_LOG(SG_AI, SG_WARN, "Could not find parking for a " <<
- acType <<
- " of flight type " << fltType <<
- " of airline " << airline <<
- " at airport " << apt->getId());
- }
+ if (firstFlight)
+ {
+ gateId = apt->getDynamics()->getAvailableParking(radius, fltType,
+ acType, airline);
+ if (gateId < 0) {
+ SG_LOG(SG_AI, SG_WARN, "Could not find parking for a " <<
+ acType <<
+ " of flight type " << fltType <<
+ " of airline " << airline <<
+ " at airport " << apt->getId());
+ }
}
string rwyClass = getRunwayClassFromTrafficType(fltType);
ac->getPerformance()->vTaxi());
pushBackWaypoint(wpt);
- double heading, lat, lon;
- aAirport->getDynamics()->getParking(gateId, &lat, &lon, &heading);
- wpt =
- createOnGround(ac, "ENDtaxi", SGGeod::fromDeg(lon, lat), airportElev,
- ac->getPerformance()->vTaxi());
+ FGParking* parkPos = aAirport->getDynamics()->getParking(gateId);
+ wpt = createOnGround(ac, "ENDtaxi", parkPos->getGeod(), airportElev,
+ ac->getPerformance()->vTaxi());
pushBackWaypoint(wpt);
}
const string & acType,
const string & airline)
{
- double heading, lat, lon;
- apt->getDynamics()->getAvailableParking(&lat, &lon, &heading,
- &gateId, radius, fltType,
+ gateId = apt->getDynamics()->getAvailableParking(radius, fltType,
acType, airline);
SGGeod lastWptPos =
{
FGAIWaypoint *wpt;
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 vTaxiReduced = vTaxi * (2.0 / 3.0);
- apt->getDynamics()->getParking(gateId, &lat, &lon, &heading);
- heading += 180.0;
- if (heading > 360)
- heading -= 360;
- geo_direct_wgs_84(0, lat, lon, heading,
- 2.2 * radius, &lat2, &lon2, &az2);
- wpt =
- createOnGround(ac, "taxiStart", SGGeod::fromDeg(lon2, lat2),
- aptElev, vTaxiReduced);
+ FGParking* parking = apt->getDynamics()->getParking(gateId);
+ double heading = SGMiscd::normalizePeriodic(0, 360, parking->getHeading() + 180.0);
+ double az; // unused
+ SGGeod pos;
+
+ SGGeodesy::direct(parking->getGeod(), heading, 2.2 * parking->getRadius(),
+ pos, az);
+
+ wpt = createOnGround(ac, "taxiStart", pos, aptElev, vTaxiReduced);
pushBackWaypoint(wpt);
- geo_direct_wgs_84(0, lat, lon, heading,
- 0.1 * radius, &lat2, &lon2, &az2);
-
- wpt =
- createOnGround(ac, "taxiStart2", SGGeod::fromDeg(lon2, lat2),
- aptElev, vTaxiReduced);
+ SGGeodesy::direct(parking->getGeod(), heading, 0.1 * parking->getRadius(),
+ pos, az);
+ wpt = createOnGround(ac, "taxiStart2", pos, aptElev, vTaxiReduced);
pushBackWaypoint(wpt);
- wpt =
- createOnGround(ac, "END-Parking", SGGeod::fromDeg(lon, lat), aptElev,
+ wpt = createOnGround(ac, "END-Parking", parking->getGeod(), aptElev,
vTaxiReduced);
pushBackWaypoint(wpt);
return true;
// TODO: Use James Turner's createOnGround functions.
bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
bool firstFlight, FGAirport *dep,
- double latitude,
- double longitude,
double radius,
const string& fltType,
const string& aircraftType,
const string& airline)
{
- double lat, lon, heading;
double vTaxi = ac->getPerformance()->vTaxi();
double vTaxiBackward = vTaxi * (-2.0/3.0);
double vTaxiReduced = vTaxi * (2.0/3.0);
if (!(dep->getDynamics()->getGroundNetwork()->exists())) {
//cerr << "Push Back fallback" << endl;
- createPushBackFallBack(ac, firstFlight, dep, latitude, longitude,
+ createPushBackFallBack(ac, firstFlight, dep,
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 {
- if (firstFlight) {
-
- 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;
+ dep->getDynamics()->getParking(gateId);
+ }
+
+ if (gateId < 0) {
+ createPushBackFallBack(ac, firstFlight, dep,
+ radius, fltType, aircraftType, airline);
+ return true;
- }
- //cerr << "getting parking " << gateId;
- //cerr << " for a " <<
- // aircraftType <<
- // " of flight type " << fltType <<
- // " of airline " << airline <<
- // " at airport " << dep->getId() << endl;
- FGParking *parking = dep->getDynamics()->getParking(gateId);
- int pushBackNode = parking->getPushBackPoint();
+ }
+
+ FGParking *parking = dep->getDynamics()->getParking(gateId);
+ int pushBackNode = parking->getPushBackPoint();
+
+ pushBackRoute = parking->getPushBackRoute();
+ if ((pushBackNode > 0) && (pushBackRoute == 0)) { // Load the already established route for this gate
+ int node, rte;
+ FGTaxiRoute route;
+ //cerr << "Creating push-back for " << gateId << " (" << parking->getName() << ") using push-back point " << pushBackNode << endl;
+ route = dep->getDynamics()->getGroundNetwork()->findShortestRoute(gateId, pushBackNode, false);
+ parking->setPushBackRoute(new FGTaxiRoute(route));
pushBackRoute = parking->getPushBackRoute();
- if ((pushBackNode > 0) && (pushBackRoute == 0)) { // Load the already established route for this gate
- int node, rte;
- FGTaxiRoute route;
- //cerr << "Creating push-back for " << gateId << " (" << parking->getName() << ") using push-back point " << pushBackNode << endl;
- 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;
+ 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;
+ 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;
}
/*******************************************************************
* network yet.
******************************************************************/
void FGAIFlightPlan::createPushBackFallBack(FGAIAircraft *ac, bool firstFlight, FGAirport *dep,
- double latitude,
- double longitude,
double radius,
const string& fltType,
const string& aircraftType,
const string& airline)
{
- double heading;
- double lat;
- double lon;
- double lat2 = 0.0;
- double lon2 = 0.0;
double az2 = 0.0;
double vTaxi = ac->getPerformance()->vTaxi();
double vTaxiBackward = vTaxi * (-2.0/3.0);
double vTaxiReduced = vTaxi * (2.0/3.0);
-
-
- 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);
+ double heading = 180.0; // this is a completely arbitrary heading!
+ FGAIWaypoint *wpt = createOnGround(ac, string("park"), dep->geod(), dep->getElevation(), vTaxiBackward);
pushBackWaypoint(wpt);
- geo_direct_wgs_84 ( 0, lat, lon, heading,
- 10,
- &lat2, &lon2, &az2 );
- coord = coord.fromDeg(lon2, lat2);
+ SGGeod coord;
+ SGGeodesy::direct(dep->geod(), heading, 10, coord, az2);
wpt = createOnGround(ac, string("park2"), coord, dep->getElevation(), vTaxiBackward);
pushBackWaypoint(wpt);
-
- geo_direct_wgs_84 ( 0, lat, lon, heading,
- 2.2*radius,
- &lat2, &lon2, &az2 );
- coord = coord.fromDeg(lon2, lat2);
+
+ SGGeodesy::direct(dep->geod(), heading, 2.2 * radius, coord, az2);
wpt = createOnGround(ac, string("taxiStart"), coord, dep->getElevation(), vTaxiReduced);
pushBackWaypoint(wpt);
if (!(fp->createPushBack(&ai_ac,
false,
apt,
- latitude,
- longitude,
aircraftRadius,
fltType,
aircraftType,
getDynamics()->getActiveRunway(rwyClass, 1, activeRunway,
heading);
rec->getAircraft()->GetFlightPlan()->setRunway(activeRunway);
- fp = rec->getAircraft()->getTrafficRef()->getDepartureAirport()->
- getDynamics()->getSID(activeRunway, heading);
+ fp = NULL;
rec->getAircraft()->GetFlightPlan()->setSID(fp);
if (fp) {
SID = fp->getName() + " departure";
SGGeod sender_pos;
double sender_alt_ft, sender_alt;
if(ground_to_air) {
- sender_alt_ft = parent->getElevation();
- sender_alt = sender_alt_ft * SG_FEET_TO_METER;
- sender_pos= SGGeod::fromDegM( parent->getLongitude(),
- parent->getLatitude(), sender_alt );
- }
+ sender_pos = parent->parent()->geod();
+ }
else {
sender_alt_ft = rec->getAltitude();
sender_alt = sender_alt_ft * SG_FEET_TO_METER;
#endif
#include <algorithm>
+#include <string>
+#include <vector>
+
+#include <boost/foreach.hpp>
#include <simgear/compiler.h>
#include <Airports/runways.hxx>
#include <ATCDCL/ATCutils.hxx>
-#include <string>
-#include <vector>
+#include "simple.hxx"
+#include "dynamics.hxx"
using std::string;
using std::vector;
using std::sort;
using std::random_shuffle;
-#include "simple.hxx"
-#include "dynamics.hxx"
-
FGAirportDynamics::FGAirportDynamics(FGAirport * ap):
- _ap(ap), rwyPrefs(ap), SIDs(ap),
- startupController (this),
+ _ap(ap), rwyPrefs(ap),
+ startupController (this),
towerController (this),
approachController (this),
atisSequenceIndex(-1),
}
-bool FGAirportDynamics::getAvailableParking(double *lat, double *lon,
- double *heading, int *gateId,
- double rad,
- const string & flType,
- const string & acType,
- const string & airline)
+int FGAirportDynamics::innerGetAvailableParking(double radius, const string & flType,
+ const string & acType,
+ const string & airline,
+ bool skipEmptyAirlineCode)
{
- bool found = false;
- bool available = false;
-
-
- 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;
- }
- }
+ 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;
}
- if (!found) {
- //cerr << "Traffic overflow at" << _ap->getId()
- // << ". flType = " << flType
- // << ". airline = " << airline
- // << " Radius = " <<rad
- // << endl;
- *lat = _ap->getLatitude();
- *lon = _ap->getLongitude();
- *heading = 0;
- *gateId = -1;
- //exit(1);
+ // too small
+ if (i->getRadius() < radius) {
+ continue;
}
- return found;
+
+ i->setAvailable(false);
+ return i->getIndex();
+ }
+
+ return -1;
}
-void FGAirportDynamics::getParking(int id, double *lat, double *lon,
- double *heading)
+int FGAirportDynamics::getAvailableParking(double radius, const string & flType,
+ const string & acType,
+ const string & airline)
{
- 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();
- }
- }
+ if (parkings.empty()) {
+ return -1;
}
+
+ // most exact seach - airline codes must be present and match
+ int result = innerGetAvailableParking(radius, flType, acType, airline, true);
+ if (result >= 0) {
+ return result;
+ }
+
+ // more tolerant - gates with empty airline codes are permitted
+ result = innerGetAvailableParking(radius, flType, acType, airline, false);
+ if (result >= 0) {
+ return result;
+ }
+
+ // fallback - ignore the airline code entirely
+ return innerGetAvailableParking(radius, flType, acType, string(), false);
}
FGParking *FGAirportDynamics::getParking(int id)
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)
{
if (id >= 0) {
void FGAirportDynamics::setRwyUse(const FGRunwayPreference & ref)
{
rwyPrefs = ref;
- //cerr << "Exiting due to not implemented yet" << endl;
- //exit(1);
}
bool FGAirportDynamics::innerGetActiveRunway(const string & trafficType,
parkings.push_back(park);
}
-double FGAirportDynamics::getLatitude() const
-{
- return _ap->getLatitude();
-}
-
-double FGAirportDynamics::getLongitude() const
-{
- return _ap->getLongitude();
-}
-
double FGAirportDynamics::getElevation() const
{
return _ap->getElevation();
}
-const string & FGAirportDynamics::getId() const
+const string FGAirportDynamics::getId() const
{
return _ap->getId();
}
return towerFreq;
}
-
-FGAIFlightPlan *FGAirportDynamics::getSID(string activeRunway,
- double heading)
-{
- return SIDs.getBest(activeRunway, heading);
-}
-
const std::string FGAirportDynamics::getAtisSequence()
{
if (atisSequenceIndex == -1) {
#include "parking.hxx"
#include "groundnetwork.hxx"
#include "runwayprefs.hxx"
-#include "sidstar.hxx"
// forward decls
class FGAirport;
FGParkingVec parkings;
FGRunwayPreference rwyPrefs;
- FGSidStar SIDs;
FGStartupController startupController;
FGGroundNetwork groundNetwork;
FGTowerController towerController;
bool innerGetActiveRunway(const std::string &trafficType, int action, std::string &runway, 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:
FGAirportDynamics(FGAirport* ap);
~FGAirportDynamics();
};
void init();
- double getLongitude() const;
- // Returns degrees
- double getLatitude() const;
- // Returns ft
+
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 addParking(FGParking& park);
- bool getAvailableParking(double *lat, double *lon,
- double *heading, int *gate, double rad, const string& fltype,
- const string& acType, const string& airline);
- void getParking (int id, double *lat, double* lon, double *heading);
+
+ /**
+ * retrieve an available parking by GateID, or -1 if no suitable
+ * 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);
void releaseParking(int id);
- string getParkingName(int i);
+ std::string getParkingName(int i);
int getNrOfParkings() {
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.
FGStartupController *getStartupController() {
class FGTaxiNode
{
-private:
+protected:
SGGeod geod;
int index;
const SGGeod& getGeod() const { return geod; }
- int getIndex() { return index; };
- int getHoldPointType() { return holdType; };
- bool getIsOnRunway() { return isOnRunway; };
+ int getIndex() const { return index; };
+ int getHoldPointType() const { return holdType; };
+ bool getIsOnRunway() const { return isOnRunway; };
FGTaxiNode *getAddress() { return this;};
FGTaxiSegmentVectorIterator getBeginRoute() { return next.begin(); };
#include "gnnode.hxx"
-using std::string;
-using std::vector;
-
class FGTaxiRoute;
private:
double heading;
double radius;
- string parkingName;
- string type;
- string airlineCodes;
+ std::string parkingName;
+ std::string type;
+ std::string airlineCodes;
bool available;
int pushBackPoint;
return *this;
};
~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 setRadius (double rad) { radius = rad; };
- void setName (const string& name) { parkingName = name; };
- void setType (const string& tpe) { type = tpe; };
- void setCodes (const string& codes){ airlineCodes= codes;};
+ void setName (const std::string& name) { parkingName = name; };
+ void setType (const std::string& tpe) { type = tpe; };
+ void setCodes (const std::string& codes){ airlineCodes= codes;};
void setPushBackRoute(FGTaxiRoute *val) { pushBackRoute = val; };
void setPushBackPoint(int val) { pushBackPoint = val; };
- bool isAvailable () { return available;};
+ bool isAvailable () const { return available;};
void setAvailable(bool val) { available = val; };
- double getHeading () { return heading; };
- double getRadius () { return radius; };
+ double getHeading () const { return heading; };
+ double getRadius () const { return radius; };
- string getType () { return type; };
- string getCodes () { return airlineCodes;};
- string getName () { return parkingName; };
+ std::string getType () const { return type; };
+ std::string getCodes () const { return airlineCodes;};
+ std::string getName () const { return parkingName; };
FGTaxiRoute * getPushBackRoute () { return pushBackRoute; };
return radius < other.radius; };
};
-typedef vector<FGParking> FGParkingVec;
-typedef vector<FGParking>::iterator FGParkingVecIterator;
-typedef vector<FGParking>::const_iterator FGParkingVecConstIterator;
+typedef std::vector<FGParking> FGParkingVec;
+typedef std::vector<FGParking>::iterator FGParkingVecIterator;
+typedef std::vector<FGParking>::const_iterator FGParkingVecConstIterator;
#endif
#include <simgear/props/props_io.hxx>
#include <simgear/debug/logstream.hxx>
#include <simgear/sg_inlines.h>
+#include <simgear/structure/exception.hxx>
#include <Environment/environment_mgr.hxx>
#include <Environment/environment.hxx>
FGRunwayPreference rwyPrefs(this);
XMLLoader::load(&rwyPrefs);
_dynamics->setRwyUse(rwyPrefs);
- XMLLoader::load(_dynamics->getSIDs());
return _dynamics;
}
#include "runwayprefloader.hxx"
#include "dynamics.hxx"
+#include "simple.hxx"
#include "runwayprefs.hxx"
using std::string;
XMLLoader::XMLLoader() {}
XMLLoader::~XMLLoader() {}
-void XMLLoader::load(FGAirportDynamics* d) {
+void XMLLoader::load(FGAirportDynamics* d)
+{
FGAirportDynamicsXMLLoader visitor(d);
- if(loadAirportXMLDataIntoVisitor(d->getId(), "groundnet", visitor)) {
+ if(loadAirportXMLDataIntoVisitor(d->parent()->ident(), "groundnet", visitor)) {
d->init();
}
}
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,
const std::string& aFileName, SGPath& aPath)
{
// simgear
#include <simgear/props/props_io.hxx>
+#include <simgear/structure/exception.hxx>
#include "globals.hxx"
#include "fg_props.hxx"
}
// 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() )
return false;
return false;
}
- int park_index = dcs->getNrOfParkings() - 1;
- bool succes;
+ int gateID;
double radius = fgGetDouble("/sim/dimensions/radius-m");
if ((parkpos == string("AVAILABLE")) && (radius > 0)) {
- double lat, lon, heading;
string fltType;
string acOperator;
SGPath acData;
}
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);
- if (succes) {
+ gateID = dcs->getAvailableParking(radius, fltType, acType, acOperator);
+ if (gateID >=0 ) {
fgGetString("/sim/presets/parkpos");
- fgSetString("/sim/presets/parkpos", dcs->getParking(park_index)->getName());
+ fgSetString("/sim/presets/parkpos", dcs->getParking(gateID)->getName());
} else {
SG_LOG( SG_GENERAL, SG_ALERT,
"Failed to find a suitable parking at airport " << id );
return false;
}
} else {
- //cerr << "We shouldn't get here when AVAILABLE" << endl;
- while (park_index >= 0 && dcs->getParkingName(park_index) != parkpos) park_index--;
- if (park_index < 0) {
+ gateID = dcs->findParkingByName(parkpos);
+ if (gateID < 0) {
SG_LOG( SG_GENERAL, SG_ALERT,
- "Failed to find parking position " << parkpos <<
- " at airport " << id );
+ "Failed to find a parking at airport " << id << ":" << parkpos);
return false;
}
}
- FGParking* parking = dcs->getParking(park_index);
+
+ FGParking* parking = dcs->getParking(gateID);
parking->setAvailable(false);
- fgApplyStartOffset(
- SGGeod::fromDeg(parking->getLongitude(), parking->getLatitude()),
- parking->getHeading());
+ fgApplyStartOffset(parking->getGeod(), parking->getHeading());
return true;
}