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:
parent
01be5529ba
commit
b1854459b3
12 changed files with 273 additions and 455 deletions
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 (!(dep->getDynamics()->getAvailableParking(&lat, &lon,
|
if (gateId < 0) {
|
||||||
&heading, &gateId,
|
createPushBackFallBack(ac, firstFlight, dep,
|
||||||
radius, fltType,
|
radius, fltType, aircraftType, airline);
|
||||||
aircraftType, airline))) {
|
return true;
|
||||||
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;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
//cerr << "getting parking " << gateId;
|
|
||||||
//cerr << " for a " <<
|
FGParking *parking = dep->getDynamics()->getParking(gateId);
|
||||||
// aircraftType <<
|
int pushBackNode = parking->getPushBackPoint();
|
||||||
// " of flight type " << fltType <<
|
|
||||||
// " of airline " << airline <<
|
pushBackRoute = parking->getPushBackRoute();
|
||||||
// " at airport " << dep->getId() << endl;
|
if ((pushBackNode > 0) && (pushBackRoute == 0)) { // Load the already established route for this gate
|
||||||
FGParking *parking = dep->getDynamics()->getParking(gateId);
|
int node, rte;
|
||||||
int pushBackNode = parking->getPushBackPoint();
|
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();
|
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);
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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()
|
|
||||||
// << ". flType = " << flType
|
|
||||||
// << ". airline = " << airline
|
|
||||||
// << " Radius = " <<rad
|
|
||||||
// << endl;
|
|
||||||
*lat = _ap->getLatitude();
|
|
||||||
*lon = _ap->getLongitude();
|
|
||||||
*heading = 0;
|
|
||||||
*gateId = -1;
|
|
||||||
//exit(1);
|
|
||||||
}
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FGAirportDynamics::getParking(int id, double *lat, double *lon,
|
// most exact seach - airline codes must be present and match
|
||||||
double *heading)
|
int result = innerGetAvailableParking(radius, flType, acType, airline, true);
|
||||||
{
|
if (result >= 0) {
|
||||||
if (id < 0) {
|
return result;
|
||||||
*lat = _ap->getLatitude();
|
}
|
||||||
*lon = _ap->getLongitude();
|
|
||||||
*heading = 0;
|
// more tolerant - gates with empty airline codes are permitted
|
||||||
} else {
|
result = innerGetAvailableParking(radius, flType, acType, airline, false);
|
||||||
FGParkingVecIterator i = parkings.begin();
|
if (result >= 0) {
|
||||||
for (i = parkings.begin(); i != parkings.end(); i++) {
|
return result;
|
||||||
if (id == i->getIndex()) {
|
}
|
||||||
*lat = i->getLatitude();
|
|
||||||
*lon = i->getLongitude();
|
// fallback - ignore the airline code entirely
|
||||||
*heading = i->getHeading();
|
return innerGetAvailableParking(radius, flType, acType, string(), false);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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(); };
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue