1
0
Fork 0

Added some code to visualize the ground networks.

This commit is contained in:
Durk Talsma 2011-04-17 10:19:58 +02:00
parent e16f772e54
commit 65e87bf2f8
11 changed files with 235 additions and 54 deletions

View file

@ -29,6 +29,7 @@
#include <simgear/math/SGMath.hxx> #include <simgear/math/SGMath.hxx>
#include <Airports/dynamics.hxx> #include <Airports/dynamics.hxx>
#include <Airports/simple.hxx> #include <Airports/simple.hxx>
#include <Scenery/scenery.hxx>
#include "atc_mgr.hxx" #include "atc_mgr.hxx"
@ -155,6 +156,10 @@ void FGATCManager::init() {
aircraftRadius, leg, &ai_ac); aircraftRadius, leg, &ai_ac);
//dialog.init(); //dialog.init();
osg::Node* node = apt->getDynamics()->getGroundNetwork()->getRenderNode();
cerr << "Adding groundnetWork to the scenegraph" << endl;
globals->get_scenery()->get_scene_graph()->addChild(node);
} }
} }
@ -180,4 +185,10 @@ void FGATCManager::update ( double time ) {
speed, speed,
altitude, time); altitude, time);
} }
/*string airport = fgGetString("/sim/presets/airport-id");
FGAirport *apt = FGAirport::findByIdent(airport);
osg::Node* node = apt->getDynamics()->getGroundNetwork()->getRenderNode();
cerr << "Adding groundnetWork to the scenegraph" << endl;
globals->get_scenery()->get_scene_graph()->addChild(node);
*/
} }

View file

