return newEta;
}
+ void ActiveRunway::printDepartureCue()
+ {
+ cout << "Departure cue for " << rwy << ": " << endl;
+ for (AircraftVecIterator atc = departureCue.begin(); atc != departureCue.end(); atc++) {
+ cout << " " << (*atc)->getCallSign() << " " << (*atc)->getTakeOffStatus();
+ cout << " " << (*atc)->_getLatitude() << " " << (*atc)->_getLongitude() << (*atc)-> getSpeed() << " " << (*atc)->getAltitude() << endl;
+ }
+
+ }
+
+ FGAIAircraft* ActiveRunway::getFirstOfStatus(int stat)
+ {
+ for (AircraftVecIterator atc =departureCue.begin(); atc != departureCue.end(); atc++) {
+ if ((*atc)->getTakeOffStatus() == stat)
+ return (*atc);
+ }
+ return 0;
+ }
+
+
+
/***************************************************************************
* FGTrafficRecord
**************************************************************************/
intVecIterator i = intentions.begin();
if ((*i) != pos) {
SG_LOG(SG_GENERAL, SG_ALERT,
- "Error in FGTrafficRecord::setPositionAndIntentions");
- //cerr << "Pos : " << pos << " Curr " << *(intentions.begin()) << endl;
+ "Error in FGTrafficRecord::setPositionAndIntentions at " << SG_ORIGIN);
+ cerr << "Pos : " << pos << " Curr " << *(intentions.begin()) << endl;
for (intVecIterator i = intentions.begin();
i != intentions.end(); i++) {
- //cerr << (*i) << " ";
+ cerr << (*i) << " ";
}
- //cerr << endl;
+ cerr << endl;
}
intentions.erase(i);
} else {
return (ac->getCallSign() == fgGetString("/sim/multiplay/callsign")) ? true : false;
};
-void FGATCController::transmit(FGTrafficRecord * rec, AtcMsgId msgId,
+void FGATCController::transmit(FGTrafficRecord * rec, FGAirportDynamics *parent, AtcMsgId msgId,
AtcMsgDir msgDir, bool audible)
{
string sender, receiver;
FGAIFlightPlan *fp;
string fltRules;
string instructionText;
+ int ground_to_air=0;
//double commFreqD;
sender = rec->getAircraft()->getTrafficRef()->getCallSign();
string tmp = sender;
sender = receiver;
receiver = tmp;
+ ground_to_air=1;
}
switch (msgId) {
case MSG_ANNOUNCE_ENGINE_START:
// Display ATC message only when one of the radios is tuned
// the relevant frequency.
// Note that distance attenuation is currently not yet implemented
+
if ((onBoardRadioFreqI0 == stationFreq)
|| (onBoardRadioFreqI1 == stationFreq)) {
if (rec->allowTransmissions()) {
+
fgSetString("/sim/messages/atc", text.c_str());
}
}
}
}
+
string FGATCController::formatATCFrequency3_2(int freq)
{
char buffer[7];
// // update position of the current aircraft
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
SG_LOG(SG_GENERAL, SG_ALERT,
- "AI error: updating aircraft without traffic record");
+ "AI error: updating aircraft without traffic record at " << SG_ORIGIN);
} else {
i->setPositionAndHeading(lat, lon, heading, speed, alt);
current = i;
// see if we already have a clearance record for the currently active runway
// NOTE: dd. 2011-08-07: Because the active runway has been constructed in the announcePosition function, we may safely assume that is
// already exists here. So, we can simplify the current code.
+
ActiveRunwayVecIterator rwy = activeRunways.begin();
+ //if (parent->getId() == fgGetString("/sim/presets/airport-id")) {
+ // for (rwy = activeRunways.begin(); rwy != activeRunways.end(); rwy++) {
+ // rwy->printDepartureCue();
+ // }
+ //}
+
+ rwy = activeRunways.begin();
while (rwy != activeRunways.end()) {
if (rwy->getRunwayName() == current->getRunway()) {
break;
}
} */
// only bother with aircraft that have a takeoff status of 2, since those are essentially under tower control
+ FGAIAircraft* ac= rwy->getFirstAircraftInDepartureCue();
+ if (ac->getTakeOffStatus() == 1) {
+ ac->setTakeOffStatus(2);
+ }
if (current->getAircraft()->getTakeOffStatus() == 2) {
+ current -> setHoldPosition(false);
+ } else {
current->setHoldPosition(true);
- int clearanceId = rwy->getCleared();
- if (clearanceId) {
- if (id == clearanceId) {
- current->setHoldPosition(false);
- }
- } else {
- if (current->getAircraft() == rwy->getFirstAircraftInDepartureCue()) {
- rwy->setCleared(id);
- }
+ }
+ int clearanceId = rwy->getCleared();
+ if (clearanceId) {
+ if (id == clearanceId) {
+ current->setHoldPosition(false);
}
} else {
-
+ if (current->getAircraft() == rwy->getFirstAircraftInDepartureCue()) {
+ rwy->setCleared(id);
+ FGAIAircraft *ac = rwy->getFirstOfStatus(1);
+ if (ac)
+ ac->setTakeOffStatus(2);
+ }
}
- }
+ }
void FGTowerController::signOff(int id)
rwy->updateDepartureCue();
} else {
SG_LOG(SG_GENERAL, SG_ALERT,
- "AI error: Attempting to erase non-existing runway clearance record in FGTowerController::signoff");
+ "AI error: Attempting to erase non-existing runway clearance record in FGTowerController::signoff at " << SG_ORIGIN);
}
}
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
SG_LOG(SG_GENERAL, SG_ALERT,
- "AI error: Aircraft without traffic record is signing off from tower");
+ "AI error: Aircraft without traffic record is signing off from tower at " << SG_ORIGIN);
} else {
i->getAircraft()->resetTakeOffStatus();
i = activeTraffic.erase(i);
}
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
SG_LOG(SG_GENERAL, SG_ALERT,
- "AI error: checking ATC instruction for aircraft without traffic record");
+ "AI error: checking ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
} else {
return i->hasInstruction();
}
}
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
SG_LOG(SG_GENERAL, SG_ALERT,
- "AI error: requesting ATC instruction for aircraft without traffic record");
+ "AI error: requesting ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
} else {
return i->getInstruction();
}
}
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
SG_LOG(SG_GENERAL, SG_ALERT,
- "AI error: checking ATC instruction for aircraft without traffic record");
+ "AI error: checking ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
} else {
return i->hasInstruction();
}
}
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
SG_LOG(SG_GENERAL, SG_ALERT,
- "AI error: requesting ATC instruction for aircraft without traffic record");
+ "AI error: requesting ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
} else {
return i->getInstruction();
}
}
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
SG_LOG(SG_GENERAL, SG_ALERT,
- "AI error: Aircraft without traffic record is signing off from tower");
+ "AI error: Aircraft without traffic record is signing off from tower at " << SG_ORIGIN);
} else {
//cerr << i->getAircraft()->getCallSign() << " signing off from startupcontroller" << endl;
i = activeTraffic.erase(i);
FGATCDialogNew::instance()->removeEntry(1);
} else {
//cerr << "creading message for " << i->getAircraft()->getCallSign() << endl;
- transmit(&(*i), msgId, msgDir, false);
+ transmit(&(*i), &(*parent), msgId, msgDir, false);
return false;
}
}
if (now > startTime) {
//cerr << "Transmitting startup msg" << endl;
- transmit(&(*i), msgId, msgDir, true);
+ transmit(&(*i), &(*parent), msgId, msgDir, true);
i->updateState();
lastTransmission = now;
available = false;
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
SG_LOG(SG_GENERAL, SG_ALERT,
- "AI error: updating aircraft without traffic record");
+ "AI error: updating aircraft without traffic record at " << SG_ORIGIN);
} else {
i->setPositionAndHeading(lat, lon, heading, speed, alt);
current = i;
if (now > startTime + 200) {
if (i->pushBackAllowed()) {
i->allowRepeatedTransmissions();
- transmit(&(*i), MSG_PERMIT_PUSHBACK_CLEARANCE,
+ transmit(&(*i), &(*parent), MSG_PERMIT_PUSHBACK_CLEARANCE,
ATC_GROUND_TO_AIR, true);
i->updateState();
} else {
- transmit(&(*i), MSG_HOLD_PUSHBACK_CLEARANCE,
+ transmit(&(*i), &(*parent), MSG_HOLD_PUSHBACK_CLEARANCE,
ATC_GROUND_TO_AIR, true);
i->suppressRepeatedTransmissions();
}
//for ( FGTaxiSegmentVectorIterator i = segments.begin(); i != segments.end(); i++) {
double dx = 0;
+ time_t now = time(NULL) + fgGetLong("/sim/time/warp");
for (TrafficVectorIterator i = activeTraffic.begin(); i != activeTraffic.end(); i++) {
if (i->isActive(300)) {
// Handle start point
} else {
elevationStart = ((i)->getAircraft()->_getAltitude() * SG_FEET_TO_METER);
}
- double elevationEnd = segment->getEnd()->getElevation();
+ double elevationEnd = segment->getEnd()->getElevationM(parent->getElevation()*SG_FEET_TO_METER);
if ((elevationEnd == 0) || (elevationEnd == parent->getElevation())) {
SGGeod center2 = end;
center2.setElevationM(SG_MAX_ELEVATION_M);
geode->addDrawable(geometry);
//osg::Node *custom_obj;
SGMaterial *mat;
- if (segment->hasBlock()) {
+ if (segment->hasBlock(now)) {
mat = matlib->find("UnidirectionalTaperRed");
} else {
mat = matlib->find("UnidirectionalTaperGreen");
obj_trans->setDataVariance(osg::Object::STATIC);
FGTaxiSegment *segment = parent->getGroundNetwork()->findSegment(k);
- double elevationStart = segment->getStart()->getElevation();
- double elevationEnd = segment->getEnd ()->getElevation();
+ double elevationStart = segment->getStart()->getElevationM(parent->getElevation()*SG_FEET_TO_METER);
+ double elevationEnd = segment->getEnd ()->getElevationM(parent->getElevation()*SG_FEET_TO_METER);
if ((elevationStart == 0) || (elevationStart == parent->getElevation())) {
SGGeod center2 = segment->getStart()->getGeod();
center2.setElevationM(SG_MAX_ELEVATION_M);
geode->addDrawable(geometry);
//osg::Node *custom_obj;
SGMaterial *mat;
- if (segment->hasBlock()) {
+ if (segment->hasBlock(now)) {
mat = matlib->find("UnidirectionalTaperRed");
} else {
mat = matlib->find("UnidirectionalTaperGreen");
// // update position of the current aircraft
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
SG_LOG(SG_GENERAL, SG_ALERT,
- "AI error: updating aircraft without traffic record");
+ "AI error: updating aircraft without traffic record at " << SG_ORIGIN);
} else {
i->setPositionAndHeading(lat, lon, heading, speed, alt);
current = i;
}
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
SG_LOG(SG_GENERAL, SG_ALERT,
- "AI error: Aircraft without traffic record is signing off from approach");
+ "AI error: Aircraft without traffic record is signing off from approach at " << SG_ORIGIN);
} else {
i = activeTraffic.erase(i);
}
}
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
SG_LOG(SG_GENERAL, SG_ALERT,
- "AI error: checking ATC instruction for aircraft without traffic record");
+ "AI error: checking ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
} else {
return i->hasInstruction();
}
}
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
SG_LOG(SG_GENERAL, SG_ALERT,
- "AI error: requesting ATC instruction for aircraft without traffic record");
+ "AI error: requesting ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
} else {
return i->getInstruction();
}
#include <Airports/dynamics.hxx>
#include <AIModel/AIAircraft.hxx>
+ #include <AIModel/performancedata.hxx>
#include <AIModel/AIFlightPlan.hxx>
#include <ATC/atc_mgr.hxx>
#include "groundnetwork.hxx"
+
/***************************************************************************
* FGTaxiSegment
**************************************************************************/
// headingDiff = fabs(headingDiff - 360);
//}
+ void FGTaxiSegment::block(int id, time_t blockTime, time_t now)
+ {
+ BlockListIterator i = blockTimes.begin();
+ while (i != blockTimes.end()) {
+ if (i->getId() == id)
+ break;
+ i++;
+ }
+ if (i == blockTimes.end()) {
+ blockTimes.push_back(Block(id, blockTime, now));
+ sort(blockTimes.begin(), blockTimes.end());
+ } else {
+ i->updateTimeStamps(blockTime, now);
+ }
+ }
+
+ // The segment has a block if any of the block times listed in the block list is
+ // smaller than the current time.
+ bool FGTaxiSegment::hasBlock(time_t now)
+ {
+ for (BlockListIterator i = blockTimes.begin(); i != blockTimes.end(); i++) {
+ if (i->getBlockTime() < now)
+ return true;
+ }
+ return false;
+ }
+
+ void FGTaxiSegment::unblock(time_t now)
+ {
+ if (blockTimes.size()) {
+ BlockListIterator i = blockTimes.begin();
+ if (i->getTimeStamp() < (now - 30)) {
+ blockTimes.erase(i);
+ }
+ }
+ }
+
+
/***************************************************************************
* FGTaxiRoute
count = 0;
currTraffic = activeTraffic.begin();
group = 0;
+ version = 0;
networkInitialized = false;
}
node != nodes.end(); node++) {
if (saveData) {
cachefile << (*node)->getIndex () << " "
- << (*node)->getElevation () << " "
+ << (*node)->getElevationM (parent->getElevation()*SG_FEET_TO_METER) << " "
<< endl;
}
delete(*node);
node != nodes.end(); node++) {
if (saveData) {
cachefile << (*node)->getIndex () << " "
- << (*node)->getElevation () << " "
+ << (*node)->getElevationM (parent->getElevation()*SG_FEET_TO_METER) << " "
<< endl;
}
}
n.setIndex(i->getIndex());
n.setLatitude(i->getLatitude());
n.setLongitude(i->getLongitude());
- n.setElevation(parent->getElevation());
+ n.setElevation(parent->getElevation()*SG_FEET_TO_METER);
nodes.push_back(new FGTaxiNode(n));
i++;
return index;
}
+ int FGGroundNetwork::findNearestNodeOnRunway(const SGGeod & aGeod)
+ {
+ double minDist = HUGE_VAL;
+ int index = -1;
+
+ for (FGTaxiNodeVectorIterator itr = nodes.begin(); itr != nodes.end();
+ itr++) {
+ if (!((*itr)->getIsOnRunway())) {
+ continue;
+ }
+ double d = SGGeodesy::distanceM(aGeod, (*itr)->getGeod());
+ if (d < minDist) {
+ minDist = d;
+ index = (*itr)->getIndex();
+ //cerr << "Minimum distance of " << minDist << " for index " << index << endl;
+ }
+ }
+
+ return index;
+ }
+
+
int FGGroundNetwork::findNearestNode(double lat, double lon)
{
return findNearestNode(SGGeod::fromDeg(lon, lat));
rec.setPositionAndHeading(lat, lon, heading, speed, alt);
rec.setRadius(radius); // only need to do this when creating the record.
rec.setAircraft(aircraft);
- activeTraffic.push_front(rec);
+ if (leg == 2) {
+ activeTraffic.push_front(rec);
+ } else {
+ activeTraffic.push_back(rec);
+ }
} else {
i->setPositionAndIntentions(currentPosition, intendedRoute);
}
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
SG_LOG(SG_GENERAL, SG_ALERT,
- "AI error: Aircraft without traffic record is signing off");
+ "AI error: Aircraft without traffic record is signing off at " << SG_ORIGIN);
} else {
i = activeTraffic.erase(i);
}
trans_num->setIntValue(-1);
// PopupCallback(n);
//cerr << "Selected transmission message " << n << endl;
- FGATCManager *atc = (FGATCManager*) globals->get_subsystem("atc");
+ //FGATCManager *atc = (FGATCManager*) globals->get_subsystem("atc");
FGATCDialogNew::instance()->removeEntry(1);
} else {
//cerr << "creating message for " << i->getAircraft()->getCallSign() << endl;
- transmit(&(*i), msgId, msgDir, false);
+ transmit(&(*i), &(*parent->getDynamics()), msgId, msgDir, false);
return false;
}
}
- transmit(&(*i), msgId, msgDir, true);
+ transmit(&(*i), &(*parent->getDynamics()), msgId, msgDir, true);
i->updateState();
lastTransmission = now;
available = false;
// update position of the current aircraft
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
SG_LOG(SG_GENERAL, SG_ALERT,
- "AI error: updating aircraft without traffic record");
+ "AI error: updating aircraft without traffic record at " << SG_ORIGIN);
} else {
i->setPositionAndHeading(lat, lon, heading, speed, alt);
current = i;
}
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
SG_LOG(SG_GENERAL, SG_ALERT,
- "AI error: Trying to access non-existing aircraft in FGGroundNetwork::checkSpeedAdjustment");
+ "AI error: Trying to access non-existing aircraft in FGGroundNetwork::checkSpeedAdjustment at " << SG_ORIGIN);
}
current = i;
//closest = current;
SGGeod curr(SGGeod::fromDegM(lon, lat, alt));
//TrafficVector iterator closest;
closest = current;
+ closestOnNetwork = current;
for (TrafficVectorIterator i = activeTraffic.begin();
i != activeTraffic.end(); i++) {
if (i == current) {
current->setSpeedAdjustment(closest->getSpeed() *
(mindist / 100));
needBraking = true;
- if (
- closest->getAircraft()->getTakeOffStatus() &&
- (current->getAircraft()->getTrafficRef()->getDepartureAirport() == closest->getAircraft()->getTrafficRef()->getDepartureAirport()) &&
- (current->getAircraft()->GetFlightPlan()->getRunway() == closest->getAircraft()->GetFlightPlan()->getRunway())
- )
- current->getAircraft()->scheduleForATCTowerDepartureControl(1);
+
+ // if (
+ // closest->getAircraft()->getTakeOffStatus() &&
+ // (current->getAircraft()->getTrafficRef()->getDepartureAirport() == closest->getAircraft()->getTrafficRef()->getDepartureAirport()) &&
+ // (current->getAircraft()->GetFlightPlan()->getRunway() == closest->getAircraft()->GetFlightPlan()->getRunway())
+ // )
+ // current->getAircraft()->scheduleForATCTowerDepartureControl(1);
} else {
current->setSpeedAdjustment(0); // This can only happen when the user aircraft is the one closest
}
}
}
}
- if ((closest == closestOnNetwork) && (current->getPriority() < closest->getPriority()) && needBraking) {
+ if ((closest->getId() == closestOnNetwork->getId()) && (current->getPriority() < closest->getPriority()) && needBraking) {
swap(current, closest);
}
}
} else {
return;
}
+ time_t now = time(NULL) + fgGetLong("/sim/time/warp");
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
SG_LOG(SG_GENERAL, SG_ALERT,
- "AI error: Trying to access non-existing aircraft in FGGroundNetwork::checkHoldPosition");
+ "AI error: Trying to access non-existing aircraft in FGGroundNetwork::checkHoldPosition at " << SG_ORIGIN);
}
current = i;
+ //
+ if (current->getAircraft()->getTakeOffStatus() == 1) {
+ current->setHoldPosition(true);
+ return;
+ }
+ if (current->getAircraft()->getTakeOffStatus() == 2) {
+ //cerr << current->getAircraft()->getCallSign() << ". Taxi in position and hold" << endl;
+ current->setHoldPosition(false);
+ current->clearSpeedAdjustment();
+ return;
+ }
bool origStatus = current->hasHoldPosition();
current->setHoldPosition(false);
SGGeod curr(SGGeod::fromDegM(lon, lat, alt));
} else {
nx = tx;
}
- if (tx->hasBlock() || nx->hasBlock() ) {
- current->setHoldPosition(true);
- }
- }
-
-
- /* 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;
- }
- }
+ //if (tx->hasBlock(now) || nx->hasBlock(now) ) {
+ // current->setHoldPosition(true);
+ //}
+ SGGeod start(SGGeod::fromDeg((i->getLongitude()), (i->getLatitude())));
+ SGGeod end (SGGeod::fromDeg(nx->getStart()->getLongitude(), nx->getStart()->getLatitude()));
- 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())))
-
- {
- if (!(isUserAircraft(i->getAircraft()))) { // test code. Don't wait for the user, let the user wait for you.
- 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;
- }
+ double distance = SGGeodesy::distanceM(start, end);
+ if (nx->hasBlock(now) && (distance < i->getRadius() * 4)) {
+ current->setHoldPosition(true);
+ } else {
+ intVecIterator ivi = i->getIntentions().begin();
+ while (ivi != i->getIntentions().end()) {
+ if ((*ivi) > 0) {
+ distance += segments[(*ivi)-1]->getLength();
+ if ((segments[(*ivi)-1]->hasBlock(now)) && (distance < i->getRadius() * 4)) {
+ current->setHoldPosition(true);
+ break;
}
}
+ ivi++;
}
- } */
+ }
+ }
bool currStatus = current->hasHoldPosition();
current->setHoldPosition(origStatus);
// 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, true);
+ transmit(&(*current), &(*parent->getDynamics()), MSG_HOLD_POSITION, ATC_GROUND_TO_AIR, true);
//cerr << "Transmittin hold short instrudtion " << currStatus << " " << available << endl;
current->setState(1);
} else {
- transmit(&(*current), MSG_RESUME_TAXI, ATC_GROUND_TO_AIR, true);
+ transmit(&(*current), &(*parent->getDynamics()), MSG_RESUME_TAXI, ATC_GROUND_TO_AIR, true);
//cerr << "Transmittig resume instrudtion " << currStatus << " " << available << endl;
current->setState(2);
}
}
if (i == activeTraffic.end() || (trafficSize == 0)) {
SG_LOG(SG_GENERAL, SG_ALERT,
- "AI error: Trying to access non-existing aircraft in FGGroundNetwork::checkForCircularWaits");
+ "AI error: Trying to access non-existing aircraft in FGGroundNetwork::checkForCircularWaits at " << SG_ORIGIN);
}
current = i;
}
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
SG_LOG(SG_GENERAL, SG_ALERT,
- "AI error: checking ATC instruction for aircraft without traffic record");
+ "AI error: checking ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
} else {
return i->hasInstruction();
}
}
if (i == activeTraffic.end() || (activeTraffic.size() == 0)) {
SG_LOG(SG_GENERAL, SG_ALERT,
- "AI error: requesting ATC instruction for aircraft without traffic record");
+ "AI error: requesting ATC instruction for aircraft without traffic record at " << SG_ORIGIN);
} else {
return i->getInstruction();
}
FGScenery * local_scenery = globals->get_scenery();
double elevation_meters = 0.0;
double elevation_feet = 0.0;
+ time_t now = time(NULL) + fgGetLong("/sim/time/warp");
//for ( FGTaxiSegmentVectorIterator i = segments.begin(); i != segments.end(); i++) {
double dx = 0;
for (TrafficVectorIterator i = activeTraffic.begin(); i != activeTraffic.end(); i++) {
} else {
elevationStart = ((i)->getAircraft()->_getAltitude());
}
- double elevationEnd = segments[pos]->getEnd()->getElevation();
+ double elevationEnd = segments[pos]->getEnd()->getElevationM(parent->getElevation()*SG_FEET_TO_METER);
//cerr << "Using elevation " << elevationEnd << endl;
if ((elevationEnd == 0) || (elevationEnd = parent->getElevation())) {
geode->addDrawable(geometry);
//osg::Node *custom_obj;
SGMaterial *mat;
- if (segments[pos]->hasBlock()) {
+ if (segments[pos]->hasBlock(now)) {
mat = matlib->find("UnidirectionalTaperRed");
} else {
mat = matlib->find("UnidirectionalTaperGreen");
obj_trans->setDataVariance(osg::Object::STATIC);
// Experimental: Calculate slope here, based on length, and the individual elevations
- double elevationStart = segments[k]->getStart()->getElevation();
- double elevationEnd = segments[k]->getEnd ()->getElevation();
+ double elevationStart = segments[k]->getStart()->getElevationM(parent->getElevation()*SG_FEET_TO_METER);
+ double elevationEnd = segments[k]->getEnd ()->getElevationM(parent->getElevation()*SG_FEET_TO_METER);
if ((elevationStart == 0) || (elevationStart == parent->getElevation())) {
SGGeod center2 = segments[k]->getStart()->getGeod();
center2.setElevationM(SG_MAX_ELEVATION_M);
geode->addDrawable(geometry);
//osg::Node *custom_obj;
SGMaterial *mat;
- if (segments[k]->hasBlock()) {
+ if (segments[k]->hasBlock(now)) {
mat = matlib->find("UnidirectionalTaperRed");
} else {
mat = matlib->find("UnidirectionalTaperGreen");
void FGGroundNetwork::update(double dt)
{
+ time_t now = time(NULL) + fgGetLong("/sim/time/warp");
for (FGTaxiSegmentVectorIterator tsi = segments.begin(); tsi != segments.end(); tsi++) {
- (*tsi)->unblock();
+ (*tsi)->unblock(now);
}
int priority = 1;
//sort(activeTraffic.begin(), activeTraffic.end(), compare_trafficrecords);
i != parent->getDynamics()->getStartupController()->getActiveTraffic().end(); i++) {
i->allowPushBack();
i->setPriority(priority++);
+ // in meters per second;
+ double vTaxi = (i->getAircraft()->getPerformance()->vTaxi() * SG_NM_TO_METER) / 3600;
if (i->isActive(60)) {
// Check for all active aircraft whether it's current pos segment is
for (intVecIterator k = i->getIntentions().begin(); k != i->getIntentions().end(); k++) {
if ((*k) == posReverse) {
i->denyPushBack();
- segments[posReverse-1]->block();
+ segments[posReverse-1]->block(i->getId(), now, now);
}
}
}
}
// if the current aircraft is still allowed to pushback, we can start reserving a route for if by blocking all the entry taxiways.
if (i->pushBackAllowed()) {
+ double length = 0;
int pos = i->getCurrentPosition();
if (pos > 0) {
FGTaxiSegment *seg = segments[pos-1];
FGTaxiNode *node = seg->getEnd();
+ length = seg->getLength();
for (FGTaxiSegmentVectorIterator tsi = segments.begin(); tsi != segments.end(); tsi++) {
if (((*tsi)->getEnd() == node) && ((*tsi) != seg)) {
- (*tsi)->block();
+ (*tsi)->block(i->getId(), now, now);
}
}
}
if (pos > 0) {
FGTaxiSegment *seg = segments[pos-1];
FGTaxiNode *node = seg->getEnd();
+ length += seg->getLength();
+ time_t blockTime = now + (length / vTaxi);
for (FGTaxiSegmentVectorIterator tsi = segments.begin(); tsi != segments.end(); tsi++) {
if (((*tsi)->getEnd() == node) && ((*tsi) != seg)) {
- (*tsi)->block();
+ (*tsi)->block(i->getId(), blockTime-30, now);
}
}
}
}
}
for (TrafficVectorIterator i = activeTraffic.begin(); i != activeTraffic.end(); i++) {
+ double length = 0;
+ double vTaxi = (i->getAircraft()->getPerformance()->vTaxi() * SG_NM_TO_METER) / 3600;
i->setPriority(priority++);
int pos = i->getCurrentPosition();
if (pos > 0) {
- if (segments[pos-1]->hasBlock()) {
- SG_LOG(SG_GENERAL, SG_ALERT, "Taxiway incursion for AI aircraft" << i->getAircraft()->getCallSign());
+ length = segments[pos-1]->getLength();
+ if (segments[pos-1]->hasBlock(now)) {
+ //SG_LOG(SG_GENERAL, SG_ALERT, "Taxiway incursion for AI aircraft" << i->getAircraft()->getCallSign());
}
}
for (ivi = i->getIntentions().begin(); ivi != i->getIntentions().end(); ivi++) {
int segIndex = (*ivi);
if (segIndex > 0) {
- if (segments[segIndex-1]->hasBlock())
+ if (segments[segIndex-1]->hasBlock(now))
break;
}
}
if (pos > 0) {
FGTaxiSegment *seg = segments[pos-1];
FGTaxiNode *node = seg->getEnd();
+ length += seg->getLength();
for (FGTaxiSegmentVectorIterator tsi = segments.begin(); tsi != segments.end(); tsi++) {
if (((*tsi)->getEnd() == node) && ((*tsi) != seg)) {
- (*tsi)->block();
+ time_t blockTime = now + (length / vTaxi);
+ (*tsi)->block(i->getId(), blockTime - 30, now);
}
}
}