]> git.mxchange.org Git - flightgear.git/commitdiff
* Updated routing algorithm. Just sorting the schedules by usage heuristics doesn...
authorDurk Talsma <durktals@gmail.com>
Wed, 26 Oct 2011 20:26:37 +0000 (22:26 +0200)
committerDurk Talsma <durktals@gmail.com>
Wed, 26 Oct 2011 20:26:37 +0000 (22:26 +0200)
* Improved groundnetwork routing algorithm. Don't uncesscarily block taxiways. Instead, use a "just-in-time" blocking system. The unblocking algorithm still needs some work, but the current version is already a major improvement over the previous version.
* Some tweaks to the handover from ground to tower controller. Aircraft could refuse to take-off of even refuse to taxi onto the runway. This now seems to be solved.

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

index 930686acf1a6d3a793cb9affa1ba40d01230b683..d50ff58dad68b5b2d3d48968613530291497e80e 100644 (file)
@@ -941,7 +941,7 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
     }*/
     double rolloutDistance =
         (vTouchdownMetric * vTouchdownMetric - vTaxiMetric * vTaxiMetric) / (2 * decelMetric);
-    cerr << " touchdown speed = " << vTouchdown << ". Rollout distance " << rolloutDistance << endl;
+    //cerr << " touchdown speed = " << vTouchdown << ". Rollout distance " << rolloutDistance << endl;
     int nPoints = 50;
     for (int i = 1; i < nPoints; i++) {
         snprintf(buffer, 12, "landing03%d", i);
@@ -983,7 +983,7 @@ bool FGAIFlightPlan::createLanding(FGAIAircraft * ac, FGAirport * apt,
             pushBackWaypoint(wpt);
         }
     }
-    cerr << "Done. " << endl;
+    //cerr << "Done. " << endl;
 
     /*
        //Runway Threshold
index 8a1e996e7d5b47f8cd9e2a6b7eddb0d86cdcebcc..124b1740fcbc4d09f7eb524e38b748deae181404 100644 (file)
@@ -187,12 +187,12 @@ void FGTrafficRecord::setPositionAndIntentions(int pos,
         if ((*i) != pos) {
             SG_LOG(SG_GENERAL, SG_ALERT,
                    "Error in FGTrafficRecord::setPositionAndIntentions at " << SG_ORIGIN);
-            //cerr << "Pos : " << pos << " Curr " << *(intentions.begin())  << endl;
+            cerr << "Pos : " << pos << " Curr " << *(intentions.begin())  << endl;
             for (intVecIterator i = intentions.begin();
                     i != intentions.end(); i++) {
-                //cerr << (*i) << " ";
+                cerr << (*i) << " ";
             }
-            //cerr << endl;
+            cerr << endl;
         }
         intentions.erase(i);
     } else {
@@ -878,11 +878,11 @@ void FGTowerController::updateAircraftInformation(int id, double lat, double lon
     // already exists here. So, we can simplify the current code.
     
     ActiveRunwayVecIterator rwy = activeRunways.begin();
-    if (parent->getId() == fgGetString("/sim/presets/airport-id")) {
-        //for (rwy = activeRunways.begin(); rwy != activeRunways.end(); rwy++) {
-        //    rwy->printDepartureCue();
-        //}
-    }
+    //if (parent->getId() == fgGetString("/sim/presets/airport-id")) {
+    //    for (rwy = activeRunways.begin(); rwy != activeRunways.end(); rwy++) {
+    //        rwy->printDepartureCue();
+    //    }
+    //}
     
     rwy = activeRunways.begin();
     while (rwy != activeRunways.end()) {
@@ -1318,6 +1318,7 @@ void FGStartupController::render(bool visible)
 
         //for ( FGTaxiSegmentVectorIterator i = segments.begin(); i != segments.end(); i++) {
         double dx = 0;
+        time_t now = time(NULL) + fgGetLong("/sim/time/warp");
         for   (TrafficVectorIterator i = activeTraffic.begin(); i != activeTraffic.end(); i++) {
             if (i->isActive(300)) {
                 // Handle start point
@@ -1387,7 +1388,7 @@ void FGStartupController::render(bool visible)
                     geode->addDrawable(geometry);
                     //osg::Node *custom_obj;
                     SGMaterial *mat;
-                    if (segment->hasBlock()) {
+                    if (segment->hasBlock(now)) {
                         mat = matlib->find("UnidirectionalTaperRed");
                     } else {
                         mat = matlib->find("UnidirectionalTaperGreen");
@@ -1464,7 +1465,7 @@ void FGStartupController::render(bool visible)
                         geode->addDrawable(geometry);
                         //osg::Node *custom_obj;
                         SGMaterial *mat;
-                        if (segment->hasBlock()) {
+                        if (segment->hasBlock(now)) {
                             mat = matlib->find("UnidirectionalTaperRed");
                         } else {
                             mat = matlib->find("UnidirectionalTaperGreen");
index fc943fb15a6a39ef36550201bac591c50a563803..f4a49dff1c10f028b833348b946ef88ccf8435b2 100644 (file)
@@ -43,6 +43,7 @@
 #include <Airports/dynamics.hxx>
 
 #include <AIModel/AIAircraft.hxx>
+#include <AIModel/performancedata.hxx>
 #include <AIModel/AIFlightPlan.hxx>
 
 #include <ATC/atc_mgr.hxx>
@@ -51,6 +52,7 @@
 
 #include "groundnetwork.hxx"
 
+
 /***************************************************************************
  * FGTaxiSegment
  **************************************************************************/
