Durk Talsma:
Auf Niederlandisch: Bij deze de patch voor de taxiway code. Deze code is nog gebaseerd op de bestaaande architectuur, gebaseerd op de FGAirport class in simple.[ch]xx Ik heb me voornamelijk gericht op nieuwe functionaliteit; de volgende submissie zal waarschijnlijk bestaan uit opschoning, opsplitsing en een implementatie van de nieuwe airport architectuur, zoals voorgesteld door David Luff. En Anglais: Here is the patch for the taxiway code. This code is still based on the exsisting architecture, which is based on the FGAirport class in simple.[ch]xx I've aimed mostly at new functionality; The next batch will probably contain code cleanups, splitups and the implementation fo the new airport architecture, as proposed by David Luff.
This commit is contained in:
parent
13945c6cd4
commit
54594e5219
5 changed files with 772 additions and 132 deletions
|
@ -104,9 +104,10 @@ private:
|
||||||
time_t start_time;
|
time_t start_time;
|
||||||
int leg;
|
int leg;
|
||||||
int gateId;
|
int gateId;
|
||||||
|
string activeRunway;
|
||||||
|
|
||||||
void createPushBack(bool, FGAirport*, double, double, double, string, string, string);
|
void createPushBack(bool, FGAirport*, double, double, double, string, string, string);
|
||||||
void createTaxi(bool, int, FGAirport *, double, string, string, string);
|
void createTaxi(bool, int, FGAirport *, double, double, double, string, string, string);
|
||||||
void createTakeOff(bool, FGAirport *, double);
|
void createTakeOff(bool, FGAirport *, double);
|
||||||
void createClimb(bool, FGAirport *, double, double);
|
void createClimb(bool, FGAirport *, double, double);
|
||||||
void createCruise(bool, FGAirport*, FGAirport*, double, double, double, double);
|
void createCruise(bool, FGAirport*, FGAirport*, double, double, double, double);
|
||||||
|
|
|
@ -50,7 +50,7 @@ void FGAIFlightPlan::create(FGAirport *dep, FGAirport *arr, int legNr, double al
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
//cerr << "Creating Taxi" << endl;
|
//cerr << "Creating Taxi" << endl;
|
||||||
createTaxi(firstFlight, 1, dep, radius, fltType, aircraftType, airline);
|
createTaxi(firstFlight, 1, dep, latitude, longitude, radius, fltType, aircraftType, airline);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
//cerr << "Creating TAkeoff" << endl;
|
//cerr << "Creating TAkeoff" << endl;
|
||||||
|
@ -74,7 +74,7 @@ void FGAIFlightPlan::create(FGAirport *dep, FGAirport *arr, int legNr, double al
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
//cerr << "Creating Taxi 2" << endl;
|
//cerr << "Creating Taxi 2" << endl;
|
||||||
createTaxi(false, 2, arr, radius, fltType, aircraftType, airline);
|
createTaxi(false, 2, arr, latitude, longitude, radius, fltType, aircraftType, airline);
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
//cerr << "Creating Parking" << endl;
|
//cerr << "Creating Parking" << endl;
|
||||||
|
@ -161,7 +161,7 @@ void FGAIFlightPlan::createPushBack(bool firstFlight, FGAirport *dep,
|
||||||
wpt->on_ground = true;
|
wpt->on_ground = true;
|
||||||
waypoints.push_back(wpt);
|
waypoints.push_back(wpt);
|
||||||
geo_direct_wgs_84 ( 0, lat, lon, heading,
|
geo_direct_wgs_84 ( 0, lat, lon, heading,
|
||||||
100,
|
radius, // push back one entire aircraft radius
|
||||||
&lat2, &lon2, &az2 );
|
&lat2, &lon2, &az2 );
|
||||||
wpt = new waypoint;
|
wpt = new waypoint;
|
||||||
wpt->name = "taxiStart";
|
wpt->name = "taxiStart";
|
||||||
|
@ -176,22 +176,14 @@ void FGAIFlightPlan::createPushBack(bool firstFlight, FGAirport *dep,
|
||||||
wpt->on_ground = true;
|
wpt->on_ground = true;
|
||||||
waypoints.push_back(wpt);
|
waypoints.push_back(wpt);
|
||||||
|
|
||||||
//wpt = new waypoint;
|
|
||||||
//wpt->name = "END";
|
|
||||||
//wpt->finished = false;
|
|
||||||
//waypoints.push_back(wpt); // add one more to prevent a segfault.
|
|
||||||
//waypoints.push_back(wpt); // add one more to prevent a segfault.
|
|
||||||
//wpt_iterator = waypoints.begin();
|
|
||||||
//if (!firstFlight)
|
|
||||||
// wpt_iterator++;
|
|
||||||
//wpt_iterator = waypoints.begin()+currWpt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* createCreate Taxi.
|
* createCreate Taxi.
|
||||||
* initialize the Aircraft at the parking location
|
* initialize the Aircraft at the parking location
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
void FGAIFlightPlan::createTaxi(bool firstFlight, int direction, FGAirport *apt, double radius, string fltType, string acType, string airline)
|
void FGAIFlightPlan::createTaxi(bool firstFlight, int direction, FGAirport *apt, double latitude, double longitude, double radius, string fltType, string acType, string airline)
|
||||||
{
|
{
|
||||||
double wind_speed;
|
double wind_speed;
|
||||||
double wind_heading;
|
double wind_heading;
|
||||||
|
@ -208,29 +200,13 @@ void FGAIFlightPlan::createTaxi(bool firstFlight, int direction, FGAirport *apt,
|
||||||
//int currWpt = wpt_iterator - waypoints.begin();
|
//int currWpt = wpt_iterator - waypoints.begin();
|
||||||
if (direction == 1)
|
if (direction == 1)
|
||||||
{
|
{
|
||||||
|
//string name;
|
||||||
|
// "NOTE: this is currently fixed to "com" for commercial traffic
|
||||||
|
// Should be changed to be used dynamically to allow "gen" and "mil"
|
||||||
|
// as well
|
||||||
// Get the current active runway, based on code from David Luff
|
apt->getActiveRunway("com", 1, &activeRunway);
|
||||||
// This should actually be unified and extended to include
|
|
||||||
// Preferential runway use schema's
|
|
||||||
//FGEnvironment
|
|
||||||
//stationweather = ((FGEnvironmentMgr *) globals->get_subsystem("environment"))
|
|
||||||
//->getEnvironment(apt->getLatitude(), apt->getLongitude(), apt->getElevation());
|
|
||||||
|
|
||||||
//wind_speed = stationweather.get_wind_speed_kt();
|
|
||||||
//wind_heading = stationweather.get_wind_from_heading_deg();
|
|
||||||
//if (wind_speed == 0) {
|
|
||||||
//wind_heading = 270; // This forces West-facing rwys to be used in no-wind situations
|
|
||||||
// which is consistent with Flightgear's initial setup.
|
|
||||||
//}
|
|
||||||
|
|
||||||
//string rwy_no = globals->get_runways()->search(apt->getId(), int(wind_heading));
|
|
||||||
string name;
|
|
||||||
apt->getActiveRunway("com", 1, &name);
|
|
||||||
if (!(globals->get_runways()->search(apt->getId(),
|
if (!(globals->get_runways()->search(apt->getId(),
|
||||||
name,
|
activeRunway,
|
||||||
&rwy)))
|
&rwy)))
|
||||||
{
|
{
|
||||||
cout << "Failed to find runway for " << apt->getId() << endl;
|
cout << "Failed to find runway for " << apt->getId() << endl;
|
||||||
|
@ -247,49 +223,137 @@ void FGAIFlightPlan::createTaxi(bool firstFlight, int direction, FGAirport *apt,
|
||||||
geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth,
|
geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth,
|
||||||
rwy._length * SG_FEET_TO_METER * 0.5 - 5.0,
|
rwy._length * SG_FEET_TO_METER * 0.5 - 5.0,
|
||||||
&lat2, &lon2, &az2 );
|
&lat2, &lon2, &az2 );
|
||||||
|
if (apt->getGroundNetwork()->exists())
|
||||||
|
{
|
||||||
|
intVec ids;
|
||||||
|
int runwayId = apt->getGroundNetwork()->findNearestNode(lat2, lon2);
|
||||||
|
//int currId = apt->getGroundNetwork()->findNearestNode(latitude,longitude);
|
||||||
|
//exit(1);
|
||||||
|
|
||||||
//Add the runway startpoint;
|
// A negative gateId indicates an overflow parking, use a
|
||||||
wpt = new waypoint;
|
// fallback mechanism for this.
|
||||||
wpt->name = "Airport Center";
|
// Starting from gate 0 is a bit of a hack...
|
||||||
wpt->latitude = apt->getLatitude();
|
FGTaxiRoute route;
|
||||||
wpt->longitude = apt->getLongitude();
|
if (gateId >= 0)
|
||||||
wpt->altitude = apt->getElevation();
|
route = apt->getGroundNetwork()->findShortestRoute(gateId, runwayId);
|
||||||
wpt->speed = 15;
|
else
|
||||||
wpt->crossat = -10000;
|
route = apt->getGroundNetwork()->findShortestRoute(0, runwayId);
|
||||||
wpt->gear_down = true;
|
intVecIterator i;
|
||||||
wpt->flaps_down= true;
|
//cerr << "creating route : ";
|
||||||
wpt->finished = false;
|
// No route found: go from gate directly to runway
|
||||||
wpt->on_ground = true;
|
if (route.empty()) {
|
||||||
waypoints.push_back(wpt);
|
//Add the runway startpoint;
|
||||||
|
wpt = new waypoint;
|
||||||
|
wpt->name = "Airport Center";
|
||||||
|
wpt->latitude = latitude;
|
||||||
|
wpt->longitude = longitude;
|
||||||
|
wpt->altitude = apt->getElevation();
|
||||||
|
wpt->speed = 15;
|
||||||
|
wpt->crossat = -10000;
|
||||||
|
wpt->gear_down = true;
|
||||||
|
wpt->flaps_down= true;
|
||||||
|
wpt->finished = false;
|
||||||
|
wpt->on_ground = true;
|
||||||
|
waypoints.push_back(wpt);
|
||||||
|
|
||||||
//Add the runway startpoint;
|
//Add the runway startpoint;
|
||||||
wpt = new waypoint;
|
wpt = new waypoint;
|
||||||
wpt->name = "Runway Takeoff";
|
wpt->name = "Runway Takeoff";
|
||||||
wpt->latitude = lat2;
|
wpt->latitude = lat2;
|
||||||
wpt->longitude = lon2;
|
wpt->longitude = lon2;
|
||||||
wpt->altitude = apt->getElevation();
|
wpt->altitude = apt->getElevation();
|
||||||
wpt->speed = 15;
|
wpt->speed = 15;
|
||||||
wpt->crossat = -10000;
|
wpt->crossat = -10000;
|
||||||
wpt->gear_down = true;
|
wpt->gear_down = true;
|
||||||
wpt->flaps_down= true;
|
wpt->flaps_down= true;
|
||||||
wpt->finished = false;
|
wpt->finished = false;
|
||||||
wpt->on_ground = true;
|
wpt->on_ground = true;
|
||||||
waypoints.push_back(wpt);
|
waypoints.push_back(wpt);
|
||||||
//wpt = new waypoint;
|
} else {
|
||||||
//wpt->finished = false;
|
int node;
|
||||||
//waypoints.push_back(wpt); // add one more to prevent a segfault.
|
route.first();
|
||||||
|
while(route.next(&node))
|
||||||
|
{
|
||||||
|
//i = ids.end()-1;
|
||||||
|
//cerr << "Creating Node: " << node << endl;
|
||||||
|
FGTaxiNode *tn = apt->getGroundNetwork()->findNode(node);
|
||||||
|
//ids.pop_back();
|
||||||
|
wpt = new waypoint;
|
||||||
|
wpt->name = "taxiway"; // fixme: should be the name of the taxiway
|
||||||
|
wpt->latitude = tn->getLatitude();
|
||||||
|
wpt->longitude = tn->getLongitude();
|
||||||
|
wpt->altitude = apt->getElevation(); // should maybe be tn->elev too
|
||||||
|
wpt->speed = 15;
|
||||||
|
wpt->crossat = -10000;
|
||||||
|
wpt->gear_down = true;
|
||||||
|
wpt->flaps_down= true;
|
||||||
|
wpt->finished = false;
|
||||||
|
wpt->on_ground = true;
|
||||||
|
waypoints.push_back(wpt);
|
||||||
|
}
|
||||||
|
cerr << endl;
|
||||||
|
}
|
||||||
|
//exit(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Add the runway startpoint;
|
||||||
|
wpt = new waypoint;
|
||||||
|
wpt->name = "Airport Center";
|
||||||
|
wpt->latitude = apt->getLatitude();
|
||||||
|
wpt->longitude = apt->getLongitude();
|
||||||
|
wpt->altitude = apt->getElevation();
|
||||||
|
wpt->speed = 15;
|
||||||
|
wpt->crossat = -10000;
|
||||||
|
wpt->gear_down = true;
|
||||||
|
wpt->flaps_down= true;
|
||||||
|
wpt->finished = false;
|
||||||
|
wpt->on_ground = true;
|
||||||
|
waypoints.push_back(wpt);
|
||||||
|
|
||||||
|
//Add the runway startpoint;
|
||||||
|
wpt = new waypoint;
|
||||||
|
wpt->name = "Runway Takeoff";
|
||||||
|
wpt->latitude = lat2;
|
||||||
|
wpt->longitude = lon2;
|
||||||
|
wpt->altitude = apt->getElevation();
|
||||||
|
wpt->speed = 15;
|
||||||
|
wpt->crossat = -10000;
|
||||||
|
wpt->gear_down = true;
|
||||||
|
wpt->flaps_down= true;
|
||||||
|
wpt->finished = false;
|
||||||
|
wpt->on_ground = true;
|
||||||
|
waypoints.push_back(wpt);
|
||||||
|
//wpt = new waypoint;
|
||||||
|
//wpt->finished = false;
|
||||||
|
//waypoints.push_back(wpt); // add one more to prevent a segfault.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else // Landing taxi
|
||||||
{
|
{
|
||||||
//direction = (rand() % 360);
|
//string name;
|
||||||
//geo_direct_wgs_84 ( 0, arr->getLatitude(), arr->getLongitude(), direction,
|
// "NOTE: this is currently fixed to "com" for commercial traffic
|
||||||
//100,
|
// Should be changed to be used dynamically to allow "gen" and "mil"
|
||||||
//&lat2, &lon2, &az2 );
|
// as well
|
||||||
|
//apt->getActiveRunway("com", 1, &name);
|
||||||
|
//if (!(globals->get_runways()->search(apt->getId(),
|
||||||
|
// name,
|
||||||
|
// &rwy)))
|
||||||
|
//{//
|
||||||
|
//cout << "Failed to find runway for " << apt->getId() << endl;
|
||||||
|
// Hmm, how do we handle a potential error like this?
|
||||||
|
// exit(1);
|
||||||
|
// }
|
||||||
|
//string test;
|
||||||
|
//apt->getActiveRunway(string("com"), 1, &test);
|
||||||
|
//exit(1);
|
||||||
|
|
||||||
// This next statement really requires the flight plan to be
|
//heading = rwy._heading;
|
||||||
// split up into smaller sections, because
|
//double azimuth = heading + 180.0;
|
||||||
// gate assignments will typically not be known until minutes before
|
//while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
|
||||||
// landing, and certainly not at the start of a 10 hour flight.
|
//geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth,
|
||||||
|
// rwy._length * SG_FEET_TO_METER * 0.5 - 5.0,
|
||||||
|
// &lat2, &lon2, &az2 );
|
||||||
apt->getAvailableParking(&lat, &lon, &heading, &gateId, radius, fltType, acType, airline);
|
apt->getAvailableParking(&lat, &lon, &heading, &gateId, radius, fltType, acType, airline);
|
||||||
heading += 180.0;
|
heading += 180.0;
|
||||||
if (heading > 360)
|
if (heading > 360)
|
||||||
|
@ -297,23 +361,105 @@ void FGAIFlightPlan::createTaxi(bool firstFlight, int direction, FGAirport *apt,
|
||||||
geo_direct_wgs_84 ( 0, lat, lon, heading,
|
geo_direct_wgs_84 ( 0, lat, lon, heading,
|
||||||
100,
|
100,
|
||||||
&lat2, &lon2, &az2 );
|
&lat2, &lon2, &az2 );
|
||||||
//Add the runway center
|
double lat3 = (*(waypoints.end()-1))->latitude;
|
||||||
wpt = new waypoint;
|
double lon3 = (*(waypoints.end()-1))->longitude;
|
||||||
wpt->name = "Airport Center";
|
cerr << (*(waypoints.end()-1))->name << endl;
|
||||||
wpt->latitude = apt->getLatitude();
|
if (apt->getGroundNetwork()->exists())
|
||||||
wpt->longitude = apt->getLongitude();
|
{
|
||||||
wpt->altitude = apt->getElevation();
|
intVec ids;
|
||||||
wpt->speed = 15;
|
int runwayId = apt->getGroundNetwork()->findNearestNode(lat3, lon3);
|
||||||
wpt->crossat = -10000;
|
//int currId = apt->getGroundNetwork()->findNearestNode(latitude,longitude);
|
||||||
wpt->gear_down = true;
|
//exit(1);
|
||||||
wpt->flaps_down= true;
|
|
||||||
wpt->finished = false;
|
// A negative gateId indicates an overflow parking, use a
|
||||||
wpt->on_ground = true;
|
// fallback mechanism for this.
|
||||||
waypoints.push_back(wpt);
|
// Starting from gate 0 is a bit of a hack...
|
||||||
|
FGTaxiRoute route;
|
||||||
|
if (gateId >= 0)
|
||||||
|
route = apt->getGroundNetwork()->findShortestRoute(runwayId, gateId);
|
||||||
|
else
|
||||||
|
route = apt->getGroundNetwork()->findShortestRoute(runwayId, 0);
|
||||||
|
intVecIterator i;
|
||||||
|
//cerr << "creating route : ";
|
||||||
|
// No route found: go from gate directly to runway
|
||||||
|
if (route.empty()) {
|
||||||
|
//Add the runway startpoint;
|
||||||
|
wpt = new waypoint;
|
||||||
|
wpt->name = "Airport Center";
|
||||||
|
wpt->latitude = latitude;
|
||||||
|
wpt->longitude = longitude;
|
||||||
|
wpt->altitude = apt->getElevation();
|
||||||
|
wpt->speed = 15;
|
||||||
|
wpt->crossat = -10000;
|
||||||
|
wpt->gear_down = true;
|
||||||
|
wpt->flaps_down= true;
|
||||||
|
wpt->finished = false;
|
||||||
|
wpt->on_ground = true;
|
||||||
|
waypoints.push_back(wpt);
|
||||||
|
|
||||||
|
//Add the runway startpoint;
|
||||||
|
wpt = new waypoint;
|
||||||
|
wpt->name = "Runway Takeoff";
|
||||||
|
wpt->latitude = lat2;
|
||||||
|
wpt->longitude = lon2;
|
||||||
|
wpt->altitude = apt->getElevation();
|
||||||
|
wpt->speed = 15;
|
||||||
|
wpt->crossat = -10000;
|
||||||
|
wpt->gear_down = true;
|
||||||
|
wpt->flaps_down= true;
|
||||||
|
wpt->finished = false;
|
||||||
|
wpt->on_ground = true;
|
||||||
|
waypoints.push_back(wpt);
|
||||||
|
} else {
|
||||||
|
int node;
|
||||||
|
route.first();
|
||||||
|
while(route.next(&node))
|
||||||
|
{
|
||||||
|
//i = ids.end()-1;
|
||||||
|
//cerr << "Creating Node: " << node << endl;
|
||||||
|
FGTaxiNode *tn = apt->getGroundNetwork()->findNode(node);
|
||||||
|
//ids.pop_back();
|
||||||
|
wpt = new waypoint;
|
||||||
|
wpt->name = "taxiway"; // fixme: should be the name of the taxiway
|
||||||
|
wpt->latitude = tn->getLatitude();
|
||||||
|
wpt->longitude = tn->getLongitude();
|
||||||
|
wpt->altitude = apt->getElevation(); // should maybe be tn->elev too
|
||||||
|
wpt->speed = 15;
|
||||||
|
wpt->crossat = -10000;
|
||||||
|
wpt->gear_down = true;
|
||||||
|
wpt->flaps_down= true;
|
||||||
|
wpt->finished = false;
|
||||||
|
wpt->on_ground = true;
|
||||||
|
waypoints.push_back(wpt);
|
||||||
|
}
|
||||||
|
cerr << endl;
|
||||||
|
}
|
||||||
|
//exit(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Add the runway startpoint;
|
||||||
|
wpt = new waypoint;
|
||||||
|
wpt->name = "Airport Center";
|
||||||
|
wpt->latitude = apt->getLatitude();
|
||||||
|
wpt->longitude = apt->getLongitude();
|
||||||
|
wpt->altitude = apt->getElevation();
|
||||||
|
wpt->speed = 15;
|
||||||
|
wpt->crossat = -10000;
|
||||||
|
wpt->gear_down = true;
|
||||||
|
wpt->flaps_down= true;
|
||||||
|
wpt->finished = false;
|
||||||
|
wpt->on_ground = true;
|
||||||
|
waypoints.push_back(wpt);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Add the final destination waypoint
|
// Add the final destination waypoint
|
||||||
wpt = new waypoint;
|
wpt = new waypoint;
|
||||||
wpt->name = "Begin Parkingg"; //apt->getId(); //wpt_node->getStringValue("name", "END");
|
wpt->name = "Begin Parking"; //apt->getId(); //wpt_node->getStringValue("name", "END");
|
||||||
wpt->latitude = lat2;
|
wpt->latitude = lat2;
|
||||||
wpt->longitude = lon2;
|
wpt->longitude = lon2;
|
||||||
wpt->altitude = apt->getElevation();
|
wpt->altitude = apt->getElevation();
|
||||||
|
@ -364,10 +510,13 @@ void FGAIFlightPlan::createTakeOff(bool firstFlight, FGAirport *apt, double spee
|
||||||
// Preferential runway use schema's
|
// Preferential runway use schema's
|
||||||
if (firstFlight)
|
if (firstFlight)
|
||||||
{
|
{
|
||||||
string name;
|
//string name;
|
||||||
apt->getActiveRunway("com", 1, &name);
|
// "NOTE: this is currently fixed to "com" for commercial traffic
|
||||||
|
// Should be changed to be used dynamically to allow "gen" and "mil"
|
||||||
|
// as well
|
||||||
|
apt->getActiveRunway("com", 1, &activeRunway);
|
||||||
if (!(globals->get_runways()->search(apt->getId(),
|
if (!(globals->get_runways()->search(apt->getId(),
|
||||||
name,
|
activeRunway,
|
||||||
&rwy)))
|
&rwy)))
|
||||||
{
|
{
|
||||||
cout << "Failed to find runway for " << apt->getId() << endl;
|
cout << "Failed to find runway for " << apt->getId() << endl;
|
||||||
|
@ -456,10 +605,13 @@ void FGAIFlightPlan::createClimb(bool firstFlight, FGAirport *apt, double speed,
|
||||||
// Preferential runway use schema's
|
// Preferential runway use schema's
|
||||||
if (firstFlight)
|
if (firstFlight)
|
||||||
{
|
{
|
||||||
string name;
|
//string name;
|
||||||
apt->getActiveRunway("com", 1, &name);
|
// "NOTE: this is currently fixed to "com" for commercial traffic
|
||||||
|
// Should be changed to be used dynamically to allow "gen" and "mil"
|
||||||
|
// as well
|
||||||
|
apt->getActiveRunway("com", 1, &activeRunway);
|
||||||
if (!(globals->get_runways()->search(apt->getId(),
|
if (!(globals->get_runways()->search(apt->getId(),
|
||||||
name,
|
activeRunway,
|
||||||
&rwy)))
|
&rwy)))
|
||||||
{
|
{
|
||||||
cout << "Failed to find runway for " << apt->getId() << endl;
|
cout << "Failed to find runway for " << apt->getId() << endl;
|
||||||
|
@ -554,10 +706,11 @@ void FGAIFlightPlan::createCruise(bool firstFlight, FGAirport *dep, FGAirport *a
|
||||||
waypoints.push_back(wpt);
|
waypoints.push_back(wpt);
|
||||||
//Beginning of Decent
|
//Beginning of Decent
|
||||||
|
|
||||||
string name;
|
//string name;
|
||||||
arr->getActiveRunway("com", 2, &name);
|
// should be changed dynamically to allow "gen" and "mil"
|
||||||
|
arr->getActiveRunway("com", 2, &activeRunway);
|
||||||
if (!(globals->get_runways()->search(arr->getId(),
|
if (!(globals->get_runways()->search(arr->getId(),
|
||||||
name,
|
activeRunway,
|
||||||
&rwy)))
|
&rwy)))
|
||||||
{
|
{
|
||||||
cout << "Failed to find runway for " << arr->getId() << endl;
|
cout << "Failed to find runway for " << arr->getId() << endl;
|
||||||
|
@ -632,10 +785,11 @@ void FGAIFlightPlan::createDecent(FGAirport *apt)
|
||||||
//resetWaypoints();
|
//resetWaypoints();
|
||||||
|
|
||||||
//Beginning of Decent
|
//Beginning of Decent
|
||||||
string name;
|
//string name;
|
||||||
apt->getActiveRunway("com", 2, &name);
|
// allow "mil" and "gen" as well
|
||||||
|
apt->getActiveRunway("com", 2, &activeRunway);
|
||||||
if (!(globals->get_runways()->search(apt->getId(),
|
if (!(globals->get_runways()->search(apt->getId(),
|
||||||
name,
|
activeRunway,
|
||||||
&rwy)))
|
&rwy)))
|
||||||
{
|
{
|
||||||
cout << "Failed to find runway for " << apt->getId() << endl;
|
cout << "Failed to find runway for " << apt->getId() << endl;
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include <simgear/compiler.h>
|
#include <simgear/compiler.h>
|
||||||
|
|
||||||
#include <plib/sg.h>
|
#include <plib/sg.h>
|
||||||
|
#include <plib/ul.h>
|
||||||
|
|
||||||
#include <Environment/environment_mgr.hxx>
|
#include <Environment/environment_mgr.hxx>
|
||||||
#include <Environment/environment.hxx>
|
#include <Environment/environment.hxx>
|
||||||
|
@ -53,6 +54,7 @@
|
||||||
#include "simple.hxx"
|
#include "simple.hxx"
|
||||||
|
|
||||||
SG_USING_STD(sort);
|
SG_USING_STD(sort);
|
||||||
|
SG_USING_STD(random_shuffle);
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* ScheduleTime
|
* ScheduleTime
|
||||||
|
@ -563,28 +565,10 @@ void FGRunwayPreference::error (const char * message, int line, int column) {
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************
|
/*****************************************************************************
|
||||||
* FGParking
|
* Helper function for parsing position string
|
||||||
********************************************************************************/
|
****************************************************************************/
|
||||||
FGParking::FGParking(double lat,
|
double processPosition(string pos)
|
||||||
double lon,
|
|
||||||
double hdg,
|
|
||||||
double rad,
|
|
||||||
int idx,
|
|
||||||
string name,
|
|
||||||
string tpe,
|
|
||||||
string codes)
|
|
||||||
{
|
|
||||||
latitude = lat;
|
|
||||||
longitude = lon;
|
|
||||||
heading = hdg;
|
|
||||||
parkingName = name;
|
|
||||||
index = idx;
|
|
||||||
type = tpe;
|
|
||||||
airlineCodes = codes;
|
|
||||||
}
|
|
||||||
|
|
||||||
double FGParking::processPosition(string pos)
|
|
||||||
{
|
{
|
||||||
string prefix;
|
string prefix;
|
||||||
string subs;
|
string subs;
|
||||||
|
@ -608,6 +592,29 @@ double FGParking::processPosition(string pos)
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************************************************
|
||||||
|
* FGParking
|
||||||
|
********************************************************************************/
|
||||||
|
FGParking::FGParking(double lat,
|
||||||
|
double lon,
|
||||||
|
double hdg,
|
||||||
|
double rad,
|
||||||
|
int idx,
|
||||||
|
string name,
|
||||||
|
string tpe,
|
||||||
|
string codes)
|
||||||
|
{
|
||||||
|
latitude = lat;
|
||||||
|
longitude = lon;
|
||||||
|
heading = hdg;
|
||||||
|
parkingName = name;
|
||||||
|
index = idx;
|
||||||
|
type = tpe;
|
||||||
|
airlineCodes = codes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* FGAirport
|
* FGAirport
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
@ -664,6 +671,22 @@ FGAirport::FGAirport(string id, double lon, double lat, double elev, string name
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialization required after XMLRead
|
||||||
|
void FGAirport::init()
|
||||||
|
{
|
||||||
|
// This may seem a bit weird to first randomly shuffle the parkings
|
||||||
|
// and then sort them again. However, parkings are sorted here by ascending
|
||||||
|
// radius. Since many parkings have similar radii, with each radius class they will
|
||||||
|
// still be allocated relatively systematically. Randomizing prior to sorting will
|
||||||
|
// prevent any initial orderings to be destroyed, leading (hopefully) to a more
|
||||||
|
// naturalistic gate assignment.
|
||||||
|
random_shuffle(parkings.begin(), parkings.end());
|
||||||
|
sort(parkings.begin(), parkings.end());
|
||||||
|
// add the gate positions to the ground network.
|
||||||
|
groundNetwork.addNodes(&parkings);
|
||||||
|
groundNetwork.init();
|
||||||
|
}
|
||||||
|
|
||||||
bool FGAirport::getAvailableParking(double *lat, double *lon, double *heading, int *gateId, double rad, string flType, string acType, string airline)
|
bool FGAirport::getAvailableParking(double *lat, double *lon, double *heading, int *gateId, double rad, string flType, string acType, string airline)
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
@ -893,6 +916,10 @@ void FGAirport::endXML () {
|
||||||
void FGAirport::startElement (const char * name, const XMLAttributes &atts) {
|
void FGAirport::startElement (const char * name, const XMLAttributes &atts) {
|
||||||
// const char *attval;
|
// const char *attval;
|
||||||
FGParking park;
|
FGParking park;
|
||||||
|
FGTaxiNode taxiNode;
|
||||||
|
FGTaxiSegment taxiSegment;
|
||||||
|
int index = 0;
|
||||||
|
taxiSegment.setIndex(index);
|
||||||
//cout << "Start element " << name << endl;
|
//cout << "Start element " << name << endl;
|
||||||
string attname;
|
string attname;
|
||||||
string value;
|
string value;
|
||||||
|
@ -933,8 +960,34 @@ void FGAirport::startElement (const char * name, const XMLAttributes &atts) {
|
||||||
park.setName((gateName+gateNumber));
|
park.setName((gateName+gateNumber));
|
||||||
parkings.push_back(park);
|
parkings.push_back(park);
|
||||||
}
|
}
|
||||||
|
if (name == string("node"))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < atts.size() ; i++)
|
||||||
|
{
|
||||||
|
attname = atts.getName(i);
|
||||||
|
if (attname == string("index"))
|
||||||
|
taxiNode.setIndex(atoi(atts.getValue(i)));
|
||||||
|
if (attname == string("lat"))
|
||||||
|
taxiNode.setLatitude(atts.getValue(i));
|
||||||
|
if (attname == string("lon"))
|
||||||
|
taxiNode.setLongitude(atts.getValue(i));
|
||||||
|
}
|
||||||
|
groundNetwork.addNode(taxiNode);
|
||||||
|
}
|
||||||
|
if (name == string("arc"))
|
||||||
|
{
|
||||||
|
taxiSegment.setIndex(++index);
|
||||||
|
for (int i = 0; i < atts.size() ; i++)
|
||||||
|
{
|
||||||
|
attname = atts.getName(i);
|
||||||
|
if (attname == string("begin"))
|
||||||
|
taxiSegment.setStartNodeRef(atoi(atts.getValue(i)));
|
||||||
|
if (attname == string("end"))
|
||||||
|
taxiSegment.setEndNodeRef(atoi(atts.getValue(i)));
|
||||||
|
}
|
||||||
|
groundNetwork.addSegment(taxiSegment);
|
||||||
|
}
|
||||||
// sort by radius, in asending order, so that smaller gates are first in the list
|
// sort by radius, in asending order, so that smaller gates are first in the list
|
||||||
sort(parkings.begin(), parkings.end());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGAirport::endElement (const char * name) {
|
void FGAirport::endElement (const char * name) {
|
||||||
|
@ -1145,6 +1198,290 @@ void FGAirport::chooseRunwayFallback(string *runway)
|
||||||
return; // generic fall back goes here
|
return; // generic fall back goes here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* FGTaxiNode
|
||||||
|
*************************************************************************/
|
||||||
|
FGTaxiNode::FGTaxiNode()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* FGTaxiSegment
|
||||||
|
**************************************************************************/
|
||||||
|
FGTaxiSegment::FGTaxiSegment()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGTaxiSegment::setStart(FGTaxiNodeVector *nodes)
|
||||||
|
{
|
||||||
|
FGTaxiNodeVectorIterator i = nodes->begin();
|
||||||
|
while (i != nodes->end())
|
||||||
|
{
|
||||||
|
if (i->getIndex() == startNode)
|
||||||
|
{
|
||||||
|
start = i->getAddress();
|
||||||
|
i->addSegment(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGTaxiSegment::setEnd(FGTaxiNodeVector *nodes)
|
||||||
|
{
|
||||||
|
FGTaxiNodeVectorIterator i = nodes->begin();
|
||||||
|
while (i != nodes->end())
|
||||||
|
{
|
||||||
|
if (i->getIndex() == endNode)
|
||||||
|
{
|
||||||
|
end = i->getAddress();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// There is probably a computationally cheaper way of
|
||||||
|
// doing this.
|
||||||
|
void FGTaxiSegment::setTrackDistance()
|
||||||
|
{
|
||||||
|
double course;
|
||||||
|
SGWayPoint first (start->getLongitude(),
|
||||||
|
start->getLatitude(),
|
||||||
|
0);
|
||||||
|
SGWayPoint second (end->getLongitude(),
|
||||||
|
end->getLatitude(),
|
||||||
|
0);
|
||||||
|
first.CourseAndDistance(second, &course, &length);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FGTaxiRoute::next(int *val)
|
||||||
|
{
|
||||||
|
//for (intVecIterator i = nodes.begin(); i != nodes.end(); i++)
|
||||||
|
// cerr << "FGTaxiRoute contains : " << *(i) << endl;
|
||||||
|
//cerr << "Offset from end: " << nodes.end() - currNode << endl;
|
||||||
|
//if (currNode != nodes.end())
|
||||||
|
// cerr << "true" << endl;
|
||||||
|
//else
|
||||||
|
// cerr << "false" << endl;
|
||||||
|
|
||||||
|
if (currNode == nodes.end())
|
||||||
|
return false;
|
||||||
|
*val = *(currNode);
|
||||||
|
currNode++;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
/***************************************************************************
|
||||||
|
* FGGroundNetwork()
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
FGGroundNetwork::FGGroundNetwork()
|
||||||
|
{
|
||||||
|
hasNetwork = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGGroundNetwork::addSegment(FGTaxiSegment seg)
|
||||||
|
{
|
||||||
|
segments.push_back(seg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGGroundNetwork::addNode(FGTaxiNode node)
|
||||||
|
{
|
||||||
|
nodes.push_back(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGGroundNetwork::addNodes(FGParkingVec *parkings)
|
||||||
|
{
|
||||||
|
FGTaxiNode n;
|
||||||
|
FGParkingVecIterator i = parkings->begin();
|
||||||
|
while (i != parkings->end())
|
||||||
|
{
|
||||||
|
n.setIndex(i->getIndex());
|
||||||
|
n.setLatitude(i->getLatitude());
|
||||||
|
n.setLongitude(i->getLongitude());
|
||||||
|
nodes.push_back(n);
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void FGGroundNetwork::init()
|
||||||
|
{
|
||||||
|
hasNetwork = true;
|
||||||
|
FGTaxiSegmentVectorIterator i = segments.begin();
|
||||||
|
while(i != segments.end()) {
|
||||||
|
//cerr << "initializing node " << i->getIndex() << endl;
|
||||||
|
i->setStart(&nodes);
|
||||||
|
i->setEnd (&nodes);
|
||||||
|
i->setTrackDistance();
|
||||||
|
//cerr << "Track distance = " << i->getLength() << endl;
|
||||||
|
//cerr << "Track ends at" << i->getEnd()->getIndex() << endl;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
//exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FGGroundNetwork::findNearestNode(double lat, double lon)
|
||||||
|
{
|
||||||
|
double minDist = HUGE;
|
||||||
|
double course, dist;
|
||||||
|
int index;
|
||||||
|
SGWayPoint first (lon,
|
||||||
|
lat,
|
||||||
|
0);
|
||||||
|
|
||||||
|
for (FGTaxiNodeVectorIterator
|
||||||
|
itr = nodes.begin();
|
||||||
|
itr != nodes.end(); itr++)
|
||||||
|
{
|
||||||
|
double course;
|
||||||
|
SGWayPoint second (itr->getLongitude(),
|
||||||
|
itr->getLatitude(),
|
||||||
|
0);
|
||||||
|
first.CourseAndDistance(second, &course, &dist);
|
||||||
|
if (dist < minDist)
|
||||||
|
{
|
||||||
|
minDist = dist;
|
||||||
|
index = itr->getIndex();
|
||||||
|
//cerr << "Minimum distance of " << minDist << " for index " << index << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
FGTaxiNode *FGGroundNetwork::findNode(int idx)
|
||||||
|
{
|
||||||
|
for (FGTaxiNodeVectorIterator
|
||||||
|
itr = nodes.begin();
|
||||||
|
itr != nodes.end(); itr++)
|
||||||
|
{
|
||||||
|
if (itr->getIndex() == idx)
|
||||||
|
return itr->getAddress();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FGTaxiRoute FGGroundNetwork::findShortestRoute(int start, int end)
|
||||||
|
{
|
||||||
|
foundRoute = false;
|
||||||
|
totalDistance = 0;
|
||||||
|
FGTaxiNode *firstNode = findNode(start);
|
||||||
|
FGTaxiNode *lastNode = findNode(end);
|
||||||
|
//prevNode = prevPrevNode = -1;
|
||||||
|
//prevNode = start;
|
||||||
|
routes.clear();
|
||||||
|
traceStack.clear();
|
||||||
|
trace(firstNode, end, 0, 0);
|
||||||
|
FGTaxiRoute empty;
|
||||||
|
|
||||||
|
if (!foundRoute)
|
||||||
|
{
|
||||||
|
cerr << "Failed to find route from waypoint " << start << " to " << end << endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
sort(routes.begin(), routes.end());
|
||||||
|
//for (intVecIterator i = route.begin(); i != route.end(); i++)
|
||||||
|
// {
|
||||||
|
// rte->push_back(*i);
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (routes.begin() != routes.end())
|
||||||
|
return *(routes.begin());
|
||||||
|
else
|
||||||
|
return empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FGGroundNetwork::trace(FGTaxiNode *currNode, int end, int depth, double distance)
|
||||||
|
{
|
||||||
|
traceStack.push_back(currNode->getIndex());
|
||||||
|
totalDistance += distance;
|
||||||
|
//cerr << "Starting trace " << depth << " total distance: " << totalDistance<< endl;
|
||||||
|
//<< currNode->getIndex() << endl;
|
||||||
|
|
||||||
|
// If the current route matches the required end point we found a valid route
|
||||||
|
// So we can add this to the routing table
|
||||||
|
if (currNode->getIndex() == end)
|
||||||
|
{
|
||||||
|
//cerr << "Found route : " << totalDistance << "" << " " << *(traceStack.end()-1) << endl;
|
||||||
|
routes.push_back(FGTaxiRoute(traceStack,totalDistance));
|
||||||
|
traceStack.pop_back();
|
||||||
|
if (!(foundRoute))
|
||||||
|
maxDistance = totalDistance;
|
||||||
|
else
|
||||||
|
if (totalDistance < maxDistance)
|
||||||
|
maxDistance = totalDistance;
|
||||||
|
foundRoute = true;
|
||||||
|
totalDistance -= distance;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// search if the currentNode has been encountered before
|
||||||
|
// if so, we should step back one level, because it is
|
||||||
|
// rather rediculous to proceed further from here.
|
||||||
|
// if the current node has not been encountered before,
|
||||||
|
// i should point to traceStack.end()-1; and we can continue
|
||||||
|
// if i is not traceStack.end, the previous node was found,
|
||||||
|
// and we should return.
|
||||||
|
// This only works at trace levels of 1 or higher though
|
||||||
|
if (depth > 0) {
|
||||||
|
intVecIterator i = traceStack.begin();
|
||||||
|
while ((*i) != currNode->getIndex()) {
|
||||||
|
//cerr << "Route so far : " << (*i) << endl;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (i != traceStack.end()-1) {
|
||||||
|
traceStack.pop_back();
|
||||||
|
totalDistance -= distance;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// If the total distance from start to the current waypoint
|
||||||
|
// is longer than that of a route we can also stop this trace
|
||||||
|
// and go back one level.
|
||||||
|
if ((totalDistance > maxDistance) && foundRoute)
|
||||||
|
{
|
||||||
|
//cerr << "Stopping rediculously long trace: " << totalDistance << endl;
|
||||||
|
traceStack.pop_back();
|
||||||
|
totalDistance -= distance;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//cerr << "2" << endl;
|
||||||
|
if (currNode->getBeginRoute() != currNode->getEndRoute())
|
||||||
|
{
|
||||||
|
//cerr << "3" << endl;
|
||||||
|
for (FGTaxiSegmentPointerVectorIterator
|
||||||
|
i = currNode->getBeginRoute();
|
||||||
|
i != currNode->getEndRoute();
|
||||||
|
i++)
|
||||||
|
{
|
||||||
|
//cerr << (*i)->getLenght() << endl;
|
||||||
|
trace((*i)->getEnd(), end, depth+1, (*i)->getLength());
|
||||||
|
// {
|
||||||
|
// // cerr << currNode -> getIndex() << " ";
|
||||||
|
// route.push_back(currNode->getIndex());
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cerr << "4" << endl;
|
||||||
|
}
|
||||||
|
traceStack.pop_back();
|
||||||
|
totalDistance -= distance;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* FGAirportList
|
* FGAirportList
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
@ -1199,6 +1536,7 @@ void FGAirportList::add( const string id, const double longitude,
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
readXML(parkpath.str(),*a);
|
readXML(parkpath.str(),*a);
|
||||||
|
a->init();
|
||||||
}
|
}
|
||||||
catch (const sg_exception &e) {
|
catch (const sg_exception &e) {
|
||||||
//cerr << "unable to read " << parkpath.str() << endl;
|
//cerr << "unable to read " << parkpath.str() << endl;
|
||||||
|
|
|
@ -36,7 +36,8 @@
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <simgear/math/point3d.hxx>
|
||||||
|
#include <simgear/route/waypoint.hxx>
|
||||||
#include <simgear/compiler.h>
|
#include <simgear/compiler.h>
|
||||||
#include <simgear/xml/easyxml.hxx>
|
#include <simgear/xml/easyxml.hxx>
|
||||||
|
|
||||||
|
@ -56,6 +57,8 @@ typedef vector<string>::const_iterator stringVecConstIterator;
|
||||||
|
|
||||||
typedef vector<time_t> timeVec;
|
typedef vector<time_t> timeVec;
|
||||||
typedef vector<time_t>::const_iterator timeVecConstIterator;
|
typedef vector<time_t>::const_iterator timeVecConstIterator;
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
class ScheduleTime {
|
class ScheduleTime {
|
||||||
private:
|
private:
|
||||||
|
@ -177,6 +180,8 @@ public:
|
||||||
virtual void error (const char * message, int line, int column);
|
virtual void error (const char * message, int line, int column);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
double processPosition(string pos);
|
||||||
|
|
||||||
class FGParking {
|
class FGParking {
|
||||||
private:
|
private:
|
||||||
double latitude;
|
double latitude;
|
||||||
|
@ -188,10 +193,9 @@ private:
|
||||||
string type;
|
string type;
|
||||||
string airlineCodes;
|
string airlineCodes;
|
||||||
|
|
||||||
|
|
||||||
bool available;
|
bool available;
|
||||||
|
|
||||||
double processPosition(string pos);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FGParking() { available = true;};
|
FGParking() { available = true;};
|
||||||
|
@ -232,7 +236,138 @@ typedef vector<FGParking> FGParkingVec;
|
||||||
typedef vector<FGParking>::iterator FGParkingVecIterator;
|
typedef vector<FGParking>::iterator FGParkingVecIterator;
|
||||||
typedef vector<FGParking>::const_iterator FGParkingVecConstIterator;
|
typedef vector<FGParking>::const_iterator FGParkingVecConstIterator;
|
||||||
|
|
||||||
|
class FGTaxiSegment; // forward reference
|
||||||
|
|
||||||
|
typedef vector<FGTaxiSegment> FGTaxiSegmentVector;
|
||||||
|
typedef vector<FGTaxiSegment*> FGTaxiSegmentPointerVector;
|
||||||
|
typedef vector<FGTaxiSegment>::iterator FGTaxiSegmentVectorIterator;
|
||||||
|
typedef vector<FGTaxiSegment*>::iterator FGTaxiSegmentPointerVectorIterator;
|
||||||
|
|
||||||
|
/**************************************************************************************
|
||||||
|
* class FGTaxiNode
|
||||||
|
*************************************************************************************/
|
||||||
|
class FGTaxiNode
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
double lat;
|
||||||
|
double lon;
|
||||||
|
int index;
|
||||||
|
FGTaxiSegmentPointerVector next; // a vector to all the segments leaving from this node
|
||||||
|
|
||||||
|
public:
|
||||||
|
FGTaxiNode();
|
||||||
|
FGTaxiNode(double, double, int);
|
||||||
|
|
||||||
|
void setIndex(int idx) { index = idx;};
|
||||||
|
void setLatitude (double val) { lat = val;};
|
||||||
|
void setLongitude(double val) { lon = val;};
|
||||||
|
void setLatitude (string val) { lat = processPosition(val); };
|
||||||
|
void setLongitude(string val) { lon = processPosition(val); };
|
||||||
|
void addSegment(FGTaxiSegment *segment) { next.push_back(segment); };
|
||||||
|
|
||||||
|
double getLatitude() { return lat;};
|
||||||
|
double getLongitude(){ return lon;};
|
||||||
|
|
||||||
|
int getIndex() { return index; };
|
||||||
|
FGTaxiNode *getAddress() { return this;};
|
||||||
|
FGTaxiSegmentPointerVectorIterator getBeginRoute() { return next.begin(); };
|
||||||
|
FGTaxiSegmentPointerVectorIterator getEndRoute() { return next.end(); };
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef vector<FGTaxiNode> FGTaxiNodeVector;
|
||||||
|
typedef vector<FGTaxiNode>::iterator FGTaxiNodeVectorIterator;
|
||||||
|
|
||||||
|
/***************************************************************************************
|
||||||
|
* class FGTaxiSegment
|
||||||
|
**************************************************************************************/
|
||||||
|
class FGTaxiSegment
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int startNode;
|
||||||
|
int endNode;
|
||||||
|
double length;
|
||||||
|
FGTaxiNode *start;
|
||||||
|
FGTaxiNode *end;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FGTaxiSegment();
|
||||||
|
FGTaxiSegment(FGTaxiNode *, FGTaxiNode *, int);
|
||||||
|
|
||||||
|
void setIndex (int val) { index = val; };
|
||||||
|
void setStartNodeRef (int val) { startNode = val; };
|
||||||
|
void setEndNodeRef (int val) { endNode = val; };
|
||||||
|
|
||||||
|
void setStart(FGTaxiNodeVector *nodes);
|
||||||
|
void setEnd (FGTaxiNodeVector *nodes);
|
||||||
|
void setTrackDistance();
|
||||||
|
|
||||||
|
FGTaxiNode * getEnd() { return end;};
|
||||||
|
double getLength() { return length; };
|
||||||
|
int getIndex() { return index; };
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef vector<int> intVec;
|
||||||
|
typedef vector<int>::iterator intVecIterator;
|
||||||
|
|
||||||
|
class FGTaxiRoute
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
intVec nodes;
|
||||||
|
double distance;
|
||||||
|
intVecIterator currNode;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FGTaxiRoute() { distance = 0; currNode = nodes.begin(); };
|
||||||
|
FGTaxiRoute(intVec nds, double dist) { nodes = nds; distance = dist; currNode = nodes.begin();};
|
||||||
|
bool operator< (const FGTaxiRoute &other) const {return distance < other.distance; };
|
||||||
|
bool empty () { return nodes.begin() == nodes.end(); };
|
||||||
|
bool next(int *val);
|
||||||
|
|
||||||
|
void first() { currNode = nodes.begin(); };
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef vector<FGTaxiRoute> TaxiRouteVector;
|
||||||
|
typedef vector<FGTaxiRoute>::iterator TaxiRouteVectorIterator;
|
||||||
|
|
||||||
|
/**************************************************************************************
|
||||||
|
* class FGGroundNetWork
|
||||||
|
*************************************************************************************/
|
||||||
|
class FGGroundNetwork
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
bool hasNetwork;
|
||||||
|
FGTaxiNodeVector nodes;
|
||||||
|
FGTaxiSegmentVector segments;
|
||||||
|
//intVec route;
|
||||||
|
intVec traceStack;
|
||||||
|
TaxiRouteVector routes;
|
||||||
|
|
||||||
|
bool foundRoute;
|
||||||
|
double totalDistance, maxDistance;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FGGroundNetwork();
|
||||||
|
|
||||||
|
void addNode (FGTaxiNode node);
|
||||||
|
void addNodes (FGParkingVec *parkings);
|
||||||
|
void addSegment(FGTaxiSegment seg);
|
||||||
|
|
||||||
|
void init();
|
||||||
|
bool exists() { return hasNetwork; };
|
||||||
|
int findNearestNode(double lat, double lon);
|
||||||
|
FGTaxiNode *findNode(int idx);
|
||||||
|
FGTaxiRoute findShortestRoute(int start, int end);
|
||||||
|
void trace(FGTaxiNode *, int, int, double dist);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/***************************************************************************************
|
||||||
|
*
|
||||||
|
**************************************************************************************/
|
||||||
class FGAirport : public XMLVisitor{
|
class FGAirport : public XMLVisitor{
|
||||||
private:
|
private:
|
||||||
string _id;
|
string _id;
|
||||||
|
@ -244,6 +379,7 @@ private:
|
||||||
bool _has_metar;
|
bool _has_metar;
|
||||||
FGParkingVec parkings;
|
FGParkingVec parkings;
|
||||||
FGRunwayPreference rwyPrefs;
|
FGRunwayPreference rwyPrefs;
|
||||||
|
FGGroundNetwork groundNetwork;
|
||||||
|
|
||||||
time_t lastUpdate;
|
time_t lastUpdate;
|
||||||
string prevTrafficType;
|
string prevTrafficType;
|
||||||
|
@ -262,6 +398,8 @@ public:
|
||||||
FGAirport(const FGAirport &other);
|
FGAirport(const FGAirport &other);
|
||||||
//operator= (FGAirport &other);
|
//operator= (FGAirport &other);
|
||||||
FGAirport(string id, double lon, double lat, double elev, string name, bool has_metar);
|
FGAirport(string id, double lon, double lat, double elev, string name, bool has_metar);
|
||||||
|
|
||||||
|
void init();
|
||||||
void getActiveRunway(string trafficType, int action, string *runway);
|
void getActiveRunway(string trafficType, int action, string *runway);
|
||||||
void chooseRunwayFallback(string *runway);
|
void chooseRunwayFallback(string *runway);
|
||||||
bool getAvailableParking(double *lat, double *lon, double *heading, int *gate, double rad, string fltype,
|
bool getAvailableParking(double *lat, double *lon, double *heading, int *gate, double rad, string fltype,
|
||||||
|
@ -272,6 +410,8 @@ public:
|
||||||
string getParkingName(int i);
|
string getParkingName(int i);
|
||||||
string getId() const { return _id;};
|
string getId() const { return _id;};
|
||||||
const string &getName() const { return _name;};
|
const string &getName() const { return _name;};
|
||||||
|
//FGAirport *getAddress() { return this; };
|
||||||
|
//const string &getName() const { return _name;};
|
||||||
// Returns degrees
|
// Returns degrees
|
||||||
double getLongitude() const { return _longitude;};
|
double getLongitude() const { return _longitude;};
|
||||||
// Returns degrees
|
// Returns degrees
|
||||||
|
@ -279,6 +419,7 @@ public:
|
||||||
// Returns ft
|
// Returns ft
|
||||||
double getElevation() const { return _elevation;};
|
double getElevation() const { return _elevation;};
|
||||||
bool getMetar() const { return _has_metar;};
|
bool getMetar() const { return _has_metar;};
|
||||||
|
FGGroundNetwork* getGroundNetwork() { return &groundNetwork; };
|
||||||
|
|
||||||
|
|
||||||
void setId(string id) { _id = id;};
|
void setId(string id) { _id = id;};
|
||||||
|
@ -325,7 +466,7 @@ public:
|
||||||
const double elevation, const string name, const bool has_metar );
|
const double elevation, const string name, const bool has_metar );
|
||||||
|
|
||||||
// search for the specified id.
|
// search for the specified id.
|
||||||
// Returns NULL if unsucessfull.
|
// Returns NULL if unsucessfull.
|
||||||
FGAirport* search( const string& id );
|
FGAirport* search( const string& id );
|
||||||
|
|
||||||
// Search for the next airport in ASCII sequence to the supplied id.
|
// Search for the next airport in ASCII sequence to the supplied id.
|
||||||
|
|
|
@ -392,9 +392,15 @@ bool FGAISchedule::update(time_t now)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//cerr << "Traffic schedule got to beyond last clause" << endl;
|
||||||
// EMH: prevent a warning, should this be 'true' instead?
|
// EMH: prevent a warning, should this be 'true' instead?
|
||||||
return false;
|
// DT: YES. Originally, this code couldn't be reached, but
|
||||||
|
// when the "if(!(AIManagerManager))" clause is false we
|
||||||
|
// fall through right to the end. This is a valid flow.
|
||||||
|
// the actual value is pretty innocent, only it triggers
|
||||||
|
// warning in TrafficManager::update().
|
||||||
|
// (which was added as a sanity check for myself in the first place. :-)
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue