]> git.mxchange.org Git - flightgear.git/commitdiff
A number of cosmetic and/or infrastructural changes.
authorDurk Talsma <durk@localhost.(none)>
Sun, 4 Sep 2011 18:27:36 +0000 (20:27 +0200)
committerDurk Talsma <durk@localhost.(none)>
Sun, 4 Sep 2011 18:27:36 +0000 (20:27 +0200)
Traffic Manager:
* Just continue routing until we run out of flights. This change removes one of the major requirements for setting the "Home port" field.
* Add a time restriction requirement for the aircraft scheduler; this became necessary after removing the limited-to-home-port routing restriction.
* Added a new field to the heuristics calculation: take into account whether an aircraft has already been used in a previous session. Rotate aircraft assignments for greater variability across sessions.
* Added a revision number to the cache files, so that old cache results, which are no longer compatible with the new file format, are discarded.

Groundnetwork and traffic control:
* Added a revision number to the cache files, so that old and incompatible results are discarded.
* The caching algorithm probably didn't store the correct data for airports that were processed while the user was quite far away. This is now corrected by checking whether the cached elevation data are equal to the generic airport elevation.
AIAircraft:
* I've been searching for the infamous aircraft bend-over-backward bug, that can occur during initialization, but to no avail yet. The only variable potentially responsible (tgt_vs) wich can explain the irregular jumping behavior, as well as the weird pitch results is initialized in AIAircraft's only constructor (through AIBase), and I can't find any situation in the ground handling code where this variable could get bizarre values. But,
* a couple of tgt_vs. calculations appear to be completely redundant. This value was calculated twice inside the ProcessFlightplan function, and subsequently again in the updateSecondaryTargetValues function. I have removed the calculations in the process flightplan function, without any apparent side effect.

src/AIModel/AIAircraft.cxx
src/ATC/trafficcontrol.cxx
src/Airports/groundnetwork.cxx
src/Traffic/Schedule.cxx
src/Traffic/Schedule.hxx
src/Traffic/TrafficMgr.cxx
src/Traffic/TrafficMgr.hxx

index 3791585ec8b8337833d0c8e37ae84708872b2248..be0556c8533dad170a0b3c56d981f1162ecf8c82 100644 (file)
@@ -1,4 +1,4 @@
-// // FGAIAircraft - FGAIBase-derived class creates an AI airplane
+// FGAIAircraft - FGAIBase-derived class creates an AI airplane
 //
 // Written by David Culp, started October 2003.
 //
@@ -48,6 +48,8 @@ using std::string;
 #include "performancedata.hxx"
 #include "performancedb.hxx"
 
+
+#define TGT_VS_CUTOFF 10000
 //#include <Airports/trafficcontroller.hxx>
 
 static string tempReg;