@@ -651,7 +653,11 @@ void FGGroundNetwork::announcePosition(int id,
         rec.setPositionAndHeading(lat, lon, heading, speed, alt);
         rec.setRadius(radius);  // only need to do this when creating the record.
         rec.setAircraft(aircraft);
-        activeTraffic.push_front(rec);
+        if (leg == 2) {
+            activeTraffic.push_front(rec);
+        } else {
+            activeTraffic.push_back(rec);   
+        }
         
     } else {
         i->setPositionAndIntentions(currentPosition, intendedRoute);
@@ -985,6 +991,7 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
     } else {
         return;
     }
+    time_t now = time(NULL) + fgGetLong("/sim/time/warp");
     if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
         SG_LOG(SG_GENERAL, SG_ALERT,
                "AI error: Trying to access non-existing aircraft in FGGroundNetwork::checkHoldPosition at " << SG_ORIGIN);
@@ -996,7 +1003,9 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
         return;
     }
     if (current->getAircraft()->getTakeOffStatus() == 2) {
+        //cerr << current->getAircraft()->getCallSign() << ". Taxi in position and hold" << endl;
         current->setHoldPosition(false);
+        current->clearSpeedAdjustment();
         return;
     }
     bool origStatus = current->hasHoldPosition();
@@ -1017,7 +1026,7 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
         } else {
             nx = tx;
         }
-        if (tx->hasBlock() || nx->hasBlock() ) {
+        if (tx->hasBlock(now) || nx->hasBlock(now) ) {
             current->setHoldPosition(true);
         }
     }
@@ -1099,7 +1108,6 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
     bool currStatus = current->hasHoldPosition();
     current->setHoldPosition(origStatus);
     // Either a Hold Position or a resume taxi transmission has been issued
-    time_t now = time(NULL) + fgGetLong("/sim/time/warp");
     if ((now - lastTransmission) > 2) {
         available = true;
     }
@@ -1348,6 +1356,7 @@ void FGGroundNetwork::render(bool visible)
         FGScenery * local_scenery = globals->get_scenery();
         double elevation_meters = 0.0;
         double elevation_feet = 0.0;
