]> git.mxchange.org Git - flightgear.git/commitdiff
AI Update:
authordurk <durk>
Sat, 11 Nov 2006 10:52:05 +0000 (10:52 +0000)
committerdurk <durk>
Sat, 11 Nov 2006 10:52:05 +0000 (10:52 +0000)
 - Ground network slow-down finally works as expected
   (although occasionally causing a traffic jam)
 - Hold position instruction now really sets speed to zero, in addition
   it actually works now for crossing and two-way traffic
 - Attempt to limit execution time of ground network trace algorithm
   to make performance acceptable at high-density networks
 - Removed remaining terminal messages
 - Various minor tweaks and clean-ups

src/AIModel/AIAircraft.cxx
src/AIModel/AIFlightPlanCreate.cxx
src/Airports/dynamics.cxx
src/Airports/groundnetwork.cxx
src/Airports/groundnetwork.hxx
src/Airports/runwayprefs.cxx
src/Airports/simple.cxx
src/Airports/trafficcontrol.cxx
src/Airports/trafficcontrol.hxx
src/Traffic/TrafficMgr.cxx
src/Traffic/TrafficMgr.hxx

index 315bbdf6ad3a9db285261d75f7d396b0b3b0c354..98d95fb5c95ab98dccb1558fc6457b8eae291fb9 100644 (file)
@@ -1034,19 +1034,20 @@ void FGAIAircraft::announcePositionToController()
        callsign += "Heavy";
       switch (leg) {
       case 3:
-       cerr << callsign << " ready to taxi to runway " << fp->getRunway() << endl;
+       //cerr << callsign << " ready to taxi to runway " << fp->getRunway() << endl;
        break;
       case 4:
-       cerr << callsign << " at runway " << fp->getRunway() << "Ready for take-off. "
-            << trafficRef->getFlightRules() << " to " << trafficRef->getArrivalAirport()->getId() 
-            << "(" << trafficRef->getArrivalAirport()->getName() << ")."<< endl;
+       //cerr << callsign << " at runway " << fp->getRunway() << "Ready for take-off. "
+       //     << trafficRef->getFlightRules() << " to " << trafficRef->getArrivalAirport()->getId() 
+       //     << "(" << trafficRef->getArrivalAirport()->getName() << ")."<< endl;
+       break;
       }
     }
     prevController = controller;
     if (controller) {
       controller->announcePosition(getID(), fp, fp->getCurrentWaypoint()->routeIndex,
                           _getLatitude(), _getLongitude(), hdg, speed, altitude_ft, 
-                                  trafficRef->getRadius(), leg);
+                                  trafficRef->getRadius(), leg, trafficRef->getCallSign());
     }
   }
 }
@@ -1061,20 +1062,22 @@ void FGAIAircraft::processATC(FGATCInstruction instruction)
   // Hold Position
   if (instruction.getHoldPosition  ()) {
     if (!holdPos) {
-      if (trafficRef)
-       cerr << trafficRef->getCallSign() << "Holding Position " << endl;
+      //if (trafficRef)
+      //cerr << trafficRef->getCallSign() << "Holding Position " << endl;
       holdPos = true;
     }
-    AccelTo(0.25);
+    AccelTo(0.0);
   } else {
     if (holdPos) {
-      if (trafficRef)
-       cerr << trafficRef->getCallSign() << " Resuming Taxi " << endl;
+      //if (trafficRef)
+      //       cerr << trafficRef->getCallSign() << " Resuming Taxi " << endl;
       holdPos = false;
     }    
     // Change speed Instruction. This can only be excecuted when there is no 
     // Hold position instruction.
     if (instruction.getChangeSpeed   ()) {
+      //  if (trafficRef)
+      //cerr << trafficRef->getCallSign() << " Changing Speed " << endl;
       AccelTo(instruction.getSpeed());
     }else {
       if (fp) AccelTo(fp->getPreviousWaypoint()->speed);
index ccb677bb80c60e05b0d1f6316674defc201e6180..01a43dcc6fbdeee9f6afd93e274002117f59d715 100644 (file)
@@ -115,11 +115,12 @@ void FGAIFlightPlan::createPushBack(bool firstFlight, FGAirport *dep,
                                                    radius, fltType, 
                                                    aircraftType, airline)))
        {
-         SG_LOG(SG_INPUT, SG_WARN, "Could not find parking for a " << 
+         SG_LOG(SG_INPUT, SG_ALERT, "Could not find parking for a " << 
                 aircraftType <<
                 " of flight type " << fltType << 
                 " of airline     " << airline <<
                 " at airport     " << dep->getId());
+         //exit(1);
        }
     }
   else
index a95c63399862b9c313bdbf7cb1d2e1f68e2b5d3e..3f6185df20e63ef4120b76a386eac598b964c7da 100644 (file)
@@ -161,11 +161,19 @@ bool FGAirportDynamics::getAvailableParking(double *lat, double *lon, double *he
              continue;
            }
          else // Airline code doesn't match