@@ -155,6 +157,7 @@ void FGAIAircraft::setPerformance(const std::string& acclass) {
 
 
  void FGAIAircraft::Run(double dt) {
+      
       FGAIAircraft::dt = dt;
     
      bool outOfSight = false, 
@@ -355,9 +358,14 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) {
             tgt_altitude_ft = prev->getAltitude();
             if (curr->getCrossat() > -1000.0) {
                 use_perf_vs = false;
-                tgt_vs = (curr->getCrossat() - altitude_ft) / (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)
-                         / 6076.0 / speed*60.0);
-                checkTcas();
+//                 tgt_vs = (curr->getCrossat() - altitude_ft) / (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)
+//                          / 6076.0 / speed*60.0);
+//                 if (fabs(tgt_vs) > TGT_VS_CUTOFF) { SG_LOG(SG_GENERAL, SG_ALERT, "Rediculously high vertical speed caculated at " << SG_ORIGIN << ". Corresponding to " << (tgt_vs * .005) << "degrees of pitch angle" << prev->getName()); };
+//                 if (tgt_vs < -1500)
+//                     tgt_vs = -1500;
+//                 if (tgt_vs > 1500) 
+//                     tgt_vs = 1500;
+//                 checkTcas();
                 tgt_altitude_ft = curr->getCrossat();
             } else {
                 use_perf_vs = true;
@@ -497,6 +505,7 @@ void FGAIAircraft::getGroundElev(double dt) {
 
 
 void FGAIAircraft::doGroundAltitude() {
+
     if ((fabs(altitude_ft - (tgt_altitude_ft+groundOffset)) > 1000.0)||
         (isStationary()))
         altitude_ft = (tgt_altitude_ft + groundOffset);
@@ -676,10 +685,11 @@ void FGAIAircraft::handleFirstWaypoint() {
     if (curr->getCrossat() > -1000.0) //use a calculated descent/climb rate
     {
         use_perf_vs = false;
-        tgt_vs = (curr->getCrossat() - prev->getAltitude())
+/*        tgt_vs = (curr->getCrossat() - prev->getAltitude())
                  / (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)
                     / 6076.0 / prev->getSpeed()*60.0);
-        checkTcas();
+        if (fabs(tgt_vs) > TGT_VS_CUTOFF) { SG_LOG(SG_GENERAL, SG_ALERT, "Rediculously high vertical speed caculated at " << SG_ORIGIN); };
+        checkTcas();*/
         tgt_altitude_ft = curr->getCrossat();
     } else {
         use_perf_vs = true;
index 47f5acc8a620e7842b07f1e7be2bc4cca823ecaf..dc0552fe7a9d2b958b46fcc9d6406d01b82e4aa1 100644 (file)
@@ -1318,7 +1318,7 @@ void FGStartupController::render(bool visible)
                     elevationStart = ((i)->getAircraft()->_getAltitude()); 
                 }
                 double elevationEnd   = segment->getEnd()->getElevation();
-                if (elevationEnd == 0) {
+                if ((elevationEnd == 0) || (elevationEnd == parent->getElevation())) {
                     SGGeod center2 = end;
                     center2.setElevationM(SG_MAX_ELEVATION_M);
                     if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
@@ -1326,7 +1326,7 @@ void FGStartupController::render(bool visible)
                             //elevation_meters += 0.5;
                     }
                     else { 
-                        elevationEnd = parent->getElevation()+8+dx;
+                        elevationEnd = parent->getElevation();
                     }
                     segment->getEnd()->setElevation(elevationEnd);
                 }
@@ -1376,7 +1376,7 @@ void FGStartupController::render(bool visible)
 
                     double elevationStart = segment->getStart()->getElevation();
                     double elevationEnd   = segment->getEnd  ()->getElevation();
-                    if (elevationStart == 0) {
+                    if ((elevationStart == 0) || (elevationStart == parent->getElevation())) {
                         SGGeod center2 = segment->getStart()->getGeod();
                         center2.setElevationM(SG_MAX_ELEVATION_M);
                         if (local_scenery->get_elevation_m( center2, elevationStart, NULL )) {
@@ -1384,11 +1384,11 @@ void FGStartupController::render(bool visible)
                             //elevation_meters += 0.5;
                         }
                         else { 
-                            elevationStart = parent->getElevation()+8+dx;
+                            elevationStart = parent->getElevation();
                         }
                         segment->getStart()->setElevation(elevationStart);
                     }
-                    if (elevationEnd == 0) {
+                    if ((elevationEnd == 0) || (elevationEnd == parent->getElevation())) {
                         SGGeod center2 = segment->getEnd()->getGeod();
                         center2.setElevationM(SG_MAX_ELEVATION_M);
                         if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
@@ -1396,7 +1396,7 @@ void FGStartupController::render(bool visible)
                             //elevation_meters += 0.5;
                         }
                         else { 
-                            elevationEnd = parent->getElevation()+8+dx;
+                            elevationEnd = parent->getElevation();
                         }
                         segment->getEnd()->setElevation(elevationEnd);
                     }
index 86beec118568cd64b26cfe9dfc99d2398abf1532..0da6af35cae8ac9e227dad55fb6ada62ef617cbe 100644 (file)
@@ -1,4 +1,3 @@
-
 // groundnet.cxx - Implimentation of the FlightGear airport ground handling code
 //
 // Written by Durk Talsma, started June 2005.
@@ -243,6 +242,7 @@ FGGroundNetwork::~FGGroundNetwork()
             saveData = true;
         }
     }
+    cachefile << "[GroundNetcachedata:ref:2011:09:04]" << endl;
     for (FGTaxiNodeVectorIterator node = nodes.begin();
          node != nodes.end(); node++) {
          if (saveData) {
@@ -286,6 +286,7 @@ void FGGroundNetwork::saveElevationCache() {
             saveData = true;
         }
     }
+    cachefile << "[GroundNetcachedata:ref:2011:09:04]" << endl;
     for (FGTaxiNodeVectorIterator node = nodes.begin();
          node != nodes.end(); node++) {
          if (saveData) {
@@ -401,17 +402,24 @@ void FGGroundNetwork::init()
             cacheData.append(airport + "-groundnet-cache.txt");
             if (cacheData.exists()) {
                 ifstream data(cacheData.c_str());
-                for (FGTaxiNodeVectorIterator i = nodes.begin();
-                     i != nodes.end(); 
-                     i++) {
-                    (*i)->setElevation(parent->getElevation() * SG_FEET_TO_METER);
-                    data >> index >> elev;
-                    if (data.eof())
-                        break;
-                    if (index != (*i)->getIndex()) {
-                        SG_LOG(SG_GENERAL, SG_ALERT, "Index read from ground network cache at airport " << airport << " does not match index in the network itself");
-                    } else {
-                        (*i)->setElevation(elev);
+                string revisionStr;
+                data >> revisionStr;
+                if (revisionStr != "[GroundNetcachedata:ref:2011:09:04]") {
+                    SG_LOG(SG_GENERAL, SG_ALERT,"GroundNetwork Warning: discarding outdated cachefile " << 
+                            cacheData.c_str() << " for Airport " << airport);
+                } else {
+                    for (FGTaxiNodeVectorIterator i = nodes.begin();
+                        i != nodes.end(); 
+                        i++) {
+                        (*i)->setElevation(parent->getElevation() * SG_FEET_TO_METER);
+                        data >> index >> elev;
+                        if (data.eof())
+                            break;
+                        if (index != (*i)->getIndex()) {
+                            SG_LOG(SG_GENERAL, SG_ALERT, "Index read from ground network cache at airport " << airport << " does not match index in the network itself");
+                        } else {
+                            (*i)->setElevation(elev);
+                        }
                     }
                 }
             }
@@ -1308,7 +1316,7 @@ void FGGroundNetwork::render(bool visible)
                 double elevationEnd   = segments[pos]->getEnd()->getElevation();
                 //cerr << "Using elevation " << elevationEnd << endl;
 
-                if (elevationEnd == 0) {
+                if ((elevationEnd == 0) || (elevationEnd = parent->getElevation())) {
                     SGGeod center2 = end;
                     center2.setElevationM(SG_MAX_ELEVATION_M);
                     if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
@@ -1316,7 +1324,7 @@ void FGGroundNetwork::render(bool visible)
                             //elevation_meters += 0.5;
                     }
                     else { 
-                        elevationEnd = parent->getElevation()+8+dx;
+                        elevationEnd = parent->getElevation();
                     }
                     segments[pos]->getEnd()->setElevation(elevationEnd);
                 }
@@ -1363,7 +1371,7 @@ void FGGroundNetwork::render(bool visible)
                     // Experimental: Calculate slope here, based on length, and the individual elevations
                     double elevationStart = segments[k]->getStart()->getElevation();
                     double elevationEnd   = segments[k]->getEnd  ()->getElevation();
-                    if (elevationStart == 0) {
+                    if ((elevationStart == 0)  || (elevationStart == parent->getElevation())) {
                         SGGeod center2 = segments[k]->getStart()->getGeod();
                         center2.setElevationM(SG_MAX_ELEVATION_M);
                         if (local_scenery->get_elevation_m( center2, elevationStart, NULL )) {
@@ -1371,11 +1379,11 @@ void FGGroundNetwork::render(bool visible)
                             //elevation_meters += 0.5;
                         }
                         else { 
-                            elevationStart = parent->getElevation()+8+dx;
+                            elevationStart = parent->getElevation();
                         }
                         segments[k]->getStart()->setElevation(elevationStart);
                     }
-                    if (elevationEnd == 0) {
+                    if ((elevationEnd == 0) || (elevationEnd == parent->getElevation())) {
                         SGGeod center2 = segments[k]->getEnd()->getGeod();
                         center2.setElevationM(SG_MAX_ELEVATION_M);
                         if (local_scenery->get_elevation_m( center2, elevationEnd, NULL )) {
@@ -1383,7 +1391,7 @@ void FGGroundNetwork::render(bool visible)
                             //elevation_meters += 0.5;
                         }
                         else { 
-                            elevationEnd = parent->getElevation()+8+dx;
+                            elevationEnd = parent->getElevation();
                         }
                         segments[k]->getEnd()->setElevation(elevationEnd);
                     }
index 0306fc4cd010edc8dd2b24de1c36be07eecbed0c..288d5eb10f8d2dc3d93feb05879fd19606e11507 100644 (file)
@@ -69,6 +69,7 @@ FGAISchedule::FGAISchedule()
   groundOffset = 0;
   distanceToUser = 0;
   valid = true;
+  lastRun = 0;
   //score = 0;
 }
 
@@ -120,6 +121,7 @@ FGAISchedule::FGAISchedule(string model,
   firstRun         = true;
   runCount         = 0;
   hits             = 0;
+  lastRun          = 0;
   initialized      = false;
   valid            = true;
 }
@@ -147,6 +149,7 @@ FGAISchedule::FGAISchedule(const FGAISchedule &other)
   firstRun           = other.firstRun;
   runCount           = other.runCount;
   hits               = other.hits;
+  lastRun            = other.lastRun;
   initialized        = other.initialized;
   valid              = other.valid;
 }
@@ -371,8 +374,7 @@ void FGAISchedule::scheduleFlights()
   if (!flights.empty()) {
     return;
   }
-  
-  SG_LOG(SG_GENERAL, SG_BULK, "Scheduling for : " << modelPath << " " <<  registration << " " << homePort);
+  SG_LOG(SG_GENERAL, SG_BULK, "Scheduling Flights for : " << modelPath << " " <<  registration << " " << homePort);
   FGScheduledFlight *flight = NULL;
   do {
     flight = findAvailableFlight(currentDestination, flightIdentifier);
@@ -400,14 +402,14 @@ void FGAISchedule::scheduleFlights()
 
     depT = depT.substr(0,24);
     arrT = arrT.substr(0,24);
-    SG_LOG(SG_GENERAL, SG_BULK, "  " << flight->getCallSign() << ":" 
-                             << "  " << flight->getDepartureAirport()->getId() << ":"
-                             << "  " << depT << ":"
-                             << " \"" << flight->getArrivalAirport()->getId() << "\"" << ":"
-                             << "  " << arrT << ":");
+    SG_LOG(SG_GENERAL, SG_BULK, "  Flight " << flight->getCallSign() << ":" 
+                             << "  "        << flight->getDepartureAirport()->getId() << ":"
+                             << "  "        << depT << ":"
+                             << " \""       << flight->getArrivalAirport()->getId() << "\"" << ":"
+                             << "  "        << arrT << ":");
   
     flights.push_back(flight);
-  } while (currentDestination != homePort);
+  } while (1); //while (currentDestination != homePort);
   SG_LOG(SG_GENERAL, SG_BULK, " Done ");
 }
 
@@ -488,7 +490,12 @@ FGScheduledFlight* FGAISchedule::findAvailableFlight (const string &currentDesti
                    continue;
               }
           }
-          //TODO: check time
+          if (flights.size()) {
+            time_t arrival = flights.back()->getArrivalTime();
+            if ((*i)->getDepartureTime() < arrival)
+                continue;
+          }
+
           // So, if we actually get here, we have a winner
           //cerr << "found flight: " << req << " : " << currentDestination << " : " <<       
           //         (*i)->getArrivalAirport()->getId() << endl;
@@ -537,48 +544,11 @@ bool compareSchedules(FGAISchedule*a, FGAISchedule*b)
   return (*a) < (*b); 
 } 
 
-
-// void FGAISchedule::setClosestDistanceToUser()
-// {
-  
-  
-//   double course;
-//   double dist;
-
-//   time_t 
-//     totalTimeEnroute, 
-//     elapsedTimeEnroute;
-//   double userLatitude  = fgGetDouble("/position/latitude-deg");
-//   double userLongitude = fgGetDouble("/position/longitude-deg");
-
-//   FGAirport *dep;
-  
-// #if defined( __CYGWIN__) || defined( __MINGW32__)
-//   #define HUGE HUGE_VAL
-// #endif
-//   distanceToUser = HUGE;
-//   FGScheduledFlightVecIterator i = flights.begin();
-//   while (i != flights.end())
-//     {
-//       dep = i->getDepartureAirport();
-//       //if (!(dep))
-//       //return HUGE;
-      
-//       SGWayPoint user (   userLongitude,
-//                       userLatitude,
-//                       i->getCruiseAlt());
-//       SGWayPoint current (dep->getLongitude(),
-//                       dep->getLatitude(),
-//                       0);
-//       user.CourseAndDistance(current, &course, &dist);
-//       if (dist < distanceToUser)
-//     {
-//       distanceToUser = dist;
-//       //cerr << "Found closest distance to user for " << registration << " to be " << distanceToUser << " at airport " << dep->getId() << endl;
-//     }
-//       i++;
-//     }
-//   //return distToUser;
-// }
+bool FGAISchedule::operator< (const FGAISchedule &other) const
+{ 
+    //cerr << "Sorting " << registration << " and "  << other.registration << endl;
+    double currentScore = score       * (1.5 - lastRun);
+    double otherScore   = other.score * (1.5 - other.lastRun);
+    return currentScore > otherScore;
+}
 
index 1f508271bb78a5c8ff6f3c13a59da61b7744c704..7c7816120a400876047306bb471b4c0069781f72 100644 (file)
@@ -56,6 +56,7 @@ class FGAISchedule
   double score;
   unsigned int runCount;
   unsigned int hits;
+  unsigned int lastRun;
   bool firstRun;
   double courseToDest;
   bool initialized;
@@ -124,8 +125,10 @@ class FGAISchedule
   FGScheduledFlight*findAvailableFlight (const string &currentDestination, const string &req);
   // used to sort in decending order of score: I've probably found a better way to
   // decending order sorting, but still need to test that.
-  bool operator< (const FGAISchedule &other) const { return (score > other.score); };
+  bool operator< (const FGAISchedule &other) const;
     void taint() { valid = false; };
+    int getLastUsed() { return (int) valid;};
+    void setLastUsed(unsigned int val) {lastRun = val; }; 
   //void * getAiRef                 () { return AIManagerRef; };
   //FGAISchedule* getAddress        () { return this;};
 
index 9ebf78c1c7c063e80ba68352d1d4073131d4a3a8..8870aa66f895fe5e3c0b9248cf62b0d04d2fee53 100644 (file)
@@ -109,6 +109,7 @@ FGTrafficManager::~FGTrafficManager()
             //cerr << "Saving AI traffic heuristics" << endl;
             saveData = true;
             cachefile.open(cacheData.str().c_str());
+            cachefile << "[TrafficManagerCachedata:ref:2011:09:04]" << endl;
         }
     }
     for (ScheduleVectorIterator sched = scheduledAircraft.begin();
@@ -116,7 +117,8 @@ FGTrafficManager::~FGTrafficManager()
         if (saveData) {
             cachefile << (*sched)->getRegistration() << " "
                 << (*sched)->getRunCount() << " "
-                << (*sched)->getHits() << endl;
+                << (*sched)->getHits() << " "
+                << (*sched)->getLastUsed() << endl;
         }
         delete(*sched);
     }
@@ -182,23 +184,31 @@ void FGTrafficManager::init()
                        airport[0], airport[1], airport[2]);
             cacheData.append(buffer);
             cacheData.append(airport + "-cache.txt");
+            string revisionStr;
             if (cacheData.exists()) {
                 ifstream data(cacheData.c_str());
-                while (1) {
-                    Heuristic h; // = new Heuristic;
-                    data >> h.registration >> h.runCount >> h.hits;
-                    if (data.eof())
-                        break;
-                    HeuristicMapIterator itr = heurMap.find(h.registration);
-                    if (itr != heurMap.end()) {
-                         SG_LOG(SG_GENERAL, SG_WARN,"Traffic Manager Warning: found duplicate tailnumber " << 
-                         h.registration << " for AI aircraft");
+                data >> revisionStr;
+                if (revisionStr != "[TrafficManagerCachedata:ref:2011:09:04]") {
+                    SG_LOG(SG_GENERAL, SG_ALERT,"Traffic Manager Warning: discarding outdated cachefile " << 
+                            cacheData.c_str() << " for Airport " << airport);
+                } else {
+                    while (1) {
+                        Heuristic h; // = new Heuristic;
+                        data >> h.registration >> h.runCount >> h.hits >> h.lastRun;
+                        if (data.eof())
+                            break;
+                        HeuristicMapIterator itr = heurMap.find(h.registration);
+                        if (itr != heurMap.end()) {
+                             SG_LOG(SG_GENERAL, SG_WARN,"Traffic Manager Warning: found duplicate tailnumber " << 
+                            h.registration << " for AI aircraft");
+                        } else {
+                            heurMap[h.registration] = h;
+                            heuristics.push_back(h);
+                        }
                     }
-                    heurMap[h.registration] = h;
-                    heuristics.push_back(h);
                 }
             }
-        }
+        } 
         for (currAircraft = scheduledAircraft.begin();
              currAircraft != scheduledAircraft.end(); currAircraft++) {
             string registration = (*currAircraft)->getRegistration();
@@ -209,25 +219,26 @@ void FGTrafficManager::init()
             } else {
                 (*currAircraft)->setrunCount(itr->second.runCount);
                 (*currAircraft)->setHits(itr->second.hits);
-                //cerr <<"Runcount " << itr->second->runCount << ".Hits " << itr->second->hits << endl;
+                (*currAircraft)->setLastUsed(itr->second.lastRun);
+                //cerr <<"Runcount " << itr->second.runCount << ". Hits " << itr->second.hits << ". Last run " << itr->second.lastRun<< endl;
             }
         }
         //cerr << "Done" << endl;
         //for (heuristicsVectorIterator hvi = heuristics.begin();
         //     hvi != heuristics.end(); hvi++) {
         //    delete(*hvi);
-        //}
+        //} 
     }
     // Do sorting and scoring separately, to take advantage of the "homeport| variable
     for (currAircraft = scheduledAircraft.begin();
          currAircraft != scheduledAircraft.end(); currAircraft++) {
         (*currAircraft)->setScore();
     }
+
     sort(scheduledAircraft.begin(), scheduledAircraft.end(),
          compareSchedules);
     currAircraft = scheduledAircraft.begin();
     currAircraftClosest = scheduledAircraft.begin();
-    
     inited = true;
 }
 
index ab1e19880deea5faeb6aadad453539df1212e3cd..c8f9faca1d5b4e94c72e9d489095a4b3b6b4f6af 100644 (file)
@@ -64,6 +64,7 @@ public:
    std::string registration;
    unsigned int runCount;
    unsigned int hits;
+   unsigned int lastRun;
 };
 
 typedef std::vector<Heuristic> heuristicsVector;