Added some code to visualize the ground networks.
This commit is contained in:
parent
e16f772e54
commit
65e87bf2f8
11 changed files with 235 additions and 54 deletions
|
@ -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);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
//}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue