From 33037b21394792559332b18d1451ae21a44d090a Mon Sep 17 00:00:00 2001 From: durk Date: Sat, 11 Nov 2006 10:52:05 +0000 Subject: [PATCH] AI Update: - 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 | 23 +-- src/AIModel/AIFlightPlanCreate.cxx | 3 +- src/Airports/dynamics.cxx | 18 +- src/Airports/groundnetwork.cxx | 265 ++++++++++++++++++++--------- src/Airports/groundnetwork.hxx | 35 +++- src/Airports/runwayprefs.cxx | 14 +- src/Airports/simple.cxx | 2 + src/Airports/trafficcontrol.cxx | 72 +++++++- src/Airports/trafficcontrol.hxx | 11 +- src/Traffic/TrafficMgr.cxx | 6 + src/Traffic/TrafficMgr.hxx | 2 +- 11 files changed, 329 insertions(+), 122 deletions(-) diff --git a/src/AIModel/AIAircraft.cxx b/src/AIModel/AIAircraft.cxx index 315bbdf6a..98d95fb5c 100644 --- a/src/AIModel/AIAircraft.cxx +++ b/src/AIModel/AIAircraft.cxx @@ -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); diff --git a/src/AIModel/AIFlightPlanCreate.cxx b/src/AIModel/AIFlightPlanCreate.cxx index ccb677bb8..01a43dcc6 100644 --- a/src/AIModel/AIFlightPlanCreate.cxx +++ b/src/AIModel/AIFlightPlanCreate.cxx @@ -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 diff --git a/src/Airports/dynamics.cxx b/src/Airports/dynamics.cxx index a95c63399..3f6185df2 100644 --- a/src/Airports/dynamics.cxx +++ b/src/Airports/dynamics.cxx @@ -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) { diff --git a/src/Airports/groundnetwork.cxx b/src/Airports/groundnetwork.cxx index 233372993..2d17d9487 100644 --- a/src/Airports/groundnetwork.cxx +++ b/src/Airports/groundnetwork.cxx @@ -41,6 +41,7 @@ //#include
//#include + #include //#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 = " < 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 { diff --git a/src/Airports/groundnetwork.hxx b/src/Airports/groundnetwork.hxx index b3dd99b9c..e90d33888 100644 --- a/src/Airports/groundnetwork.hxx +++ b/src/Airports/groundnetwork.hxx @@ -25,6 +25,7 @@ #define _GROUNDNETWORK_HXX_ #include +#include #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 FGTaxiSegmentVector; typedef vector::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 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 intVec; typedef vector::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 TaxiRouteVector; typedef vector::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); diff --git a/src/Airports/runwayprefs.cxx b/src/Airports/runwayprefs.cxx index 60e7f0710..90767d728 100644 --- a/src/Airports/runwayprefs.cxx +++ b/src/Airports/runwayprefs.cxx @@ -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; } diff --git a/src/Airports/simple.cxx b/src/Airports/simple.cxx index cf969de1f..7813d38d2 100644 --- a/src/Airports/simple.cxx +++ b/src/Airports/simple.cxx @@ -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; } diff --git a/src/Airports/trafficcontrol.cxx b/src/Airports/trafficcontrol.cxx index 1fd721a83..aaa971d38 100644 --- a/src/Airports/trafficcontrol.cxx +++ b/src/Airports/trafficcontrol.cxx @@ -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); diff --git a/src/Airports/trafficcontrol.hxx b/src/Airports/trafficcontrol.hxx index e0329a569..edf67e574 100644 --- a/src/Airports/trafficcontrol.hxx +++ b/src/Airports/trafficcontrol.hxx @@ -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); diff --git a/src/Traffic/TrafficMgr.cxx b/src/Traffic/TrafficMgr.cxx index 43cce5f74..e26537236 100644 --- a/src/Traffic/TrafficMgr.cxx +++ b/src/Traffic/TrafficMgr.cxx @@ -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; diff --git a/src/Traffic/TrafficMgr.hxx b/src/Traffic/TrafficMgr.hxx index 20b1d0fdd..4a46fcbeb 100644 --- a/src/Traffic/TrafficMgr.hxx +++ b/src/Traffic/TrafficMgr.hxx @@ -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; -- 2.39.5