From: durk Date: Fri, 30 Jan 2009 18:48:44 +0000 (+0000) Subject: Development for two new features: X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=c6f88e5b9be767d93fd34f3b01c0e949fbd0044b;p=flightgear.git Development for two new features: * Some support for geometry information provided by the custom scenery project. Current support is for AI groundnets and runway use files only since this is a switch that involves a lot of data verification and updating, during the transistion the actual path where the data can be read from is user configurable. setting the property /sim/traffic-manager/use-custom-scenery-data to true will cause flightgear to read the ground networks from the scenery directory (--{fg-scenery}/Airports/[I]/[C]/[A]/[ICAO].groundnet.xml to be precise). Setting this property to false will retain the original behvior. * For departing aircraft, runway takeoff calculations will be done on the basis of the performance database. For testing purposes, a performance estimate for a heavy jet has been added. --- diff --git a/src/AIModel/AIAircraft.cxx b/src/AIModel/AIAircraft.cxx index 6207ffbda..3f8bb05a8 100644 --- a/src/AIModel/AIAircraft.cxx +++ b/src/AIModel/AIAircraft.cxx @@ -353,7 +353,6 @@ bool FGAIAircraft::loadNextLeg() { return false; } setCallSign(trafficRef->getCallSign()); - //props->setStringValue("callsign", callsign.c_str()); leg = 1; fp->setLeg(leg); } @@ -366,10 +365,11 @@ bool FGAIAircraft::loadNextLeg() { } else { double cruiseAlt = trafficRef->getCruiseAlt() * 100; - fp->create (dep, + fp->create (this, + dep, arr, leg, - cruiseAlt, //(trafficRef->getCruiseAlt() * 100), // convert from FL to feet + cruiseAlt, trafficRef->getSpeed(), _getLatitude(), _getLongitude(), diff --git a/src/AIModel/AIAircraft.hxx b/src/AIModel/AIAircraft.hxx index e391c6a45..fd4fd2ad0 100644 --- a/src/AIModel/AIAircraft.hxx +++ b/src/AIModel/AIAircraft.hxx @@ -76,6 +76,7 @@ public: virtual const char* getTypeString(void) const { return "aircraft"; } // included as performance data needs them, who else? + inline PerformanceData* getPerformance() { return _performance; }; inline bool onGround() const { return no_roll; }; inline double getSpeed() const { return speed; }; inline double getRoll() const { return roll; }; diff --git a/src/AIModel/AIFlightPlan.cxx b/src/AIModel/AIFlightPlan.cxx index 5bdbdeb84..4d130991f 100644 --- a/src/AIModel/AIFlightPlan.cxx +++ b/src/AIModel/AIFlightPlan.cxx @@ -101,7 +101,8 @@ FGAIFlightPlan::FGAIFlightPlan(const string& filename) // Position computed by the traffic manager, as well // as setting speeds and altitude computed by the // traffic manager. -FGAIFlightPlan::FGAIFlightPlan(const std::string& p, +FGAIFlightPlan::FGAIFlightPlan(FGAIAircraft *ac, + const std::string& p, double course, time_t start, FGAirport *dep, @@ -202,7 +203,7 @@ FGAIFlightPlan::FGAIFlightPlan(const std::string& p, SG_LOG(SG_GENERAL, SG_INFO, "Route from " << dep->getId() << " to " << arr->getId() << ". Set leg to : " << leg); wpt_iterator = waypoints.begin(); - create(dep,arr, leg, alt, speed, lat, lon, + create(ac, dep,arr, leg, alt, speed, lat, lon, firstLeg, radius, fltType, acType, airline); wpt_iterator = waypoints.begin(); //cerr << "after create: " << (*wpt_iterator)->name << endl; diff --git a/src/AIModel/AIFlightPlan.hxx b/src/AIModel/AIFlightPlan.hxx index 0e9e29e40..2e24af376 100644 --- a/src/AIModel/AIFlightPlan.hxx +++ b/src/AIModel/AIFlightPlan.hxx @@ -23,16 +23,20 @@ #include #include + #include #include #include "AIBase.hxx" + + using std::vector; using std::string; class FGTaxiRoute; class FGRunway; +class FGAIAircraft; class FGAIFlightPlan { @@ -56,7 +60,8 @@ public: } waypoint; FGAIFlightPlan(const string& filename); - FGAIFlightPlan(const std::string& p, + FGAIFlightPlan(FGAIAircraft *, + const std::string& p, double course, time_t start, FGAirport *dep, @@ -86,7 +91,7 @@ public: double getBearing(double lat, double lon, waypoint* next) const; time_t getStartTime() const { return start_time; } - void create(FGAirport *dep, FGAirport *arr, int leg, double alt, double speed, double lat, double lon, + void create(FGAIAircraft *, FGAirport *dep, FGAirport *arr, int leg, double alt, double speed, double lat, double lon, bool firstLeg, double radius, const string& fltType, const string& aircraftType, const string& airline); void setLeg(int val) { leg = val;} @@ -126,7 +131,7 @@ private: void createPushBack(bool, FGAirport*, double, double, double, const string&, const string&, const string&); void createPushBackFallBack(bool, FGAirport*, double, double, double, const string&, const string&, const string&); - void createTakeOff(bool, FGAirport *, double, const string&); + void createTakeOff(FGAIAircraft *, bool, FGAirport *, double, const string&); void createClimb(bool, FGAirport *, double, double, const string&); void createCruise(bool, FGAirport*, FGAirport*, double, double, double, double, const string&); void createDecent(FGAirport *, const string&); diff --git a/src/AIModel/AIFlightPlanCreate.cxx b/src/AIModel/AIFlightPlanCreate.cxx index 35d2c75d1..6df509e4a 100644 --- a/src/AIModel/AIFlightPlanCreate.cxx +++ b/src/AIModel/AIFlightPlanCreate.cxx @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include #include @@ -41,7 +43,7 @@ // Check lat/lon values during initialization; -void FGAIFlightPlan::create(FGAirport *dep, FGAirport *arr, int legNr, +void FGAIFlightPlan::create(FGAIAircraft *ac, FGAirport *dep, FGAirport *arr, int legNr, double alt, double speed, double latitude, double longitude, bool firstFlight,double radius, const string& fltType, const string& aircraftType, @@ -58,7 +60,7 @@ void FGAIFlightPlan::create(FGAirport *dep, FGAirport *arr, int legNr, createTakeoffTaxi(firstFlight, dep, radius, fltType, aircraftType, airline); break; case 3: - createTakeOff(firstFlight, dep, speed, fltType); + createTakeOff(ac, firstFlight, dep, speed, fltType); break; case 4: createClimb(firstFlight, dep, speed, alt, fltType); @@ -336,43 +338,55 @@ void FGAIFlightPlan::createLandingTaxi(FGAirport *apt, * CreateTakeOff * initialize the Aircraft at the parking location ******************************************************************/ -void FGAIFlightPlan::createTakeOff(bool firstFlight, FGAirport *apt, double speed, const string &fltType) +void FGAIFlightPlan::createTakeOff(FGAIAircraft *ac, bool firstFlight, FGAirport *apt, double speed, const string &fltType) { - waypoint *wpt; - - // Get the current active runway, based on code from David Luff - // This should actually be unified and extended to include - // Preferential runway use schema's - if (firstFlight) - { - string rwyClass = getRunwayClassFromTrafficType(fltType); - apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway); - rwy = apt->getRunwayByIdent(activeRunway); - } - - double airportElev = apt->getElevation(); - // Acceleration point, 105 meters into the runway, - SGGeod accelPoint = rwy->pointOnCenterline(105.0); - wpt = createOnGround("accel", accelPoint, airportElev, speed); - waypoints.push_back(wpt); + double accel = ac->getPerformance()->acceleration(); + double vRotate = ac->getPerformance()->vRotate(); + // Acceleration = dV / dT + // Acceleration X dT = dV + // dT = dT / Acceleration + //d = (Vf^2 - Vo^2) / (2*a) + double accelTime = (vRotate - 15) / accel; + cerr << "Using " << accelTime << " as total acceleration time" << endl; + double accelDistance = (vRotate*vRotate - 15*15) / (2*accel); + cerr << "Using " << accelDistance << " " << accel << " " << vRotate << endl; + waypoint *wpt; + // Get the current active runway, based on code from David Luff + // This should actually be unified and extended to include + // Preferential runway use schema's + // NOTE: DT (2009-01-18: IIRC, this is currently already the case, + // because the getActive runway function takes care of that. + if (firstFlight) + { + string rwyClass = getRunwayClassFromTrafficType(fltType); + apt->getDynamics()->getActiveRunway(rwyClass, 1, activeRunway); + rwy = apt->getRunwayByIdent(activeRunway); + } + + double airportElev = apt->getElevation(); + // Acceleration point, 105 meters into the runway, + SGGeod accelPoint = rwy->pointOnCenterline(105.0); + wpt = createOnGround("accel", accelPoint, airportElev, speed); + waypoints.push_back(wpt); - //Start Climbing to 3000 ft. Let's do this - // at the center of the runway for now: - wpt = cloneWithPos(wpt, "SOC", rwy->geod()); - wpt->altitude = airportElev+1000; - wpt->on_ground = false; - waypoints.push_back(wpt); - - wpt = cloneWithPos(wpt, "3000 ft", rwy->end()); - wpt->altitude = airportElev+3000; - waypoints.push_back(wpt); - -// Finally, add two more waypoints, so that aircraft will remain under - // Tower control until they have reached the 3000 ft climb point - SGGeod pt = rwy->pointOnCenterline(5000 + rwy->lengthM() * 0.5); - wpt = cloneWithPos(wpt, "5000 ft", pt); - wpt->altitude = airportElev+5000; - waypoints.push_back(wpt); + //Start Climbing to 3000 ft. Let's do this + // at the center of the runway for now: + SGGeod rotate = rwy->pointOnCenterline(105.0+accelDistance); + wpt = cloneWithPos(wpt, "SOC", rotate); + wpt->altitude = airportElev+1000; + wpt->on_ground = false; + waypoints.push_back(wpt); + + wpt = cloneWithPos(wpt, "3000 ft", rwy->end()); + wpt->altitude = airportElev+3000; + waypoints.push_back(wpt); + + // Finally, add two more waypoints, so that aircraft will remain under + // Tower control until they have reached the 3000 ft climb point + SGGeod pt = rwy->pointOnCenterline(5000 + rwy->lengthM() * 0.5); + wpt = cloneWithPos(wpt, "5000 ft", pt); + wpt->altitude = airportElev+5000; + waypoints.push_back(wpt); } /******************************************************************* diff --git a/src/AIModel/performancedata.hxx b/src/AIModel/performancedata.hxx index 5df158e8e..65d64486a 100644 --- a/src/AIModel/performancedata.hxx +++ b/src/AIModel/performancedata.hxx @@ -9,7 +9,7 @@ class FGAIAircraft; /** Data storage for aircraft performance data. This is used to properly simulate the flight of AIAircrafts. - @author Thomas Förster + @author Thomas F�rster */ class PerformanceData { @@ -38,10 +38,11 @@ public: bool gearExtensible(const FGAIAircraft* ac); - inline double climbRate() { return _climbRate; }; - inline double descentRate() { return _descentRate; }; - inline double vRotate() { return _vRotate; }; - inline double maximumBankAngle() { return _maxbank; }; + inline double climbRate () { return _climbRate; }; + inline double descentRate () { return _descentRate; }; + inline double vRotate () { return _vRotate; }; + inline double maximumBankAngle () { return _maxbank; }; + inline double acceleration () { return _acceleration; }; private: double _acceleration; diff --git a/src/AIModel/performancedb.cxx b/src/AIModel/performancedb.cxx index aec66f3d6..e8dd2361e 100644 --- a/src/AIModel/performancedb.cxx +++ b/src/AIModel/performancedb.cxx @@ -3,6 +3,9 @@ PerformanceDB::PerformanceDB() { // these are the 6 classes originally defined in the PERFSTRUCT + // Plus a few more for testing + registerPerformanceData("heavy_jet", new PerformanceData( + 4.0, 2.0, 3000.0, 1500.0, 150.0, 160.0, 300.0, 430.0, 300.0, 170.0, 150.0, 15.0)); registerPerformanceData("light", new PerformanceData( 2.0, 2.0, 450.0, 1000.0, 70.0, 70.0, 80.0, 100.0, 80.0, 70.0, 60.0, 15.0)); registerPerformanceData("ww2_fighter", new PerformanceData( diff --git a/src/Airports/xmlloader.cxx b/src/Airports/xmlloader.cxx index 205defa82..1009f8a0e 100644 --- a/src/Airports/xmlloader.cxx +++ b/src/Airports/xmlloader.cxx @@ -26,40 +26,89 @@ XMLLoader::XMLLoader() {} XMLLoader::~XMLLoader() {} -void XMLLoader::load(FGAirportDynamics* d) { - FGAirportDynamicsXMLLoader visitor(d); +string XMLLoader::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); +} - SGPath parkpath( globals->get_fg_root() ); - parkpath.append( "/AI/Airports/" ); - parkpath.append( d->getId() ); - parkpath.append( "parking.xml" ); - - if (parkpath.exists()) { - try { - readXML(parkpath.str(), visitor); - d->init(); - } catch (const sg_exception &e) { - //cerr << "unable to read " << parkpath.str() << endl; +void XMLLoader::load(FGAirportDynamics* d) { + FGAirportDynamicsXMLLoader visitor(d); + if (fgGetBool("/sim/traffic-manager/use-custom-scenery-data") == false) { + SGPath parkpath( globals->get_fg_root() ); + parkpath.append( "/AI/Airports/" ); + parkpath.append( d->getId() ); + parkpath.append( "parking.xml" ); + if (parkpath.exists()) { + try { + readXML(parkpath.str(), visitor); + d->init(); + } + catch (const sg_exception &e) { + } + } else { + string_list sc = globals->get_fg_scenery(); + char buffer[32]; + snprintf(buffer, 32, "%s.groundnet.xml", d->getId().c_str() ); + string airportDir = XMLLoader::expandICAODirs(d->getId()); + for (string_list_iterator i = sc.begin(); i != sc.end(); i++) { + SGPath parkpath( *i ); + parkpath.append( "Airports" ); + parkpath.append ( airportDir ); + parkpath.append( string (buffer) ); + if (parkpath.exists()) { + try { + readXML(parkpath.str(), visitor); + d->init(); + } + catch (const sg_exception &e) { + } + return; + } + } } - } - } void XMLLoader::load(FGRunwayPreference* p) { - FGRunwayPreferenceXMLLoader visitor(p); - - SGPath rwyPrefPath( globals->get_fg_root() ); - rwyPrefPath.append( "AI/Airports/" ); - rwyPrefPath.append( p->getId() ); - rwyPrefPath.append( "rwyuse.xml" ); - - //if (ai_dirs.find(id.c_str()) != ai_dirs.end() - // && rwyPrefPath.exists()) - if (rwyPrefPath.exists()) { - try { - readXML(rwyPrefPath.str(), visitor); - } catch (const sg_exception &e) { - //cerr << "unable to read " << rwyPrefPath.str() << endl; + FGRunwayPreferenceXMLLoader visitor(p); + if (fgGetBool("/sim/traffic-manager/use-custom-scenery-data") == false) { + SGPath rwyPrefPath( globals->get_fg_root() ); + rwyPrefPath.append( "AI/Airports/" ); + rwyPrefPath.append( p->getId() ); + rwyPrefPath.append( "rwyuse.xml" ); + if (rwyPrefPath.exists()) { + try { + readXML(rwyPrefPath.str(), visitor); + } + catch (const sg_exception &e) { + } + } + } else { + string_list sc = globals->get_fg_scenery(); + char buffer[32]; + snprintf(buffer, 32, "%s.rwyuse.xml", p->getId().c_str() ); + string airportDir = expandICAODirs(p->getId()); + for (string_list_iterator i = sc.begin(); i != sc.end(); i++) { + SGPath rwypath( *i ); + rwypath.append( "Airports" ); + rwypath.append ( airportDir ); + rwypath.append( string(buffer) ); + if (rwypath.exists()) { + try { + readXML(rwypath.str(), visitor); + } + catch (const sg_exception &e) { + } + return; + } + } } - } } + diff --git a/src/Airports/xmlloader.hxx b/src/Airports/xmlloader.hxx index fd07636c3..436e86994 100644 --- a/src/Airports/xmlloader.hxx +++ b/src/Airports/xmlloader.hxx @@ -22,11 +22,12 @@ class FGAirportDynamics; class FGRunwayPreference; + class XMLLoader { public: XMLLoader(); ~XMLLoader(); - + static string expandICAODirs(const string in); static void load(FGRunwayPreference* p); static void load(FGAirportDynamics* d); diff --git a/src/Main/globals.cxx b/src/Main/globals.cxx index 0e5433006..d4cbdd5a4 100644 --- a/src/Main/globals.cxx +++ b/src/Main/globals.cxx @@ -208,9 +208,11 @@ void FGGlobals::set_fg_scenery (const string &scenery) { ulDir *td = ulOpenDir( pt.c_str() ); ulDir *od = ulOpenDir( po.c_str() ); - if (td == NULL && od == NULL) + // "Terrain" and "Airports" directory don't exist. add directory as is + // otherwise, automatically append either Terrain, Objects, or both + //if (td == NULL && od == NULL) fg_scenery.push_back( path_list[i] ); - else { + //else { if (td != NULL) { fg_scenery.push_back( pt.str() ); ulCloseDir( td ); @@ -219,7 +221,7 @@ void FGGlobals::set_fg_scenery (const string &scenery) { fg_scenery.push_back( po.str() ); ulCloseDir( od ); } - } + //} // insert a marker for FGTileEntry::load(), so that // FG_SCENERY=A:B becomes list ["A/Terrain", "A/Objects", "", // "B/Terrain", "B/Objects", ""] diff --git a/src/Traffic/Schedule.cxx b/src/Traffic/Schedule.cxx index b8e023f90..4da197644 100644 --- a/src/Traffic/Schedule.cxx +++ b/src/Traffic/Schedule.cxx @@ -427,7 +427,7 @@ bool FGAISchedule::update(time_t now) aircraft->setAltitude((*i)->getCruiseAlt()*100); // convert from FL to feet aircraft->setSpeed(speed); aircraft->setBank(0); - aircraft->SetFlightPlan(new FGAIFlightPlan(flightPlanName, courseToDest, deptime, + aircraft->SetFlightPlan(new FGAIFlightPlan(aircraft, flightPlanName, courseToDest, deptime, dep, arr,true, radius, (*i)->getCruiseAlt()*100, lat, lon, speed, flightType, acType,