]> git.mxchange.org Git - flightgear.git/commitdiff
AITraffic exits the runway as soon as possible (in theory; the code still needs some...
authorDurk Talsma <durktals@gmail.com>
Sun, 9 Oct 2011 21:44:42 +0000 (23:44 +0200)
committerDurk Talsma <durktals@gmail.com>
Sun, 9 Oct 2011 21:44:42 +0000 (23:44 +0200)
src/AIModel/AIAircraft.cxx
src/AIModel/AIFlightPlan.cxx
src/AIModel/AIFlightPlan.hxx
src/AIModel/AIFlightPlanCreate.cxx
src/AIModel/performancedata.hxx
src/Airports/dynamicloader.cxx
src/Airports/groundnetwork.cxx
src/Airports/groundnetwork.hxx
src/Traffic/Schedule.cxx
src/Traffic/Schedule.hxx

index efb346a6b1e83b0e98af5569c4808ae452675117..0b23e2c061458ce169a17973db43a13de997e59c 100644 (file)
@@ -805,7 +805,7 @@ bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr) {
     //          << lead_dist << " " << curr->name 
     //          << " Ground target speed " << groundTargetSpeed << endl;
     double bearing = 0;
-    if (speed > 50) { // don't do bearing calculations for ground traffic
+     // don't do bearing calculations for ground traffic
        bearing = getBearing(fp->getBearing(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr));
        if (bearing < minBearing) {
             minBearing = bearing;
@@ -817,8 +817,7 @@ bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr) {
             } else {
                 speedFraction = 1.0;
             }
-       }
-    } 
+       } 
     if (trafficRef) {
          //cerr << "Tracking callsign : \"" << fgGetString("/ai/track-callsign") << "\"" << endl;
 /*         if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
@@ -826,11 +825,14 @@ bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr) {
                    << _getAltitude() << " "<< _getLatitude() << " " << _getLongitude() << " " << dist_to_go << " " << lead_dist << " " << curr->name << " " << vs << " " << tgt_vs << " " << bearing << " " << minBearing << " " << speedFraction << endl; 
          }*/
      }
-    if ((dist_to_go < lead_dist) || (bearing > (minBearing * 1.1))) {
+    if ((dist_to_go < lead_dist) ||
+        ((dist_to_go > prev_dist_to_go) && (bearing > (minBearing * 1.1))) ) {
         minBearing = 360;
         speedFraction = 1.0;
+        prev_dist_to_go = HUGE_VAL;
         return true;
     } else {
+        prev_dist_to_go = dist_to_go;
         return false;
     }
 }
