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
This commit is contained in:
parent
bb7c889bbb
commit
33037b2139
11 changed files with 329 additions and 122 deletions
|
@ -1034,19 +1034,20 @@ void FGAIAircraft::announcePositionToController()
|
||||||
callsign += "Heavy";
|
callsign += "Heavy";
|
||||||
switch (leg) {
|
switch (leg) {
|
||||||
case 3:
|
case 3:
|
||||||
cerr << callsign << " ready to taxi to runway " << fp->getRunway() << endl;
|
//cerr << callsign << " ready to taxi to runway " << fp->getRunway() << endl;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
cerr << callsign << " at runway " << fp->getRunway() << "Ready for take-off. "
|
//cerr << callsign << " at runway " << fp->getRunway() << "Ready for take-off. "
|
||||||
<< trafficRef->getFlightRules() << " to " << trafficRef->getArrivalAirport()->getId()
|
// << trafficRef->getFlightRules() << " to " << trafficRef->getArrivalAirport()->getId()
|
||||||
<< "(" << trafficRef->getArrivalAirport()->getName() << ")."<< endl;
|
// << "(" << trafficRef->getArrivalAirport()->getName() << ")."<< endl;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prevController = controller;
|
prevController = controller;
|
||||||
if (controller) {
|
if (controller) {
|
||||||
controller->announcePosition(getID(), fp, fp->getCurrentWaypoint()->routeIndex,
|
controller->announcePosition(getID(), fp, fp->getCurrentWaypoint()->routeIndex,
|
||||||
_getLatitude(), _getLongitude(), hdg, speed, altitude_ft,
|
_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
|
// Hold Position
|
||||||
if (instruction.getHoldPosition ()) {
|
if (instruction.getHoldPosition ()) {
|
||||||
if (!holdPos) {
|
if (!holdPos) {
|
||||||
if (trafficRef)
|
//if (trafficRef)
|
||||||
cerr << trafficRef->getCallSign() << "Holding Position " << endl;
|
//cerr << trafficRef->getCallSign() << "Holding Position " << endl;
|
||||||
holdPos = true;
|
holdPos = true;
|
||||||
}
|
}
|
||||||
AccelTo(0.25);
|
AccelTo(0.0);
|
||||||
} else {
|
} else {
|
||||||
if (holdPos) {
|
if (holdPos) {
|
||||||
if (trafficRef)
|
//if (trafficRef)
|
||||||
cerr << trafficRef->getCallSign() << " Resuming Taxi " << endl;
|
// cerr << trafficRef->getCallSign() << " Resuming Taxi " << endl;
|
||||||
holdPos = false;
|
holdPos = false;
|
||||||
}
|
}
|
||||||
// Change speed Instruction. This can only be excecuted when there is no
|
// Change speed Instruction. This can only be excecuted when there is no
|
||||||
// Hold position instruction.
|
// Hold position instruction.
|
||||||
if (instruction.getChangeSpeed ()) {
|
if (instruction.getChangeSpeed ()) {
|
||||||
|
// if (trafficRef)
|
||||||
|
//cerr << trafficRef->getCallSign() << " Changing Speed " << endl;
|
||||||
AccelTo(instruction.getSpeed());
|
AccelTo(instruction.getSpeed());
|
||||||
}else {
|
}else {
|
||||||
if (fp) AccelTo(fp->getPreviousWaypoint()->speed);
|
if (fp) AccelTo(fp->getPreviousWaypoint()->speed);
|
||||||
|
|
|
@ -115,11 +115,12 @@ void FGAIFlightPlan::createPushBack(bool firstFlight, FGAirport *dep,
|
||||||
radius, fltType,
|
radius, fltType,
|
||||||
aircraftType, airline)))
|
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 <<
|
aircraftType <<
|
||||||
" of flight type " << fltType <<
|
" of flight type " << fltType <<
|
||||||
" of airline " << airline <<
|
" of airline " << airline <<
|
||||||
" at airport " << dep->getId());
|
" at airport " << dep->getId());
|
||||||
|
//exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -161,11 +161,19 @@ bool FGAirportDynamics::getAvailableParking(double *lat, double *lon, double *he
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else // Airline code doesn't match
|
else // Airline code doesn't match
|
||||||
|
{
|
||||||
|
//cerr << "Code = " << airline << ": Codes " << i->getCodes();
|
||||||
if (i->getCodes().find(airline, 0) == string::npos)
|
if (i->getCodes().find(airline, 0) == string::npos)
|
||||||
{
|
{
|
||||||
available = false;
|
available = false;
|
||||||
|
//cerr << "Unavailable" << endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//cerr << "Available" << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Type doesn't match
|
// Type doesn't match
|
||||||
if (i->getType() != flType)
|
if (i->getType() != flType)
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
//#include <Main/fg_props.hxx>
|
//#include <Main/fg_props.hxx>
|
||||||
//#include <Airports/runways.hxx>
|
//#include <Airports/runways.hxx>
|
||||||
|
|
||||||
|
|
||||||
#include <AIModel/AIFlightPlan.hxx>
|
#include <AIModel/AIFlightPlan.hxx>
|
||||||
|
|
||||||
//#include STL_STRING
|
//#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) {
|
bool compare_nodes(FGTaxiNode *a, FGTaxiNode *b) {
|
||||||
return (*a) < (*b);
|
return (*a) < (*b);
|
||||||
|
@ -69,6 +78,7 @@ return (*a) < (*b);
|
||||||
FGTaxiSegment::FGTaxiSegment()
|
FGTaxiSegment::FGTaxiSegment()
|
||||||
{
|
{
|
||||||
oppositeDirection = 0;
|
oppositeDirection = 0;
|
||||||
|
isActive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGTaxiSegment::setStart(FGTaxiNodeVector *nodes)
|
void FGTaxiSegment::setStart(FGTaxiNodeVector *nodes)
|
||||||
|
@ -100,11 +110,13 @@ void FGTaxiSegment::setEnd(FGTaxiNodeVector *nodes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// There is probably a computationally cheaper way of
|
// There is probably a computationally cheaper way of
|
||||||
// doing this.
|
// doing this.
|
||||||
void FGTaxiSegment::setTrackDistance()
|
void FGTaxiSegment::setTrackDistance()
|
||||||
{
|
{
|
||||||
double course;
|
//double course;
|
||||||
SGWayPoint first (start->getLongitude(),
|
SGWayPoint first (start->getLongitude(),
|
||||||
start->getLatitude(),
|
start->getLatitude(),
|
||||||
0);
|
0);
|
||||||
|
@ -114,10 +126,26 @@ void FGTaxiSegment::setTrackDistance()
|
||||||
first.CourseAndDistance(second, &course, &length);
|
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) {
|
bool compare_segments(FGTaxiSegment *a, FGTaxiSegment *b) {
|
||||||
return (*a) < (*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
|
* FGTaxiRoute
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
@ -204,6 +232,8 @@ FGGroundNetwork::FGGroundNetwork()
|
||||||
foundRoute = false;
|
foundRoute = false;
|
||||||
totalDistance = 0;
|
totalDistance = 0;
|
||||||
maxDistance = 0;
|
maxDistance = 0;
|
||||||
|
maxDepth = 1000;
|
||||||
|
count = 0;
|
||||||
currTraffic = activeTraffic.begin();
|
currTraffic = activeTraffic.begin();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -271,6 +301,7 @@ void FGGroundNetwork::init()
|
||||||
i++;
|
i++;
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
i = segments.begin();
|
i = segments.begin();
|
||||||
while(i != segments.end()) {
|
while(i != segments.end()) {
|
||||||
FGTaxiSegmentVectorIterator j = (*i)->getEnd()->getBeginRoute();
|
FGTaxiSegmentVectorIterator j = (*i)->getEnd()->getBeginRoute();
|
||||||
|
@ -283,17 +314,21 @@ void FGGroundNetwork::init()
|
||||||
int start2 = (*j)->getStart()->getIndex();
|
int start2 = (*j)->getStart()->getIndex();
|
||||||
int end2 = (*j)->getEnd()->getIndex();
|
int end2 = (*j)->getEnd()->getIndex();
|
||||||
int oppIndex = (*j)->getIndex();
|
int oppIndex = (*j)->getIndex();
|
||||||
// cerr << "Opposite of " << (*i)->getIndex() << " (" << start1 << "," << end1 << ") "
|
//cerr << "Opposite of " << (*i)->getIndex() << " (" << start1 << "," << end1 << ") "
|
||||||
// << "happens to be " << oppIndex << " (" << start2 << "," << end2 << ") " << endl;
|
// << "happens to be " << oppIndex << " (" << start2 << "," << end2 << ") " << endl;
|
||||||
|
(*i)->setOpposite(*j);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
//cerr << "Done initializing ground network" << endl;
|
||||||
//exit(1);
|
//exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int FGGroundNetwork::findNearestNode(double lat, double lon)
|
int FGGroundNetwork::findNearestNode(double lat, double lon)
|
||||||
{
|
{
|
||||||
double minDist = HUGE_VAL;
|
double minDist = HUGE_VAL;
|
||||||
|
@ -359,6 +394,8 @@ FGTaxiSegment *FGGroundNetwork::findSegment(int idx)
|
||||||
|
|
||||||
FGTaxiRoute FGGroundNetwork::findShortestRoute(int start, int end)
|
FGTaxiRoute FGGroundNetwork::findShortestRoute(int start, int end)
|
||||||
{
|
{
|
||||||
|
double course;
|
||||||
|
double length;
|
||||||
foundRoute = false;
|
foundRoute = false;
|
||||||
totalDistance = 0;
|
totalDistance = 0;
|
||||||
FGTaxiNode *firstNode = findNode(start);
|
FGTaxiNode *firstNode = findNode(start);
|
||||||
|
@ -368,14 +405,41 @@ FGTaxiRoute FGGroundNetwork::findShortestRoute(int start, int end)
|
||||||
routes.clear();
|
routes.clear();
|
||||||
nodesStack.clear();
|
nodesStack.clear();
|
||||||
routesStack.clear();
|
routesStack.clear();
|
||||||
//cerr << "Begin of Trace " << endl;
|
// 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);
|
trace(firstNode, end, 0, 0);
|
||||||
|
// maxDepth--;
|
||||||
|
// }
|
||||||
|
//while ((routes.size() != 0) && (maxDepth > 0));
|
||||||
//cerr << "End of Trace" << endl;
|
//cerr << "End of Trace" << endl;
|
||||||
FGTaxiRoute empty;
|
FGTaxiRoute empty;
|
||||||
|
|
||||||
if (!foundRoute)
|
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);
|
exit(1);
|
||||||
}
|
}
|
||||||
sort(routes.begin(), routes.end());
|
sort(routes.begin(), routes.end());
|
||||||
|
@ -385,7 +449,19 @@ FGTaxiRoute FGGroundNetwork::findShortestRoute(int start, int end)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if (routes.begin() != routes.end())
|
if (routes.begin() != routes.end())
|
||||||
|
{
|
||||||
|
// 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());
|
return *(routes.begin());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return empty;
|
return empty;
|
||||||
}
|
}
|
||||||
|
@ -401,23 +477,25 @@ void FGGroundNetwork::trace(FGTaxiNode *currNode, int end, int depth, double dis
|
||||||
}
|
}
|
||||||
nodesStack.push_back(currNode->getIndex());
|
nodesStack.push_back(currNode->getIndex());
|
||||||
totalDistance += distance;
|
totalDistance += distance;
|
||||||
//cerr << "Starting trace " << depth << " total distance: " << totalDistance<< " "
|
//cerr << "Starting trace " << currNode->getIndex() << " " << "total distance: " << totalDistance << endl;
|
||||||
// << currNode->getIndex() << endl;
|
// << currNode->getIndex() << endl;
|
||||||
|
|
||||||
// If the current route matches the required end point we found a valid route
|
// If the current route matches the required end point we found a valid route
|
||||||
// So we can add this to the routing table
|
// So we can add this to the routing table
|
||||||
if (currNode->getIndex() == end)
|
if (currNode->getIndex() == end)
|
||||||
{
|
{
|
||||||
//cerr << "Found route : " << totalDistance << "" << " " << *(nodesStack.end()-1) << endl;
|
maxDepth = depth;
|
||||||
routes.push_back(FGTaxiRoute(nodesStack,routesStack,totalDistance));
|
//cerr << "Found route : " << totalDistance << "" << " " << *(nodesStack.end()-1) << " Depth = " << depth << endl;
|
||||||
|
routes.push_back(FGTaxiRoute(nodesStack,routesStack,totalDistance, depth));
|
||||||
if (nodesStack.empty() || routesStack.empty())
|
if (nodesStack.empty() || routesStack.empty())
|
||||||
{
|
{
|
||||||
printRoutingError(string("while finishing route"));
|
printRoutingError(string("while finishing route"));
|
||||||
}
|
}
|
||||||
nodesStack.pop_back();
|
nodesStack.pop_back();
|
||||||
routesStack.pop_back();
|
routesStack.pop_back();
|
||||||
if (!(foundRoute))
|
if (!(foundRoute)) {
|
||||||
maxDistance = totalDistance;
|
maxDistance = totalDistance;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
if (totalDistance < maxDistance)
|
if (totalDistance < maxDistance)
|
||||||
maxDistance = totalDistance;
|
maxDistance = totalDistance;
|
||||||
|
@ -451,10 +529,22 @@ void FGGroundNetwork::trace(FGTaxiNode *currNode, int end, int depth, double dis
|
||||||
totalDistance -= distance;
|
totalDistance -= distance;
|
||||||
return;
|
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
|
// If the total distance from start to the current waypoint
|
||||||
// is longer than that of a route we can also stop this trace
|
// is longer than that of a route we can also stop this trace
|
||||||
// and go back one level.
|
// and go back one level.
|
||||||
if ((totalDistance > maxDistance) && foundRoute)
|
if ((totalDistance > maxDistance) && foundRoute)
|
||||||
|
//if (foundRoute)
|
||||||
{
|
{
|
||||||
//cerr << "Stopping rediculously long trace: " << totalDistance << endl;
|
//cerr << "Stopping rediculously long trace: " << totalDistance << endl;
|
||||||
if (nodesStack.empty() || routesStack.empty())
|
if (nodesStack.empty() || routesStack.empty())
|
||||||
|
@ -471,7 +561,36 @@ void FGGroundNetwork::trace(FGTaxiNode *currNode, int end, int depth, double dis
|
||||||
//cerr << "2" << endl;
|
//cerr << "2" << endl;
|
||||||
if (currNode->getBeginRoute() != currNode->getEndRoute())
|
if (currNode->getBeginRoute() != currNode->getEndRoute())
|
||||||
{
|
{
|
||||||
|
double course, length;
|
||||||
//cerr << "3" << endl;
|
//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
|
for (FGTaxiSegmentVectorIterator
|
||||||
i = currNode->getBeginRoute();
|
i = currNode->getBeginRoute();
|
||||||
i != currNode->getEndRoute();
|
i != currNode->getEndRoute();
|
||||||
|
@ -529,7 +648,8 @@ void FGGroundNetwork::printRoutingError(string mess)
|
||||||
|
|
||||||
void FGGroundNetwork::announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentPosition,
|
void FGGroundNetwork::announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentPosition,
|
||||||
double lat, double lon, double heading,
|
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();
|
TrafficVectorIterator i = activeTraffic.begin();
|
||||||
// Search search if the current id alread has an entry
|
// 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.setPositionAndIntentions(currentPosition, intendedRoute);
|
||||||
rec.setPositionAndHeading(lat, lon, heading, speed, alt);
|
rec.setPositionAndHeading(lat, lon, heading, speed, alt);
|
||||||
rec.setRadius(radius); // only need to do this when creating the record.
|
rec.setRadius(radius); // only need to do this when creating the record.
|
||||||
|
rec.setCallSign(callsign);
|
||||||
activeTraffic.push_back(rec);
|
activeTraffic.push_back(rec);
|
||||||
} else {
|
} else {
|
||||||
i->setPositionAndIntentions(currentPosition, intendedRoute);
|
i->setPositionAndIntentions(currentPosition, intendedRoute);
|
||||||
|
@ -625,6 +746,7 @@ void FGGroundNetwork::checkSpeedAdjustment(int id, double lat,
|
||||||
TrafficVectorIterator current, closest;
|
TrafficVectorIterator current, closest;
|
||||||
TrafficVectorIterator i = activeTraffic.begin();
|
TrafficVectorIterator i = activeTraffic.begin();
|
||||||
bool otherReasonToSlowDown = false;
|
bool otherReasonToSlowDown = false;
|
||||||
|
bool previousInstruction;
|
||||||
if (activeTraffic.size())
|
if (activeTraffic.size())
|
||||||
{
|
{
|
||||||
//while ((i->getId() != id) && (i != activeTraffic.end()))
|
//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");
|
SG_LOG(SG_GENERAL, SG_ALERT, "AI error: Trying to access non-existing aircraft in FGGroundNetwork::checkSpeedAdjustment");
|
||||||
}
|
}
|
||||||
current = i;
|
current = i;
|
||||||
|
previousInstruction = current->getSpeedAdjustment();
|
||||||
double mindist = HUGE;
|
double mindist = HUGE;
|
||||||
if (activeTraffic.size())
|
if (activeTraffic.size())
|
||||||
{
|
{
|
||||||
|
@ -726,66 +849,28 @@ void FGGroundNetwork::checkSpeedAdjustment(int id, double lat,
|
||||||
//cerr << "Distance : " << dist << " bearing : " << bearing << " heading : " << heading
|
//cerr << "Distance : " << dist << " bearing : " << bearing << " heading : " << heading
|
||||||
// << " course : " << course << endl;
|
// << " course : " << course << endl;
|
||||||
current->clearSpeedAdjustment();
|
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)
|
||||||
|
{
|
||||||
|
double maxAllowableDistance = (1.1*current->getRadius()) + (1.1*closest->getRadius());
|
||||||
|
if (mindist < 2*maxAllowableDistance)
|
||||||
|
{
|
||||||
if (current->getId() == closest->getWaitsForId())
|
if (current->getId() == closest->getWaitsForId())
|
||||||
return;
|
return;
|
||||||
else
|
else
|
||||||
current->setWaitsForId(closest->getId());
|
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)
|
if (closest != current)
|
||||||
current->setSpeedAdjustment(closest->getSpeed()* (mindist/100));
|
current->setSpeedAdjustment(closest->getSpeed()* (mindist/100));
|
||||||
else
|
else
|
||||||
current->setSpeedAdjustment(0); // This can only happen when the user aircraft is the one closest
|
current->setSpeedAdjustment(0); // This can only happen when the user aircraft is the one closest
|
||||||
//cerr << "Adjusting speed to " << closest->getSpeed() * (mindist / 100) << " "
|
if (mindist < maxAllowableDistance)
|
||||||
// << "Bearing = " << minbearing << " Distance = " << mindist
|
|
||||||
// << " Latitude = " <<lat << " longitude = " << lon << endl;
|
|
||||||
//<< " Latitude = " <<closest->getLatitude()
|
|
||||||
//<< " longitude = " << closest->getLongitude()
|
|
||||||
// << endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
double newSpeed = (maxAllowableDistance-mindist);
|
//double newSpeed = (maxAllowableDistance-mindist);
|
||||||
current->setSpeedAdjustment(newSpeed);
|
//current->setSpeedAdjustment(newSpeed);
|
||||||
}
|
//if (mindist < 0.5* maxAllowableDistance)
|
||||||
}
|
// {
|
||||||
}
|
current->setSpeedAdjustment(0);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -850,10 +935,12 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
|
||||||
i->getAltitude ());
|
i->getAltitude ());
|
||||||
//other.CourseAndDistance(curr, &course, &dist);
|
//other.CourseAndDistance(curr, &course, &dist);
|
||||||
bool needsToWait;
|
bool needsToWait;
|
||||||
|
bool opposing;
|
||||||
if (current->isOpposing(this, *i, node))
|
if (current->isOpposing(this, *i, node))
|
||||||
{
|
{
|
||||||
needsToWait = true;
|
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
|
// 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
|
// 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
|
// have a hold instruction as soon as we're within a reasonable
|
||||||
|
@ -864,8 +951,9 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
opposing = false;
|
||||||
other.CourseAndDistance(nodePos, &course, &dist);
|
other.CourseAndDistance(nodePos, &course, &dist);
|
||||||
if (dist > 2.0*i->getRadius())
|
if (dist > 200) // 2.0*i->getRadius())
|
||||||
{
|
{
|
||||||
needsToWait = false;
|
needsToWait = false;
|
||||||
//cerr << "Hold check 3 : " << id <<" Other aircraft approaching node is still far away. (" << dist << " nm). Can safely continue "
|
//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
|
else
|
||||||
{
|
{
|
||||||
needsToWait = true;
|
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);
|
curr.CourseAndDistance(nodePos, &course, &dist);
|
||||||
if (!(i->hasHoldPosition()))
|
if (!(i->hasHoldPosition()))
|
||||||
{
|
{
|
||||||
|
|
||||||
if ((dist < 2.5*current->getRadius()) &&
|
if ((dist < 200) && //2.5*current->getRadius()) &&
|
||||||
(needsToWait) &&
|
(needsToWait) &&
|
||||||
(!(current->getId() == i->getWaitsForId())) &&
|
(i->onRoute(this, *current)) &&
|
||||||
(!(current->getSpeedAdjustment())))
|
//((i->onRoute(this, *current)) || ((!(i->getSpeedAdjustment())))) &&
|
||||||
|
(!(current->getId() == i->getWaitsForId())))
|
||||||
|
//(!(i->getSpeedAdjustment()))) // &&
|
||||||
|
//(!(current->getSpeedAdjustment())))
|
||||||
|
|
||||||
{
|
{
|
||||||
current->setHoldPosition(true);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#define _GROUNDNETWORK_HXX_
|
#define _GROUNDNETWORK_HXX_
|
||||||
|
|
||||||
#include <simgear/compiler.h>
|
#include <simgear/compiler.h>
|
||||||
|
#include <simgear/route/waypoint.hxx>
|
||||||
|
|
||||||
|
|
||||||
#include STL_STRING
|
#include STL_STRING
|
||||||
|
@ -33,7 +34,6 @@
|
||||||
SG_USING_STD(string);
|
SG_USING_STD(string);
|
||||||
SG_USING_STD(vector);
|
SG_USING_STD(vector);
|
||||||
|
|
||||||
|
|
||||||
#include "parking.hxx"
|
#include "parking.hxx"
|
||||||
#include "trafficcontrol.hxx"
|
#include "trafficcontrol.hxx"
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ SG_USING_STD(vector);
|
||||||
|
|
||||||
class FGTaxiSegment; // forward reference
|
class FGTaxiSegment; // forward reference
|
||||||
class FGAIFlightPlan; // forward reference
|
class FGAIFlightPlan; // forward reference
|
||||||
|
class FGAirport; // forward reference
|
||||||
|
|
||||||
typedef vector<FGTaxiSegment*> FGTaxiSegmentVector;
|
typedef vector<FGTaxiSegment*> FGTaxiSegmentVector;
|
||||||
typedef vector<FGTaxiSegment*>::iterator FGTaxiSegmentVectorIterator;
|
typedef vector<FGTaxiSegment*>::iterator FGTaxiSegmentVectorIterator;
|
||||||
|
@ -78,6 +79,8 @@ public:
|
||||||
FGTaxiSegmentVectorIterator getBeginRoute() { return next.begin(); };
|
FGTaxiSegmentVectorIterator getBeginRoute() { return next.begin(); };
|
||||||
FGTaxiSegmentVectorIterator getEndRoute() { return next.end(); };
|
FGTaxiSegmentVectorIterator getEndRoute() { return next.end(); };
|
||||||
bool operator<(const FGTaxiNode &other) const { return index < other.index; };
|
bool operator<(const FGTaxiNode &other) const { return index < other.index; };
|
||||||
|
|
||||||
|
void sortEndSegments(bool);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef vector<FGTaxiNode*> FGTaxiNodeVector;
|
typedef vector<FGTaxiNode*> FGTaxiNodeVector;
|
||||||
|
@ -92,11 +95,16 @@ private:
|
||||||
int startNode;
|
int startNode;
|
||||||
int endNode;
|
int endNode;
|
||||||
double length;
|
double length;
|
||||||
|
double course;
|
||||||
|
double headingDiff;
|
||||||
|
bool isActive;
|
||||||
FGTaxiNode *start;
|
FGTaxiNode *start;
|
||||||
FGTaxiNode *end;
|
FGTaxiNode *end;
|
||||||
int index;
|
int index;
|
||||||
FGTaxiSegment *oppositeDirection;
|
FGTaxiSegment *oppositeDirection;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FGTaxiSegment();
|
FGTaxiSegment();
|
||||||
//FGTaxiSegment(FGTaxiNode *, FGTaxiNode *, int);
|
//FGTaxiSegment(FGTaxiNode *, FGTaxiNode *, int);
|
||||||
|
@ -119,15 +127,22 @@ public:
|
||||||
FGTaxiSegment *getAddress() { return this;};
|
FGTaxiSegment *getAddress() { return this;};
|
||||||
|
|
||||||
bool operator<(const FGTaxiSegment &other) const { return index < other.index; };
|
bool operator<(const FGTaxiSegment &other) const { return index < other.index; };
|
||||||
|
bool hasSmallerHeadingDiff (const FGTaxiSegment &other) const { return headingDiff < other.headingDiff; };
|
||||||
FGTaxiSegment *opposite() { return oppositeDirection; };
|
FGTaxiSegment *opposite() { return oppositeDirection; };
|
||||||
|
void setCourseDiff(double crse);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef vector<int> intVec;
|
typedef vector<int> intVec;
|
||||||
typedef vector<int>::iterator intVecIterator;
|
typedef vector<int>::iterator intVecIterator;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************************
|
/***************************************************************************************
|
||||||
* class FGTaxiRoute
|
* class FGTaxiRoute
|
||||||
**************************************************************************************/
|
**************************************************************************************/
|
||||||
|
@ -137,16 +152,18 @@ private:
|
||||||
intVec nodes;
|
intVec nodes;
|
||||||
intVec routes;
|
intVec routes;
|
||||||
double distance;
|
double distance;
|
||||||
|
int depth;
|
||||||
intVecIterator currNode;
|
intVecIterator currNode;
|
||||||
intVecIterator currRoute;
|
intVecIterator currRoute;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FGTaxiRoute() { distance = 0; currNode = nodes.begin(); currRoute = routes.begin();};
|
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;
|
nodes = nds;
|
||||||
routes = rts;
|
routes = rts;
|
||||||
distance = dist;
|
distance = dist;
|
||||||
currNode = nodes.begin();
|
currNode = nodes.begin();
|
||||||
|
depth = dpth;
|
||||||
};
|
};
|
||||||
bool operator< (const FGTaxiRoute &other) const {return distance < other.distance; };
|
bool operator< (const FGTaxiRoute &other) const {return distance < other.distance; };
|
||||||
bool empty () { return nodes.begin() == nodes.end(); };
|
bool empty () { return nodes.begin() == nodes.end(); };
|
||||||
|
@ -156,12 +173,14 @@ public:
|
||||||
|
|
||||||
void first() { currNode = nodes.begin(); currRoute = routes.begin(); };
|
void first() { currNode = nodes.begin(); currRoute = routes.begin(); };
|
||||||
int size() { return nodes.size(); };
|
int size() { return nodes.size(); };
|
||||||
|
int getDepth() { return depth; };
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef vector<FGTaxiRoute> TaxiRouteVector;
|
typedef vector<FGTaxiRoute> TaxiRouteVector;
|
||||||
typedef vector<FGTaxiRoute>::iterator TaxiRouteVectorIterator;
|
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:
|
private:
|
||||||
bool hasNetwork;
|
bool hasNetwork;
|
||||||
|
int maxDepth;
|
||||||
|
int count;
|
||||||
FGTaxiNodeVector nodes;
|
FGTaxiNodeVector nodes;
|
||||||
FGTaxiSegmentVector segments;
|
FGTaxiSegmentVector segments;
|
||||||
//intVec route;
|
//intVec route;
|
||||||
|
@ -179,10 +200,13 @@ private:
|
||||||
TaxiRouteVector routes;
|
TaxiRouteVector routes;
|
||||||
TrafficVector activeTraffic;
|
TrafficVector activeTraffic;
|
||||||
TrafficVectorIterator currTraffic;
|
TrafficVectorIterator currTraffic;
|
||||||
|
SGWayPoint destination;
|
||||||
|
|
||||||
bool foundRoute;
|
bool foundRoute;
|
||||||
double totalDistance, maxDistance;
|
double totalDistance, maxDistance;
|
||||||
FGTowerController *towerController;
|
FGTowerController *towerController;
|
||||||
|
FGAirport *parent;
|
||||||
|
|
||||||
|
|
||||||
void printRoutingError(string);
|
void printRoutingError(string);
|
||||||
|
|
||||||
|
@ -208,8 +232,11 @@ public:
|
||||||
FGTaxiRoute findShortestRoute(int start, int end);
|
FGTaxiRoute findShortestRoute(int start, int end);
|
||||||
void trace(FGTaxiNode *, int, int, double dist);
|
void trace(FGTaxiNode *, int, int, double dist);
|
||||||
|
|
||||||
|
void setParent(FGAirport *par) { parent = par; };
|
||||||
|
|
||||||
virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
|
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 signOff(int id);
|
||||||
virtual void update(int id, double lat, double lon, double heading, double speed, double alt, double dt);
|
virtual void update(int id, double lat, double lon, double heading, double speed, double alt, double dt);
|
||||||
virtual bool hasInstruction(int id);
|
virtual bool hasInstruction(int id);
|
||||||
|
|
|
@ -255,12 +255,12 @@ void RunwayGroup::setActive(const string &aptId,
|
||||||
//cerr << "Crosswnd : " << crossWind << endl;
|
//cerr << "Crosswnd : " << crossWind << endl;
|
||||||
if ((tailWind > maxTail) || (crossWind > maxCross))
|
if ((tailWind > maxTail) || (crossWind > maxCross))
|
||||||
{
|
{
|
||||||
//cerr << "Invalid : ";
|
//cerr << "Invalid : " << endl;
|
||||||
validSelection = false;
|
validSelection = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//cerr << "Valid : ";
|
//cerr << "Valid : " << endl;;
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
SG_LOG( SG_GENERAL, SG_INFO, "Failed to find runway " << name << " at " << aptId );
|
SG_LOG( SG_GENERAL, SG_INFO, "Failed to find runway " << name << " at " << aptId );
|
||||||
|
@ -269,19 +269,19 @@ void RunwayGroup::setActive(const string &aptId,
|
||||||
}
|
}
|
||||||
if (validSelection)
|
if (validSelection)
|
||||||
{
|
{
|
||||||
//cerr << "Valid : ";
|
//cerr << "Valid selection : " << i << endl;;
|
||||||
foundValidSelection = true;
|
foundValidSelection = true;
|
||||||
for (stringVecIterator it = currentlyActive->begin();
|
for (stringVecIterator it = currentlyActive->begin();
|
||||||
it != currentlyActive->end(); it++)
|
it != currentlyActive->end(); it++)
|
||||||
{
|
{
|
||||||
if ((*it) == name)
|
if ((*it) == name)
|
||||||
match++;
|
match++;
|
||||||
|
}
|
||||||
if (match >= bestMatch) {
|
if (match >= bestMatch) {
|
||||||
bestMatch = match;
|
bestMatch = match;
|
||||||
bestChoice = i;
|
bestChoice = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
//cerr << "Preference " << i << " bestMatch " << bestMatch << " choice " << bestChoice << endl;
|
//cerr << "Preference " << i << " bestMatch " << bestMatch << " choice " << bestChoice << endl;
|
||||||
}
|
}
|
||||||
if (foundValidSelection)
|
if (foundValidSelection)
|
||||||
|
|
|
@ -108,7 +108,9 @@ FGAirportDynamics * FGAirport::getDynamics()
|
||||||
if (parkpath.exists()) {
|
if (parkpath.exists()) {
|
||||||
try {
|
try {
|
||||||
readXML(parkpath.str(),*dynamics);
|
readXML(parkpath.str(),*dynamics);
|
||||||
|
//cerr << "Initializing " << getId() << endl;
|
||||||
dynamics->init();
|
dynamics->init();
|
||||||
|
dynamics->getGroundNetwork()->setParent(this);
|
||||||
} catch (const sg_exception &e) {
|
} catch (const sg_exception &e) {
|
||||||
//cerr << "unable to read " << parkpath.str() << endl;
|
//cerr << "unable to read " << parkpath.str() << endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,11 +54,11 @@ void FGTrafficRecord::setPositionAndIntentions(int pos, FGAIFlightPlan *route)
|
||||||
//cerr << "setting intentions ";
|
//cerr << "setting intentions ";
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
int val = route->getRouteIndex(i);
|
int val = route->getRouteIndex(i);
|
||||||
|
//cerr << val<< " ";
|
||||||
if ((val) && (val != pos))
|
if ((val) && (val != pos))
|
||||||
{
|
{
|
||||||
intentions.push_back(val);
|
intentions.push_back(val);
|
||||||
//cerr << val<< " ";
|
//cerr << "[set] ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//cerr << endl;
|
//cerr << endl;
|
||||||
|
@ -76,7 +76,7 @@ bool FGTrafficRecord::checkPositionAndIntentions(FGTrafficRecord &other)
|
||||||
//cerr << "Start check 1" << endl;
|
//cerr << "Start check 1" << endl;
|
||||||
if (currentPos == other.currentPos)
|
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;
|
result = true;
|
||||||
}
|
}
|
||||||
// else if (other.intentions.size())
|
// else if (other.intentions.size())
|
||||||
|
@ -100,7 +100,7 @@ bool FGTrafficRecord::checkPositionAndIntentions(FGTrafficRecord &other)
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (i != intentions.end()) {
|
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;
|
result = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,6 +178,45 @@ int FGTrafficRecord::crosses(FGGroundNetwork *net, FGTrafficRecord &other)
|
||||||
return -1;
|
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)
|
bool FGTrafficRecord::isOpposing (FGGroundNetwork *net, FGTrafficRecord &other, int node)
|
||||||
{
|
{
|
||||||
// Check if current segment is the reverse segment for the other aircraft
|
// 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++)
|
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())
|
if (other.intentions.size())
|
||||||
{
|
{
|
||||||
for (intVecIterator j = other.intentions.begin(); j != other.intentions.end(); j++)
|
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() ==
|
if (opp->getIndex() ==
|
||||||
net->findSegment(*j)->getIndex())
|
net->findSegment(*j)->getIndex())
|
||||||
{
|
{
|
||||||
// cerr << "Nodes " << net->findSegment(*i)->getIndex()
|
//cerr << "Nodes " << net->findSegment(*i)->getIndex()
|
||||||
// << " and " << net->findSegment(*j)->getIndex()
|
// << " and " << net->findSegment(*j)->getIndex()
|
||||||
// << " are opposites " << endl;
|
// << " are opposites " << endl;
|
||||||
if (net->findSegment(*i)->getStart()->getIndex() == node) {
|
if (net->findSegment(*i)->getStart()->getIndex() == node) {
|
||||||
{
|
{
|
||||||
//cerr << "Found the node" << endl;
|
//cerr << "Found the node " << node << endl;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,7 +325,8 @@ FGTowerController::FGTowerController() :
|
||||||
//
|
//
|
||||||
void FGTowerController::announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentPosition,
|
void FGTowerController::announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentPosition,
|
||||||
double lat, double lon, double heading,
|
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();
|
TrafficVectorIterator i = activeTraffic.begin();
|
||||||
// Search whether the current id alread has an entry
|
// 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.setPositionAndHeading(lat, lon, heading, speed, alt);
|
||||||
rec.setRunway(intendedRoute->getRunway());
|
rec.setRunway(intendedRoute->getRunway());
|
||||||
rec.setLeg(leg);
|
rec.setLeg(leg);
|
||||||
|
rec.setCallSign(callsign);
|
||||||
activeTraffic.push_back(rec);
|
activeTraffic.push_back(rec);
|
||||||
} else {
|
} else {
|
||||||
i->setPositionAndHeading(lat, lon, heading, speed, alt);
|
i->setPositionAndHeading(lat, lon, heading, speed, alt);
|
||||||
|
|
|
@ -101,7 +101,8 @@ public:
|
||||||
virtual ~FGATCController() {};
|
virtual ~FGATCController() {};
|
||||||
virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
|
virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
|
||||||
double lat, double lon,
|
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 signOff(int id) = 0;
|
||||||
virtual void update(int id, double lat, double lon,
|
virtual void update(int id, double lat, double lon,
|
||||||
double heading, double speed, double alt, double dt) = 0;
|
double heading, double speed, double alt, double dt) = 0;
|
||||||
|
@ -126,6 +127,7 @@ private:
|
||||||
FGATCInstruction instruction;
|
FGATCInstruction instruction;
|
||||||
double latitude, longitude, heading, speed, altitude, radius;
|
double latitude, longitude, heading, speed, altitude, radius;
|
||||||
string runway;
|
string runway;
|
||||||
|
string callsign;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -144,6 +146,8 @@ public:
|
||||||
int crosses (FGGroundNetwork *, FGTrafficRecord &other);
|
int crosses (FGGroundNetwork *, FGTrafficRecord &other);
|
||||||
bool isOpposing (FGGroundNetwork *, FGTrafficRecord &other, int node);
|
bool isOpposing (FGGroundNetwork *, FGTrafficRecord &other, int node);
|
||||||
|
|
||||||
|
bool onRoute(FGGroundNetwork *, FGTrafficRecord &other);
|
||||||
|
|
||||||
bool getSpeedAdjustment() { return instruction.getChangeSpeed(); };
|
bool getSpeedAdjustment() { return instruction.getChangeSpeed(); };
|
||||||
|
|
||||||
double getLatitude () { return latitude ; };
|
double getLatitude () { return latitude ; };
|
||||||
|
@ -167,6 +171,8 @@ public:
|
||||||
void setWaitsForId(int id) { waitsForId = id; };
|
void setWaitsForId(int id) { waitsForId = id; };
|
||||||
|
|
||||||
string getRunway() { return runway; };
|
string getRunway() { return runway; };
|
||||||
|
void setCallSign(string clsgn) { callsign = clsgn; };
|
||||||
|
string getCallSign() { return callsign; };
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -206,7 +212,8 @@ public:
|
||||||
virtual ~FGTowerController() {};
|
virtual ~FGTowerController() {};
|
||||||
virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
|
virtual void announcePosition(int id, FGAIFlightPlan *intendedRoute, int currentRoute,
|
||||||
double lat, double lon,
|
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 signOff(int id);
|
||||||
virtual void update(int id, double lat, double lon,
|
virtual void update(int id, double lat, double lon,
|
||||||
double heading, double speed, double alt, double dt);
|
double heading, double speed, double alt, double dt);
|
||||||
|
|
|
@ -77,6 +77,7 @@ SG_USING_STD(sort);
|
||||||
FGTrafficManager::FGTrafficManager()
|
FGTrafficManager::FGTrafficManager()
|
||||||
{
|
{
|
||||||
score = 0;
|
score = 0;
|
||||||
|
runCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FGTrafficManager:: ~FGTrafficManager()
|
FGTrafficManager:: ~FGTrafficManager()
|
||||||
|
@ -121,6 +122,11 @@ void FGTrafficManager::init()
|
||||||
|
|
||||||
void FGTrafficManager::update(double something)
|
void FGTrafficManager::update(double something)
|
||||||
{
|
{
|
||||||
|
if (runCount < 1000)
|
||||||
|
{
|
||||||
|
runCount++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
time_t now = time(NULL) + fgGetLong("/sim/time/warp");
|
time_t now = time(NULL) + fgGetLong("/sim/time/warp");
|
||||||
if (scheduledAircraft.size() == 0)
|
if (scheduledAircraft.size() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -49,7 +49,7 @@ private:
|
||||||
port, timeString, departurePort, departureTime, arrivalPort, arrivalTime,
|
port, timeString, departurePort, departureTime, arrivalPort, arrivalTime,
|
||||||
repeat, acType, airline, m_class, flighttype;
|
repeat, acType, airline, m_class, flighttype;
|
||||||
int cruiseAlt;
|
int cruiseAlt;
|
||||||
int score;
|
int score, runCount;
|
||||||
double radius, offset;
|
double radius, offset;
|
||||||
bool heavy;
|
bool heavy;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue