]> git.mxchange.org Git - flightgear.git/commitdiff
Development for two new features:
authordurk <durk>
Fri, 30 Jan 2009 18:48:44 +0000 (18:48 +0000)
committerTim Moore <timoore@redhat.com>
Sun, 1 Feb 2009 22:44:10 +0000 (23:44 +0100)
 * 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.

src/AIModel/AIAircraft.cxx
src/AIModel/AIAircraft.hxx
src/AIModel/AIFlightPlan.cxx
src/AIModel/AIFlightPlan.hxx
src/AIModel/AIFlightPlanCreate.cxx
src/AIModel/performancedata.hxx
src/AIModel/performancedb.cxx
src/Airports/xmlloader.cxx
src/Airports/xmlloader.hxx
src/Main/globals.cxx
src/Traffic/Schedule.cxx

index 6207ffbdafa51ce234ce0f9b8c247b893f50800b..3f8bb05a871351cf1dbf559baf0e86cead70a246 100644 (file)
@@ -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(),
index e391c6a4547f63c089a01fa60645a8a91fb7c9f3..fd4fd2ad0813c2423006304b6ef6ccc4c823a613 100644 (file)
@@ -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; };
index 5bdbdeb843430df68761064855c1a903d263d50b..4d130991fe0a782e4fdbb1a75de93fc6e67bb179 100644 (file)
@@ -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;
index 0e9e29e40624a93ced4b6bbde4badd06ffa348cd..2e24af376894867dd327fd3a0c537f6eeaab8f5b 100644 (file)
 #include <vector>
 #include <string>
 
+
 #include <Airports/simple.hxx>
 #include <Navaids/awynet.hxx>
 
 #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&);
index 35d2c75d163684f96bcaf41f077fd299c279de1e..6df509e4a208eb3f545b5104b04458eb11797ea6 100644 (file)
@@ -26,6 +26,8 @@
 #include <simgear/math/sg_geodesy.hxx>
 #include <Airports/runways.hxx>
 #include <Airports/dynamics.hxx>
+#include <AIAircraft.hxx>
+#include <performancedata.hxx>
 
 #include <Environment/environment_mgr.hxx>
 #include <Environment/environment.hxx>
@@ -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);
 }
   
 /*******************************************************************
index 5df158e8e7e72faddc32afc74a974e75bd01bbf7..65d64486ab71f891355c8a4fb20a01f78100d486 100644 (file)
@@ -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 <t.foerster@biologie.hu-berlin.de>
+       @author Thomas Frster <t.foerster@biologie.hu-berlin.de>
 */
 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;
index aec66f3d697a88ee5f7c68b0bf01f3df159f9cd6..e8dd2361e93ab2adeb88a5f894b5b3b9546791c7 100644 (file)
@@ -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(
index 205defa8207c2d9fb68c96a67aad9139d5ad7dd1..1009f8a0e4ac76e5310ae1e4ad6766ed1e207efa 100644 (file)
 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;
+            }
+        }
     }
-  }
 }
+
index fd07636c39d7d1179edc431dffe00f1a9e2ccdb5..436e86994d0e1a31ef0f1ac741c07ccdb9806630 100644 (file)
@@ -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);
   
index 0e5433006f6e162982be0fa24e146430dfb94c0f..d4cbdd5a4266dcf0f5631ca1282e7c64928911e0 100644 (file)
@@ -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", ""]
index b8e023f90682f9d0b85ce5c98f832020efae4a51..4da19764428f54e0c9b09eff7ff19405018b97cd 100644 (file)
@@ -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,