@@ -880,6 +882,11 @@ bool FGAIAircraft::handleAirportEndPoints(FGAIWaypoint* prev, time_t now) {
     if (prev->contains(string("Accel"))) {
         takeOffStatus = 3;
     }
+    //if (prev->contains(string("landing"))) {
+    //    if (speed < _performance->vTaxi() * 2) {
+    //        fp->shortenToFirst(2, "legend");
+    //    }
+    //}
     /*if (prev->contains(string("final"))) {
         
          cerr << getCallSign() << " " 
@@ -1114,6 +1121,9 @@ void FGAIAircraft::updateHeading() {
                 //     << hdg << ". Target " << tgt_heading <<  ". Diff " << fabs(sum - tgt_heading) << ". Speed " << speed << "Heading change rate : " << headingChangeRate << " bacnk sence " << bank_sense << endl;
            hdg += headingChangeRate * dt * sqrt(fabs(speed) / 15);
             headingError = headingDiff;
+            if (fabs(headingError) < 1.0) {
+                hdg = tgt_heading;
+            }
         } else {
             if (fabs(speed) > 1.0) {
                 turn_radius_ft = 0.088362 * speed * speed
index fd639f787f54782b18cc06780f49b417836457b1..a0487c2736f45765c6a8b4cce7a4bb9c18cbd696 100644 (file)
@@ -409,10 +409,19 @@ void FGAIFlightPlan::DecrementWaypoint(bool eraseWaypoints )
     }
     else
         wpt_iterator--;
+}
 
+void FGAIFlightPlan::eraseLastWaypoint()
+{
+    delete (waypoints.back());
+    waypoints.pop_back();;
+    wpt_iterator = waypoints.begin();
+    wpt_iterator++;
 }
 
 
+
+
 // gives distance in feet from a position to a waypoint
 double FGAIFlightPlan::getDistanceToGo(double lat, double lon, FGAIWaypoint* wp) const{
   return SGGeodesy::distanceM(SGGeod::fromDeg(lon, lat), 
@@ -545,4 +554,12 @@ double FGAIFlightPlan::checkTrackLength(string wptName) {
         trackDistance = 0; // name not found
     }
     return trackDistance;
-}
\ No newline at end of file
+}
+
+void FGAIFlightPlan::shortenToFirst(unsigned int number, string name)
+{
+    while (waypoints.size() > number + 3) {
+        eraseLastWaypoint();
+    }
+    (waypoints.back())->setName((waypoints.back())->getName() + name);
+}
index 1b95cad47af6c08a6c9ce225bcfcd1540e3d1ad1..0ab27c2c066b36714fcb65a8dd8d6b0e04d530aa 100644 (file)
@@ -164,6 +164,8 @@ public:
   FGAIFlightPlan* getSID() { return sid; };
   FGAIWaypoint *getWayPoint(int i) { return waypoints[i]; };
   FGAIWaypoint *getLastWaypoint() { return waypoints.back(); };
+  
+  void shortenToFirst(unsigned int number, std::string name);
 
 private:
   FGAIFlightPlan *sid;
@@ -195,6 +197,7 @@ private:
   bool createParking(FGAIAircraft *, FGAirport *, double radius);
   void deleteWaypoints(); 
   void resetWaypoints();
+  void eraseLastWaypoint();
 
   bool createLandingTaxi(FGAIAircraft *, FGAirport *apt, double radius, const std::string& fltType, const std::string& acType, const std::string& airline);
   void createDefaultLandingTaxi(FGAIAircraft *, FGAirport* aAirport);
index edeff639f96ab7056b8caf228964fe10aa88c592..215d3fb17207e1c921bd2d9c0e713ffcb0484750 100644 (file)
@@ -36,6 +36,7 @@
 
 #include <Environment/environment_mgr.hxx>
 #include <Environment/environment.hxx>
+#include <FDM/LaRCsim/basic_aero.h>
 
 
 /* FGAIFlightPlan::create()
@@ -242,7 +243,12 @@ bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight,
     }
 
     intVec ids;
-    int runwayId = gn->findNearestNode(runwayTakeoff);
+    int runwayId = 0;
+    if (gn->getVersion() > 0) {
+        runwayId = gn->findNearestNodeOnRunway(runwayTakeoff);
+    } else {
+        runwayId = gn->findNearestNode(runwayTakeoff);
+    }
 
     // A negative gateId indicates an overflow parking, use a
     // fallback mechanism for this. 
@@ -379,7 +385,13 @@ bool FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac, FGAirport * apt,
     }
 
     intVec ids;
-    int runwayId = gn->findNearestNode(lastWptPos);
+    int runwayId = 0;
+    if (gn->getVersion() == 1) {
+        runwayId = gn->findNearestNodeOnRunway(lastWptPos);
+    } else {
+        runwayId = gn->findNearestNode(lastWptPos);
+    }
+    //cerr << "Using network node " << runwayId << endl;
     // A negative gateId indicates an overflow parking, use a
     // fallback mechanism for this. 
     // Starting from gate 0 is a bit of a hack...
@@ -878,7 +890,12 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
                                    const string & fltType)
 {
     double vTouchdown = ac->getPerformance()->vTouchdown();
-    //double vTaxi = ac->getPerformance()->vTaxi();
+    double vTaxi      = ac->getPerformance()->vTaxi();
+    double decel     = ac->getPerformance()->deceleration() * 1.5;
+    
+    double vTouchdownMetric = (vTouchdown  * SG_NM_TO_METER) / 3600;
+    double vTaxiMetric      = (vTaxi       * SG_NM_TO_METER) / 3600;
+    double decelMetric      = (decel       * SG_NM_TO_METER) / 3600;
 
     //string rwyClass = getRunwayClassFromTrafficType(fltType);
     //double heading = ac->getTrafficRef()->getCourse();
@@ -917,15 +934,50 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
         coord = rwy->pointOnCenterline((currentDist * (i / nPoints)));
         wpt = createInAir(ac, buffer, coord, currentAltitude, (vTouchdown));
     }*/
-    
-    for (int i = 1; i < 10; i++) {
-        snprintf(buffer, 12, "wpt%d", i);
+    double rolloutDistance =
+        (vTouchdownMetric * vTouchdownMetric - vTaxiMetric * vTaxiMetric) / (2 * decelMetric);
+    //cerr << " touchdown speed = " << vTouchdown << ". Rollout distance " << rolloutDistance << endl;
+    int nPoints = 50;
+    for (int i = 1; i < nPoints; i++) {
+        snprintf(buffer, 12, "landing03%d", i);
         
-        coord = rwy->pointOnCenterline((rwy->lengthM() * 0.9) * (i / 10.0));
-        wpt = createOnGround(ac, buffer, coord, currElev, (vTouchdown / i));
-        wpt->setCrossat(apt->getElevation());
+        coord = rwy->pointOnCenterline((rolloutDistance * ((double) i / (double) nPoints)));
+        wpt = createOnGround(ac, buffer, coord, currElev, vTaxi);
+        wpt->setCrossat(currElev);
         waypoints.push_back(wpt);
     }
+    double mindist = 1.1 * rolloutDistance;
+    double maxdist = rwy->lengthM();
+    //cerr << "Finding nearest exit" << endl;
+    FGGroundNetwork *gn = apt->getDynamics()->getGroundNetwork();
+    if (gn) {
+        double min = 0;
+        for (int i = ceil(mindist); i < floor(maxdist); i++) {
+            coord = rwy->pointOnCenterline(mindist);
+            int nodeId = 0;
+            if (gn->getVersion() > 0) {
+                nodeId = gn->findNearestNodeOnRunway(coord);
+            } else {
+                nodeId = gn->findNearestNode(coord);
+            }
+            if (tn)
+                tn = gn->findNode(nodeId);
+            else {
+                break;
+            }
+            
+            double dist = SGGeodesy::distanceM(coord, tn->getGeod());
+            if (dist < (min + 0.75)) {
+                break;
+            }
+            min = dist;
+        }
+        if (tn) {
+            wpt = createOnGround(ac, buffer, tn->getGeod(), currElev, vTaxi);
+            waypoints.push_back(wpt);
+        }
+    }
+    cerr << "Done. " << endl;
 
     /*
        //Runway Threshold
index d18e24b863ea94ebf8700225c6fc5f845b210b81..a966b577601303378d354fea8ac596edd6437145 100644 (file)
@@ -43,6 +43,7 @@ public:
     inline double vRotate          () { return _vRotate; };
     inline double maximumBankAngle () { return _maxbank; };
     inline double acceleration     () { return _acceleration; };
+    inline double deceleration     () { return _deceleration; };
     inline double vTaxi            () { return _vTaxi; };
     inline double vTakeoff         () { return _vTakeOff; };
     inline double vClimb           () { return _vClimb; };
index 7da29ae73ccaa0d423cd74c06fbc63f8599356fd..26af2b7112aacae5b55c4ce4869bf25306d8b530 100644 (file)
@@ -146,6 +146,10 @@ void  FGAirportDynamicsXMLLoader::startElement (const char * name, const XMLAttr
 
 void  FGAirportDynamicsXMLLoader::endElement (const char * name) {
   //cout << "End element " << name << endl;
+  if (name == string("version")) {
+       _dynamics->getGroundNetwork()->addVersion(atoi(value.c_str()));
+       //std::cerr << "version" << value<< std::endl;
+  }
   if (name == string("AWOS")) {
        _dynamics->addAwosFreq(atoi(value.c_str()));
        //cerr << "Adding AWOS" << value<< endl;
index 12faa8515a783aeefcdc1eb591269362b002fca8..a3a3245fe9af7d711be60af249d1cd22abc483d7 100644 (file)
@@ -220,6 +220,7 @@ FGGroundNetwork::FGGroundNetwork()
     count = 0;
     currTraffic = activeTraffic.begin();
     group = 0;
+    version = 0;
     networkInitialized = false;
 
 }
@@ -452,6 +453,28 @@ int FGGroundNetwork::findNearestNode(const SGGeod & aGeod)
     return index;
 }
 
+int FGGroundNetwork::findNearestNodeOnRunway(const SGGeod & aGeod)
+{
+    double minDist = HUGE_VAL;
+    int index = -1;
+
+    for (FGTaxiNodeVectorIterator itr = nodes.begin(); itr != nodes.end();
+            itr++) {
+        if (!((*itr)->getIsOnRunway())) {
+            continue;
+        }
+        double d = SGGeodesy::distanceM(aGeod, (*itr)->getGeod());
+        if (d < minDist) {
+            minDist = d;
+            index = (*itr)->getIndex();
+            //cerr << "Minimum distance of " << minDist << " for index " << index << endl;
+        }
+    }
+
+    return index;
+}
+
+
 int FGGroundNetwork::findNearestNode(double lat, double lon)
 {
     return findNearestNode(SGGeod::fromDeg(lon, lat));
index cec19d38bfcc666659ca0db819185f03c03dd606..c80829a3b65d1a6c5ed89ead027b42b74a67ddaf 100644 (file)
@@ -292,6 +292,7 @@ private:
     time_t nextSave;
     //int maxDepth;
     int count;
+    int version;
     FGTaxiNodeVector    nodes;
     FGTaxiNodeVector    pushBackNodes;
     FGTaxiSegmentVector segments;
@@ -324,6 +325,9 @@ public:
     void addNode   (const FGTaxiNode& node);
     void addNodes  (FGParkingVec *parkings);
     void addSegment(const FGTaxiSegment& seg);
+    void setVersion (int v) { version = v;};
+    
+    int getVersion() { return version; };
 
     void init();
     bool exists() {
@@ -335,6 +339,7 @@ public:
 
     int findNearestNode(double lat, double lon);
     int findNearestNode(const SGGeod& aGeod);
+    int findNearestNodeOnRunway(const SGGeod& aGeod);
 
     FGTaxiNode *findNode(unsigned idx);
     FGTaxiSegment *findSegment(unsigned idx);
@@ -365,6 +370,7 @@ public:
     virtual void update(double dt);
 
     void saveElevationCache();
+    void addVersion(int v) {version = v; };
 };
 
 
index 235154385c1f6c8e0ee06018bc0221777c2fdfff..1af0ca112a130b60a0a8ecce2100b22b3c8af966 100644 (file)
@@ -423,7 +423,7 @@ void FGAISchedule::scheduleFlights(time_t now)
                              << "  "        << arrT << ":");
   
     flights.push_back(flight);
-  } while (1); //(currentDestination != startingPort);
+  } while (currentDestination != startingPort);
   SG_LOG(SG_GENERAL, SG_BULK, " Done ");
 }
 
@@ -507,7 +507,8 @@ FGScheduledFlight* FGAISchedule::findAvailableFlight (const string &currentDesti
           }
           if (flights.size()) {
             time_t arrival = flights.back()->getArrivalTime();
-            if ((*i)->getDepartureTime() < (arrival+(20*60)))
+            int groundTime = groundTimeFromRadius();
+            if ((*i)->getDepartureTime() < (arrival+(groundTime)))
                 continue;
           }
           if (min != 0) {
@@ -531,6 +532,23 @@ FGScheduledFlight* FGAISchedule::findAvailableFlight (const string &currentDesti
      return NULL;
 }
 
+int FGAISchedule::groundTimeFromRadius()
+{
+    if (radius < 10) 
+        return 15 * 60;
+    else if (radius < 15)
+        return 20 * 60;
+    else if (radius < 20)
+        return 30 * 60;
+    else if (radius < 25)
+        return 50 * 60;
+    else if (radius < 30)
+        return 90 * 60;
+    else 
+        return 120 * 60;
+}
+
+
 double FGAISchedule::getSpeed()
 {
   FGScheduledFlightVecIterator i = flights.begin();
index 27385ed0d3e0a515a5710f17cb983d7f26e174c3..e41334e6b7fd9eca5c2a9bfd1e6873cc4d2206d5 100644 (file)
@@ -63,6 +63,7 @@ class FGAISchedule
   bool valid;
 
   void scheduleFlights(time_t now);
+  int groundTimeFromRadius();
   
   /**
    * Transition this schedule from distant mode to AI mode;