From: Torsten Dreyer Date: Tue, 19 May 2015 09:56:01 +0000 (+0200) Subject: Merge commit 'c8115f516c47fd389b34f59055d3c2e9a6b697e2' into next X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=076f61f2b7e1f774bc827f34ab4a24dcc1998571;hp=c8115f516c47fd389b34f59055d3c2e9a6b697e2;p=flightgear.git Merge commit 'c8115f516c47fd389b34f59055d3c2e9a6b697e2' into next --- diff --git a/src/AIModel/AIFlightPlanCreate.cxx b/src/AIModel/AIFlightPlanCreate.cxx index 676cb4cc9..e39fb57ca 100644 --- a/src/AIModel/AIFlightPlanCreate.cxx +++ b/src/AIModel/AIFlightPlanCreate.cxx @@ -211,7 +211,7 @@ bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight, const string & acType, const string & airline) { - + int route; // If this function is called during initialization, // make sure we obtain a valid gate ID first // and place the model at the location of the gate. @@ -270,7 +270,7 @@ bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight, if (node == -1) { node = park->guid(); } else if (node == 0) { - // HAndle case where parking doens't have a node + // Handle case where parking doesn't have a node if (firstFlight) { node = park->guid(); } else { @@ -298,20 +298,24 @@ bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight, // but make sure we always keep two active waypoints // to prevent a segmentation fault for (int i = 0; i < nrWaypointsToSkip - 3; i++) { - taxiRoute.next(&node); + taxiRoute.next(&node, &route); } gate.release(); // free up our gate as required } else { if (taxiRoute.size() > 1) { - taxiRoute.next(&node); // chop off the first waypoint, because that is already the last of the pushback route + taxiRoute.next(&node, &route); // chop off the first waypoint, because that is already the last of the pushback route } } // push each node on the taxi route as a waypoint - // int route; + //cerr << "Building taxi route" << endl; - while (taxiRoute.next(&node)) { + + // Note that the line wpt->setRouteIndex was commented out by revision [afcdbd] 2012-01-01, + // which breaks the rendering functions. + // These can probably be generated on the fly however. + while (taxiRoute.next(&node, &route)) { char buffer[10]; snprintf(buffer, 10, "%lld", (long long int) node); FGTaxiNode *tn = @@ -319,7 +323,7 @@ bool FGAIFlightPlan::createTakeoffTaxi(FGAIAircraft * ac, bool firstFlight, FGAIWaypoint *wpt = createOnGround(ac, buffer, tn->geod(), apt->getElevation(), ac->getPerformance()->vTaxi()); - // wpt->setRouteIndex(route); + wpt->setRouteIndex(route); //cerr << "Nodes left " << taxiRoute->nodesLeft() << " "; if (taxiRoute.nodesLeft() == 1) { // Note that we actually have hold points in the ground network, but this is just an initial test. @@ -371,6 +375,7 @@ bool FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac, FGAirport * apt, const string & acType, const string & airline) { + int route; gate = apt->getDynamics()->getAvailableParking(radius, fltType, acType, airline); @@ -409,14 +414,15 @@ bool FGAIFlightPlan::createLandingTaxi(FGAIAircraft * ac, FGAirport * apt, // those are created by createParking() // int route; for (int i = 0; i < size - 2; i++) { - taxiRoute.next(&node); + taxiRoute.next(&node, &route); char buffer[10]; snprintf(buffer, 10, "%lld", (long long int) node); FGTaxiNode *tn = gn->findNode(node); FGAIWaypoint *wpt = createOnGround(ac, buffer, tn->geod(), apt->getElevation(), ac->getPerformance()->vTaxi()); - // wpt->setRouteIndex(route); + + wpt->setRouteIndex(route); pushBackWaypoint(wpt); } return true; diff --git a/src/AIModel/AIFlightPlanCreatePushBack.cxx b/src/AIModel/AIFlightPlanCreatePushBack.cxx index 0e7efc80c..d19f61e55 100644 --- a/src/AIModel/AIFlightPlanCreatePushBack.cxx +++ b/src/AIModel/AIFlightPlanCreatePushBack.cxx @@ -51,6 +51,7 @@ bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac, double vTaxi = ac->getPerformance()->vTaxi(); double vTaxiBackward = vTaxi * (-2.0/3.0); double vTaxiReduced = vTaxi * (2.0/3.0); + // Active runway can be conditionally set by ATC, so at the start of a new flight, this // must be reset. activeRunway.clear(); @@ -95,15 +96,17 @@ bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac, } route.first(); - PositionedID node, previous= 0; + PositionedID node; + int rte; - while (route.next(&node)) + while (route.next(&node, &rte)) { char buffer[10]; snprintf (buffer, 10, "%lld", (long long int) node); FGTaxiNode *tn = groundNet->findNode(node); FGAIWaypoint *wpt = createOnGround(ac, string(buffer), tn->geod(), dep->getElevation(), vTaxiBackward); - + + /* if (previous) { FGTaxiSegment* segment = groundNet->findSegment(previous, node); wpt->setRouteIndex(segment->getIndex()); @@ -111,10 +114,11 @@ bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac, // not on the route yet, make up a unique segment ID int x = (int) tn->guid(); wpt->setRouteIndex(x); - } - + }*/ + + wpt->setRouteIndex(rte); pushBackWaypoint(wpt); - previous = node; + //previous = node; } // some special considerations for the last point: waypoints.back()->setName(string("PushBackPoint")); diff --git a/src/AIModel/submodel.cxx b/src/AIModel/submodel.cxx index b3721466a..b93a779a7 100644 --- a/src/AIModel/submodel.cxx +++ b/src/AIModel/submodel.cxx @@ -302,8 +302,8 @@ bool FGSubmodelMgr::release(submodel *sm, double dt) ballist->setXoffset(sm->x_offset); ballist->setYoffset(sm->y_offset); ballist->setZoffset(sm->z_offset); - ballist->setPitchoffset(sm->pitch_offset); - ballist->setYawoffset(sm->yaw_offset); + ballist->setPitchoffset(sm->pitch_offset->get_value()); + ballist->setYawoffset(sm->yaw_offset->get_value()); ballist->setParentNodes(_selected_ac); ballist->setContentsNode(sm->contents_node); ballist->setWeight(sm->weight); @@ -353,6 +353,8 @@ void FGSubmodelMgr::transform(submodel *sm) if (sm->speed_node != 0) sm->speed = sm->speed_node->getDoubleValue(); + double yaw_offset = sm->yaw_offset->get_value(); + double pitch_offset = sm->pitch_offset->get_value(); //cout << " name " << name << " id " << id << " sub id" << sub_id << endl; @@ -434,8 +436,8 @@ void FGSubmodelMgr::transform(submodel *sm) // Get submodel initial velocity vector angles in XZ and XY planes. // This vector should be added to aircraft's vector. - IC.elevation += (sm->yaw_offset * sinRx) + (sm->pitch_offset * cosRx); - IC.azimuth += (sm->yaw_offset * cosRx) - (sm->pitch_offset * sinRx); + IC.elevation += (yaw_offset * sinRx) + (pitch_offset * cosRx); + IC.azimuth += (yaw_offset * cosRx) - (pitch_offset * sinRx); // calculate the total speed north IC.total_speed_north = sm->speed * cos(IC.elevation * SG_DEGREES_TO_RADIANS) @@ -547,8 +549,6 @@ void FGSubmodelMgr::setData(int id, const string& path, bool serviceable) sm->x_offset = entry_node->getDoubleValue("x-offset", 0.0); sm->y_offset = entry_node->getDoubleValue("y-offset", 0.0); sm->z_offset = entry_node->getDoubleValue("z-offset", 0.0); - sm->yaw_offset = entry_node->getDoubleValue("yaw-offset", 0.0); - sm->pitch_offset = entry_node->getDoubleValue("pitch-offset", 0.0); sm->drag_area = entry_node->getDoubleValue("eda", 0.034); sm->life = entry_node->getDoubleValue("life", 900.0); sm->buoyancy = entry_node->getDoubleValue("buoyancy", 0); @@ -571,6 +571,15 @@ void FGSubmodelMgr::setData(int id, const string& path, bool serviceable) sm->random = entry_node->getBoolValue("random", false); sm->randomness = entry_node->getDoubleValue("randomness", 0.5); + SGPropertyNode_ptr prop_root = fgGetNode("/", true); + SGPropertyNode n; + + SGPropertyNode_ptr a = entry_node->getNode("yaw-offset"); + sm->yaw_offset = new FGXMLAutopilot::InputValue(*prop_root, a ? *a : n ); + + a = entry_node->getNode("pitch-offset"); + sm->pitch_offset = new FGXMLAutopilot::InputValue(*prop_root, a ? *a : n ); + if (sm->contents_node != 0) sm->contents = sm->contents_node->getDoubleValue(); @@ -652,8 +661,6 @@ void FGSubmodelMgr::setSubData(int id, const string& path, bool serviceable) sm->x_offset = entry_node->getDoubleValue("x-offset", 0.0); sm->y_offset = entry_node->getDoubleValue("y-offset", 0.0); sm->z_offset = entry_node->getDoubleValue("z-offset", 0.0); - sm->yaw_offset = entry_node->getDoubleValue("yaw-offset", 0.0); - sm->pitch_offset = entry_node->getDoubleValue("pitch-offset", 0.0); sm->drag_area = entry_node->getDoubleValue("eda", 0.034); sm->life = entry_node->getDoubleValue("life", 900.0); sm->buoyancy = entry_node->getDoubleValue("buoyancy", 0); @@ -676,6 +683,15 @@ void FGSubmodelMgr::setSubData(int id, const string& path, bool serviceable) sm->random = entry_node->getBoolValue("random", false); sm->randomness = entry_node->getDoubleValue("randomness", 0.5); + SGPropertyNode_ptr prop_root = fgGetNode("/", true); + SGPropertyNode n; + + SGPropertyNode_ptr a = entry_node->getNode("yaw-offset"); + sm->yaw_offset = new FGXMLAutopilot::InputValue(*prop_root, a ? *a : n ); + + a = entry_node->getNode("pitch-offset"); + sm->pitch_offset = new FGXMLAutopilot::InputValue(*prop_root, a ? *a : n ); + if (sm->contents_node != 0) sm->contents = sm->contents_node->getDoubleValue(); diff --git a/src/AIModel/submodel.hxx b/src/AIModel/submodel.hxx index 5d01d3d76..21583b2f7 100644 --- a/src/AIModel/submodel.hxx +++ b/src/AIModel/submodel.hxx @@ -15,6 +15,8 @@ #include #include +#include + #include #include @@ -44,8 +46,8 @@ public: double x_offset; double y_offset; double z_offset; - double yaw_offset; - double pitch_offset; + FGXMLAutopilot::InputValue_ptr yaw_offset; + FGXMLAutopilot::InputValue_ptr pitch_offset; double drag_area; double life; double buoyancy; diff --git a/src/ATC/atc_mgr.cxx b/src/ATC/atc_mgr.cxx index 416229ca7..1b3a4dc27 100644 --- a/src/ATC/atc_mgr.cxx +++ b/src/ATC/atc_mgr.cxx @@ -42,7 +42,7 @@ FGATCManager::FGATCManager() { } FGATCManager::~FGATCManager() { - + delete pk; } void FGATCManager::init() { @@ -105,10 +105,11 @@ void FGATCManager::init() { FGAirport *apt = FGAirport::findByIdent(airport); if (apt && onGround) {// && !runway.empty()) { FGAirportDynamics* dcs = apt->getDynamics(); - ParkingAssignment pk(dcs->getParkingByName(parking)); + pk = new ParkingAssignment(dcs->getParkingByName(parking)); // No valid parking location, so either at the runway or at a random location. - if (pk.isValid()) { + if (pk->isValid()) { + dcs->setParkingAvailable(pk->parking()->guid(), false); fp = new FGAIFlightPlan; controller = apt->getDynamics()->getStartupController(); int stationFreq = apt->getDynamics()->getGroundFrequency(1); @@ -120,11 +121,11 @@ void FGATCManager::init() { leg = 1; //double, lat, lon, head; // Unused variables; //int getId = apt->getDynamics()->getParking(gateId, &lat, &lon, &head); - aircraftRadius = pk.parking()->getRadius(); - string fltType = pk.parking()->getType(); // gate / ramp, ga, etc etc. + aircraftRadius = pk->parking()->getRadius(); + string fltType = pk->parking()->getType(); // gate / ramp, ga, etc etc. string aircraftType; // Unused. string airline; // Currently used for gate selection, but a fallback mechanism will apply when not specified. - fp->setGate(pk); + fp->setGate(*pk); if (!(fp->createPushBack(&ai_ac, false, apt, @@ -208,16 +209,17 @@ void FGATCManager::update ( double time ) { //cerr << "Shutting down the atc_mgr" << endl; return; } - //cerr << "Size of waypoint cue " << size << " "; - //for (int i = 0; i < size; i++) { - // int val = fp->getRouteIndex(i); - //cerr << fp->getWayPoint(i)->getName() << " "; + // Test code: Print how far we're progressing along the taxi route. + //std::cerr << "Size of waypoint cue " << size << " "; + for (int i = 0; i < size; i++) { + int val = fp->getRouteIndex(i); + //std::cerr << fp->getWayPoint(i)->getName() << " "; //if ((val) && (val != pos)) { - //intentions.push_back(val); - //cerr << "[done ] " << endl; + // intentions.push_back(val); + // std::cerr << "[done ] " << std::endl; //} - //} - //cerr << "[done ] " << endl; + } + //std::cerr << "[done ] " << std::endl; } if (fp) { //cerr << "Currently at leg : " << fp->getLeg() << endl; diff --git a/src/ATC/atc_mgr.hxx b/src/ATC/atc_mgr.hxx index 09d40197a..03d37690c 100644 --- a/src/ATC/atc_mgr.hxx +++ b/src/ATC/atc_mgr.hxx @@ -53,6 +53,7 @@ private: bool networkVisible; bool initSucceeded; SGPropertyNode_ptr trans_num; + ParkingAssignment *pk; public: FGATCManager(); diff --git a/src/ATC/atcdialog.cxx b/src/ATC/atcdialog.cxx index f2b96f464..67a037735 100644 --- a/src/ATC/atcdialog.cxx +++ b/src/ATC/atcdialog.cxx @@ -48,147 +48,147 @@ using std::string; static SGPropertyNode *getNamedNode(SGPropertyNode *prop, const char *name) { - SGPropertyNode* p; - - for (int i = 0; i < prop->nChildren(); i++) - if ((p = getNamedNode(prop->getChild(i), name))) - return p; - - if (!strcmp(prop->getStringValue("name"), name)) - return prop; - return 0; + SGPropertyNode* p; + + for (int i = 0; i < prop->nChildren(); i++) + if ((p = getNamedNode(prop->getChild(i), name))) + return p; + + if (!strcmp(prop->getStringValue("name"), name)) + return prop; + return 0; } static void atcUppercase(string &s) { - for(unsigned int i=0; icommStations().empty()); - } + virtual FGPositioned::Type maxType() const { + return FGPositioned::SEAPORT; + } + + virtual bool passAirport(FGAirport* aApt) const + { + return (!aApt->commStations().empty()); + } }; void FGATCDialogNew::frequencySearch() { - const char *dialog_name = "atc-freq-search"; - SGPropertyNode_ptr dlg = _gui->getDialogProperties(dialog_name); - if (!dlg) - return; - - _gui->closeDialog(dialog_name); - - SGPropertyNode_ptr button_group = getNamedNode(dlg, "quick-buttons"); - // remove all dynamic airport/ATC buttons - button_group->removeChildren("button"); - - AirportsWithATC filt; - FGPositionedList results = FGPositioned::findWithinRange(globals->get_aircraft_position(), 50.0, &filt); - FGPositioned::sortByRange(results, globals->get_aircraft_position()); - for (unsigned int r=0; (rgetNode("button", r, true); - copyProperties(button_group->getNode("button-template", true), entry); - entry->removeChildren("enabled"); - entry->setStringValue("legend", results[r]->ident()); - entry->setStringValue("binding[0]/icao", results[r]->ident()); - } - - // (un)hide message saying no things in range - SGPropertyNode_ptr range_error = getNamedNode(dlg, "no-atc-in-range"); - range_error->setBoolValue("visible", !results.empty()); - - _gui->showDialog(dialog_name); + const char *dialog_name = "atc-freq-search"; + SGPropertyNode_ptr dlg = _gui->getDialogProperties(dialog_name); + if (!dlg) + return; + + _gui->closeDialog(dialog_name); + + SGPropertyNode_ptr button_group = getNamedNode(dlg, "quick-buttons"); + // remove all dynamic airport/ATC buttons + button_group->removeChildren("button"); + + AirportsWithATC filt; + FGPositionedList results = FGPositioned::findWithinRange(globals->get_aircraft_position(), 50.0, &filt); + FGPositioned::sortByRange(results, globals->get_aircraft_position()); + for (unsigned int r=0; (rgetNode("button", r, true); + copyProperties(button_group->getNode("button-template", true), entry); + entry->removeChildren("enabled"); + entry->setStringValue("legend", results[r]->ident()); + entry->setStringValue("binding[0]/icao", results[r]->ident()); + } + + // (un)hide message saying no things in range + SGPropertyNode_ptr range_error = getNamedNode(dlg, "no-atc-in-range"); + range_error->setBoolValue("visible", !results.empty()); + + _gui->showDialog(dialog_name); } void FGATCDialogNew::frequencyDisplay(const std::string& ident) { - const char *dialog_name = "atc-freq-display"; - SGPropertyNode_ptr dlg = _gui->getDialogProperties(dialog_name); - if (!dlg) - return; - - _gui->closeDialog(dialog_name); - - SGPropertyNode_ptr freq_group = getNamedNode(dlg, "frequency-list"); - // remove all frequency entries - freq_group->removeChildren("group"); - - std::string uident(ident); - atcUppercase(uident); - string label; - - const FGAirport *a = fgFindAirportID(uident); - if (!a) { - label = "Airport " + ident + " not found in database."; - mkDialog(label.c_str()); - return; - } - - // set title - label = uident + " Frequencies"; - dlg->setStringValue("text/label", label.c_str()); - - const flightgear::CommStationList& comms(a->commStations()); - if (comms.empty()) { - label = "No frequencies found for airport " + uident; - mkDialog(label.c_str()); - return; - } - - for (unsigned int c=0; c < comms.size(); ++c) { - flightgear::CommStation* comm = comms[c]; - - // add frequency line (modified copy of ) - SGPropertyNode *entry = freq_group->getNode("group", c, true); - copyProperties(freq_group->getNode("group-template", true), entry); - entry->removeChildren("enabled"); - - entry->setStringValue("text[0]/label", comm->ident()); - - char buf[8]; - snprintf(buf, 8, "%.2f", comm->freqMHz()); - if(buf[5] == '3') buf[5] = '2'; - if(buf[5] == '8') buf[5] = '7'; - buf[7] = '\0'; - - entry->setStringValue("text[1]/label", buf); - } - - _gui->showDialog(dialog_name); + const char *dialog_name = "atc-freq-display"; + SGPropertyNode_ptr dlg = _gui->getDialogProperties(dialog_name); + if (!dlg) + return; + + _gui->closeDialog(dialog_name); + + SGPropertyNode_ptr freq_group = getNamedNode(dlg, "frequency-list"); + // remove all frequency entries + freq_group->removeChildren("group"); + + std::string uident(ident); + atcUppercase(uident); + string label; + + const FGAirport *a = fgFindAirportID(uident); + if (!a) { + label = "Airport " + ident + " not found in database."; + mkDialog(label.c_str()); + return; + } + + // set title + label = uident + " Frequencies"; + dlg->setStringValue("text/label", label.c_str()); + + const flightgear::CommStationList& comms(a->commStations()); + if (comms.empty()) { + label = "No frequencies found for airport " + uident; + mkDialog(label.c_str()); + return; + } + + for (unsigned int c=0; c < comms.size(); ++c) { + flightgear::CommStation* comm = comms[c]; + + // add frequency line (modified copy of ) + SGPropertyNode *entry = freq_group->getNode("group", c, true); + copyProperties(freq_group->getNode("group-template", true), entry); + entry->removeChildren("enabled"); + + entry->setStringValue("text[0]/label", comm->ident()); + + char buf[8]; + snprintf(buf, 8, "%.2f", comm->freqMHz()); + if(buf[5] == '3') buf[5] = '2'; + if(buf[5] == '8') buf[5] = '7'; + buf[7] = '\0'; + + entry->setStringValue("text[1]/label", buf); + } + + _gui->showDialog(dialog_name); } static bool doFrequencySearch( const SGPropertyNode* ) { - FGATCDialogNew::instance()->frequencySearch(); - return true; + FGATCDialogNew::instance()->frequencySearch(); + return true; } static bool doFrequencyDisplay( const SGPropertyNode* args ) { - std::string icao = args->getStringValue("icao"); - if (icao.empty()) { - icao = fgGetString("/sim/atc/freq-airport"); - } - - FGATCDialogNew::instance()->frequencyDisplay(icao); - return true; + std::string icao = args->getStringValue("icao"); + if (icao.empty()) { + icao = fgGetString("/sim/atc/freq-airport"); + } + + FGATCDialogNew::instance()->frequencyDisplay(icao); + return true; } FGATCDialogNew * FGATCDialogNew::_instance = NULL; FGATCDialogNew::FGATCDialogNew() -: _gui(NULL), - dialogVisible(true) + : _gui(NULL), + dialogVisible(true) { } @@ -204,7 +204,7 @@ void FGATCDialogNew::init() { // Add ATC-freq-search to the command list globals->get_commands()->addCommand("ATC-freq-search", doFrequencySearch); globals->get_commands()->addCommand("ATC-freq-display", doFrequencyDisplay); - + // initialize properties polled in Update() //globals->get_props()->setStringValue("/sim/atc/freq-airport", ""); globals->get_props()->setIntValue("/sim/atc/transmission-num", -1); @@ -213,9 +213,9 @@ void FGATCDialogNew::init() { // Display the ATC popup dialog box with options relevant to the users current situation. -// +// // So, the first thing we need to do is check the frequency that our pilot's nav radio -// is currently tuned to. The dialog should always contain an option to to tune the +// is currently tuned to. The dialog should always contain an option to to tune the // to a particular frequency, // Okay, let's see, according to my interpretation of David Luff's original code, @@ -248,9 +248,9 @@ void FGATCDialogNew::update(double dt) { const char *dialog_name = "atc-dialog"; _gui = (NewGUI *)globals->get_subsystem("gui"); if (!_gui) { - return; + return; } - + SGPropertyNode_ptr dlg = _gui->getDialogProperties(dialog_name); if (!dlg) return; @@ -265,21 +265,21 @@ void FGATCDialogNew::update(double dt) { // loop over all entries that should fill up the dialog; use 10 items for now... BOOST_FOREACH(const std::string& i, commands) { snprintf(buf, bufsize, "/sim/atc/opt[%d]", commandNr); - fgSetBool(buf, false); + fgSetBool(buf, false); SGPropertyNode *entry = button_group->getNode("button", commandNr, true); copyProperties(button_group->getNode("button-template", true), entry); - entry->removeChildren("enabled"); - 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); + entry->removeChildren("enabled"); + 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++; + //current++; } if (dialogVisible) { diff --git a/src/ATC/trafficcontrol.cxx b/src/ATC/trafficcontrol.cxx index 907818cfb..e25bb0a43 100644 --- a/src/ATC/trafficcontrol.cxx +++ b/src/ATC/trafficcontrol.cxx @@ -1048,7 +1048,7 @@ FGATCInstruction FGTowerController::getInstruction(int id) } void FGTowerController::render(bool visible) { - //cerr << "FGTowerController::render function not yet implemented" << endl; + //std::cerr << "FGTowerController::render function not yet implemented" << std::endl; } string FGTowerController::getName() { @@ -1315,7 +1315,7 @@ static void WorldCoordinate(osg::Matrix& obj_pos, double lat, void FGStartupController::render(bool visible) { - + //std::cerr << "Rendering startup controller" << std::endl; SGMaterialLib *matlib = globals->get_matlib(); if (group) { //int nr = ; @@ -1716,7 +1716,7 @@ ActiveRunway *FGApproachController::getRunway(const string& name) } void FGApproachController::render(bool visible) { - //cerr << "FGApproachController::render function not yet implemented" << endl; + std::cerr << "FGApproachController::render function not yet implemented" << std::endl; } diff --git a/src/Airports/groundnetwork.cxx b/src/Airports/groundnetwork.cxx index 7f82d2da2..a6ad1f5c4 100644 --- a/src/Airports/groundnetwork.cxx +++ b/src/Airports/groundnetwork.cxx @@ -145,13 +145,22 @@ void FGTaxiSegment::unblock(time_t now) /*************************************************************************** * FGTaxiRoute **************************************************************************/ -bool FGTaxiRoute::next(PositionedID *nde) +bool FGTaxiRoute::next(PositionedID *nde, int *rte) { + if (nodes.size() != (routes.size()) + 1) { + SG_LOG(SG_GENERAL, SG_ALERT, "ALERT: Misconfigured TaxiRoute : " << nodes.size() << " " << routes.size()); + throw sg_range_exception("Misconfigured taxi route"); + } if (currNode == nodes.end()) return false; - *nde = *(currNode); - + if (currNode != nodes.begin()) { + *rte = *(currRoute); + currRoute++; + } else { + // Handle special case for the first node. + *rte = -1 * *(currRoute); + } currNode++; return true; }; @@ -255,7 +264,7 @@ void FGGroundNetwork::init(FGAirport* pr) segment->setIndex(index++); if (segment->oppositeDirection) { - continue; // already establish + continue; // already established } FGTaxiSegment* opp = findSegment(segment->endNode, segment->startNode); @@ -469,14 +478,21 @@ FGTaxiRoute FGGroundNetwork::findShortestRoute(PositionedID start, PositionedID // assemble route from backtrace information PositionedIDVec nodes; + intVec routes; FGTaxiNode *bt = lastNode; + while (searchData[bt].previousNode != 0) { nodes.push_back(bt->guid()); + FGTaxiSegment *segment = findSegment(searchData[bt].previousNode->guid(), bt->guid()); + int idx = segment->getIndex(); + routes.push_back(idx); bt = searchData[bt].previousNode; + } nodes.push_back(start); reverse(nodes.begin(), nodes.end()); - return FGTaxiRoute(nodes, searchData[lastNode].score, 0); + reverse(routes.begin(), routes.end()); + return FGTaxiRoute(nodes, routes, searchData[lastNode].score, 0); } /* ATC Related Functions */ @@ -489,7 +505,9 @@ void FGGroundNetwork::announcePosition(int id, double radius, int leg, FGAIAircraft * aircraft) { + assert(parent); + init(parent); TrafficVectorIterator i = activeTraffic.begin(); // Search search if the current id alread has an entry @@ -1140,7 +1158,6 @@ static void WorldCoordinate(osg::Matrix& obj_pos, double lat, void FGGroundNetwork::render(bool visible) { - SGMaterialLib *matlib = globals->get_matlib(); if (group) { //int nr = ; @@ -1163,7 +1180,8 @@ void FGGroundNetwork::render(bool visible) //for ( FGTaxiSegmentVectorIterator i = segments.begin(); i != segments.end(); i++) { //double dx = 0; for (TrafficVectorIterator i = activeTraffic.begin(); i != activeTraffic.end(); i++) { - // Handle start point + // Handle start point i.e. the segment that is connected to the aircraft itself on the starting end + // and to the the first "real" taxi segment on the other end. int pos = i->getCurrentPosition() - 1; if (pos >= 0) { @@ -1178,7 +1196,7 @@ void FGGroundNetwork::render(bool visible) double coveredDistance = length * 0.5; SGGeod center; SGGeodesy::direct(start, heading, coveredDistance, center, az2); - //cerr << "Active Aircraft : Centerpoint = (" << center.getLatitudeDeg() << ", " << center.getLongitudeDeg() << "). Heading = " << heading << endl; + //std::cerr << "Active Aircraft : Centerpoint = (" << center.getLatitudeDeg() << ", " << center.getLongitudeDeg() << "). Heading = " << heading << std::endl; /////////////////////////////////////////////////////////////////////////////// // Make a helper function out of this osg::Matrix obj_pos; @@ -1242,8 +1260,9 @@ void FGGroundNetwork::render(bool visible) group->addChild( obj_trans ); ///////////////////////////////////////////////////////////////////// } else { - //cerr << "BIG FAT WARNING: current position is here : " << pos << endl; + //std::cerr << "BIG FAT WARNING: current position is here : " << pos << std::endl; } + // Next: Draw the other taxi segments. for (intVecIterator j = (i)->getIntentions().begin(); j != (i)->getIntentions().end(); j++) { osg::Matrix obj_pos; int k = (*j)-1; diff --git a/src/Airports/groundnetwork.hxx b/src/Airports/groundnetwork.hxx index 76eaa899e..80b7e0256 100644 --- a/src/Airports/groundnetwork.hxx +++ b/src/Airports/groundnetwork.hxx @@ -108,32 +108,41 @@ class FGTaxiRoute { private: PositionedIDVec nodes; + intVec routes; double distance; PositionedIDVec::iterator currNode; + intVec::iterator currRoute; public: FGTaxiRoute() { distance = 0; currNode = nodes.begin(); + currRoute = routes.begin(); }; - FGTaxiRoute(const PositionedIDVec& nds, double dist, int dpth) { + FGTaxiRoute(const PositionedIDVec& nds, intVec rts, double dist, int dpth) { nodes = nds; + routes = rts; distance = dist; currNode = nodes.begin(); + currRoute = routes.begin(); }; FGTaxiRoute& operator= (const FGTaxiRoute &other) { nodes = other.nodes; + routes = other.routes; distance = other.distance; currNode = nodes.begin(); + currRoute = routes.begin(); return *this; }; FGTaxiRoute(const FGTaxiRoute& copy) : nodes(copy.nodes), + routes(copy.routes), distance(copy.distance), - currNode(nodes.begin()) + currNode(nodes.begin()), + currRoute(routes.begin()) {}; bool operator< (const FGTaxiRoute &other) const { @@ -142,10 +151,11 @@ public: bool empty () { return nodes.empty(); }; - bool next(PositionedID *nde); + bool next(PositionedID *nde, int *rte); void first() { currNode = nodes.begin(); + currRoute = routes.begin(); }; int size() { return nodes.size(); diff --git a/src/Airports/xmlloader.cxx b/src/Airports/xmlloader.cxx index 8291358b4..a4dddabc6 100644 --- a/src/Airports/xmlloader.cxx +++ b/src/Airports/xmlloader.cxx @@ -50,9 +50,9 @@ void XMLLoader::load(FGAirportDynamics* d) } flightgear::NavDataCache* cache = flightgear::NavDataCache::instance(); - if (!cache->isCachedFileModified(path) || cache->isReadOnly()) { - return; - } + //if (!cache->isCachedFileModified(path) || cache->isReadOnly()) { + // return; + //} SG_LOG(SG_NAVAID, SG_INFO, "reading groundnet data from " << path); SGTimeStamp t; diff --git a/src/Main/positioninit.cxx b/src/Main/positioninit.cxx index f3bac6f7e..6acbe2159 100644 --- a/src/Main/positioninit.cxx +++ b/src/Main/positioninit.cxx @@ -183,6 +183,10 @@ static bool setPosFromAirportIDandHdg( const string& id, double tgt_hdg ) { // Set current_options lon/lat given an airport id and parkig position name static bool fgSetPosFromAirportIDandParkpos( const string& id, const string& parkpos ) { + string fltType; + string acOperator; + string acType; // Currently not used by findAvailable parking, so safe to leave empty. + SGPath acData; if ( id.empty() ) return false; @@ -202,9 +206,7 @@ static bool fgSetPosFromAirportIDandParkpos( const string& id, const string& par ParkingAssignment pka; double radius = fgGetDouble("/sim/dimensions/radius-m"); if ((parkpos == string("AVAILABLE")) && (radius > 0)) { - string fltType; - string acOperator; - SGPath acData; + try { acData = globals->get_fg_home(); acData.append("aircraft-data"); @@ -232,9 +234,10 @@ static bool fgSetPosFromAirportIDandParkpos( const string& id, const string& par acOperator = fgGetString("/sim/aircraft-operator" ); } - string acType; // Currently not used by findAvailable parking, so safe to leave empty. + pka = dcs->getAvailableParking(radius, fltType, acType, acOperator); if (pka.isValid()) { + // why is the following line necessary? fgGetString("/sim/presets/parkpos"); fgSetString("/sim/presets/parkpos", pka.parking()->getName()); } else { @@ -243,6 +246,7 @@ static bool fgSetPosFromAirportIDandParkpos( const string& id, const string& par return false; } } else { + pka = dcs->getParkingByName(parkpos); if (!pka.isValid()) { SG_LOG( SG_GENERAL, SG_ALERT, @@ -250,7 +254,14 @@ static bool fgSetPosFromAirportIDandParkpos( const string& id, const string& par return false; } } - + // Why is the following line necessary? + fgGetString("/sim/presets/parkpos"); + fgSetString("/sim/presets/parkpos", pka.parking()->getName()); + // The problem is, this line doesn't work because the ParkingAssignment's refcounting mechanism: + // The parking will be released after this function returns. + // As a temporary measure, I'll try to reserve the parking via the atc_manager, which should work, because it uses the same + // mechanism as the AI traffic code. + dcs->setParkingAvailable(pka.parking()->guid(), false); fgApplyStartOffset(pka.parking()->geod(), pka.parking()->getHeading()); return true; } diff --git a/src/Sound/soundmanager.cxx b/src/Sound/soundmanager.cxx index 906ffd798..bb1b83418 100644 --- a/src/Sound/soundmanager.cxx +++ b/src/Sound/soundmanager.cxx @@ -71,9 +71,10 @@ void FGSoundManager::init() _device_name = fgGetNode("/sim/sound/device-name"); _currentView = fgGetNode("sim/current-view"); - _viewPosLon = fgGetNode("sim/current-view/viewer-lon-deg"); - _viewPosLat = fgGetNode("sim/current-view/viewer-lat-deg"); - _viewPosElev = fgGetNode("sim/current-view/viewer-elev-ft"); + + _viewX = _currentView->getNode("viewer-x-m", true); + _viewY = _currentView->getNode("viewer-y-m", true); + _viewZ = _currentView->getNode("viewer-z-m", true); _velocityNorthFPS = fgGetNode("velocities/speed-north-fps", true); _velocityEastFPS = fgGetNode("velocities/speed-east-fps", true); @@ -172,12 +173,12 @@ void FGSoundManager::update(double dt) } if (enabled) { - SGGeod viewPosGeod(SGGeod::fromDegFt(_viewPosLon->getDoubleValue(), - _viewPosLat->getDoubleValue(), - _viewPosElev->getDoubleValue())); - SGVec3d cartPos = SGVec3d::fromGeod(viewPosGeod); + SGVec3d cartPos(_viewX->getDoubleValue(), + _viewY->getDoubleValue(), + _viewZ->getDoubleValue()); + SGGeod geodPos = SGGeod::fromCart(cartPos); - set_position(cartPos, viewPosGeod); + set_position(cartPos, geodPos); SGQuatd viewOrientation; for (int i=0; i<4; ++i) { diff --git a/src/Sound/soundmanager.hxx b/src/Sound/soundmanager.hxx index 7f5a16499..f76be4b80 100644 --- a/src/Sound/soundmanager.hxx +++ b/src/Sound/soundmanager.hxx @@ -55,7 +55,7 @@ private: bool _is_initialized, _enabled; SGPropertyNode_ptr _sound_working, _sound_enabled, _volume, _device_name; SGPropertyNode_ptr _currentView; - SGPropertyNode_ptr _viewPosLon, _viewPosLat, _viewPosElev; + SGPropertyNode_ptr _viewX, _viewY, _viewZ; SGPropertyNode_ptr _velocityNorthFPS, _velocityEastFPS, _velocityDownFPS; SGPropertyNode_ptr _viewXoffset, _viewYoffset, _viewZoffset; std::auto_ptr _listener; diff --git a/src/Traffic/TrafficMgr.cxx b/src/Traffic/TrafficMgr.cxx index c4abd8364..e17c801cf 100644 --- a/src/Traffic/TrafficMgr.cxx +++ b/src/Traffic/TrafficMgr.cxx @@ -454,14 +454,21 @@ void FGTrafficManager::shutdown() ::snprintf(buffer, 128, "%c/%c/%c/", airport[0], airport[1], airport[2]); cacheData.append(buffer); + cacheData.append(airport + "-cache.txt"); + + // Note: Intuitively, this doesn't make sense, but I do need to create the full file path first + // before creating the directories. The SimGear fgpath code has changed so that it first chops off + // the trailing dir separator and then determines the directory part of the file path by searching + // for the last dir separator. Effecively, this causes a full element of the directory tree to be + // skipped. + SG_LOG(SG_GENERAL, SG_DEBUG, "Trying to create dir for : " << cacheData.c_str()); if (!cacheData.exists()) { cacheData.create_dir(0755); } - cacheData.append(airport + "-cache.txt"); - //cerr << "Saving AI traffic heuristics" << endl; saveData = true; cachefile.open(cacheData.str().c_str()); cachefile << "[TrafficManagerCachedata:ref:2011:09:04]" << endl; + } } diff --git a/src/Viewer/viewer.cxx b/src/Viewer/viewer.cxx index a18c51b23..7061f76cb 100644 --- a/src/Viewer/viewer.cxx +++ b/src/Viewer/viewer.cxx @@ -310,11 +310,15 @@ FGViewer::setGoalPitchOffset_deg (double goal_pitch_offset_deg) { _dirty = true; _goal_pitch_offset_deg = goal_pitch_offset_deg; - if ( _goal_pitch_offset_deg < -90 ) { - _goal_pitch_offset_deg = -90.0; + /* The angle is set to 1/1000th of a degree from the poles to avoid the + * singularity where the azimuthal angle becomes undefined, inducing optical + * artefacts. The arbitrary angle offset is visually unnoticeable while + * avoiding any possible floating point truncation artefacts. */ + if ( _goal_pitch_offset_deg < -89.999 ) { + _goal_pitch_offset_deg = -89.999; } - if ( _goal_pitch_offset_deg > 90.0 ) { - _goal_pitch_offset_deg = 90.0; + if ( _goal_pitch_offset_deg > 89.999 ) { + _goal_pitch_offset_deg = 89.999; } }