@ -91,8 +91,61 @@ void FGATCDialogNew::addEntry(int nr, string txt) {
commands.push_back(txt); commands.push_back(txt);
} }
void FGATCDialogNew::removeEntry(int nr) {
commands.clear();
}
void FGATCDialogNew::PopupDialog() { void FGATCDialogNew::PopupDialog() {
/*double onBoardRadioFreq0 =
fgGetDouble("/instrumentation/comm[0]/frequencies/selected-mhz");
double onBoardRadioFreq1 =
fgGetDouble("/instrumentation/comm[1]/frequencies/selected-mhz");
const char *dialog_name = "atc-dialog";
_gui = (NewGUI *)globals->get_subsystem("gui");
SGPropertyNode_ptr dlg = _gui->getDialogProperties(dialog_name);
if (!dlg)
return;
_gui->closeDialog(dialog_name);
SGPropertyNode_ptr button_group = getNamedNode(dlg, "transmission-choice");
button_group->removeChildren("button", false);
const int bufsize = 32;
char buf[bufsize];
int commandNr = 0;
// loop over all entries that should fill up the dialog; use 10 items for now...
for (StringVecIterator i = commands.begin(); i != commands.end(); i++) {
snprintf(buf, bufsize, "/sim/atc/opt[%d]", commandNr);
fgSetBool(buf, false);
SGPropertyNode *entry = button_group->getNode("button", commandNr, true);
copyProperties(button_group->getNode("button-template", true), entry);
entry->removeChildren("enabled", true);
entry->setStringValue("property", buf);
entry->setIntValue("keynum", '1' + commandNr);
if (commandNr == 0)
entry->setBoolValue("default", true);
snprintf(buf, bufsize, "%d", 1 + commandNr);
string legend = string(buf) + (*i); //"; // + current->menuentry;
entry->setStringValue("legend", legend.c_str());
entry->setIntValue("binding/value", commandNr);
commandNr++;
//current++;
}
*/
//if (dialogVisible) {
// _gui->closeDialog(dialog_name);
//} else {
// _gui->showDialog(dialog_name);
//}
dialogVisible = !dialogVisible;
return;
}
void FGATCDialogNew::update(double dt) {
double onBoardRadioFreq0 = double onBoardRadioFreq0 =
fgGetDouble("/instrumentation/comm[0]/frequencies/selected-mhz"); fgGetDouble("/instrumentation/comm[0]/frequencies/selected-mhz");
double onBoardRadioFreq1 = double onBoardRadioFreq1 =
@ -136,11 +189,8 @@ void FGATCDialogNew::PopupDialog() {
} else { } else {
_gui->showDialog(dialog_name); _gui->showDialog(dialog_name);
} }
dialogVisible = !dialogVisible; //dialogVisible = !dialogVisible;
return; return;
}
void FGATCDialogNew::update(double dt) {
/* /*
static SGPropertyNode_ptr trans_num = globals->get_props()->getNode("/sim/atc/transmission-num", true); static SGPropertyNode_ptr trans_num = globals->get_props()->getNode("/sim/atc/transmission-num", true);
int n = trans_num->getIntValue(); int n = trans_num->getIntValue();

View file

@ -60,6 +60,7 @@ public:
void update(double dt); void update(double dt);
void PopupDialog(); void PopupDialog();
void addEntry(int, string); void addEntry(int, string);
void removeEntry(int);
}; };
extern FGATCDialogNew *currentATCDialog; extern FGATCDialogNew *currentATCDialog;

View file

@ -399,6 +399,10 @@ void FGTrafficRecord::setHeadingAdjustment(double heading)
bool FGTrafficRecord::pushBackAllowed() bool FGTrafficRecord::pushBackAllowed()
{ {
// With the user ATC / AI integration, checking whether the user's aircraft is near no longer works, because
// this will effectively block the user's aircraft itself from receiving pushback clearance.
// So, what can we do?
/*
double course, az2, dist; double course, az2, dist;
SGGeod curr(SGGeod::fromDegM(getLongitude(), SGGeod curr(SGGeod::fromDegM(getLongitude(),
getLatitude(), getAltitude())); getLatitude(), getAltitude()));
@ -409,7 +413,12 @@ bool FGTrafficRecord::pushBackAllowed()
SGGeodesy::inverse(curr, user, course, az2, dist); SGGeodesy::inverse(curr, user, course, az2, dist);
//cerr << "Distance to user : " << dist << endl; //cerr << "Distance to user : " << dist << endl;
return (dist > 250); return (dist > 250);
*/
// In essence, we should check whether the pusbback route itself, as well as the associcated
// taxiways near the pushback point are free of traffic.
// To do so, we need to
} }
@ -1023,6 +1032,8 @@ bool FGStartupController::checkTransmissionState(int st, time_t now, time_t star
trans_num->setIntValue(-1); trans_num->setIntValue(-1);
// PopupCallback(n); // PopupCallback(n);
cerr << "Selected transmission message" << n << endl; cerr << "Selected transmission message" << n << endl;
FGATCManager *atc = (FGATCManager*) globals->get_subsystem("atc");
atc->getATCDialog()->removeEntry(1);
} else { } else {
cerr << "creading message for " << i->getAircraft()->getCallSign() << endl; cerr << "creading message for " << i->getAircraft()->getCallSign() << endl;
transmit(&(*i), msgId, msgDir, false); transmit(&(*i), msgId, msgDir, false);
@ -1092,6 +1103,7 @@ void FGStartupController::updateAircraftInformation(int id, double lat, double l
} }
checkTransmissionState(5, now, (startTime + 140), i, MSG_INITIATE_CONTACT, ATC_AIR_TO_GROUND); checkTransmissionState(5, now, (startTime + 140), i, MSG_INITIATE_CONTACT, ATC_AIR_TO_GROUND);
checkTransmissionState(6, now, (startTime + 150), i, MSG_ACKNOWLEDGE_INITIATE_CONTACT, ATC_GROUND_TO_AIR); checkTransmissionState(6, now, (startTime + 150), i, MSG_ACKNOWLEDGE_INITIATE_CONTACT, ATC_GROUND_TO_AIR);
checkTransmissionState(7, now, (startTime + 180), i, MSG_REQUEST_PUSHBACK_CLEARANCE, ATC_AIR_TO_GROUND);

View file