-           if (i->getCodes().find(airline, 0) == string::npos)
-             {
-               available = false;
-               continue;
-             }
+           {
+             //cerr << "Code = " << airline << ": Codes " << i->getCodes();
+             if (i->getCodes().find(airline, 0) == string::npos)
+               {
+                 available = false;
+                 //cerr << "Unavailable" << endl;
+                 continue;
+               }
+             else
+               {
+                 //cerr << "Available" << endl;
+               }
+           }
          // Type doesn't match
          if (i->getType() != flType)
            {
index 2333729933e265c8521ece8d9076dfb74859fea8..2d17d948795d330bc957eb2ca6ee257b5c694705 100644 (file)
@@ -41,6 +41,7 @@
 //#include <Main/fg_props.hxx>
 //#include <Airports/runways.hxx>
 
+
 #include <AIModel/AIFlightPlan.hxx>
 
 //#include STL_STRING
@@ -58,6 +59,14 @@ FGTaxiNode::FGTaxiNode()
 {
 }
 
+void FGTaxiNode::sortEndSegments(bool byLength)
+{
+  if (byLength)
+    sort(next.begin(), next.end(), sortByLength);
+  else
+    sort(next.begin(), next.end(), sortByHeadingDiff);
+}
+
 
 bool compare_nodes(FGTaxiNode *a, FGTaxiNode *b) {
 return (*a) < (*b);
@@ -69,6 +78,7 @@ return (*a) < (*b);
 FGTaxiSegment::FGTaxiSegment()
 {
   oppositeDirection = 0;
+  isActive = true;
 }
 
 void FGTaxiSegment::setStart(FGTaxiNodeVector *nodes)
@@ -100,11 +110,13 @@ void FGTaxiSegment::setEnd(FGTaxiNodeVector *nodes)
     }
 }
 
+
+
 // There is probably a computationally cheaper way of 
 // doing this.
 void FGTaxiSegment::setTrackDistance()
 {
-  double course;
+  //double course;
   SGWayPoint first  (start->getLongitude(),
                     start->getLatitude(),
                     0);
@@ -114,10 +126,26 @@ void FGTaxiSegment::setTrackDistance()
   first.CourseAndDistance(second, &course, &length);
 }
 
+
+void FGTaxiSegment::setCourseDiff(double crse)
+{
+  headingDiff = fabs(course-crse);
+  
+  if (headingDiff > 180)
+    headingDiff = fabs(headingDiff - 360);
+}
+
 bool compare_segments(FGTaxiSegment *a, FGTaxiSegment *b) {
 return (*a) < (*b);
 }
 
+bool sortByHeadingDiff(FGTaxiSegment *a, FGTaxiSegment *b) {
+  return a->hasSmallerHeadingDiff(*b);
+}
+
+bool sortByLength(FGTaxiSegment *a, FGTaxiSegment *b) {
+  return a->getLength() > b->getLength();
+}
 /***************************************************************************
  * FGTaxiRoute
  **************************************************************************/
@@ -204,6 +232,8 @@ FGGroundNetwork::FGGroundNetwork()
   foundRoute = false;
   totalDistance = 0;
   maxDistance = 0;
+  maxDepth    = 1000;
+  count       = 0;
   currTraffic = activeTraffic.begin();
 
 }
@@ -271,6 +301,7 @@ void FGGroundNetwork::init()
     i++;
     index++;
   }
   i = segments.begin();
   while(i != segments.end()) {
     FGTaxiSegmentVectorIterator j = (*i)->getEnd()->getBeginRoute(); 
@@ -283,17 +314,21 @@ void FGGroundNetwork::init()
            int start2 = (*j)->getStart()->getIndex();
            int end2   = (*j)->getEnd()->getIndex();
            int oppIndex = (*j)->getIndex();
-//         cerr << "Opposite of  " << (*i)->getIndex() << " (" << start1 << "," << end1 << ") "
-//              << "happens to be " << oppIndex      << " (" << start2 << "," << end2 << ") " << endl;
+           //cerr << "Opposite of  " << (*i)->getIndex() << " (" << start1 << "," << end1 << ") "
+           //   << "happens to be " << oppIndex      << " (" << start2 << "," << end2 << ") " << endl;
+           (*i)->setOpposite(*j);
            break;
          }
          j++;
       }
     i++;
   }
+  //cerr << "Done initializing ground network" << endl;
   //exit(1);
 }
 