+        time_t now = time(NULL) + fgGetLong("/sim/time/warp");
         //for ( FGTaxiSegmentVectorIterator i = segments.begin(); i != segments.end(); i++) {
         double dx = 0;
         for   (TrafficVectorIterator i = activeTraffic.begin(); i != activeTraffic.end(); i++) {
@@ -1417,7 +1426,7 @@ void FGGroundNetwork::render(bool visible)
                 geode->addDrawable(geometry);
                 //osg::Node *custom_obj;
                 SGMaterial *mat;
-                if (segments[pos]->hasBlock()) {
+                if (segments[pos]->hasBlock(now)) {
                     mat = matlib->find("UnidirectionalTaperRed");
                 } else {
                     mat = matlib->find("UnidirectionalTaperGreen");
@@ -1491,7 +1500,7 @@ void FGGroundNetwork::render(bool visible)
                     geode->addDrawable(geometry);
                     //osg::Node *custom_obj;
                     SGMaterial *mat;
-                    if (segments[k]->hasBlock()) {
+                    if (segments[k]->hasBlock(now)) {
                         mat = matlib->find("UnidirectionalTaperRed");
                     } else {
                         mat = matlib->find("UnidirectionalTaperGreen");
@@ -1516,8 +1525,9 @@ string FGGroundNetwork::getName() {
 
 void FGGroundNetwork::update(double dt)
 {
+    time_t now = time(NULL) + fgGetLong("/sim/time/warp");
     for (FGTaxiSegmentVectorIterator tsi = segments.begin(); tsi != segments.end(); tsi++) {
-        (*tsi)->unblock();
+        (*tsi)->unblock(now);
     }
     int priority = 1;
     //sort(activeTraffic.begin(), activeTraffic.end(), compare_trafficrecords);
@@ -1527,6 +1537,8 @@ void FGGroundNetwork::update(double dt)
             i != parent->getDynamics()->getStartupController()->getActiveTraffic().end(); i++) {
         i->allowPushBack();
         i->setPriority(priority++);
+        // in meters per second;
+        double vTaxi = (i->getAircraft()->getPerformance()->vTaxi() * SG_NM_TO_METER) / 3600;
         if (i->isActive(60)) {
 
             // Check for all active aircraft whether it's current pos segment is
@@ -1540,7 +1552,7 @@ void FGGroundNetwork::update(double dt)
                         for (intVecIterator k = i->getIntentions().begin(); k != i->getIntentions().end(); k++) {
                             if ((*k) == posReverse) {
                                 i->denyPushBack();
-                                segments[posReverse-1]->block();
+                                segments[posReverse-1]->block(now);
                             }
                         }
                     }
@@ -1548,13 +1560,15 @@ void FGGroundNetwork::update(double dt)
             }
             // if the current aircraft is still allowed to pushback, we can start reserving a route for if by blocking all the entry taxiways.
             if (i->pushBackAllowed()) {
+                double length = 0;
                 int pos = i->getCurrentPosition();
                 if (pos > 0) {
                     FGTaxiSegment *seg = segments[pos-1];
                     FGTaxiNode *node = seg->getEnd();
+                    length = seg->getLength();
                     for (FGTaxiSegmentVectorIterator tsi = segments.begin(); tsi != segments.end(); tsi++) {
                         if (((*tsi)->getEnd() == node) && ((*tsi) != seg)) {
-                            (*tsi)->block();
+                            (*tsi)->block(now);
                         }
                     }
                 }
@@ -1563,9 +1577,11 @@ void FGGroundNetwork::update(double dt)
                     if (pos > 0) {
                         FGTaxiSegment *seg = segments[pos-1];
                         FGTaxiNode *node = seg->getEnd();
+                        length += seg->getLength();
+                        time_t blockTime = now + (length / vTaxi);
                         for (FGTaxiSegmentVectorIterator tsi = segments.begin(); tsi != segments.end(); tsi++) {
                             if (((*tsi)->getEnd() == node) && ((*tsi) != seg)) {
-                                (*tsi)->block();
+                                (*tsi)->block(blockTime-30);
                             }
                         }
                     }
@@ -1574,10 +1590,13 @@ void FGGroundNetwork::update(double dt)
         }
     }
     for   (TrafficVectorIterator i = activeTraffic.begin(); i != activeTraffic.end(); i++) {
+        double length = 0;
+        double vTaxi = (i->getAircraft()->getPerformance()->vTaxi() * SG_NM_TO_METER) / 3600;
         i->setPriority(priority++);
         int pos = i->getCurrentPosition();
         if (pos > 0) {
-            if (segments[pos-1]->hasBlock()) {
+            length = segments[pos-1]->getLength();
+            if (segments[pos-1]->hasBlock(now)) {
                 //SG_LOG(SG_GENERAL, SG_ALERT, "Taxiway incursion for AI aircraft" << i->getAircraft()->getCallSign());
             }
 
@@ -1586,7 +1605,7 @@ void FGGroundNetwork::update(double dt)
         for (ivi = i->getIntentions().begin(); ivi != i->getIntentions().end(); ivi++) {
             int segIndex = (*ivi);
             if (segIndex > 0) {
-                if (segments[segIndex-1]->hasBlock())
+                if (segments[segIndex-1]->hasBlock(now))
                     break;
             }
         }
@@ -1596,9 +1615,11 @@ void FGGroundNetwork::update(double dt)
             if (pos > 0) {
                 FGTaxiSegment *seg = segments[pos-1];
                 FGTaxiNode *node = seg->getEnd();
+                length += seg->getLength();
                 for (FGTaxiSegmentVectorIterator tsi = segments.begin(); tsi != segments.end(); tsi++) {
                     if (((*tsi)->getEnd() == node) && ((*tsi) != seg)) {
-                        (*tsi)->block();
+                        time_t blockTime = now + (length / vTaxi);
+                        (*tsi)->block(blockTime - 30);
                     }
                 }
             }
index c80829a3b65d1a6c5ed89ead027b42b74a67ddaf..0f1eefc077c6091aabc24aa6cb12e5a49482f79c 100644 (file)
@@ -67,7 +67,7 @@ private:
     SGGeod center;
     bool isActive;
     bool isPushBackRoute;
-    bool isBlocked;
+    time_t isBlocked;
     FGTaxiNode *start;
     FGTaxiNode *end;
     int index;
@@ -144,14 +144,21 @@ public:
         isPushBackRoute = val;
     };
     void setDimensions(double elevation);
-    void block() {
-        isBlocked = true;
+    void block(time_t time) {
+        if (isBlocked) {
+            if (time < isBlocked) {
+                isBlocked = time;
+            }
+        } else {
+            isBlocked = time;
+        }
     }
-    void unblock() {
-        isBlocked = false;
+    void unblock(time_t now) {
+        if ((now - isBlocked) > 60)
+            isBlocked = 0;
     };
-    bool hasBlock() {
-        return isBlocked;
+    bool hasBlock(time_t now) {
+        return isBlocked ? (isBlocked < now) : 0;
     };
 
     FGTaxiNode * getEnd() {
index 39e870c46d3c2ab402f7da48cdd0552a11edfecb..4314d0237b5abed9679d36ca7fd0148c14d800fe 100644 (file)
@@ -374,18 +374,24 @@ void FGAISchedule::scheduleFlights(time_t now)
   if (!flights.empty()) {
     return;
   }
-  string startingPort;
+  //string startingPort;
   string userPort = fgGetString("/sim/presets/airport-id");
   SG_LOG(SG_GENERAL, SG_BULK, "Scheduling Flights for : " << modelPath << " " <<  registration << " " << homePort);
   FGScheduledFlight *flight = NULL;
   do {
-    flight = findAvailableFlight(currentDestination, flightIdentifier);
-    
+    if (currentDestination.empty()) {
+        flight = findAvailableFlight(userPort, flightIdentifier, now, (now+6400));
+        if (!flight)
+            flight = findAvailableFlight(currentDestination, flightIdentifier);
+    } else {
+        flight = findAvailableFlight(currentDestination, flightIdentifier);
+    }
     if (!flight) {
       break;
     }
-
-   
+    //if (startingPort.empty()) {
+    //    startingPort = flight->getDepartureAirport()->getId();
+    //}
     currentDestination = flight->getArrivalAirport()->getId();
     //cerr << "Current destination " <<  currentDestination << endl;
     if (!initialized) {
@@ -393,7 +399,10 @@ void FGAISchedule::scheduleFlights(time_t now)
        //cerr << "Scheduled " << registration <<  " " << score << " for Flight " 
        //     << flight-> getCallSign() << " from " << departurePort << " to " << currentDestination << endl;
         if (userPort == departurePort) {
+            lastRun = 1;
             hits++;
+        } else {
+            lastRun = 0;
         }
         //runCount++;
         initialized = true;
index e41334e6b7fd9eca5c2a9bfd1e6873cc4d2206d5..e3c8d84512c3efbb75dca1af1c0a6b1c2724bbc8 100644 (file)
@@ -128,7 +128,7 @@ class FGAISchedule
   // decending order sorting, but still need to test that.
   bool operator< (const FGAISchedule &other) const;
     void taint() { valid = false; };
-    int getLastUsed() { return (int) valid;};
+    int getLastUsed() { return lastRun; };
     void setLastUsed(unsigned int val) {lastRun = val; }; 
   //void * getAiRef                 () { return AIManagerRef; };
   //FGAISchedule* getAddress        () { return this;};