From: durk Date: Sun, 1 Mar 2009 09:58:12 +0000 (+0000) Subject: Some initial code for AI Aircraft making use of SIDs. Current code is a bit X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=c7e9c7a61052ab01162a85f6912452524b714706;p=flightgear.git 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. --- diff --git a/src/AIModel/AIFlightPlan.hxx b/src/AIModel/AIFlightPlan.hxx index 50ba8d6f1..c3a0cff0f 100644 --- a/src/AIModel/AIFlightPlan.hxx +++ b/src/AIModel/AIFlightPlan.hxx @@ -155,7 +155,9 @@ 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 diff --git a/src/AIModel/AIFlightPlanCreate.cxx b/src/AIModel/AIFlightPlanCreate.cxx index 87c253148..22a2616ed 100644 --- a/src/AIModel/AIFlightPlanCreate.cxx +++ b/src/AIModel/AIFlightPlanCreate.cxx @@ -24,6 +24,9 @@ #include "AIFlightPlan.hxx" #include +#include +#include + #include #include #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,17 +415,90 @@ void FGAIFlightPlan::createClimb(FGAIAircraft *ac, bool firstFlight, FGAirport * apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway, heading); rwy = apt->getRunwayByIdent(activeRunway); } - - SGGeod climb1 = rwy->pointOnCenterline(10*SG_NM_TO_METER); - wpt = createInAir(ac, "10000ft climb", climb1, speed, 10000); - wpt->gear_down = true; - wpt->flaps_down= true; - waypoints.push_back(wpt); + 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; + wpt->flaps_down= true; + waypoints.push_back(wpt); + + SGGeod climb2 = rwy->pointOnCenterline(20*SG_NM_TO_METER); + wpt = cloneWithPos(ac, wpt, "18000ft climb", climb2); + wpt->altitude = 18000; + waypoints.push_back(wpt); + } +} - SGGeod climb2 = rwy->pointOnCenterline(20*SG_NM_TO_METER); - 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); }