@ -96,10 +96,11 @@ void FGAirportDynamics::init()
random_shuffle(parkings.begin(), parkings.end()); random_shuffle(parkings.begin(), parkings.end());
sort(parkings.begin(), parkings.end()); sort(parkings.begin(), parkings.end());
// add the gate positions to the ground network. // add the gate positions to the ground network.
groundNetwork.setParent(_ap);
groundNetwork.addNodes(&parkings); groundNetwork.addNodes(&parkings);
groundNetwork.init(); groundNetwork.init();
groundNetwork.setTowerController(&towerController); groundNetwork.setTowerController(&towerController);
groundNetwork.setParent(_ap);
} }
bool FGAirportDynamics::getAvailableParking(double *lat, double *lon, bool FGAirportDynamics::getAvailableParking(double *lat, double *lon,

View file

@ -72,6 +72,9 @@ private:
string chooseRunwayFallback(); string chooseRunwayFallback();
bool innerGetActiveRunway(const string &trafficType, int action, string &runway, double heading); bool innerGetActiveRunway(const string &trafficType, int action, string &runway, double heading);
string chooseRwyByHeading(stringVec rwys, double heading); string chooseRwyByHeading(stringVec rwys, double heading);
double elevation;
public: public:
FGAirportDynamics(FGAirport* ap); FGAirportDynamics(FGAirport* ap);
FGAirportDynamics(const FGAirportDynamics &other); FGAirportDynamics(const FGAirportDynamics &other);

View file

@ -31,9 +31,9 @@ double processPosition(const string &pos)
return value; return value;
} }
bool sortByHeadingDiff(FGTaxiSegment *a, FGTaxiSegment *b) { //bool sortByHeadingDiff(FGTaxiSegment *a, FGTaxiSegment *b) {
return a->hasSmallerHeadingDiff(*b); // return a->hasSmallerHeadingDiff(*b);
} //}
bool sortByLength(FGTaxiSegment *a, FGTaxiSegment *b) { bool sortByLength(FGTaxiSegment *a, FGTaxiSegment *b) {
return a->getLength() > b->getLength(); return a->getLength() > b->getLength();
@ -42,7 +42,10 @@ bool sortByLength(FGTaxiSegment *a, FGTaxiSegment *b) {
/************************************************************************** /**************************************************************************
* FGTaxiNode * FGTaxiNode
*************************************************************************/ *************************************************************************/
void FGTaxiNode::setElevation(double val)
{
geod.setElevationM(val);
}
void FGTaxiNode::setLatitude (double val) void FGTaxiNode::setLatitude (double val)
{ {
@ -64,10 +67,10 @@ void FGTaxiNode::setLongitude(const string& val)
geod.setLongitudeDeg(processPosition(val)); geod.setLongitudeDeg(processPosition(val));
} }
void FGTaxiNode::sortEndSegments(bool byLength) //void FGTaxiNode::sortEndSegments(bool byLength)
{ //{
if (byLength) // if (byLength)
sort(next.begin(), next.end(), sortByLength); // sort(next.begin(), next.end(), sortByLength);
else // else
sort(next.begin(), next.end(), sortByHeadingDiff); // sort(next.begin(), next.end(), sortByHeadingDiff);
} //}

View file

@ -83,6 +83,7 @@ FGTaxiNode &operator =(const FGTaxiNode &other)
void setIndex(int idx) { index = idx; }; void setIndex(int idx) { index = idx; };
void setLatitude (double val); void setLatitude (double val);
void setLongitude(double val); void setLongitude(double val);
void setElevation(double val);
void setLatitude (const std::string& val); void setLatitude (const std::string& val);
void setLongitude(const std::string& val); void setLongitude(const std::string& val);
void addSegment(FGTaxiSegment *segment) { next.push_back(segment); }; void addSegment(FGTaxiSegment *segment) { next.push_back(segment); };
@ -99,6 +100,7 @@ FGTaxiNode &operator =(const FGTaxiNode &other)
double getPathScore() { return pathScore; }; double getPathScore() { return pathScore; };
double getLatitude() { return geod.getLatitudeDeg();}; double getLatitude() { return geod.getLatitudeDeg();};
double getLongitude(){ return geod.getLongitudeDeg();}; double getLongitude(){ return geod.getLongitudeDeg();};
double getElevation() { return geod.getElevationM();};
const SGGeod& getGeod() const { return geod; } const SGGeod& getGeod() const { return geod; }
@ -111,7 +113,7 @@ FGTaxiNode &operator =(const FGTaxiNode &other)
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); //void sortEndSegments(bool);
}; };

View file

