-
- TrafficVectorIterator current;
- TrafficVectorIterator i = activeTraffic.begin();
- if (activeTraffic.size())
- {
- //while ((i->getId() != id) && i != activeTraffic.end())
- while (i != activeTraffic.end()) {
- if (i->getId() == id) {
- break;
- }
- i++;
- }
- }
- else
- {
- return ;
- }
- if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
- SG_LOG(SG_GENERAL, SG_ALERT, "AI error: Trying to access non-existing aircraft in FGGroundNetwork::checkHoldPosition");
- }
- current = i;
- current->setHoldPosition(false);
- SGGeod curr(SGGeod::fromDegM(lon, lat, alt));
-
- for (i = activeTraffic.begin();
- i != activeTraffic.end(); i++)
- {
- if (i->getId() != current->getId())
- {
- int node = current->crosses(this, *i);
- if (node != -1)
- {
- FGTaxiNode* taxiNode = findNode(node);
-
- // Determine whether it's save to continue or not.
- // If we have a crossing route, there are two possibilities:
- // 1) This is an interestion
- // 2) This is oncoming two-way traffic, using the same taxiway.
- //cerr << "Hold check 1 : " << id << " has common node " << node << endl;
-
- SGGeod other(SGGeod::fromDegM(i->getLongitude(), i->getLatitude(), i->getAltitude()));
- bool needsToWait;
- bool opposing;
- if (current->isOpposing(this, *i, node))
- {
- needsToWait = true;
- 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
- // distance from the offending node.
- // This may be a bit of a conservative estimate though, as it may
- // be well possible that both aircraft can both continue to taxi
- // without crashing into each other.
- }
- else
- {
- opposing = false;
- if (SGGeodesy::distanceM(other, taxiNode->getGeod()) > 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 "
- // << endl;
- }
- else
- {
- needsToWait = true;
- //cerr << "Hold check 4: " << id << " Would need to wait for other aircraft : distance = " << dist << " meters" << endl;
- }
- }
-
- double dist = SGGeodesy::distanceM(curr, taxiNode->getGeod());
- if (!(i->hasHoldPosition()))
- {
-
- 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);
- current->setWaitsForId(i->getId());
- //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
- {
- //cerr << "Hold check 6: " << id << " No need to hold yet: Distance to node : " << dist << " nm"<< endl;
- }
- }
- }
- }
+ TrafficVectorIterator current;
+ TrafficVectorIterator i = activeTraffic.begin();
+ if (activeTraffic.size()) {
+ //while ((i->getId() != id) && i != activeTraffic.end())
+ while (i != activeTraffic.end()) {
+ if (i->getId() == id) {
+ break;
+ }
+ i++;
+ }
+ } else {
+ return;
+ }
+ if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
+ SG_LOG(SG_GENERAL, SG_ALERT,
+ "AI error: Trying to access non-existing aircraft in FGGroundNetwork::checkHoldPosition");
+ }
+ current = i;
+ bool origStatus = current->hasHoldPosition();
+ current->setHoldPosition(false);
+ SGGeod curr(SGGeod::fromDegM(lon, lat, alt));
+
+ for (i = activeTraffic.begin(); i != activeTraffic.end(); i++) {
+ if (i->getId() != current->getId()) {
+ int node = current->crosses(this, *i);
+ if (node != -1) {
+ FGTaxiNode *taxiNode = findNode(node);
+
+ // Determine whether it's save to continue or not.
+ // If we have a crossing route, there are two possibilities:
+ // 1) This is an interestion
+ // 2) This is oncoming two-way traffic, using the same taxiway.
+ //cerr << "Hold check 1 : " << id << " has common node " << node << endl;
+
+ SGGeod other(SGGeod::
+ fromDegM(i->getLongitude(), i->getLatitude(),
+ i->getAltitude()));
+ bool needsToWait;
+ bool opposing;
+ if (current->isOpposing(this, *i, node)) {
+ needsToWait = true;
+ 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
+ // distance from the offending node.
+ // This may be a bit of a conservative estimate though, as it may
+ // be well possible that both aircraft can both continue to taxi
+ // without crashing into each other.
+ } else {
+ opposing = false;
+ if (SGGeodesy::distanceM(other, taxiNode->getGeod()) > 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 "
+ // << endl;
+ } else {
+ needsToWait = true;
+ //cerr << "Hold check 4: " << id << " Would need to wait for other aircraft : distance = " << dist << " meters" << endl;
+ }
+ }
+
+ double dist =
+ SGGeodesy::distanceM(curr, taxiNode->getGeod());
+ if (!(i->hasHoldPosition())) {
+
+ 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);
+ current->setWaitsForId(i->getId());
+ //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 {
+ //cerr << "Hold check 6: " << id << " No need to hold yet: Distance to node : " << dist << " nm"<< endl;
+ }
+ }
+ }
+ }
+ }
+ bool currStatus = current->hasHoldPosition();
+
+ // Either a Hold Position or a resume taxi transmission has been issued
+ time_t now = time(NULL) + fgGetLong("/sim/time/warp");
+ if ((now - lastTransmission) > 2) {
+ available = true;
+ }
+ if ((origStatus != currStatus) && available) {
+ //cerr << "Issueing hold short instrudtion " << currStatus << " " << available << endl;
+ if (currStatus == true) { // No has a hold short instruction
+ transmit(&(*current), MSG_HOLD_POSITION, ATC_GROUND_TO_AIR);
+ //cerr << "Transmittin hold short instrudtion " << currStatus << " " << available << endl;
+ current->setState(1);
+ } else {
+ transmit(&(*current), MSG_RESUME_TAXI, ATC_GROUND_TO_AIR);
+ //cerr << "Transmittig resume instrudtion " << currStatus << " " << available << endl;
+ current->setState(2);
+ }
+ lastTransmission = now;
+ available = false;
+ // Don't act on the changed instruction until the transmission is confirmed
+ // So set back to original status
+ current->setHoldPosition(origStatus);
+ //cerr << "Current state " << current->getState() << endl;
+ } else {
+ }
+ int state = current->getState();
+ if ((state == 1) && (available)) {
+ //cerr << "ACKNOWLEDGE HOLD" << endl;
+ transmit(&(*current), MSG_ACKNOWLEDGE_HOLD_POSITION, ATC_AIR_TO_GROUND);
+ current->setState(0);
+ current->setHoldPosition(true);
+ lastTransmission = now;
+ available = false;
+
+ }
+ if ((state == 2) && (available)) {
+ //cerr << "ACKNOWLEDGE RESUME" << endl;
+ transmit(&(*current), MSG_ACKNOWLEDGE_RESUME_TAXI, ATC_AIR_TO_GROUND);
+ current->setState(0);
+ current->setHoldPosition(false);
+ lastTransmission = now;
+ available = false;