+
+
 int FGGroundNetwork::findNearestNode(double lat, double lon)
 {
   double minDist = HUGE_VAL;
@@ -359,6 +394,8 @@ FGTaxiSegment *FGGroundNetwork::findSegment(int idx)
 
 FGTaxiRoute FGGroundNetwork::findShortestRoute(int start, int end) 
 {
+  double course;
+  double length;
   foundRoute = false;
   totalDistance = 0;
   FGTaxiNode *firstNode = findNode(start);
@@ -368,14 +405,41 @@ FGTaxiRoute FGGroundNetwork::findShortestRoute(int start, int end)
   routes.clear();
   nodesStack.clear();
   routesStack.clear();
-  //cerr << "Begin of Trace " << endl;
-  trace(firstNode, end, 0, 0);
-  //cerr << "End of Trace" << endl;
-  FGTaxiRoute empty;
+  // calculate distance and heading "as the crow flies" between starn and end points"
+  SGWayPoint first(firstNode->getLongitude(),
+                  firstNode->getLatitude(),
+                  0);
+  destination = SGWayPoint(lastNode->getLongitude(),
+              lastNode->getLatitude(),
+              0);
   
+  first.CourseAndDistance(destination, &course, &length);
+  for (FGTaxiSegmentVectorIterator 
+        itr = segments.begin();
+       itr != segments.end(); itr++)
+    {
+      (*itr)->setCourseDiff(course);
+    } 
+  //FGTaxiNodeVectorIterator nde = nodes.begin();
+  //while (nde != nodes.end()) {
+  //  (*nde)->sortEndSegments();
+  //  nde++;
+  //}  
+  maxDepth = 1000;
+  //do
+  //  {
+  //    cerr << "Begin of Trace " << start << " to "<< end << " maximum depth = " << maxDepth << endl;
+      trace(firstNode, end, 0, 0);
+      //    maxDepth--;
+      //    }
+      //while ((routes.size() != 0) && (maxDepth > 0));
+      //cerr << "End of Trace" << endl;
+  FGTaxiRoute empty;
   if (!foundRoute)
     {
-      SG_LOG( SG_GENERAL, SG_ALERT, "Failed to find route from waypoint " << start << " to " << end );
+      SG_LOG( SG_GENERAL, SG_ALERT, "Failed to find route from waypoint " << start << " to " << end << " at " << 
+             parent->getId());
       exit(1);
     }
   sort(routes.begin(), routes.end());
@@ -385,7 +449,19 @@ FGTaxiRoute FGGroundNetwork::findShortestRoute(int start, int end)
   //  }
   
   if (routes.begin() != routes.end())
-    return *(routes.begin());
+    {
+     //  if ((routes.begin()->getDepth() < 0.5 * maxDepth) && (maxDepth > 1))
+//     {
+//       maxDepth--;
+//       cerr << "Max search depth decreased to : " << maxDepth;
+//     }
+//       else
+//     { 
+//       maxDepth++; 
+//       cerr << "Max search depth increased to : " << maxDepth;
+//     }
+      return *(routes.begin());
+    }
   else
     return empty;
 }
@@ -401,23 +477,25 @@ void FGGroundNetwork::trace(FGTaxiNode *currNode, int end, int depth, double dis
     }
   nodesStack.push_back(currNode->getIndex());
   totalDistance += distance;
-  //cerr << "Starting trace " << depth << " total distance: " << totalDistance<< " "
+  //cerr << "Starting trace " << currNode->getIndex() << " " << "total distance: " << totalDistance << endl;
   //     << currNode->getIndex() << endl;
 
   // If the current route matches the required end point we found a valid route
   // So we can add this to the routing table
   if (currNode->getIndex() == end)
     {
-      //cerr << "Found route : " <<  totalDistance << "" << " " << *(nodesStack.end()-1) << endl;
-      routes.push_back(FGTaxiRoute(nodesStack,routesStack,totalDistance));
+      maxDepth = depth;
+      //cerr << "Found route : " <<  totalDistance << "" << " " << *(nodesStack.end()-1) << " Depth = " << depth << endl;
+      routes.push_back(FGTaxiRoute(nodesStack,routesStack,totalDistance, depth));
       if (nodesStack.empty() || routesStack.empty())
        {
          printRoutingError(string("while finishing route"));
        }
       nodesStack.pop_back();
       routesStack.pop_back();
-      if (!(foundRoute))
+      if (!(foundRoute)) {
        maxDistance = totalDistance;
+      }
       else
        if (totalDistance < maxDistance)
          maxDistance = totalDistance;
@@ -451,10 +529,22 @@ void FGGroundNetwork::trace(FGTaxiNode *currNode, int end, int depth, double dis
       totalDistance -= distance;
       return;
     }
+    if (depth >= maxDepth) {
+      count++;
+      if (!(count % 100000)) {
+       maxDepth--; // Gradually decrease maxdepth, to prevent "eternal searches"
+       //cerr << "Reducing maxdepth to " << maxDepth << endl;
+      }
+      nodesStack.pop_back();
+      routesStack.pop_back();
+      totalDistance -= distance;
+      return;
+    }
     // If the total distance from start to the current waypoint
     // is longer than that of a route we can also stop this trace 
     // and go back one level. 
     if ((totalDistance > maxDistance) && foundRoute)
+      //if (foundRoute)
       {
        //cerr << "Stopping rediculously long trace: " << totalDistance << endl;
        if (nodesStack.empty() || routesStack.empty())
@@ -471,7 +561,36 @@ void FGGroundNetwork::trace(FGTaxiNode *currNode, int end, int depth, double dis
   //cerr << "2" << endl;
   if (currNode->getBeginRoute() != currNode->getEndRoute())
     {
+      double course, length;
       //cerr << "3" << endl;
+      // calculate distance and heading "as the crow flies" between starn and end points"
+      SGWayPoint first(currNode->getLongitude(),
+                      currNode->getLatitude(),
+                      0);
+      //SGWayPoint second (lastNode->getLongitude(),
+      //                lastNode->getLatitude(),
+      //                    0);
+  
+      first.CourseAndDistance(destination, &course, &length);
+      //for (FGTaxiSegmentVectorIterator 
+      //            itr = segments.begin();
+      //          itr != segments.end(); itr++)
+      //       {
+      //         (*itr)->setCourseDiff(course);
+      //       } 
+      //FGTaxiNodeVectorIterator nde = nodes.begin();
+      //while (nde != nodes.end()) {
+      //(*nde)->sortEndSegments();
+      //nde++;
+      
+      for (FGTaxiSegmentVectorIterator 
+            i = currNode->getBeginRoute();
+          i != currNode->getEndRoute();
+          i++)
+       {
+         (*i)->setCourseDiff(course);
+       }
+      currNode->sortEndSegments(foundRoute);
       for (FGTaxiSegmentVectorIterator 
             i = currNode->getBeginRoute();
           i != currNode->getEndRoute();
@@ -529,7 +648,8 @@ void FGGroundNetwork::printRoutingError(string mess)
 
 void FGGroundNetwork::announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentPosition,
                                       double lat, double lon, double heading, 
-                                      double speed, double alt, double radius, int leg)
+                                      double speed, double alt, double radius, int leg,
+                                      string callsign)
 {
    TrafficVectorIterator i = activeTraffic.begin();
    // Search search if the current id alread has an entry
@@ -550,6 +670,7 @@ void FGGroundNetwork::announcePosition(int id, FGAIFlightPlan *intendedRoute, in
      rec.setPositionAndIntentions(currentPosition, intendedRoute);
      rec.setPositionAndHeading(lat, lon, heading, speed, alt);
      rec.setRadius(radius); // only need to do this when creating the record.
+     rec.setCallSign(callsign);
      activeTraffic.push_back(rec);
    } else {
      i->setPositionAndIntentions(currentPosition, intendedRoute); 
@@ -625,6 +746,7 @@ void FGGroundNetwork::checkSpeedAdjustment(int id, double lat,
   TrafficVectorIterator current, closest;
   TrafficVectorIterator i = activeTraffic.begin();
   bool otherReasonToSlowDown = false;
+  bool previousInstruction;
   if (activeTraffic.size()) 
     {
       //while ((i->getId() != id) && (i != activeTraffic.end()))
@@ -643,6 +765,7 @@ void FGGroundNetwork::checkSpeedAdjustment(int id, double lat,
     SG_LOG(SG_GENERAL, SG_ALERT, "AI error: Trying to access non-existing aircraft in FGGroundNetwork::checkSpeedAdjustment");
   }
   current = i;
+  previousInstruction = current->getSpeedAdjustment();
   double mindist = HUGE;
   if (activeTraffic.size()) 
     {
@@ -726,68 +849,30 @@ void FGGroundNetwork::checkSpeedAdjustment(int id, double lat,
       //cerr << "Distance : " << dist << " bearing : " << bearing << " heading : " << heading 
       //   << " course : " << course << endl;
       current->clearSpeedAdjustment();
-      // Only clear the heading adjustment at positive speeds, otherwise the waypoint following
-      // code wreaks havoc
-      if (speed > 0.2)
-       current->clearHeadingAdjustment();
-      // All clear
-      if (mindist > 100)
-       {
-         //current->clearSpeedAdjustment();
-         //current->clearHeadingAdjustment();
-       } 
-      else
+    
+      if (current->checkPositionAndIntentions(*closest) || otherReasonToSlowDown) 
        {
-         
-         if (current->getId() == closest->getWaitsForId())
-           return;
-         else 
-           current->setWaitsForId(closest->getId());
-         
-         
-         // Getting close: Slow down to a bit less than the other aircraft
-         double maxAllowableDistance = (1.1*current->getRadius()) + (1.1*closest->getRadius());
-         if (mindist > maxAllowableDistance)
-           {
-             if (current->checkPositionAndIntentions(*closest) || otherReasonToSlowDown) 
-               {
-                 // Adjust speed, but don't let it drop to below 1 knots
-                 //if (fabs(speed) > 1)
-                 if (!(current->hasHeadingAdjustment())) 
-                   {
-                     if (closest != current)
-                       current->setSpeedAdjustment(closest->getSpeed()* (mindist/100));
-                     else
-                       current->setSpeedAdjustment(0); // This can only happen when the user aircraft is the one closest
-                     //cerr << "Adjusting speed to " << closest->getSpeed() * (mindist / 100) << " " 
-                     //         << "Bearing = " << minbearing << " Distance = " << mindist
-                     //         << " Latitude = " <<lat << " longitude = " << lon << endl;
-                     //<< " Latitude = " <<closest->getLatitude() 
-                     //<< " longitude = " << closest->getLongitude() 
-                     //  << endl;
-                   }
-                 else
-                   {
-                     double newSpeed = (maxAllowableDistance-mindist);
-                     current->setSpeedAdjustment(newSpeed);
-                   } 
-               }
-           }
-         else
-           { 
-             if (!(current->hasHeadingAdjustment())) 
-               {
-                 double newSpeed;
-                 if (mindist > 10) {
-                   //  newSpeed = 0.01;
-                   //  current->setSpeedAdjustment(newSpeed);
-                 } else {
-                   newSpeed = -1 * (maxAllowableDistance-mindist);
-                   current->setSpeedAdjustment(newSpeed);
-                   current->setHeadingAdjustment(heading);
-                 }
-               }
-           }
+          double maxAllowableDistance = (1.1*current->getRadius()) + (1.1*closest->getRadius());
+          if (mindist < 2*maxAllowableDistance)
+            {
+              if (current->getId() == closest->getWaitsForId())
+                return;
+              else 
+                current->setWaitsForId(closest->getId());
+              if (closest != current)
+                current->setSpeedAdjustment(closest->getSpeed()* (mindist/100));
+              else
+                current->setSpeedAdjustment(0); // This can only happen when the user aircraft is the one closest
+              if (mindist < maxAllowableDistance)
+                {
+                  //double newSpeed = (maxAllowableDistance-mindist);
+                  //current->setSpeedAdjustment(newSpeed);
+                  //if (mindist < 0.5* maxAllowableDistance)
+                  //  {
+                      current->setSpeedAdjustment(0);
+                      //  }
+                }
+            }
        }
     }
 }
@@ -850,10 +935,12 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
                                   i->getAltitude  ());
              //other.CourseAndDistance(curr, &course, &dist);
              bool needsToWait;
+             bool opposing;
              if (current->isOpposing(this, *i, node))
                {
                  needsToWait = true;
-                 //cerr << "Hold check 2 : " << id << "  has opposing segment " << endl;
+                 opposing    = true;
+                 //cerr << "Hold check 2 : " << node << "  has opposing segment " << endl;
                  // issue a "Hold Position" as soon as we're close to the offending node
                  // For now, I'm doing this as long as the other aircraft doesn't
                  // have a hold instruction as soon as we're within a reasonable 
@@ -864,8 +951,9 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
                } 
              else 
                {
+                 opposing = false;
                  other.CourseAndDistance(nodePos, &course, &dist);
-                 if (dist > 2.0*i->getRadius())
+                 if (dist > 200) // 2.0*i->getRadius())
                    {
                      needsToWait = false; 
                      //cerr << "Hold check 3 : " << id <<"  Other aircraft approaching node is still far away. (" << dist << " nm). Can safely continue " 
@@ -874,21 +962,32 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
                  else 
                    {
                      needsToWait = true;
-                     //cerr << "Hold check 4: " << id << "  Would need to wait for other aircraft : distance = " << dist << " nm" << endl;
+                     //cerr << "Hold check 4: " << id << "  Would need to wait for other aircraft : distance = " << dist << " meters" << endl;
                    }
                }
              curr.CourseAndDistance(nodePos, &course, &dist);
              if (!(i->hasHoldPosition()))
                {
                  
-                 if ((dist < 2.5*current->getRadius()) && 
-                     (needsToWait) && 
-                     (!(current->getId() == i->getWaitsForId())) &&
-                     (!(current->getSpeedAdjustment())))
+                 if ((dist < 200) && //2.5*current->getRadius()) && 
+                     (needsToWait) &&
+                     (i->onRoute(this, *current)) &&
+                     //((i->onRoute(this, *current)) || ((!(i->getSpeedAdjustment())))) &&
+                     (!(current->getId() == i->getWaitsForId())))
+                     //(!(i->getSpeedAdjustment()))) // &&
+                     //(!(current->getSpeedAdjustment())))
                    
                    {
                      current->setHoldPosition(true);
-                     //cerr << "Hold check 5: " << id <<"  Setting Hold Position: distance to node : " << dist << " nm"<< endl;
+                     //cerr << "Hold check 5: " << current->getCallSign() <<"  Setting Hold Position: distance to node ("  << node << ") "
+                     //           << dist << " meters. Waiting for " << i->getCallSign();
+                     //if (opposing)
+                     //cerr <<" [opposing] " << endl;
+                     //else
+                     //        cerr << "[non-opposing] " << endl;
+                     //if (i->hasSpeefAdjustment())
+                     //        {
+                     //          cerr << " (which in turn waits for ) " << i->
                    }
                  else
                    {
index b3dd99b9c1751b5f1d2c14d31a7e6588a0e9c993..e90d338883563580cc5c93eb663bffdf537328d2 100644 (file)
@@ -25,6 +25,7 @@
 #define _GROUNDNETWORK_HXX_
 
 #include <simgear/compiler.h>
+#include <simgear/route/waypoint.hxx>
 
 
 #include STL_STRING
@@ -33,7 +34,6 @@
 SG_USING_STD(string);
 SG_USING_STD(vector);
 
-
 #include "parking.hxx"
 #include "trafficcontrol.hxx"
 
@@ -41,6 +41,7 @@ SG_USING_STD(vector);
 
 class FGTaxiSegment; // forward reference
 class FGAIFlightPlan; // forward reference
+class FGAirport;      // forward reference
 
 typedef vector<FGTaxiSegment*>  FGTaxiSegmentVector;
 typedef vector<FGTaxiSegment*>::iterator FGTaxiSegmentVectorIterator;
@@ -78,6 +79,8 @@ public:
   FGTaxiSegmentVectorIterator getBeginRoute() { return next.begin(); };
   FGTaxiSegmentVectorIterator getEndRoute()   { return next.end();   }; 
   bool operator<(const FGTaxiNode &other) const { return index < other.index; };
+
+  void sortEndSegments(bool);
 };
 
 typedef vector<FGTaxiNode*> FGTaxiNodeVector;
@@ -92,11 +95,16 @@ private:
   int startNode;
   int endNode;
   double length;
+  double course;
+  double headingDiff;
+  bool isActive;
   FGTaxiNode *start;
   FGTaxiNode *end;
   int index;
   FGTaxiSegment *oppositeDirection;
 
+
 public:
   FGTaxiSegment();
   //FGTaxiSegment(FGTaxiNode *, FGTaxiNode *, int);
@@ -119,15 +127,22 @@ public:
  FGTaxiSegment *getAddress() { return this;};
 
   bool operator<(const FGTaxiSegment &other) const { return index < other.index; };
+  bool hasSmallerHeadingDiff (const FGTaxiSegment &other) const { return headingDiff < other.headingDiff; };
   FGTaxiSegment *opposite() { return oppositeDirection; };
+  void setCourseDiff(double crse);
+
 
   
 };
 
 
+
+
 typedef vector<int> intVec;
 typedef vector<int>::iterator intVecIterator;
 
+
+
 /***************************************************************************************
  * class FGTaxiRoute
  **************************************************************************************/
@@ -137,16 +152,18 @@ private:
   intVec nodes;
   intVec routes;
   double distance;
+  int depth;
   intVecIterator currNode;
   intVecIterator currRoute;
 
 public:
   FGTaxiRoute() { distance = 0; currNode = nodes.begin(); currRoute = routes.begin();};
-  FGTaxiRoute(intVec nds, intVec rts, double dist) { 
+  FGTaxiRoute(intVec nds, intVec rts, double dist, int dpth) { 
     nodes = nds; 
     routes = rts;
     distance = dist; 
     currNode = nodes.begin();
+    depth = dpth;
   };
   bool operator< (const FGTaxiRoute &other) const {return distance < other.distance; };
   bool empty () { return nodes.begin() == nodes.end(); };
@@ -156,12 +173,14 @@ public:
   
   void first() { currNode = nodes.begin(); currRoute = routes.begin(); };
   int size() { return nodes.size(); };
+  int getDepth() { return depth; };
 };
 
 typedef vector<FGTaxiRoute> TaxiRouteVector;
 typedef vector<FGTaxiRoute>::iterator TaxiRouteVectorIterator;
 
-
+bool sortByHeadingDiff(FGTaxiSegment *a, FGTaxiSegment *b);
+bool sortByLength     (FGTaxiSegment *a, FGTaxiSegment *b);
 
 
 /**************************************************************************************
@@ -171,6 +190,8 @@ class FGGroundNetwork : public FGATCController
 {
 private:
   bool hasNetwork;
+  int maxDepth;
+  int count;
   FGTaxiNodeVector    nodes;
   FGTaxiSegmentVector segments;
   //intVec route;
@@ -179,10 +200,13 @@ private:
   TaxiRouteVector routes;
   TrafficVector activeTraffic;
   TrafficVectorIterator currTraffic;
+  SGWayPoint destination;
   
   bool foundRoute;
   double totalDistance, maxDistance;
   FGTowerController *towerController;
+  FGAirport *parent;
+  
 
   void printRoutingError(string);
 
@@ -208,8 +232,11 @@ public:
   FGTaxiRoute findShortestRoute(int start, int end);
   void trace(FGTaxiNode *, int, int, double dist);
 
+  void setParent(FGAirport *par) { parent = par; };
+
   virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute, 
-                               double lat, double lon, double hdg, double spd, double alt, double radius, int leg);
+                               double lat, double lon, double hdg, double spd, double alt, 
+                               double radius, int leg, string callsign);
   virtual void signOff(int id);
   virtual void update(int id, double lat, double lon, double heading, double speed, double alt, double dt);
   virtual bool hasInstruction(int id);
index 60e7f0710456fcbf78baf1e029b396e81e0ae3e5..90767d728a2407d5256b09b62a18ff323035efb8 100644 (file)
@@ -255,12 +255,12 @@ void RunwayGroup::setActive(const string &aptId,
                  //cerr << "Crosswnd : " << crossWind << endl;
                  if ((tailWind > maxTail) || (crossWind > maxCross))
                    {
-                     //cerr << "Invalid : ";
+                     //cerr << "Invalid : " << endl;
                      validSelection = false;
                   }
                  else 
                    {
-                     //cerr << "Valid   : ";
+                     //cerr << "Valid   : " << endl;;
                  }
                }else {
                SG_LOG( SG_GENERAL, SG_INFO, "Failed to find runway " << name << " at " << aptId );
@@ -269,18 +269,18 @@ void RunwayGroup::setActive(const string &aptId,
            }
          if (validSelection) 
            {
-             //cerr << "Valid   : ";
+             //cerr << "Valid selection  : " << i << endl;;
              foundValidSelection = true;
              for (stringVecIterator it = currentlyActive->begin(); 
                   it != currentlyActive->end(); it++)
                {
                  if ((*it) == name)
                    match++;
-                 if (match >= bestMatch) {
-                   bestMatch = match;
-                   bestChoice = i;
-                 }
                }
+             if (match >= bestMatch) {
+               bestMatch = match;
+               bestChoice = i;
+             }
            } 
          //cerr << "Preference " << i << " bestMatch " << bestMatch << " choice " << bestChoice << endl;
        }
index cf969de1ff60232eed7357c1699a3f4d005e02b0..7813d38d22e36745d9811a002c02d4e0559724de 100644 (file)
@@ -108,7 +108,9 @@ FGAirportDynamics * FGAirport::getDynamics()
         if (parkpath.exists()) {
             try {
                 readXML(parkpath.str(),*dynamics);
+               //cerr << "Initializing " << getId() << endl;
                 dynamics->init();
+               dynamics->getGroundNetwork()->setParent(this);
             } catch (const sg_exception &e) {
                 //cerr << "unable to read " << parkpath.str() << endl;
             }
index 1fd721a830d8ba5a699425a1f6be2cc5381bd114..aaa971d38db132d86b2095a4a190e424c5cfbb90 100644 (file)
@@ -54,11 +54,11 @@ void FGTrafficRecord::setPositionAndIntentions(int pos, FGAIFlightPlan *route)
      //cerr << "setting intentions ";
      for (int i = 0; i < size; i++) {
        int val = route->getRouteIndex(i);
-   
+       //cerr << val<< " ";
        if ((val) && (val != pos))
        {
          intentions.push_back(val); 
-         //cerr << val<< " ";
+         //cerr << "[set] ";
        }
      }
      //cerr << endl;
@@ -76,7 +76,7 @@ bool FGTrafficRecord::checkPositionAndIntentions(FGTrafficRecord &other)
    //cerr << "Start check 1" << endl;
    if (currentPos == other.currentPos) 
      {
-       //cerr << "Check Position and intentions: current matches" << endl;
+       //cerr << callsign << ": Check Position and intentions: we are on the same taxiway" << other.callsign << "Index = " << currentPos << endl;
        result = true;
      }
   //  else if (other.intentions.size()) 
@@ -100,7 +100,7 @@ bool FGTrafficRecord::checkPositionAndIntentions(FGTrafficRecord &other)
        i++;
      }
      if (i != intentions.end()) {
-       //cerr << "Check Position and intentions: .other.current matches" << endl;
+       //cerr << callsign << ": Check Position and intentions: .other.current matches" << other.callsign << "Index = " << (*i) << endl;
        result = true;
      }
    }
@@ -178,6 +178,45 @@ int FGTrafficRecord::crosses(FGGroundNetwork *net, FGTrafficRecord &other)
   return -1;
 }
 
+bool FGTrafficRecord::onRoute(FGGroundNetwork *net, FGTrafficRecord &other)
+{
+  int node = -1, othernode = -1;
+  if (currentPos >0)
+    node = net->findSegment(currentPos)->getEnd()->getIndex();
+  if (other.currentPos > 0)
+    othernode = net->findSegment(other.currentPos)->getEnd()->getIndex();
+  if ((node == othernode) && (node != -1))
+    return true;
+  if (other.intentions.size())
+    {
+      for (intVecIterator i = other.intentions.begin(); i != other.intentions.end(); i++)
+       {
+         if (*i > 0) 
+           {
+             othernode = net->findSegment(*i)->getEnd()->getIndex();
+             if ((node == othernode) && (node > -1))
+               return true;
+           }
+       }
+    }
+  //if (other.currentPos > 0)
+  //  othernode = net->findSegment(other.currentPos)->getEnd()->getIndex();
+  //if (intentions.size())
+  //  {
+  //    for (intVecIterator i = intentions.begin(); i != intentions.end(); i++)
+  //   {
+  //     if (*i > 0) 
+  //       {
+  //         node = net->findSegment(*i)->getEnd()->getIndex();
+  //         if ((node == othernode) && (node > -1))
+  //           return true;
+  //       }
+  //   }
+  //  }
+  return false;
+}
+
+
 bool FGTrafficRecord::isOpposing (FGGroundNetwork *net, FGTrafficRecord &other, int node)
 {
    // Check if current segment is the reverse segment for the other aircraft
@@ -193,6 +232,19 @@ bool FGTrafficRecord::isOpposing (FGGroundNetwork *net, FGTrafficRecord &other,
       
        for (intVecIterator i = intentions.begin(); i != intentions.end(); i++)
        {
+         if (opp = net->findSegment(other.currentPos)->opposite())
+           {
+             if ((*i) > 0)
+               if (opp->getIndex() == net->findSegment(*i)->getIndex())
+                 {
+                   if (net->findSegment(*i)->getStart()->getIndex() == node) {
+                     {
+                       //cerr << "Found the node " << node << endl;
+                       return true;
+                     }
+                   }
+                 }
+           }
          if (other.intentions.size())
            {
              for (intVecIterator j = other.intentions.begin(); j != other.intentions.end(); j++)
@@ -204,12 +256,12 @@ bool FGTrafficRecord::isOpposing (FGGroundNetwork *net, FGTrafficRecord &other,
                        if (opp->getIndex() == 
                            net->findSegment(*j)->getIndex())
                          {
-//                         cerr << "Nodes " << net->findSegment(*i)->getIndex()
-//                              << " and  " << net->findSegment(*j)->getIndex()
-//                              << " are opposites " << endl;
+                           //cerr << "Nodes " << net->findSegment(*i)->getIndex()
+                           //   << " and  " << net->findSegment(*j)->getIndex()
+                           //   << " are opposites " << endl;
                            if (net->findSegment(*i)->getStart()->getIndex() == node) {
                              {
-                               //cerr << "Found the node" << endl;
+                               //cerr << "Found the node " << node << endl;
                                return true;
                              }
                            }
@@ -273,7 +325,8 @@ FGTowerController::FGTowerController() :
 // 
 void FGTowerController::announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentPosition,
                                         double lat, double lon, double heading, 
-                                        double speed, double alt, double radius, int leg)
+                                        double speed, double alt, double radius, int leg,
+                                        string callsign)
 {
   TrafficVectorIterator i = activeTraffic.begin();
   // Search whether the current id alread has an entry
@@ -295,6 +348,7 @@ void FGTowerController::announcePosition(int id, FGAIFlightPlan *intendedRoute,
     rec.setPositionAndHeading(lat, lon, heading, speed, alt);
     rec.setRunway(intendedRoute->getRunway());
     rec.setLeg(leg);
+    rec.setCallSign(callsign);
     activeTraffic.push_back(rec);
   } else {
     i->setPositionAndHeading(lat, lon, heading, speed, alt);
index e0329a569d71d5c4b8ac46d85d9121bea67f1126..edf67e574820a97763eb9a6d581be84215180647 100644 (file)
@@ -101,7 +101,8 @@ public:
   virtual ~FGATCController() {};
   virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
                                double lat, double lon,
-                               double hdg, double spd, double alt, double radius, int leg) = 0;
+                               double hdg, double spd, double alt, double radius, int leg,
+                               string callsign) = 0;
   virtual void             signOff(int id) = 0;
   virtual void             update(int id, double lat, double lon, 
                                  double heading, double speed, double alt, double dt) = 0;
@@ -126,6 +127,7 @@ private:
   FGATCInstruction instruction;
   double latitude, longitude, heading, speed, altitude, radius;
   string runway;
+  string callsign;
   
   
 public:
@@ -144,6 +146,8 @@ public:
   int  crosses                   (FGGroundNetwork *, FGTrafficRecord &other); 
   bool isOpposing                (FGGroundNetwork *, FGTrafficRecord &other, int node);
 
+  bool onRoute(FGGroundNetwork *, FGTrafficRecord &other);
+
   bool getSpeedAdjustment() { return instruction.getChangeSpeed(); };
   
   double getLatitude () { return latitude ; };
@@ -167,6 +171,8 @@ public:
   void setWaitsForId(int id) { waitsForId = id; };
 
   string getRunway() { return runway; };
+  void setCallSign(string clsgn) { callsign = clsgn; };
+  string getCallSign() { return callsign; };
 
 };
 
@@ -206,7 +212,8 @@ public:
   virtual ~FGTowerController() {};
   virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
                                double lat, double lon,
-                               double hdg, double spd, double alt, double radius, int leg);
+                               double hdg, double spd, double alt, double radius, int leg,
+                               string callsign);
   virtual void             signOff(int id);
   virtual void             update(int id, double lat, double lon, 
                                  double heading, double speed, double alt, double dt);
index 43cce5f746a7f1cf5a9dfaf745f191e6e0c6f107..e265372366193683cb6d549d5b70fcfbebab9624 100644 (file)
@@ -77,6 +77,7 @@ SG_USING_STD(sort);
 FGTrafficManager::FGTrafficManager()
 {
   score = 0;
+  runCount = 0;
 }
 
 FGTrafficManager:: ~FGTrafficManager()
@@ -121,6 +122,11 @@ void FGTrafficManager::init()
 
 void FGTrafficManager::update(double something)
 {
+  if (runCount < 1000)
+    {
+      runCount++;
+      return;
+    }
   time_t now = time(NULL) + fgGetLong("/sim/time/warp");
   if (scheduledAircraft.size() == 0)
     return;
index 20b1d0fddb7984350ba63ec751558d944b8f3f6e..4a46fcbeb7a68d9baccc65c68420c99dd5c0e62a 100644 (file)
@@ -49,7 +49,7 @@ private:
     port, timeString, departurePort, departureTime, arrivalPort, arrivalTime,
     repeat, acType, airline, m_class, flighttype;
   int cruiseAlt;
-  int score;
+  int score, runCount;
   double radius, offset;
   bool heavy;