@ -27,8 +27,15 @@
#include <math.h> #include <math.h>
#include <algorithm> #include <algorithm>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/MatrixTransform>
#include <osg/Shape>
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include <simgear/route/waypoint.hxx> #include <simgear/route/waypoint.hxx>
#include <simgear/scene/material/EffectGeode.hxx>
#include <Airports/simple.hxx> #include <Airports/simple.hxx>
#include <Airports/dynamics.hxx> #include <Airports/dynamics.hxx>
@ -77,19 +84,26 @@ 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::setDimensions(double elevation)
{ {
length = SGGeodesy::distanceM(start->getGeod(), end->getGeod()); length = SGGeodesy::distanceM(start->getGeod(), end->getGeod());
//heading = SGGeodesy::headingDeg(start->getGeod(), end->getGeod());
double az2; //, distanceM;
SGGeodesy::inverse(start->getGeod(), end->getGeod(), heading, az2, length);
double coveredDistance = length * 0.5;
SGGeodesy::direct(start->getGeod(), heading, coveredDistance, center, az2);
cerr << "Centerpoint = (" << center.getLatitudeDeg() << ", " << center.getLongitudeDeg() << "). Heading = " << heading << endl;
} }
void FGTaxiSegment::setCourseDiff(double crse) //void FGTaxiSegment::setCourseDiff(double crse)
{ //{
headingDiff = fabs(course - crse); // headingDiff = fabs(course - crse);
if (headingDiff > 180) // if (headingDiff > 180)
headingDiff = fabs(headingDiff - 360); // headingDiff = fabs(headingDiff - 360);
} //}
/*************************************************************************** /***************************************************************************
@ -227,6 +241,7 @@ void FGGroundNetwork::addNodes(FGParkingVec * parkings)
n.setIndex(i->getIndex()); n.setIndex(i->getIndex());
n.setLatitude(i->getLatitude()); n.setLatitude(i->getLatitude());
n.setLongitude(i->getLongitude()); n.setLongitude(i->getLongitude());
n.setElevation(parent->getElevation());
nodes.push_back(new FGTaxiNode(n)); nodes.push_back(new FGTaxiNode(n));
i++; i++;
@ -245,7 +260,7 @@ void FGGroundNetwork::init()
while (i != segments.end()) { while (i != segments.end()) {
(*i)->setStart(&nodes); (*i)->setStart(&nodes);
(*i)->setEnd(&nodes); (*i)->setEnd(&nodes);
(*i)->setTrackDistance(); (*i)->setDimensions(parent->getElevation());
(*i)->setIndex(index); (*i)->setIndex(index);
if ((*i)->isPushBack()) { if ((*i)->isPushBack()) {
pushBackNodes.push_back((*i)->getEnd()); pushBackNodes.push_back((*i)->getEnd());
@ -511,6 +526,36 @@ void FGGroundNetwork::signOff(int id)
} }
} }
bool FGGroundNetwork::checkTransmissionState(int minState, int maxState, TrafficVectorIterator i, time_t now, AtcMsgId msgId,
AtcMsgDir msgDir)
{
int state = i->getState();
if ((state >= minState) && (state <= maxState) && available) {
if ((msgDir == ATC_AIR_TO_GROUND) && isUserAircraft(i->getAircraft())) {
cerr << "Checking state " << state << " for " << i->getAircraft()->getCallSign() << endl;
static SGPropertyNode_ptr trans_num = globals->get_props()->getNode("/sim/atc/transmission-num", true);
int n = trans_num->getIntValue();
if (n >= 0) {
trans_num->setIntValue(-1);
// PopupCallback(n);
cerr << "Selected transmission message" << n << endl;
} else {
cerr << "creading message for " << i->getAircraft()->getCallSign() << endl;
transmit(&(*i), msgId, msgDir, false);
return false;
}
}
//cerr << "Transmitting startup msg" << endl;
transmit(&(*i), msgId, msgDir, true);
i->updateState();
lastTransmission = now;
available = false;
return true;
}
return false;
}
void FGGroundNetwork::updateAircraftInformation(int id, double lat, double lon, void FGGroundNetwork::updateAircraftInformation(int id, double lat, double lon,
double heading, double speed, double alt, double heading, double speed, double alt,
double dt) double dt)
@ -568,23 +613,14 @@ void FGGroundNetwork::updateAircraftInformation(int id, double lat, double lon,
if ((now - lastTransmission) > 15) { if ((now - lastTransmission) > 15) {
available = true; available = true;
} }
if ((state < 3) && available) { if (checkTransmissionState(0,2, current, now, MSG_REQUEST_TAXI_CLEARANCE, ATC_AIR_TO_GROUND)) {
transmit(&(*current), MSG_REQUEST_TAXI_CLEARANCE, ATC_AIR_TO_GROUND, true);
current->setState(3); current->setState(3);
lastTransmission = now;
available = false;
} }
if ((state == 3) && available) { if (checkTransmissionState(3,3, current, now, MSG_ISSUE_TAXI_CLEARANCE, ATC_GROUND_TO_AIR)) {
transmit(&(*current), MSG_ISSUE_TAXI_CLEARANCE, ATC_GROUND_TO_AIR, true);
current->setState(4); current->setState(4);
lastTransmission = now;
available = false;
} }
if ((state == 4) && available) { if (checkTransmissionState(4,4, current, now, MSG_ACKNOWLEDGE_TAXI_CLEARANCE, ATC_AIR_TO_GROUND)) {
transmit(&(*current), MSG_ACKNOWLEDGE_TAXI_CLEARANCE, ATC_AIR_TO_GROUND, true);
current->setState(5); current->setState(5);
lastTransmission = now;
available = false;
} }
if ((state == 5) && available) { if ((state == 5) && available) {
current->setState(0); current->setState(0);
@ -862,8 +898,17 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
//cerr << "Current state " << current->getState() << endl; //cerr << "Current state " << current->getState() << endl;
} else { } else {
} }
int state = current->getState(); //int state = current->getState();
if ((state == 1) && (available)) { if (checkTransmissionState(1,1, current, now, MSG_ACKNOWLEDGE_HOLD_POSITION, ATC_AIR_TO_GROUND)) {
current->setState(0);
current->setHoldPosition(true);
}
if (checkTransmissionState(2,2, current, now, MSG_ACKNOWLEDGE_RESUME_TAXI, ATC_AIR_TO_GROUND)) {
current->setState(0);
current->setHoldPosition(false);
}
/*if ((state == 1) && (available)) {
//cerr << "ACKNOWLEDGE HOLD" << endl; //cerr << "ACKNOWLEDGE HOLD" << endl;
transmit(&(*current), MSG_ACKNOWLEDGE_HOLD_POSITION, ATC_AIR_TO_GROUND, true); transmit(&(*current), MSG_ACKNOWLEDGE_HOLD_POSITION, ATC_AIR_TO_GROUND, true);
current->setState(0); current->setState(0);
@ -879,7 +924,7 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
current->setHoldPosition(false); current->setHoldPosition(false);
lastTransmission = now; lastTransmission = now;
available = false; available = false;
} }*/
} }
/** /**
@ -1036,3 +1081,51 @@ FGATCInstruction FGGroundNetwork::getInstruction(int id)
} }
return FGATCInstruction(); return FGATCInstruction();
} }
// Note that this function is copied from simgear. for maintanance purposes, it's probabtl better to make a general function out of that.
static void WorldCoordinate(osg::Matrix& obj_pos, double lat,
double lon, double elev, double hdg)
{
SGGeod geod = SGGeod::fromDegM(lon, lat, elev);
obj_pos = geod.makeZUpFrame();
// hdg is not a compass heading, but a counter-clockwise rotation
// around the Z axis
obj_pos.preMult(osg::Matrix::rotate(hdg * SGD_DEGREES_TO_RADIANS,
0.0, 0.0, 1.0));
}
osg::Node* FGGroundNetwork::getRenderNode()
{
osg::Group* group = new osg::Group;
for ( FGTaxiSegmentVectorIterator i = segments.begin(); i != segments.end(); i++) {
osg::Matrix obj_pos;
osg::MatrixTransform *obj_trans = new osg::MatrixTransform;
obj_trans->setDataVariance(osg::Object::STATIC);
WorldCoordinate( obj_pos, (*i)->getLatitude(), (*i)->getLongitude(), parent->elevation()+10, -((*i)->getHeading()) );
obj_trans->setMatrix( obj_pos );
//osg::Vec3 center(0, 0, 0)
float width = (*i)->getLength() /2.0;
osg::Vec3 corner(-width, 0, 0.25f);
osg::Vec3 widthVec(2*width + 1, 0, 0);
osg::Vec3 heightVec(0, 0, 1);
osg::Geometry* geometry;
geometry = osg::createTexturedQuadGeometry(corner, widthVec, heightVec);
simgear::EffectGeode* geode = new simgear::EffectGeode;
geode->setName("test");
geode->addDrawable(geometry);
//osg::Node *custom_obj;
obj_trans->addChild(geode);
// wire as much of the scene graph together as we can
//->addChild( obj_trans );
group->addChild( obj_trans );
}
return group;
}

View file

@ -56,8 +56,8 @@ private:
int startNode; int startNode;
int endNode; int endNode;
double length; double length;
double course; double heading;
double headingDiff; SGGeod center;
bool isActive; bool isActive;
bool isPushBackRoute; bool isPushBackRoute;
FGTaxiNode *start; FGTaxiNode *start;
@ -72,8 +72,7 @@ public:
startNode(0), startNode(0),
endNode(0), endNode(0),
length(0), length(0),
course(0), heading(0),
headingDiff(0),
isActive(0), isActive(0),
isPushBackRoute(0), isPushBackRoute(0),
start(0), start(0),
@ -87,8 +86,8 @@ public:
startNode (other.startNode), startNode (other.startNode),
endNode (other.endNode), endNode (other.endNode),
length (other.length), length (other.length),
course (other.course), heading (other.heading),
headingDiff (other.headingDiff), center (other.center),
isActive (other.isActive), isActive (other.isActive),
isPushBackRoute (other.isPushBackRoute), isPushBackRoute (other.isPushBackRoute),
start (other.start), start (other.start),
@ -103,8 +102,8 @@ public:
startNode = other.startNode; startNode = other.startNode;
endNode = other.endNode; endNode = other.endNode;
length = other.length; length = other.length;
course = other.course; heading = other.heading;
headingDiff = other.headingDiff; center = other.center;
isActive = other.isActive; isActive = other.isActive;
isPushBackRoute = other.isPushBackRoute; isPushBackRoute = other.isPushBackRoute;
start = other.start; start = other.start;
@ -123,13 +122,15 @@ public:
void setStart(FGTaxiNodeVector *nodes); void setStart(FGTaxiNodeVector *nodes);
void setEnd (FGTaxiNodeVector *nodes); void setEnd (FGTaxiNodeVector *nodes);
void setPushBackType(bool val) { isPushBackRoute = val; }; void setPushBackType(bool val) { isPushBackRoute = val; };
void setTrackDistance(); void setDimensions(double elevation);
FGTaxiNode * getEnd() { return end;}; FGTaxiNode * getEnd() { return end;};
FGTaxiNode * getStart() { return start; }; FGTaxiNode * getStart() { return start; };
double getLength() { return length; }; double getLength() { return length; };
int getIndex() { return index; }; int getIndex() { return index; };
double getLatitude() { return center.getLatitudeDeg(); };
double getLongitude() { return center.getLongitudeDeg(); };
double getHeading() { return heading; };
bool isPushBack() { return isPushBackRoute; }; bool isPushBack() { return isPushBackRoute; };
int getPenalty(int nGates); int getPenalty(int nGates);
@ -137,7 +138,7 @@ 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; }; //bool hasSmallerHeadingDiff (const FGTaxiSegment &other) const { return headingDiff < other.headingDiff; };
FGTaxiSegment *opposite() { return oppositeDirection; }; FGTaxiSegment *opposite() { return oppositeDirection; };
void setCourseDiff(double crse); void setCourseDiff(double crse);
@ -273,7 +274,10 @@ public:
virtual bool hasInstruction(int id); virtual bool hasInstruction(int id);
virtual FGATCInstruction getInstruction(int id); virtual FGATCInstruction getInstruction(int id);
bool checkTransmissionState(int minState, int MaxState, TrafficVectorIterator i, time_t now, AtcMsgId msgId,
AtcMsgDir msgDir);
bool checkForCircularWaits(int id); bool checkForCircularWaits(int id);
osg::Node* getRenderNode();
}; };

View file

@ -152,6 +152,7 @@ bool FGTileMgr::sched_tile( const SGBucket& b, double priority, bool current_vie
if ( tile_cache.insert_tile( t ) ) if ( tile_cache.insert_tile( t ) )
{ {
// Attach to scene graph // Attach to scene graph
t->addToSceneGraph(globals->get_scenery()->get_terrain_branch()); t->addToSceneGraph(globals->get_scenery()->get_terrain_branch());
} else } else
{ {