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());
}
}
}
// 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);
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
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)
{
//#include <Main/fg_props.hxx>
//#include <Airports/runways.hxx>
+
#include <AIModel/AIFlightPlan.hxx>
//#include STL_STRING
{
}
+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);
FGTaxiSegment::FGTaxiSegment()
{
oppositeDirection = 0;
+ isActive = true;
}
void FGTaxiSegment::setStart(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);
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
**************************************************************************/
foundRoute = false;
totalDistance = 0;
maxDistance = 0;
+ maxDepth = 1000;
+ count = 0;
currTraffic = activeTraffic.begin();
}
i++;
index++;
}
+
i = segments.begin();
while(i != segments.end()) {
FGTaxiSegmentVectorIterator j = (*i)->getEnd()->getBeginRoute();
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;
FGTaxiRoute FGGroundNetwork::findShortestRoute(int start, int end)
{
+ double course;
+ double length;
foundRoute = false;
totalDistance = 0;
FGTaxiNode *firstNode = findNode(start);
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());
// }
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;
}
}
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;
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())
//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();
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
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);
TrafficVectorIterator current, closest;
TrafficVectorIterator i = activeTraffic.begin();
bool otherReasonToSlowDown = false;
+ bool previousInstruction;
if (activeTraffic.size())
{
//while ((i->getId() != id) && (i != activeTraffic.end()))
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())
{
//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);
+ // }
+ }
+ }
}
}
}
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
}
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 "
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
{
#define _GROUNDNETWORK_HXX_
#include <simgear/compiler.h>
+#include <simgear/route/waypoint.hxx>
#include STL_STRING
SG_USING_STD(string);
SG_USING_STD(vector);
-
#include "parking.hxx"
#include "trafficcontrol.hxx"
class FGTaxiSegment; // forward reference
class FGAIFlightPlan; // forward reference
+class FGAirport; // forward reference
typedef vector<FGTaxiSegment*> FGTaxiSegmentVector;
typedef vector<FGTaxiSegment*>::iterator FGTaxiSegmentVectorIterator;
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;
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);
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
**************************************************************************************/
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(); };
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);
/**************************************************************************************
{
private:
bool hasNetwork;
+ int maxDepth;
+ int count;
FGTaxiNodeVector nodes;
FGTaxiSegmentVector segments;
//intVec route;
TaxiRouteVector routes;
TrafficVector activeTraffic;
TrafficVectorIterator currTraffic;
+ SGWayPoint destination;
bool foundRoute;
double totalDistance, maxDistance;
FGTowerController *towerController;
+ FGAirport *parent;
+
void printRoutingError(string);
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);
//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 );
}
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;
}
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;
}
//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;
//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())
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;
}
}
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
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++)
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;
}
}
//
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
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);
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;
FGATCInstruction instruction;
double latitude, longitude, heading, speed, altitude, radius;
string runway;
+ string callsign;
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 ; };
void setWaitsForId(int id) { waitsForId = id; };
string getRunway() { return runway; };
+ void setCallSign(string clsgn) { callsign = clsgn; };
+ string getCallSign() { return callsign; };
};
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);
FGTrafficManager::FGTrafficManager()
{
score = 0;
+ runCount = 0;
}
FGTrafficManager:: ~FGTrafficManager()
void FGTrafficManager::update(double something)
{
+ if (runCount < 1000)
+ {
+ runCount++;
+ return;
+ }
time_t now = time(NULL) + fgGetLong("/sim/time/warp");
if (scheduledAircraft.size() == 0)
return;
port, timeString, departurePort, departureTime, arrivalPort, arrivalTime,
repeat, acType, airline, m_class, flighttype;
int cruiseAlt;
- int score;
+ int score, runCount;
double radius, offset;
bool heavy;