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 <Airports/dynamics.hxx>
#include <Airports/simple.hxx>
#include <Scenery/scenery.hxx>
#include "atc_mgr.hxx"
@ -155,6 +156,10 @@ void FGATCManager::init() {
aircraftRadius, leg, &ai_ac);
//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,
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,9 +91,62 @@ void FGATCDialogNew::addEntry(int nr, string txt) {
commands.push_back(txt);
}
void FGATCDialogNew::removeEntry(int nr) {
commands.clear();
}
void FGATCDialogNew::PopupDialog() {
double onBoardRadioFreq0 =
/*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 =
fgGetDouble("/instrumentation/comm[0]/frequencies/selected-mhz");
double onBoardRadioFreq1 =
fgGetDouble("/instrumentation/comm[1]/frequencies/selected-mhz");
@ -136,11 +189,8 @@ void FGATCDialogNew::PopupDialog() {
} else {
_gui->showDialog(dialog_name);
}
dialogVisible = !dialogVisible;
//dialogVisible = !dialogVisible;
return;
}
void FGATCDialogNew::update(double dt) {
/*
static SGPropertyNode_ptr trans_num = globals->get_props()->getNode("/sim/atc/transmission-num", true);
int n = trans_num->getIntValue();

View file

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

View file

@ -399,6 +399,10 @@ void FGTrafficRecord::setHeadingAdjustment(double heading)
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;
SGGeod curr(SGGeod::fromDegM(getLongitude(),
getLatitude(), getAltitude()));
@ -409,7 +413,12 @@ bool FGTrafficRecord::pushBackAllowed()
SGGeodesy::inverse(curr, user, course, az2, dist);
//cerr << "Distance to user : " << dist << endl;
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);
// PopupCallback(n);
cerr << "Selected transmission message" << n << endl;
FGATCManager *atc = (FGATCManager*) globals->get_subsystem("atc");
atc->getATCDialog()->removeEntry(1);
} else {
cerr << "creading message for " << i->getAircraft()->getCallSign() << endl;
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(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());
sort(parkings.begin(), parkings.end());
// add the gate positions to the ground network.
groundNetwork.setParent(_ap);
groundNetwork.addNodes(&parkings);
groundNetwork.init();
groundNetwork.setTowerController(&towerController);
groundNetwork.setParent(_ap);
}
bool FGAirportDynamics::getAvailableParking(double *lat, double *lon,

View file

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

View file

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

View file

@ -83,6 +83,7 @@ FGTaxiNode &operator =(const FGTaxiNode &other)
void setIndex(int idx) { index = idx; };
void setLatitude (double val);
void setLongitude(double val);
void setElevation(double val);
void setLatitude (const std::string& val);
void setLongitude(const std::string& val);
void addSegment(FGTaxiSegment *segment) { next.push_back(segment); };
@ -99,6 +100,7 @@ FGTaxiNode &operator =(const FGTaxiNode &other)
double getPathScore() { return pathScore; };
double getLatitude() { return geod.getLatitudeDeg();};
double getLongitude(){ return geod.getLongitudeDeg();};
double getElevation() { return geod.getElevationM();};
const SGGeod& getGeod() const { return geod; }
@ -111,7 +113,7 @@ FGTaxiNode &operator =(const FGTaxiNode &other)
FGTaxiSegmentVectorIterator getEndRoute() { return next.end(); };
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 <algorithm>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/MatrixTransform>
#include <osg/Shape>
#include <simgear/debug/logstream.hxx>
#include <simgear/route/waypoint.hxx>
#include <simgear/scene/material/EffectGeode.hxx>
#include <Airports/simple.hxx>
#include <Airports/dynamics.hxx>
@ -77,19 +84,26 @@ void FGTaxiSegment::setEnd(FGTaxiNodeVector * nodes)
// There is probably a computationally cheaper way of
// doing this.
void FGTaxiSegment::setTrackDistance()
void FGTaxiSegment::setDimensions(double elevation)
{
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)
{
headingDiff = fabs(course - crse);
//void FGTaxiSegment::setCourseDiff(double crse)
//{
// headingDiff = fabs(course - crse);
if (headingDiff > 180)
headingDiff = fabs(headingDiff - 360);
}
// if (headingDiff > 180)
// headingDiff = fabs(headingDiff - 360);
//}
/***************************************************************************
@ -227,6 +241,7 @@ void FGGroundNetwork::addNodes(FGParkingVec * parkings)
n.setIndex(i->getIndex());
n.setLatitude(i->getLatitude());
n.setLongitude(i->getLongitude());
n.setElevation(parent->getElevation());
nodes.push_back(new FGTaxiNode(n));
i++;
@ -245,7 +260,7 @@ void FGGroundNetwork::init()
while (i != segments.end()) {
(*i)->setStart(&nodes);
(*i)->setEnd(&nodes);
(*i)->setTrackDistance();
(*i)->setDimensions(parent->getElevation());
(*i)->setIndex(index);
if ((*i)->isPushBack()) {
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,
double heading, double speed, double alt,
double dt)
@ -568,23 +613,14 @@ void FGGroundNetwork::updateAircraftInformation(int id, double lat, double lon,
if ((now - lastTransmission) > 15) {
available = true;
}
if ((state < 3) && available) {
transmit(&(*current), MSG_REQUEST_TAXI_CLEARANCE, ATC_AIR_TO_GROUND, true);
current->setState(3);
lastTransmission = now;
available = false;
if (checkTransmissionState(0,2, current, now, MSG_REQUEST_TAXI_CLEARANCE, ATC_AIR_TO_GROUND)) {
current->setState(3);
}
if ((state == 3) && available) {
transmit(&(*current), MSG_ISSUE_TAXI_CLEARANCE, ATC_GROUND_TO_AIR, true);
if (checkTransmissionState(3,3, current, now, MSG_ISSUE_TAXI_CLEARANCE, ATC_GROUND_TO_AIR)) {
current->setState(4);
lastTransmission = now;
available = false;
}
if ((state == 4) && available) {
transmit(&(*current), MSG_ACKNOWLEDGE_TAXI_CLEARANCE, ATC_AIR_TO_GROUND, true);
if (checkTransmissionState(4,4, current, now, MSG_ACKNOWLEDGE_TAXI_CLEARANCE, ATC_AIR_TO_GROUND)) {
current->setState(5);
lastTransmission = now;
available = false;
}
if ((state == 5) && available) {
current->setState(0);
@ -862,8 +898,17 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
//cerr << "Current state " << current->getState() << endl;
} else {
}
int state = current->getState();
if ((state == 1) && (available)) {
//int state = current->getState();
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;
transmit(&(*current), MSG_ACKNOWLEDGE_HOLD_POSITION, ATC_AIR_TO_GROUND, true);
current->setState(0);
@ -879,8 +924,8 @@ void FGGroundNetwork::checkHoldPosition(int id, double lat,
current->setHoldPosition(false);
lastTransmission = now;
available = false;
}
}
}*/
}
/**
* Check whether situations occur where the current aircraft is waiting for itself
@ -1036,3 +1081,51 @@ FGATCInstruction FGGroundNetwork::getInstruction(int id)
}
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 endNode;
double length;
double course;
double headingDiff;
double heading;
SGGeod center;
bool isActive;
bool isPushBackRoute;
FGTaxiNode *start;
@ -72,8 +72,7 @@ public:
startNode(0),
endNode(0),
length(0),
course(0),
headingDiff(0),
heading(0),
isActive(0),
isPushBackRoute(0),
start(0),
@ -87,8 +86,8 @@ public:
startNode (other.startNode),
endNode (other.endNode),
length (other.length),
course (other.course),
headingDiff (other.headingDiff),
heading (other.heading),
center (other.center),
isActive (other.isActive),
isPushBackRoute (other.isPushBackRoute),
start (other.start),
@ -103,8 +102,8 @@ public:
startNode = other.startNode;
endNode = other.endNode;
length = other.length;
course = other.course;
headingDiff = other.headingDiff;
heading = other.heading;
center = other.center;
isActive = other.isActive;
isPushBackRoute = other.isPushBackRoute;
start = other.start;
@ -123,13 +122,15 @@ public:
void setStart(FGTaxiNodeVector *nodes);
void setEnd (FGTaxiNodeVector *nodes);
void setPushBackType(bool val) { isPushBackRoute = val; };
void setTrackDistance();
void setDimensions(double elevation);
FGTaxiNode * getEnd() { return end;};
FGTaxiNode * getStart() { return start; };
double getLength() { return length; };
int getIndex() { return index; };
double getLatitude() { return center.getLatitudeDeg(); };
double getLongitude() { return center.getLongitudeDeg(); };
double getHeading() { return heading; };
bool isPushBack() { return isPushBackRoute; };
int getPenalty(int nGates);
@ -137,7 +138,7 @@ public:
FGTaxiSegment *getAddress() { return this;};
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; };
void setCourseDiff(double crse);
@ -273,7 +274,10 @@ public:
virtual bool hasInstruction(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);
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 ) )
{
// Attach to scene graph
t->addToSceneGraph(globals->get_scenery()->get_terrain_branch());
} else
{