1
0
Fork 0

Some initial code for AI Aircraft making use of SIDs. Current code is a bit

experimental: Only one SID per runway is supported, and the waypoints are
read from file at every request, which is not very efficient. The current
code is only executed when FlightGear is configured to use airport dynamics
data from the scenery repository, instead of the base package. Since the
latter is still the default, I believe that this will provide enough safe-
guarding to commit SID/STAR support in small, incremental steps.
Next step will be buffering and support for multiple departure routes per
runway.
This commit is contained in:
durk 2009-03-01 09:58:12 +00:00 committed by Tim Moore
parent 78e45727d0
commit c7e9c7a610
2 changed files with 91 additions and 11 deletions

View file

@ -156,6 +156,8 @@ private:
//void createCruiseFallback(bool, FGAirport*, FGAirport*, double, double, double, double);
void evaluateRoutePart(double deplat, double deplon, double arrlat, double arrlon);
bool loadSID(const string& filename);
string expandICAODirs(const string in);
};
#endif // _FG_AIFLIGHTPLAN_HXX

View file

@ -24,6 +24,9 @@
#include "AIFlightPlan.hxx"
#include <simgear/math/sg_geodesy.hxx>
#include <simgear/props/props.hxx>
#include <simgear/props/props_io.hxx>
#include <Airports/runways.hxx>
#include <Airports/dynamics.hxx>
#include "AIAircraft.hxx"
@ -403,6 +406,8 @@ void FGAIFlightPlan::createTakeOff(FGAIAircraft *ac, bool firstFlight, FGAirport
void FGAIFlightPlan::createClimb(FGAIAircraft *ac, bool firstFlight, FGAirport *apt, double speed, double alt, const string &fltType)
{
waypoint *wpt;
bool planLoaded = false;
string fPLName;
if (firstFlight) {
string rwyClass = getRunwayClassFromTrafficType(fltType);
@ -410,7 +415,25 @@ void FGAIFlightPlan::createClimb(FGAIAircraft *ac, bool firstFlight, FGAirport *
apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway, heading);
rwy = apt->getRunwayByIdent(activeRunway);
}
if (fgGetBool("/sim/traffic-manager/use-custom-scenery-data") == true) {
string_list sc = globals->get_fg_scenery();
char buffer[64];
// NOTE: Currently for testing only. A slightly more elaborate naming convention
// needs to be dropped here.
snprintf(buffer, 64, "%s.SID-%s-01.xml", apt->getId().c_str(), activeRunway.c_str() );
string airportDir = expandICAODirs(apt->getId());
for (string_list_iterator i = sc.begin(); i != sc.end(); i++) {
SGPath aptpath( *i );
aptpath.append( "Airports" );
aptpath.append ( airportDir );
aptpath.append( string(buffer) );
if (aptpath.exists()) {
planLoaded = loadSID(aptpath.str());
cerr << "Reading " << aptpath.str() << endl;
}
}
}
if (!planLoaded) {
SGGeod climb1 = rwy->pointOnCenterline(10*SG_NM_TO_METER);
wpt = createInAir(ac, "10000ft climb", climb1, speed, 10000);
wpt->gear_down = true;
@ -421,6 +444,61 @@ void FGAIFlightPlan::createClimb(FGAIAircraft *ac, bool firstFlight, FGAirport *
wpt = cloneWithPos(ac, wpt, "18000ft climb", climb2);
wpt->altitude = 18000;
waypoints.push_back(wpt);
}
}
bool FGAIFlightPlan::loadSID(const string& filename)
{
SGPropertyNode root;
try {
readProperties(filename, &root);
} catch (const sg_exception &e) {
SG_LOG(SG_GENERAL, SG_ALERT,
"Error reading AI flight plan: " << filename);
// cout << path.str() << endl;
return false;
}
SGPropertyNode * node = root.getNode("flightplan");
for (int i = 0; i < node->nChildren(); i++) {
//cout << "Reading waypoint " << i << endl;
waypoint* wpt = new waypoint;
SGPropertyNode * wpt_node = node->getChild(i);
wpt->name = wpt_node->getStringValue("name", "END");
wpt->latitude = wpt_node->getDoubleValue("lat", 0);
wpt->longitude = wpt_node->getDoubleValue("lon", 0);
wpt->altitude = wpt_node->getDoubleValue("alt", 0);
wpt->speed = wpt_node->getDoubleValue("ktas", 0);
wpt->crossat = wpt_node->getDoubleValue("crossat", -10000);
wpt->gear_down = wpt_node->getBoolValue("gear-down", false);
wpt->flaps_down= wpt_node->getBoolValue("flaps-down", false);
wpt->on_ground = wpt_node->getBoolValue("on-ground", false);
wpt->time_sec = wpt_node->getDoubleValue("time-sec", 0);
wpt->time = wpt_node->getStringValue("time", "");
if (wpt->name == "END") wpt->finished = true;
else wpt->finished = false;
waypoints.push_back( wpt );
}
//wpt_iterator = waypoints.begin();
//cout << waypoints.size() << " waypoints read." << endl;
return true;
}
// NOTE: This is just copied from Airports/readXML.
string FGAIFlightPlan::expandICAODirs(const string in){
//cerr << "Expanding " << in << endl;
if (in.size() == 4) {
char buffer[11];
snprintf(buffer, 11, "%c/%c/%c", in[0], in[1], in[2]);
//cerr << "result: " << buffer << endl;
return string(buffer);
} else {
return in;
}
//exit(1);
}