From c2a3d24ef3c77f4c1457f69c21ef7fc5091494b8 Mon Sep 17 00:00:00 2001 From: James Turner <zakalawe@mac.com> Date: Fri, 14 Jan 2011 20:04:20 +0000 Subject: [PATCH 01/25] Make the Nasal NaN check less aggressive - still SG_ALERT, but return nil instead of terminating the Nasal script completely. --- src/Scripting/NasalSys.cxx | 2 +- src/Scripting/nasal-props.cxx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Scripting/NasalSys.cxx b/src/Scripting/NasalSys.cxx index 158d852e5..1f952b325 100644 --- a/src/Scripting/NasalSys.cxx +++ b/src/Scripting/NasalSys.cxx @@ -190,7 +190,7 @@ static naRef f_getprop(naContext c, naRef me, int argc, naRef* args) double dv = p->getDoubleValue(); if (osg::isNaN(dv)) { SG_LOG(SG_GENERAL, SG_ALERT, "Nasal getprop: property " << p->getPath() << " is NaN"); - naRuntimeError(c, "getprop() would have read NaN"); + return naNil(); } return naNum(dv); diff --git a/src/Scripting/nasal-props.cxx b/src/Scripting/nasal-props.cxx index 0ea341b08..214cc5c9a 100644 --- a/src/Scripting/nasal-props.cxx +++ b/src/Scripting/nasal-props.cxx @@ -173,7 +173,7 @@ static naRef f_getValue(naContext c, naRef me, int argc, naRef* args) double dv = (*node)->getDoubleValue(); if (osg::isNaN(dv)) { SG_LOG(SG_GENERAL, SG_ALERT, "Nasal getValue: property " << (*node)->getPath() << " is NaN"); - naRuntimeError(c, "props.getValue() would have read NaN"); + return naNil(); } return naNum(dv); From 4043e797744a9ebc4e143c3160f0755c3ef46c6e Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Mon, 10 Jan 2011 20:53:46 +0100 Subject: [PATCH 02/25] AI traffic performance boost for busy airports Stop ground elevation (scenery) checks for stationary AI aircraft. --- src/AIModel/AIAircraft.cxx | 18 ++++++++++++++++-- src/AIModel/AIAircraft.hxx | 3 +++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/AIModel/AIAircraft.cxx b/src/AIModel/AIAircraft.cxx index 52459a9cf..addfba9f7 100644 --- a/src/AIModel/AIAircraft.cxx +++ b/src/AIModel/AIAircraft.cxx @@ -84,6 +84,7 @@ FGAIAircraft::FGAIAircraft(FGAISchedule *ref) : FGAIBase(otAircraft) { holdPos = false; needsTaxiClearance = false; + _needsGroundElevation = true; _performance = 0; //TODO initialize to JET_TRANSPORT from PerformanceDB dt = 0; @@ -179,6 +180,8 @@ void FGAIAircraft::checkVisibility() void FGAIAircraft::AccelTo(double speed) { tgt_speed = speed; + if (!isStationary()) + _needsGroundElevation = true; } @@ -334,7 +337,7 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) { use_perf_vs = true; } } - tgt_speed = prev->speed; + AccelTo(prev->speed); hdg_lock = alt_lock = true; no_roll = prev->on_ground; } @@ -403,6 +406,8 @@ bool FGAIAircraft::loadNextLeg(double distance) { void FGAIAircraft::getGroundElev(double dt) { dt_elev_count += dt; + if (!needGroundElevation()) + return; // Update minimally every three secs, but add some randomness // to prevent all AI objects doing this in synchrony if (dt_elev_count < (3.0) + (rand() % 10)) @@ -424,14 +429,22 @@ void FGAIAircraft::getGroundElev(double dt) { { double alt; if (getGroundElevationM(SGGeod::fromGeodM(pos, 20000), alt, 0)) + { tgt_altitude_ft = alt * SG_METER_TO_FEET; + if (isStationary()) + { + // aircraft is stationary and we obtained altitude for this spot - we're done. + _needsGroundElevation = false; + } + } } } } void FGAIAircraft::doGroundAltitude() { - if (fabs(altitude_ft - (tgt_altitude_ft+groundOffset)) > 1000.0) + if ((fabs(altitude_ft - (tgt_altitude_ft+groundOffset)) > 1000.0)|| + (fabs(speed)<0.0001)) altitude_ft = (tgt_altitude_ft + groundOffset); else altitude_ft += 0.1 * ((tgt_altitude_ft+groundOffset) - altitude_ft); @@ -601,6 +614,7 @@ void FGAIAircraft::handleFirstWaypoint() { Transform(); // make sure aip is initialized. getGroundElev(60.1); // make sure it's executed first time around, so force a large dt value doGroundAltitude(); + _needsGroundElevation = true; // check ground elevation again (maybe scenery wasn't available yet) } // Make sure to announce the aircraft's position announcePositionToController(); diff --git a/src/AIModel/AIAircraft.hxx b/src/AIModel/AIAircraft.hxx index 26ceb5120..1d8103726 100644 --- a/src/AIModel/AIAircraft.hxx +++ b/src/AIModel/AIAircraft.hxx @@ -141,6 +141,8 @@ private: void updateActualState(); void handleATCRequests(); void checkVisibility(); + inline bool isStationary() { return ((fabs(speed)<=0.0001)&&(fabs(tgt_speed)<=0.0001));} + inline bool needGroundElevation() { if (!isStationary()) _needsGroundElevation=true;return _needsGroundElevation;} double sign(double x); @@ -160,6 +162,7 @@ private: bool reachedWaypoint; bool needsTaxiClearance; + bool _needsGroundElevation; time_t timeElapsed; PerformanceData* _performance; // the performance data for this aircraft From 5ec5c34255d2488d5a7b255cf9c95520eccf3ac5 Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Mon, 10 Jan 2011 21:19:51 +0100 Subject: [PATCH 03/25] Minor update Missed this place during code clean-up --- src/AIModel/AIAircraft.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AIModel/AIAircraft.cxx b/src/AIModel/AIAircraft.cxx index addfba9f7..8d7df9225 100644 --- a/src/AIModel/AIAircraft.cxx +++ b/src/AIModel/AIAircraft.cxx @@ -444,7 +444,7 @@ void FGAIAircraft::getGroundElev(double dt) { void FGAIAircraft::doGroundAltitude() { if ((fabs(altitude_ft - (tgt_altitude_ft+groundOffset)) > 1000.0)|| - (fabs(speed)<0.0001)) + (isStationary())) altitude_ft = (tgt_altitude_ft + groundOffset); else altitude_ft += 0.1 * ((tgt_altitude_ft+groundOffset) - altitude_ft); From f025c65c60ba34c2fd91bc52f201463d992cf613 Mon Sep 17 00:00:00 2001 From: John Denker <jsd@av8n.com> Date: Mon, 30 Nov 2009 03:19:17 -0700 Subject: [PATCH 04/25] Fix ADF bugs ... including still driving the needle when power off. ADF bug fixes from John Denker. Changes from current behaviour are: * Include the power button in the electrical checks * Raise the required input voltage from 1V to 8V * Don't reset the heading to 90 degrees when out of range or no power (heading is now only reset to 90 in ANT or TEST mode) --- src/Instrumentation/adf.cxx | 23 ++++++++++++++--------- src/Instrumentation/adf.hxx | 1 + 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/Instrumentation/adf.cxx b/src/Instrumentation/adf.cxx index 6da2a2ed4..41ee7700e 100644 --- a/src/Instrumentation/adf.cxx +++ b/src/Instrumentation/adf.cxx @@ -101,6 +101,10 @@ ADF::init () _bearing_node = node->getChild("indicated-bearing-deg", 0, true); _ident_node = node->getChild("ident", 0, true); _ident_audible_node = node->getChild("ident-audible", 0, true); + _power_btn_node = node->getChild("power-btn", 0, true); + + if (_power_btn_node->getType() == simgear::props::NONE) + _power_btn_node->setBoolValue(true); // front end didn't implement a power button SGSoundMgr *smgr = globals->get_soundmgr(); _sgr = smgr->find("avionics", true); @@ -117,13 +121,19 @@ void ADF::update (double delta_time_sec) { // If it's off, don't waste any time. - if (_electrical_node->getDoubleValue() < 1.0 - || !_serviceable_node->getBoolValue()) { - set_bearing(delta_time_sec, 90); + if (_electrical_node->getDoubleValue() < 8.0 + || !_serviceable_node->getBoolValue() + || !_power_btn_node->getBoolValue() ) { _ident_node->setStringValue(""); return; } + string mode = _mode_node->getStringValue(); + if (mode == "ant" || mode == "test") set_bearing(delta_time_sec, 90); + if (mode != "bfo" && mode != "adf") { + _ident_node->setStringValue(""); + return; + } // Get the frequency int frequency_khz = _frequency_node->getIntValue(); if (frequency_khz != _last_frequency_khz) { @@ -144,11 +154,7 @@ ADF::update (double delta_time_sec) if (_time_before_search_sec < 0) search(frequency_khz, longitude_rad, latitude_rad, altitude_m); - // If it's off, don't bother. - string mode = _mode_node->getStringValue(); - if (!_transmitter_valid || (mode != "bfo" && mode != "adf")) - { - set_bearing(delta_time_sec, 90); + if (!_transmitter_valid) { _ident_node->setStringValue(""); return; } @@ -208,7 +214,6 @@ ADF::update (double delta_time_sec) } } else { _in_range_node->setBoolValue(false); - set_bearing(delta_time_sec, 90); _ident_node->setStringValue(""); _sgr->stop( _adf_ident ); } diff --git a/src/Instrumentation/adf.hxx b/src/Instrumentation/adf.hxx index f2c2bdeb8..88817a8ee 100644 --- a/src/Instrumentation/adf.hxx +++ b/src/Instrumentation/adf.hxx @@ -82,6 +82,7 @@ private: SGPropertyNode_ptr _ident_node; SGPropertyNode_ptr _ident_audible_node; SGPropertyNode_ptr _volume_node; + SGPropertyNode_ptr _power_btn_node; double _time_before_search_sec; From 5fc0be88202264eee65cea8f7db64bdba3ae59ee Mon Sep 17 00:00:00 2001 From: Torsten Dreyer <Torsten@t3r.de> Date: Wed, 19 Jan 2011 19:36:04 +0100 Subject: [PATCH 05/25] Fix bug #253, at least partially make options --wind=nnn@mm --visibility --visibility-miles --ceiling --turbulence work again. These options now write properties in the /environment/config/presets branch. The values will be applied in the property-rules in FGDATA/Environment/interpolator.xml --- projects/VC90/FlightGear/FlightGear.vcproj | 8 ++ src/Environment/CMakeLists.txt | 3 +- src/Environment/Makefile.am | 3 +- src/Environment/metarproperties.cxx | 54 +++++++-- src/Environment/metarproperties.hxx | 8 ++ src/Environment/presets.cxx | 132 +++++++++++++++++++++ src/Environment/presets.hxx | 94 +++++++++++++++ src/Main/fg_commands.cxx | 27 ++--- src/Main/options.cxx | 19 ++- src/Main/util.cxx | 74 +----------- src/Main/util.hxx | 23 ---- 11 files changed, 317 insertions(+), 128 deletions(-) create mode 100755 src/Environment/presets.cxx create mode 100755 src/Environment/presets.hxx diff --git a/projects/VC90/FlightGear/FlightGear.vcproj b/projects/VC90/FlightGear/FlightGear.vcproj index fc364e851..a5df20be7 100644 --- a/projects/VC90/FlightGear/FlightGear.vcproj +++ b/projects/VC90/FlightGear/FlightGear.vcproj @@ -3413,6 +3413,14 @@ RelativePath="..\..\..\src\Environment\terrainsampler.hxx" > </File> + <File + RelativePath="..\..\..\src\Environment\presets.cxx" + > + </File> + <File + RelativePath="..\..\..\src\Environment\presets.hxx" + > + </File> </Filter> <Filter Name="Lib_Model" diff --git a/src/Environment/CMakeLists.txt b/src/Environment/CMakeLists.txt index 8d9c64d44..69fa003ed 100644 --- a/src/Environment/CMakeLists.txt +++ b/src/Environment/CMakeLists.txt @@ -15,6 +15,7 @@ set(SOURCES realwx_ctrl.cxx ridge_lift.cxx terrainsampler.cxx + presets.cxx ) -flightgear_component(Environment "${SOURCES}") \ No newline at end of file +flightgear_component(Environment "${SOURCES}") diff --git a/src/Environment/Makefile.am b/src/Environment/Makefile.am index 5e9bcc463..90b732315 100644 --- a/src/Environment/Makefile.am +++ b/src/Environment/Makefile.am @@ -16,6 +16,7 @@ libEnvironment_a_SOURCES = \ precipitation_mgr.cxx precipitation_mgr.hxx \ ridge_lift.cxx ridge_lift.hxx \ ephemeris.cxx ephemeris.hxx \ - terrainsampler.cxx terrainsampler.cxx + terrainsampler.cxx terrainsampler.cxx \ + presets.cxx presets.cxx INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src diff --git a/src/Environment/metarproperties.cxx b/src/Environment/metarproperties.cxx index 63071d02c..6d8c1c51a 100644 --- a/src/Environment/metarproperties.cxx +++ b/src/Environment/metarproperties.cxx @@ -158,10 +158,10 @@ MetarProperties::MetarProperties( SGPropertyNode_ptr rootNode ) : _tiedProperties.Tie("max-visibility-m", &_max_visibility ); _tiedProperties.Tie("base-wind-range-from", &_base_wind_range_from ); _tiedProperties.Tie("base-wind-range-to", &_base_wind_range_to ); - _tiedProperties.Tie("base-wind-speed-kt", &_wind_speed ); - _tiedProperties.Tie("base-wind-dir-deg", &_base_wind_dir ); - _tiedProperties.Tie("base-wind-from-north-fps", &_wind_from_north_fps ); - _tiedProperties.Tie("base-wind-from-east-fps", &_wind_from_east_fps ); + _tiedProperties.Tie("base-wind-speed-kt", this, &MetarProperties::get_wind_speed, &MetarProperties::set_wind_speed ); + _tiedProperties.Tie("base-wind-dir-deg", this, &MetarProperties::get_base_wind_dir, &MetarProperties::set_base_wind_dir ); + _tiedProperties.Tie("base-wind-from-north-fps", this, &MetarProperties::get_wind_from_north_fps, &MetarProperties::set_wind_from_north_fps ); + _tiedProperties.Tie("base-wind-from-east-fps",this, &MetarProperties::get_wind_from_east_fps, &MetarProperties::set_wind_from_east_fps ); _tiedProperties.Tie("gust-wind-speed-kt", &_gusts ); _tiedProperties.Tie("temperature-degc", &_temperature ); _tiedProperties.Tie("dewpoint-degc", &_dewpoint ); @@ -218,14 +218,11 @@ void MetarProperties::set_metar( const char * metar ) vis->setDoubleValue("max-m", v); } - _base_wind_dir = m->getWindDir(); + set_base_wind_dir(m->getWindDir()); _base_wind_range_from = m->getWindRangeFrom(); _base_wind_range_to = m->getWindRangeTo(); - _wind_speed = m->getWindSpeed_kt(); + set_wind_speed(m->getWindSpeed_kt()); - double speed_fps = _wind_speed * SG_NM_TO_METER * SG_METER_TO_FEET / 3600.0; - _wind_from_north_fps = speed_fps * cos((double)_base_wind_dir * SGD_DEGREES_TO_RADIANS); - _wind_from_east_fps = speed_fps * sin((double)_base_wind_dir * SGD_DEGREES_TO_RADIANS); _gusts = m->getGustSpeed_kt(); _temperature = m->getTemperature_C(); _dewpoint = m->getDewpoint_C(); @@ -408,4 +405,43 @@ double MetarProperties::get_magnetic_dip_deg() const return _magneticVariation->get_dip_deg( _station_longitude, _station_latitude, _station_elevation ); } +static inline void calc_wind_hs( double north_fps, double east_fps, int & heading_deg, double & speed_kt ) +{ + speed_kt = sqrt((north_fps)*(north_fps)+(east_fps)*(east_fps)) * 3600.0 / (SG_NM_TO_METER * SG_METER_TO_FEET); + heading_deg = SGMiscd::roundToInt( + SGMiscd::normalizeAngle2( atan2( east_fps, north_fps ) ) * SGD_RADIANS_TO_DEGREES ); +} + +void MetarProperties::set_wind_from_north_fps( double value ) +{ + _wind_from_north_fps = value; + calc_wind_hs( _wind_from_north_fps, _wind_from_east_fps, _base_wind_dir, _wind_speed ); +} + +void MetarProperties::set_wind_from_east_fps( double value ) +{ + _wind_from_east_fps = value; + calc_wind_hs( _wind_from_north_fps, _wind_from_east_fps, _base_wind_dir, _wind_speed ); +} + +static inline void calc_wind_ne( double heading_deg, double speed_kt, double & north_fps, double & east_fps ) +{ + double speed_fps = speed_kt * SG_NM_TO_METER * SG_METER_TO_FEET / 3600.0; + north_fps = speed_fps * cos(heading_deg * SGD_DEGREES_TO_RADIANS); + east_fps = speed_fps * sin(heading_deg * SGD_DEGREES_TO_RADIANS); +} + +void MetarProperties::set_base_wind_dir( double value ) +{ + _base_wind_dir = value; + calc_wind_ne( (double)_base_wind_dir, _wind_speed, _wind_from_north_fps, _wind_from_east_fps ); +} + +void MetarProperties::set_wind_speed( double value ) +{ + _wind_speed = value; + calc_wind_ne( (double)_base_wind_dir, _wind_speed, _wind_from_north_fps, _wind_from_east_fps ); +} + + } // namespace Environment diff --git a/src/Environment/metarproperties.hxx b/src/Environment/metarproperties.hxx index bec445b15..0e157169e 100644 --- a/src/Environment/metarproperties.hxx +++ b/src/Environment/metarproperties.hxx @@ -51,6 +51,14 @@ private: const char * get_decoded() const { return _decoded.c_str(); } double get_magnetic_variation_deg() const; double get_magnetic_dip_deg() const; + double get_wind_from_north_fps() const { return _wind_from_north_fps; } + double get_wind_from_east_fps() const { return _wind_from_east_fps; } + double get_base_wind_dir() const { return _base_wind_dir; } + double get_wind_speed() const { return _wind_speed; } + void set_wind_from_north_fps( double value ); + void set_wind_from_east_fps( double value ); + void set_base_wind_dir( double value ); + void set_wind_speed( double value ); SGPropertyNode_ptr _rootNode; SGPropertyNode_ptr _metarValidNode; diff --git a/src/Environment/presets.cxx b/src/Environment/presets.cxx new file mode 100755 index 000000000..55da64630 --- /dev/null +++ b/src/Environment/presets.cxx @@ -0,0 +1,132 @@ +// presets.cxx -- Wrap environment presets +// +// Written by Torsten Dreyer, January 2011 +// +// Copyright (C) 2010 Torsten Dreyer Torsten(at)t3r(dot)de +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include "presets.hxx" + +#include <simgear/math/SGMisc.hxx> +#include <Main/fg_props.hxx> + +namespace Environment { +namespace Presets { + +PresetBase::PresetBase( const char * overrideNodePath ) + : _overrideNodePath( overrideNodePath ) +{ +} + +void PresetBase::setOverride( bool value ) +{ + /* + Don't initialize node in constructor because the class is used as a singleton + and created as a static variable in the initialization sequence when globals() + is not yet initialized and returns null. + */ + if( _overrideNode == NULL ) + _overrideNode = fgGetNode( _overrideNodePath.c_str(), true ); + _overrideNode->setBoolValue( value ); +} + + +Wind::Wind() : + PresetBase("/environment/config/presets/wind-override") +{ +} + + +void Wind::preset( double min_hdg, double max_hdg, double speed_kt, double gust_kt ) +{ + // see: PresetBase::setOverride() + + //TODO: handle variable wind and gusts + if( _fromNorthNode == NULL ) + _fromNorthNode = fgGetNode("/environment/config/presets/wind-from-north-fps", true ); + + if( _fromEastNode == NULL ) + _fromEastNode = fgGetNode("/environment/config/presets/wind-from-east-fps", true ); + + double avgHeading_rad = + SGMiscd::normalizeAngle2( + (SGMiscd::normalizeAngle(min_hdg*SG_DEGREES_TO_RADIANS) + + SGMiscd::normalizeAngle(max_hdg*SG_DEGREES_TO_RADIANS))/2); + + double speed_fps = speed_kt * SG_NM_TO_METER * SG_METER_TO_FEET / 3600.0; + _fromNorthNode->setDoubleValue( speed_fps * cos(avgHeading_rad) ); + _fromEastNode->setDoubleValue( speed_fps * sin(avgHeading_rad) ); + setOverride( true ); +} + +Visibility::Visibility() : + PresetBase("/environment/config/presets/visibility-m-override") +{ +} + +void Visibility::preset( double visibility_m ) +{ + // see: PresetBase::setOverride() + if( _visibilityNode == NULL ) + _visibilityNode = fgGetNode("/environment/config/presets/visibility-m", true ); + + _visibilityNode->setDoubleValue(visibility_m ); + setOverride( true ); +} + +Turbulence::Turbulence() : + PresetBase("/environment/config/presets/turbulence-magnitude-norm-override") +{ +} + + +void Turbulence::preset(double magnitude_norm) +{ + // see: PresetBase::setOverride() + if( _magnitudeNode == NULL ) + _magnitudeNode = fgGetNode("/environment/config/presets/turbulence-magnitude-norm", true ); + + _magnitudeNode->setDoubleValue( magnitude_norm ); + setOverride( true ); +} + +Ceiling::Ceiling() : + PresetBase("/environment/config/presets/ceiling-override") +{ +} + + +void Ceiling::preset( double elevation, double thickness ) +{ + // see: PresetBase::setOverride() + if( _elevationNode == NULL ) + _elevationNode = fgGetNode("/environment/config/presets/ceiling-elevation-ft", true); + + if( _thicknessNode == NULL ) + _thicknessNode = fgGetNode("/environment/config/presets/ceiling-elevation-ft", true); + + _elevationNode->setDoubleValue( elevation ); + _thicknessNode->setDoubleValue( thickness ); + setOverride( true ); +} + +} // namespace Presets +} // namespace Environment + diff --git a/src/Environment/presets.hxx b/src/Environment/presets.hxx new file mode 100755 index 000000000..2f5b1ba12 --- /dev/null +++ b/src/Environment/presets.hxx @@ -0,0 +1,94 @@ +// presets.hxx -- Wrap environment presets +// +// Written by Torsten Dreyer, January 2011 +// +// Copyright (C) 2010 Torsten Dreyer Torsten(at)t3r(dot)de +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// + +#ifndef __ENVIRONMENT_PRESETS_HXX +#define __ENVIRONMENT_PRESETS_HXX + +#include <simgear/structure/Singleton.hxx> +#include <simgear/props/props.hxx> + +namespace Environment { + +/** + * @brief A wrapper for presets of environment properties + * mainly set from the command line with --wind=270@10, + * visibility=1600 etc. + */ +namespace Presets { + +class PresetBase { +public: + PresetBase( const char * overrideNodePath ); + virtual void disablePreset() { setOverride(false); } +protected: + void setOverride( bool value ); +private: + std::string _overrideNodePath; + SGPropertyNode_ptr _overrideNode; +}; + +class Ceiling : public PresetBase { +public: + Ceiling(); + void preset( double elevation, double thickness ); +private: + SGPropertyNode_ptr _elevationNode; + SGPropertyNode_ptr _thicknessNode; +}; + +typedef simgear::Singleton<Ceiling> CeilingSingleton; + +class Turbulence : public PresetBase { +public: + Turbulence(); + void preset( double magnitude_norm ); +private: + SGPropertyNode_ptr _magnitudeNode; +}; + +typedef simgear::Singleton<Turbulence> TurbulenceSingleton; + +class Wind : public PresetBase { +public: + Wind(); + void preset( double min_hdg, double max_hdg, double speed, double gust ); +private: + SGPropertyNode_ptr _fromNorthNode; + SGPropertyNode_ptr _fromEastNode; +}; + +typedef simgear::Singleton<Wind> WindSingleton; + +class Visibility : public PresetBase { +public: + Visibility(); + void preset( double visibility_m ); +private: + SGPropertyNode_ptr _visibilityNode; +}; + +typedef simgear::Singleton<Visibility> VisibilitySingleton; + +} // namespace Presets + +} // namespace Environment + +#endif //__ENVIRONMENT_PRESETS_HXX diff --git a/src/Main/fg_commands.cxx b/src/Main/fg_commands.cxx index a8c45e999..2c7a24e70 100644 --- a/src/Main/fg_commands.cxx +++ b/src/Main/fg_commands.cxx @@ -25,7 +25,6 @@ #include <Cockpit/panel.hxx> #include <Cockpit/panel_io.hxx> -#include <Environment/environment.hxx> #include <FDM/flight.hxx> #include <GUI/gui.h> #include <GUI/new_gui.hxx> @@ -47,6 +46,7 @@ #include "viewmgr.hxx" #include "main.hxx" #include <Main/viewer.hxx> +#include <Environment/presets.hxx> using std::string; using std::ifstream; @@ -558,6 +558,9 @@ do_tile_cache_reload (const SGPropertyNode * arg) } +#if 0 +These do_set_(some-environment-parameters) are deprecated and no longer +useful/functional - Torsten Dreyer, January 2011 /** * Set the sea level outside air temperature and assigning that to all * boundary and aloft environment layers. @@ -684,7 +687,7 @@ do_set_dewpoint_degc (const SGPropertyNode * arg) dummy.set_dewpoint_degc( dewpoint_degc ); return do_set_dewpoint_sea_level_degc(dummy.get_dewpoint_sea_level_degc()); } - +#endif /** * Update the lighting manually. */ @@ -1260,29 +1263,21 @@ do_replay (const SGPropertyNode * arg) return true; } - +/* static bool do_decrease_visibility (const SGPropertyNode * arg) { - double new_value = fgGetDouble("/environment/visibility-m") * 0.9; - fgSetDouble("/environment/visibility-m", new_value); - fgDefaultWeatherValue("visibility-m", new_value); - globals->get_subsystem("environment")->reinit(); - + Environment::Presets::VisibilitySingleton::instance()->adjust( 0.9 ); return true; } static bool do_increase_visibility (const SGPropertyNode * arg) { - double new_value = fgGetDouble("/environment/visibility-m") * 1.1; - fgSetDouble("/environment/visibility-m", new_value); - fgDefaultWeatherValue("visibility-m", new_value); - globals->get_subsystem("environment")->reinit(); - + Environment::Presets::VisibilitySingleton::instance()->adjust( 1.1 ); return true; } - +*/ /** * An fgcommand to allow loading of xml files via nasal, * the xml file's structure will be made available within @@ -1454,10 +1449,12 @@ static struct { { "screen-capture", do_screen_capture }, { "hires-screen-capture", do_hires_screen_capture }, { "tile-cache-reload", do_tile_cache_reload }, + /* { "set-sea-level-air-temp-degc", do_set_sea_level_degc }, { "set-outside-air-temp-degc", do_set_oat_degc }, { "set-dewpoint-sea-level-air-temp-degc", do_set_dewpoint_sea_level_degc }, { "set-dewpoint-temp-degc", do_set_dewpoint_degc }, + */ { "timeofday", do_timeofday }, { "property-toggle", do_property_toggle }, { "property-assign", do_property_assign }, @@ -1480,8 +1477,10 @@ static struct { { "presets-commit", do_presets_commit }, { "log-level", do_log_level }, { "replay", do_replay }, + /* { "decrease-visibility", do_decrease_visibility }, { "increase-visibility", do_increase_visibility }, + */ { "loadxml", do_load_xml_to_proptree}, { "savexml", do_save_xml_from_proptree }, { "press-cockpit-button", do_press_cockpit_button }, diff --git a/src/Main/options.cxx b/src/Main/options.cxx index 1931bb341..8af748298 100644 --- a/src/Main/options.cxx +++ b/src/Main/options.cxx @@ -56,6 +56,7 @@ #include "util.hxx" #include "viewmgr.hxx" #include <Main/viewer.hxx> +#include <Environment/presets.hxx> #include <simgear/version.h> #include <osg/Version> @@ -994,18 +995,14 @@ fgOptViewOffset( const char *arg ) static int fgOptVisibilityMeters( const char *arg ) { - double visibility = atof( arg ); - fgDefaultWeatherValue("visibility-m", visibility); - fgSetDouble("/environment/visibility-m", visibility); + Environment::Presets::VisibilitySingleton::instance()->preset( atof( arg ) ); return FG_OPTIONS_OK; } static int fgOptVisibilityMiles( const char *arg ) { - double visibility = atof( arg ) * 5280.0 * SG_FEET_TO_METER; - fgDefaultWeatherValue("visibility-m", visibility); - fgSetDouble("/environment/visibility-m", visibility); + Environment::Presets::VisibilitySingleton::instance()->preset( atof( arg ) * 5280.0 * SG_FEET_TO_METER ); return FG_OPTIONS_OK; } @@ -1016,7 +1013,7 @@ fgOptRandomWind( const char *arg ) double max_hdg = min_hdg + (20 - sqrt(sg_random() * 400)); double speed = sg_random() * sg_random() * 40; double gust = speed + (10 - sqrt(sg_random() * 100)); - fgSetupWind(min_hdg, max_hdg, speed, gust); + Environment::Presets::WindSingleton::instance()->preset(min_hdg, max_hdg, speed, gust); return FG_OPTIONS_OK; } @@ -1028,14 +1025,14 @@ fgOptWind( const char *arg ) SG_LOG( SG_GENERAL, SG_ALERT, "bad wind value " << arg ); return FG_OPTIONS_ERROR; } - fgSetupWind(min_hdg, max_hdg, speed, gust); + Environment::Presets::WindSingleton::instance()->preset(min_hdg, max_hdg, speed, gust); return FG_OPTIONS_OK; } static int fgOptTurbulence( const char *arg ) { - fgDefaultWeatherValue("turbulence/magnitude-norm", atof(arg)); + Environment::Presets::TurbulenceSingleton::instance()->preset( atof(arg) ); return FG_OPTIONS_OK; } @@ -1052,9 +1049,7 @@ fgOptCeiling( const char *arg ) elevation = atof(spec.substr(0, pos).c_str()); thickness = atof(spec.substr(pos + 1).c_str()); } - fgSetDouble("/environment/clouds/layer[0]/elevation-ft", elevation); - fgSetDouble("/environment/clouds/layer[0]/thickness-ft", thickness); - fgSetString("/environment/clouds/layer[0]/coverage", "overcast"); + Environment::Presets::CeilingSingleton::instance()->preset( elevation, thickness ); return FG_OPTIONS_OK; } diff --git a/src/Main/util.cxx b/src/Main/util.cxx index 7c20530a3..2cd15b5b0 100644 --- a/src/Main/util.cxx +++ b/src/Main/util.cxx @@ -17,7 +17,10 @@ // // $Id$ - +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + #include <simgear/compiler.h> #include <math.h> @@ -28,6 +31,8 @@ using std::vector; #include <simgear/debug/logstream.hxx> +#include <simgear/math/SGLimits.hxx> +#include <simgear/math/SGMisc.hxx> #include "fg_io.hxx" #include "fg_props.hxx" @@ -38,73 +43,6 @@ using std::vector; #include "osgDB/Registry" #endif -void -fgDefaultWeatherValue (const char * propname, double value) -{ - unsigned int i; - - SGPropertyNode * branch = fgGetNode("/environment/config/boundary", true); - vector<SGPropertyNode_ptr> entries = branch->getChildren("entry"); - for (i = 0; i < entries.size(); i++) { - entries[i]->setDoubleValue(propname, value); - } - - branch = fgGetNode("/environment/config/aloft", true); - entries = branch->getChildren("entry"); - for (i = 0; i < entries.size(); i++) { - entries[i]->setDoubleValue(propname, value); - } -} - - -void -fgSetupWind (double min_hdg, double max_hdg, double speed, double gust) -{ - // Initialize to a reasonable state - fgDefaultWeatherValue("wind-from-heading-deg", min_hdg); - fgDefaultWeatherValue("wind-speed-kt", speed); - - SG_LOG(SG_GENERAL, SG_INFO, "WIND: " << min_hdg << '@' << - speed << " knots" << endl); - - // Now, add some variety to the layers - min_hdg += 10; - if (min_hdg > 360) - min_hdg -= 360; - speed *= 1.1; - fgSetDouble("/environment/config/boundary/entry[1]/wind-from-heading-deg", - min_hdg); - fgSetDouble("/environment/config/boundary/entry[1]/wind-speed-kt", - speed); - - min_hdg += 20; - if (min_hdg > 360) - min_hdg -= 360; - speed *= 1.1; - fgSetDouble("/environment/config/aloft/entry[0]/wind-from-heading-deg", - min_hdg); - fgSetDouble("/environment/config/aloft/entry[0]/wind-speed-kt", - speed); - - min_hdg += 10; - if (min_hdg > 360) - min_hdg -= 360; - speed *= 1.1; - fgSetDouble("/environment/config/aloft/entry[1]/wind-from-heading-deg", - min_hdg); - fgSetDouble("/environment/config/aloft/entry[1]/wind-speed-kt", - speed); - - min_hdg += 10; - if (min_hdg > 360) - min_hdg -= 360; - speed *= 1.1; - fgSetDouble("/environment/config/aloft/entry[2]/wind-from-heading-deg", - min_hdg); - fgSetDouble("/environment/config/aloft/entry[2]/wind-speed-kt", - speed); -} - // Originally written by Alex Perry. double fgGetLowPass (double current, double target, double timeratio) diff --git a/src/Main/util.hxx b/src/Main/util.hxx index dcd75b130..acb25ac0d 100644 --- a/src/Main/util.hxx +++ b/src/Main/util.hxx @@ -26,29 +26,6 @@ #endif -/** - * Initialize a single value through all existing weather levels. - * - * This function is useful mainly from the command-line. - * - * @param propname The name of the subproperty to initialized. - * @param value The initial value. - */ -extern void fgDefaultWeatherValue (const char * propname, double value); - - -/** - * Set up a plausible wind layout, boundary and aloft, - * based on just a few parameters. - * - * @param min_hdg Minimal wind heading - * @param max_hdg Maximal wind heading - * @param speed Windspeed in knots - * @param gust Wind gust variation in knots - */ -extern void fgSetupWind (double min_hdg, double max_hdg, - double speed, double gust); - /** * Move a value towards a target. * From 258a4436aa7c481a230c1c83511c9df516d170ad Mon Sep 17 00:00:00 2001 From: Torsten Dreyer <Torsten@t3r.de> Date: Fri, 21 Jan 2011 10:35:04 +0100 Subject: [PATCH 06/25] Fix bug 255, support turbulence to weather menu --- src/Environment/Makefile.am | 2 +- src/Environment/environment.cxx | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/Environment/Makefile.am b/src/Environment/Makefile.am index 90b732315..c3b1b5fbf 100644 --- a/src/Environment/Makefile.am +++ b/src/Environment/Makefile.am @@ -17,6 +17,6 @@ libEnvironment_a_SOURCES = \ ridge_lift.cxx ridge_lift.hxx \ ephemeris.cxx ephemeris.hxx \ terrainsampler.cxx terrainsampler.cxx \ - presets.cxx presets.cxx + presets.cxx presets.hxx INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src diff --git a/src/Environment/environment.cxx b/src/Environment/environment.cxx index a27189b24..4e245554b 100644 --- a/src/Environment/environment.cxx +++ b/src/Environment/environment.cxx @@ -27,14 +27,9 @@ #include <boost/tuple/tuple.hpp> -#include <simgear/constants.h> -#include <simgear/debug/logstream.hxx> -#include <simgear/math/interpolater.hxx> #include <simgear/props/props.hxx> -#include <simgear/environment/visual_enviro.hxx> #include <Main/fg_props.hxx> -#include <signal.h> #include "environment.hxx" #include "atmosphere.hxx" @@ -472,9 +467,6 @@ FGEnvironment::get_wind_from_down_fps () const double FGEnvironment::get_turbulence_magnitude_norm () const { - if( sgEnviro.get_turbulence_enable_state() ) - if (fgGetBool("/environment/realwx/enabled")||fgGetBool("/environment/metar/valid")) - return sgEnviro.get_cloud_turbulence(); return turbulence_magnitude_norm; } From 99ee9a1bbb60eb4fd17ff9cec252fb8c88305b56 Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Fri, 21 Jan 2011 19:55:42 +0100 Subject: [PATCH 07/25] GPWS: avoid "altitude_callout_voice != NULL" assertion Properly remember which active alerts were already voiced. Added NULL-pointer safety check --- src/Instrumentation/mk_viii.cxx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Instrumentation/mk_viii.cxx b/src/Instrumentation/mk_viii.cxx index 745ed6c2e..8fb871a4a 100755 --- a/src/Instrumentation/mk_viii.cxx +++ b/src/Instrumentation/mk_viii.cxx @@ -2319,6 +2319,8 @@ MK_VIII::VoicePlayer::get_sample (const char *name) void MK_VIII::VoicePlayer::play (Voice *_voice, unsigned int flags) { + if (!_voice) + return; if (test_bits(flags, PLAY_NOW) || ! voice || voice->element->silence) { if (voice) @@ -2978,9 +2980,10 @@ MK_VIII::AlertHandler::update () mk->voice_player.play(mk_voice(bank_angle_pause_bank_angle)); } - // set new state - - old_alerts = voice_alerts; + // remember all alerts voiced so far... + old_alerts |= voice_alerts; + // ... forget those no longer active + old_alerts &= alerts; repeated_alerts = 0; } From d365689d5c1641369219bbc07ba74016a72cd266 Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Fri, 21 Jan 2011 23:44:23 +0100 Subject: [PATCH 08/25] Fix crash in GPS module. Fixes crash on exit (during property untie). Also potential run-time crash. --- src/Instrumentation/gps.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Instrumentation/gps.cxx b/src/Instrumentation/gps.cxx index 853d49d46..f0ecf6f04 100644 --- a/src/Instrumentation/gps.cxx +++ b/src/Instrumentation/gps.cxx @@ -1158,7 +1158,7 @@ double GPS::getWP1Bearing() const double GPS::getWP1MagBearing() const { - if (!_dataValid) { + if (!_dataValid || !_wayptController.get()) { return -9999.0; } From db3717a30eaff128d6d029bd798b40cac86ca260 Mon Sep 17 00:00:00 2001 From: James Turner <zakalawe@mac.com> Date: Wed, 19 Jan 2011 12:14:59 +0000 Subject: [PATCH 09/25] Working Cmake-terrasync-libsvn support. Probably needs additional refinement, but testable. --- CMakeModules/FindSvnClient.cmake | 17 ++++++++--------- utils/TerraSync/CMakeLists.txt | 5 ++--- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/CMakeModules/FindSvnClient.cmake b/CMakeModules/FindSvnClient.cmake index 51f4452bf..717b8b04d 100644 --- a/CMakeModules/FindSvnClient.cmake +++ b/CMakeModules/FindSvnClient.cmake @@ -6,11 +6,8 @@ include (CheckIncludeFile) find_program(HAVE_APR_CONFIG apr-1-config) if(HAVE_APR_CONFIG) - execute_process(COMMAND apr-1-config --includes - OUTPUT_VARIABLE RAW_APR_INCLUDES - OUTPUT_STRIP_TRAILING_WHITESPACE) - execute_process(COMMAND apr-1-config --cppflags + execute_process(COMMAND apr-1-config --cppflags --includes OUTPUT_VARIABLE APR_CFLAGS OUTPUT_STRIP_TRAILING_WHITESPACE) @@ -20,7 +17,6 @@ if(HAVE_APR_CONFIG) # clean up some vars, or other CMake pieces complain string(STRIP ${RAW_APR_LIBS} APR_LIBS) - string(STRIP ${RAW_APR_INCLUDES} APR_INCLUDES) else(HAVE_APR_CONFIG) message(STATUS "apr-1-config not found, implement manual search for APR") @@ -38,12 +34,15 @@ find_path(LIBSVN_INCLUDE_DIR svn_client.h check_library_exists(svn_client-1 svn_client_checkout "" HAVE_LIB_SVNCLIENT) check_library_exists(svn_subr-1 svn_cmdline_init "" HAVE_LIB_SVNSUBR) +check_library_exists(svn_ra-1 svn_ra_initialize "" HAVE_LIB_SVNRA) include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBSVN DEFAULT_MSG HAVE_LIB_SVNSUBR - HAVE_LIB_SVNCLIENT LIBSVN_INCLUDE_DIR) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBSVN DEFAULT_MSG + HAVE_LIB_SVNSUBR + HAVE_LIB_SVNCLIENT + HAVE_LIB_SVNRA + LIBSVN_INCLUDE_DIR) if(LIBSVN_FOUND) - set(LIBSVN_LIBRARIES "svn_client-1" "svn_subr-1" ${APR_LIBS}) - set(LIBSVN_INCLUDE_DIRS ${LIBSVN_INCLUDE_DIR} ${APR_INCLUDES}) + set(LIBSVN_LIBRARIES "svn_client-1" "svn_subr-1" "svn_ra-1" ${APR_LIBS}) endif(LIBSVN_FOUND) diff --git a/utils/TerraSync/CMakeLists.txt b/utils/TerraSync/CMakeLists.txt index c44af48bf..86526eb0b 100644 --- a/utils/TerraSync/CMakeLists.txt +++ b/utils/TerraSync/CMakeLists.txt @@ -1,8 +1,6 @@ if(LIBSVN_FOUND) - message(STATUS "includes '${LIBSVN_INCLUDE_DIRS}'") - include_directories(${LIBSVN_INCLUDE_DIRS}) - add_definitions(${APR_CFLAGS}) + include_directories(${LIBSVN_INCLUDE_DIR}) endif(LIBSVN_FOUND) add_executable(terrasync terrasync.cxx) @@ -14,6 +12,7 @@ target_link_libraries(terrasync if(LIBSVN_FOUND) target_link_libraries(terrasync ${LIBSVN_LIBRARIES}) + set_property(TARGET terrasync APPEND PROPERTY COMPILE_FLAGS ${APR_CFLAGS}) endif() From 45b239fe2677093d1e1d245e4dec2e591f093f73 Mon Sep 17 00:00:00 2001 From: James Turner <zakalawe@mac.com> Date: Sat, 22 Jan 2011 19:25:34 +0000 Subject: [PATCH 10/25] Support the 1.4 SVN checkout API --- utils/TerraSync/terrasync.cxx | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/utils/TerraSync/terrasync.cxx b/utils/TerraSync/terrasync.cxx index bcf6e0ca8..8776cdc5a 100644 --- a/utils/TerraSync/terrasync.cxx +++ b/utils/TerraSync/terrasync.cxx @@ -229,16 +229,31 @@ void sync_tree(const char* dir) { if (mysvn_setup() != EXIT_SUCCESS) exit(1); apr_pool_t *subpool = svn_pool_create(mysvn_pool); + +#if (SVN_VER_MINOR >= 5) err = svn_client_checkout3(NULL, command, dest_base_dir, mysvn_rev_peg, mysvn_rev, svn_depth_infinity, - 0, - 0, + 0, // ignore-externals = false + 0, // allow unver obstructions = false mysvn_ctx, subpool); +#else + // version 1.4 API + err = svn_client_checkout2(NULL, + command, + dest_base_dir, + mysvn_rev_peg, + mysvn_rev, + 1, // recurse=true - same as svn_depth_infinity for checkout3 above + 0, // ignore externals = false + mysvn_ctx, + subpool); +#endif + if (err) { // Report errors from the checkout attempt cout << "failed: " << endl From 0ad9ac4f3daf6360c91898d877ec8dbdbe08de06 Mon Sep 17 00:00:00 2001 From: James Turner <zakalawe@mac.com> Date: Sat, 22 Jan 2011 18:49:54 +0000 Subject: [PATCH 11/25] Fix Apple libsvn include for isysroot (SDK) builds. --- utils/TerraSync/CMakeLists.txt | 11 +++++++---- utils/TerraSync/terrasync.cxx | 2 ++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/utils/TerraSync/CMakeLists.txt b/utils/TerraSync/CMakeLists.txt index 86526eb0b..88b208c16 100644 --- a/utils/TerraSync/CMakeLists.txt +++ b/utils/TerraSync/CMakeLists.txt @@ -1,7 +1,4 @@ -if(LIBSVN_FOUND) - include_directories(${LIBSVN_INCLUDE_DIR}) -endif(LIBSVN_FOUND) add_executable(terrasync terrasync.cxx) @@ -12,7 +9,13 @@ target_link_libraries(terrasync if(LIBSVN_FOUND) target_link_libraries(terrasync ${LIBSVN_LIBRARIES}) - set_property(TARGET terrasync APPEND PROPERTY COMPILE_FLAGS ${APR_CFLAGS}) + set_property(TARGET terrasync APPEND PROPERTY COMPILE_FLAGS "${APR_CFLAGS}") + + IF(APPLE) + set_property(SOURCE terrasync.cxx PROPERTY COMPILE_FLAGS "-iwithsysroot ${LIBSVN_INCLUDE_DIR}") + ELSE() + include_directories(${LIBSVN_INCLUDE_DIR}) + ENDIF(APPLE) endif() diff --git a/utils/TerraSync/terrasync.cxx b/utils/TerraSync/terrasync.cxx index 8776cdc5a..f1a2cc46b 100644 --- a/utils/TerraSync/terrasync.cxx +++ b/utils/TerraSync/terrasync.cxx @@ -183,8 +183,10 @@ int mysvn_setup(void) { if (err) return svn_cmdline_handle_exit_error(err, pool, "terrasync: "); mysvn_ctx->auth_baton = ab; +#if (SVN_VER_MINOR >= 5) mysvn_ctx->conflict_func = NULL; mysvn_ctx->conflict_baton = NULL; +#endif // Now our magic revisions mysvn_rev = (svn_opt_revision_t*) apr_palloc(pool, sizeof(svn_opt_revision_t)); From 59d06d130d4803836de43cda40575a1e8e90c52c Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Sun, 23 Jan 2011 00:45:06 +0100 Subject: [PATCH 12/25] Make route editing sane. Drag&drop, insert and remove now update the current waypoint as expected. --- src/Autopilot/route_mgr.cxx | 16 ++++++++++------ src/GUI/WaypointList.cxx | 6 ++++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/Autopilot/route_mgr.cxx b/src/Autopilot/route_mgr.cxx index 127e2c397..8f2cacf59 100644 --- a/src/Autopilot/route_mgr.cxx +++ b/src/Autopilot/route_mgr.cxx @@ -352,11 +352,6 @@ flightgear::WayptRef FGRouteMgr::removeWayptAtIndex(int aIndex) SG_LOG(SG_AUTOPILOT, SG_WARN, "removeWayptAtIndex with invalid index:" << aIndex); return NULL; } - - if (_currentIndex > index) { - --_currentIndex; // shift current index down if necessary - } - WayptVec::iterator it = _route.begin(); it += index; @@ -364,6 +359,15 @@ flightgear::WayptRef FGRouteMgr::removeWayptAtIndex(int aIndex) _route.erase(it); update_mirror(); + + if (_currentIndex == index) { + currentWaypointChanged(); // current waypoint was removed + } + else + if (_currentIndex > index) { + --_currentIndex; // shift current index down if necessary + } + _edited->fireValueChanged(); checkFinished(); @@ -680,7 +684,7 @@ void FGRouteMgr::insertWayptAtIndex(Waypt* aWpt, int aIndex) WayptVec::iterator it = _route.begin(); it += index; - if (_currentIndex > index) { + if (_currentIndex >= index) { ++_currentIndex; } diff --git a/src/GUI/WaypointList.cxx b/src/GUI/WaypointList.cxx index 31c5e480c..f525f213b 100644 --- a/src/GUI/WaypointList.cxx +++ b/src/GUI/WaypointList.cxx @@ -83,9 +83,15 @@ public: --destIndex; } + int currentWpIndex = currentWaypoint(); WayptRef w(_rm->removeWayptAtIndex(srcIndex)); SG_LOG(SG_GENERAL, SG_INFO, "wpt:" << w->ident()); _rm->insertWayptAtIndex(w, destIndex); + + if (srcIndex == currentWpIndex) { + // current waypoint was moved + _rm->jumpToIndex(destIndex); + } } virtual void setUpdateCallback(SGCallback* cb) From ee26505e28888d70990f98990c5788236b49a276 Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Sun, 23 Jan 2011 15:07:09 +0100 Subject: [PATCH 13/25] Added sanity checks to MP receive/send. Stop invalid data (NaN values) from being sent or received via MP. --- src/MultiPlayer/multiplaymgr.cxx | 49 ++++++++++++++++++++++++++++---- src/MultiPlayer/multiplaymgr.hxx | 3 +- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/src/MultiPlayer/multiplaymgr.cxx b/src/MultiPlayer/multiplaymgr.cxx index 1d36ec257..89d2eb85a 100644 --- a/src/MultiPlayer/multiplaymgr.cxx +++ b/src/MultiPlayer/multiplaymgr.cxx @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////// // -// multiplaymgr.hpp +// multiplaymgr.cxx // // Written by Duncan McCreanor, started February 2003. // duncan.mccreanor@airservicesaustralia.com @@ -526,14 +526,44 @@ union FGMultiplayMgr::MsgBuf T_MsgHdr Header; }; +bool +FGMultiplayMgr::isSane(const FGExternalMotionData& motionInfo) +{ + // check for corrupted data (NaNs) + bool isCorrupted = false; + isCorrupted |= ((osg::isNaN(motionInfo.time )) || + (osg::isNaN(motionInfo.lag )) || + (osg::isNaN(motionInfo.orientation(3) ))); + for (unsigned i = 0; (i < 3)&&(!isCorrupted); ++i) + { + isCorrupted |= ((osg::isNaN(motionInfo.position(i) ))|| + (osg::isNaN(motionInfo.orientation(i) ))|| + (osg::isNaN(motionInfo.linearVel(i)) )|| + (osg::isNaN(motionInfo.angularVel(i)) )|| + (osg::isNaN(motionInfo.linearAccel(i)) )|| + (osg::isNaN(motionInfo.angularAccel(i)) )); + } + return !isCorrupted; +} + void FGMultiplayMgr::SendMyPosition(const FGExternalMotionData& motionInfo) { if ((! mInitialised) || (! mHaveServer)) return; + if (! mHaveServer) { - SG_LOG( SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::SendMyPosition - no server"); - return; + SG_LOG( SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::SendMyPosition - no server"); + return; + } + + if (!isSane(motionInfo)) + { + // Current local data is invalid (NaN), so stop MP transmission. + // => Be nice to older FG versions (no NaN checks) and don't waste bandwidth. + SG_LOG(SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::SendMyPosition - " + << "Local data is invalid (NaN). Data not transmitted."); + return; } static MsgBuf msgBuf; @@ -780,7 +810,7 @@ FGMultiplayMgr::update(double) } if (MsgHdr->Version != PROTO_VER) { SG_LOG( SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::MP_ProcessData - " - << "message has invalid protocoll number!" ); + << "message has invalid protocol number!" ); break; } if (MsgHdr->MsgLen != bytes) { @@ -858,6 +888,15 @@ FGMultiplayMgr::ProcessPosMsg(const FGMultiplayMgr::MsgBuf& Msg, for (unsigned i = 0; i < 3; ++i) motionInfo.angularAccel(i) = XDR_decode_float(PosMsg->angularAccel[i]); + // sanity check: do not allow injection of corrupted data (NaNs) + if (!isSane(motionInfo)) + { + // drop this message, keep old position until receiving valid data + SG_LOG(SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::ProcessPosMsg - " + << "Position message with invalid data (NaN) received from " + << MsgHdr->Callsign); + return; + } //cout << "INPUT MESSAGE\n"; @@ -953,7 +992,7 @@ FGMultiplayMgr::ProcessPosMsg(const FGMultiplayMgr::MsgBuf& Msg, SG_LOG(SG_NETWORK, SG_DEBUG, "Unknown Prop type " << pData->id << " " << pData->type); xdr++; break; - } + } motionInfo.properties.push_back(pData); } diff --git a/src/MultiPlayer/multiplaymgr.hxx b/src/MultiPlayer/multiplaymgr.hxx index 5a08e1aab..8475c0ef1 100644 --- a/src/MultiPlayer/multiplaymgr.hxx +++ b/src/MultiPlayer/multiplaymgr.hxx @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////// // -// multiplaymgr.hpp +// multiplaymgr.hxx // // Written by Duncan McCreanor, started February 2003. // duncan.mccreanor@airservicesaustralia.com @@ -81,6 +81,7 @@ private: void ProcessPosMsg(const MsgBuf& Msg, const simgear::IPAddress& SenderAddress, long stamp); void ProcessChatMsg(const MsgBuf& Msg, const simgear::IPAddress& SenderAddress); + bool isSane(const FGExternalMotionData& motionInfo); /// maps from the callsign string to the FGAIMultiplayer typedef std::map<std::string, SGSharedPtr<FGAIMultiplayer> > MultiPlayerMap; From e64b3823974cb1d822ffb376d15d323a818bc9e5 Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Sun, 23 Jan 2011 15:24:28 +0100 Subject: [PATCH 14/25] Report stopped MP transmission at higher log level, it's too important to be a "debug only" message. --- src/MultiPlayer/multiplaymgr.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MultiPlayer/multiplaymgr.cxx b/src/MultiPlayer/multiplaymgr.cxx index 89d2eb85a..7657ad4ee 100644 --- a/src/MultiPlayer/multiplaymgr.cxx +++ b/src/MultiPlayer/multiplaymgr.cxx @@ -561,7 +561,7 @@ FGMultiplayMgr::SendMyPosition(const FGExternalMotionData& motionInfo) { // Current local data is invalid (NaN), so stop MP transmission. // => Be nice to older FG versions (no NaN checks) and don't waste bandwidth. - SG_LOG(SG_NETWORK, SG_DEBUG, "FGMultiplayMgr::SendMyPosition - " + SG_LOG(SG_NETWORK, SG_ALERT, "FGMultiplayMgr::SendMyPosition - " << "Local data is invalid (NaN). Data not transmitted."); return; } From 6cb4fbcf0afb760a3be3631f86cdb292a4ea1377 Mon Sep 17 00:00:00 2001 From: Torsten Dreyer <Torsten@t3r.de> Date: Mon, 24 Jan 2011 19:41:56 +0100 Subject: [PATCH 15/25] Bugfix: reset transparency of non fog/mist/haze layers --- src/Environment/metarproperties.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Environment/metarproperties.cxx b/src/Environment/metarproperties.cxx index 6d8c1c51a..171d716af 100644 --- a/src/Environment/metarproperties.cxx +++ b/src/Environment/metarproperties.cxx @@ -374,6 +374,7 @@ void MetarProperties::set_metar( const char * metar ) -9999.0 : metarClouds[i].getAltitude_ft() + _station_elevation; + layerNode->setDoubleValue( "alpha", 1.0 ); layerNode->setStringValue( "coverage", coverage_string[coverage] ); layerNode->setDoubleValue( "coverage-type", SGCloudLayer::getCoverageType(coverage_string[coverage]) ); layerNode->setDoubleValue( "elevation-ft", elevation ); From 53e8fbfcbb3ddac0dc261043fea7bd24dfa6e62d Mon Sep 17 00:00:00 2001 From: James Turner <zakalawe@mac.com> Date: Tue, 25 Jan 2011 00:26:07 +0000 Subject: [PATCH 16/25] Andreas Gaeb: fix #222 (JSBSIm reset problems) --- src/FDM/JSBSim/JSBSim.cxx | 2 ++ src/FDM/JSBSim/models/FGPropagate.cpp | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/FDM/JSBSim/JSBSim.cxx b/src/FDM/JSBSim/JSBSim.cxx index d92d265f0..4fb0f43ed 100644 --- a/src/FDM/JSBSim/JSBSim.cxx +++ b/src/FDM/JSBSim/JSBSim.cxx @@ -292,6 +292,8 @@ FGJSBsim::FGJSBsim( double dt ) fgGetDouble("/fdm/jsbsim/systems/hook/tailhook-offset-x-in", 196), fgGetDouble("/fdm/jsbsim/systems/hook/tailhook-offset-y-in", 0), fgGetDouble("/fdm/jsbsim/systems/hook/tailhook-offset-z-in", -16)); + last_hook_tip[0] = 0; last_hook_tip[1] = 0; last_hook_tip[2] = 0; + last_hook_root[0] = 0; last_hook_root[1] = 0; last_hook_root[2] = 0; crashed = false; } diff --git a/src/FDM/JSBSim/models/FGPropagate.cpp b/src/FDM/JSBSim/models/FGPropagate.cpp index 5405c8639..d917420d8 100644 --- a/src/FDM/JSBSim/models/FGPropagate.cpp +++ b/src/FDM/JSBSim/models/FGPropagate.cpp @@ -78,7 +78,8 @@ static const char *IdHdr = ID_PROPAGATE; CLASS IMPLEMENTATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -FGPropagate::FGPropagate(FGFDMExec* fdmex) : FGModel(fdmex) +FGPropagate::FGPropagate(FGFDMExec* fdmex) : FGModel(fdmex), +LocalTerrainRadius(0), SeaLevelRadius(0), VehicleRadius(0) { Debug(0); Name = "FGPropagate"; From 67978f92e553953f8b13710d57741602d796e08f Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Fri, 28 Jan 2011 00:06:23 +0100 Subject: [PATCH 17/25] Proposed fix for #251: Waypoint handling Do not consider destination/runway waypoints as done, when these are far away - even if the course is off by > 90 degrees. --- src/Instrumentation/rnav_waypt_controller.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Instrumentation/rnav_waypt_controller.cxx b/src/Instrumentation/rnav_waypt_controller.cxx index 09ac2b812..278484d0a 100644 --- a/src/Instrumentation/rnav_waypt_controller.cxx +++ b/src/Instrumentation/rnav_waypt_controller.cxx @@ -221,7 +221,7 @@ private: /** * Special controller for runways. For runways, we want very narrow deviation - * contraints, and to understand that any point along the paved area is + * constraints, and to understand that any point along the paved area is * equivalent to being 'at' the runway. */ class RunwayCtl : public WayptController @@ -252,7 +252,7 @@ public: double _courseDev = brg - _targetTrack; SG_NORMALIZE_RANGE(_courseDev, -180.0, 180.0); - if (fabs(_courseDev) > 90.0) { + if ((fabs(_courseDev) > 90.0) && (_distanceM < _rnav->overflightArmDistanceM())) { setDone(); } } From b649f97b19b60ae273bf18e25b9539363b3d1c9a Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Sun, 6 Feb 2011 15:33:27 +0100 Subject: [PATCH 18/25] Fix for bug #204 and #222 by Bertrand Coconnier; NaNs (bug #222) were basically generated because the method JSBSim::unbind() was not implemented in JSBSim.cxx. --- src/FDM/JSBSim/JSBSim.cxx | 27 ++++++++++++++++++++++++++ src/FDM/JSBSim/JSBSim.hxx | 5 +++-- src/FDM/JSBSim/models/FGPropulsion.cpp | 8 ++++++-- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/FDM/JSBSim/JSBSim.cxx b/src/FDM/JSBSim/JSBSim.cxx index 4fb0f43ed..a2d217ba2 100644 --- a/src/FDM/JSBSim/JSBSim.cxx +++ b/src/FDM/JSBSim/JSBSim.cxx @@ -424,6 +424,33 @@ void FGJSBsim::init() /******************************************************************************/ +void checkTied ( FGPropertyManager *node ) +{ + int N = node->nChildren(); + string name; + + for (int i=0; i<N; i++) { + if (node->getChild(i)->nChildren() ) { + checkTied( (FGPropertyManager*)node->getChild(i) ); + } + if ( node->getChild(i)->isTied() ) { + name = ((FGPropertyManager*)node->getChild(i))->GetFullyQualifiedName(); + node->Untie(name); + } + } +} + +/******************************************************************************/ + +void FGJSBsim::unbind() +{ + SGPropertyNode* instance = globals->get_props()->getNode("/fdm/jsbsim"); + checkTied((FGPropertyManager*)instance); + FGInterface::unbind(); +} + +/******************************************************************************/ + // Run an iteration of the EOM (equations of motion) void FGJSBsim::update( double dt ) diff --git a/src/FDM/JSBSim/JSBSim.hxx b/src/FDM/JSBSim/JSBSim.hxx index 1a8037167..a01146bcc 100644 --- a/src/FDM/JSBSim/JSBSim.hxx +++ b/src/FDM/JSBSim/JSBSim.hxx @@ -110,6 +110,9 @@ public: /// Reset flight params to a specific position void init(); + /// Unbind properties + void unbind(); + /// @name Position Parameter Set //@{ /** Set geocentric latitude @@ -283,8 +286,6 @@ private: void update_gear(void); void update_external_forces(double t_off); - - void resetPropertyState(); }; diff --git a/src/FDM/JSBSim/models/FGPropulsion.cpp b/src/FDM/JSBSim/models/FGPropulsion.cpp index 57d2852f3..05a2da4c4 100644 --- a/src/FDM/JSBSim/models/FGPropulsion.cpp +++ b/src/FDM/JSBSim/models/FGPropulsion.cpp @@ -307,18 +307,23 @@ bool FGPropulsion::Load(Element* el) try { if (type == "piston_engine") { HavePistonEngine = true; + if (!IsBound) bind(); Engines.push_back(new FGPiston(FDMExec, document, numEngines)); } else if (type == "turbine_engine") { HaveTurbineEngine = true; + if (!IsBound) bind(); Engines.push_back(new FGTurbine(FDMExec, document, numEngines)); } else if (type == "turboprop_engine") { HaveTurboPropEngine = true; + if (!IsBound) bind(); Engines.push_back(new FGTurboProp(FDMExec, document, numEngines)); } else if (type == "rocket_engine") { HaveRocketEngine = true; + if (!IsBound) bind(); Engines.push_back(new FGRocket(FDMExec, document, numEngines)); } else if (type == "electric_engine") { HaveElectricEngine = true; + if (!IsBound) bind(); Engines.push_back(new FGElectric(FDMExec, document, numEngines)); } else { cerr << "Unknown engine type: " << type << endl; @@ -345,7 +350,6 @@ bool FGPropulsion::Load(Element* el) if (el->FindElement("dump-rate")) DumpRate = el->FindElementValueAsNumberConvertTo("dump-rate", "LBS/MIN"); - if (!IsBound) bind(); PostLoad(el, PropertyManager); return true; @@ -642,7 +646,7 @@ void FGPropulsion::bind(void) typedef int (FGPropulsion::*iPMF)(void) const; IsBound = true; - PropertyManager->Tie("propulsion/set-running", this, (iPMF)0, &FGPropulsion::InitRunning, true); + PropertyManager->Tie("propulsion/set-running", this, (iPMF)0, &FGPropulsion::InitRunning, false); if (HaveTurbineEngine) { PropertyManager->Tie("propulsion/starter_cmd", this, (iPMF)0, &FGPropulsion::SetStarter, true); PropertyManager->Tie("propulsion/cutoff_cmd", this, (iPMF)0, &FGPropulsion::SetCutoff, true); From 68728c944962f17a3754c63b4d61e58ff5bcd365 Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Sun, 30 Jan 2011 16:05:28 +0100 Subject: [PATCH 19/25] Betrand Coconnier: fix bugs #47,#184: roll/pitch/speed via command-line Specifying initial roll, pitch and speed should be working again. --- src/FDM/flight.cxx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/FDM/flight.cxx b/src/FDM/flight.cxx index 5676e688b..d501d1507 100644 --- a/src/FDM/flight.cxx +++ b/src/FDM/flight.cxx @@ -268,15 +268,15 @@ FGInterface::bind () // Orientation fgTie("/orientation/roll-deg", this, &FGInterface::get_Phi_deg, - &FGInterface::set_Phi_deg); + &FGInterface::set_Phi_deg, false); fgSetArchivable("/orientation/roll-deg"); fgTie("/orientation/pitch-deg", this, &FGInterface::get_Theta_deg, - &FGInterface::set_Theta_deg); + &FGInterface::set_Theta_deg, false); fgSetArchivable("/orientation/pitch-deg"); fgTie("/orientation/heading-deg", this, &FGInterface::get_Psi_deg, - &FGInterface::set_Psi_deg); + &FGInterface::set_Psi_deg, false); fgSetArchivable("/orientation/heading-deg"); fgTie("/orientation/track-deg", this, &FGInterface::get_Track); @@ -331,11 +331,11 @@ FGInterface::bind () // LaRCSim are fixed (LaRCSim adds the // earth's rotation to the east velocity). fgTie("/velocities/speed-north-fps", this, - &FGInterface::get_V_north, &FGInterface::set_V_north); + &FGInterface::get_V_north, &FGInterface::set_V_north, false); fgTie("/velocities/speed-east-fps", this, - &FGInterface::get_V_east, &FGInterface::set_V_east); + &FGInterface::get_V_east, &FGInterface::set_V_east, false); fgTie("/velocities/speed-down-fps", this, - &FGInterface::get_V_down, &FGInterface::set_V_down); + &FGInterface::get_V_down, &FGInterface::set_V_down, false); fgTie("/velocities/north-relground-fps", this, &FGInterface::get_V_north_rel_ground); From 6b6d7059de394bf270c8a0660820c5fc0a4c7fd4 Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Sat, 5 Feb 2011 17:49:26 +0100 Subject: [PATCH 20/25] Improved fix for #204 and #222: JSBSim::unbind() needs to untie _all_ its properties Extends and partially reverts commit 287cc74965e11ff3888117a9d9b88ed2bdbb9252 Previous fix did not consider properties outside the /fdm/jsbsim branch. FGPropertyManager now keeps track of all its tied properties - and provides a method to cleanly untie them again. --- src/FDM/JSBSim/FGFDMExec.h | 7 +++++-- src/FDM/JSBSim/JSBSim.cxx | 21 +------------------ .../JSBSim/input_output/FGPropertyManager.cpp | 18 ++++++++++++++++ .../JSBSim/input_output/FGPropertyManager.h | 8 +++++++ 4 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/FDM/JSBSim/FGFDMExec.h b/src/FDM/JSBSim/FGFDMExec.h index 10736f4a4..c1038c471 100644 --- a/src/FDM/JSBSim/FGFDMExec.h +++ b/src/FDM/JSBSim/FGFDMExec.h @@ -101,8 +101,8 @@ CLASS DOCUMENTATION file: @code - fdmex = new FGFDMExec( � ); - result = fdmex->LoadModel( � ); + fdmex = new FGFDMExec( ... ); + result = fdmex->LoadModel( ... ); @endcode When an aircraft model is loaded, the config file is parsed and for each of the @@ -226,6 +226,9 @@ public: /// Default destructor ~FGFDMExec(); + /** Unbind all tied JSBSim properties. */ + void unbind(void) {instance->unbind();} + /** This routine places a model into the runlist at the specified rate. The "rate" is not really a clock rate. It represents how many calls to the FGFDMExec::Run() method must be made before the model is executed. A diff --git a/src/FDM/JSBSim/JSBSim.cxx b/src/FDM/JSBSim/JSBSim.cxx index a2d217ba2..ba35d6900 100644 --- a/src/FDM/JSBSim/JSBSim.cxx +++ b/src/FDM/JSBSim/JSBSim.cxx @@ -424,28 +424,9 @@ void FGJSBsim::init() /******************************************************************************/ -void checkTied ( FGPropertyManager *node ) -{ - int N = node->nChildren(); - string name; - - for (int i=0; i<N; i++) { - if (node->getChild(i)->nChildren() ) { - checkTied( (FGPropertyManager*)node->getChild(i) ); - } - if ( node->getChild(i)->isTied() ) { - name = ((FGPropertyManager*)node->getChild(i))->GetFullyQualifiedName(); - node->Untie(name); - } - } -} - -/******************************************************************************/ - void FGJSBsim::unbind() { - SGPropertyNode* instance = globals->get_props()->getNode("/fdm/jsbsim"); - checkTied((FGPropertyManager*)instance); + fdmex->unbind(); FGInterface::unbind(); } diff --git a/src/FDM/JSBSim/input_output/FGPropertyManager.cpp b/src/FDM/JSBSim/input_output/FGPropertyManager.cpp index 11e566965..899565ed2 100755 --- a/src/FDM/JSBSim/input_output/FGPropertyManager.cpp +++ b/src/FDM/JSBSim/input_output/FGPropertyManager.cpp @@ -49,6 +49,19 @@ COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs] namespace JSBSim { bool FGPropertyManager::suppress_warning = true; +std::vector<std::string> FGPropertyManager::tied_properties; + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void FGPropertyManager::unbind(void) +{ + vector<string>::iterator it; + for (it = tied_properties.begin();it < tied_properties.end();it++) + { + Untie(*it); + } + tied_properties.clear(); +} //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -301,6 +314,7 @@ void FGPropertyManager::Untie (const string &name) void FGPropertyManager::Tie (const string &name, bool *pointer, bool useDefault) { + tied_properties.push_back(name); if (!tie(name.c_str(), SGRawValuePointer<bool>(pointer), useDefault)) cerr << "Failed to tie property " << name << " to a pointer" << endl; else if (debug_lvl & 0x20) @@ -312,6 +326,7 @@ void FGPropertyManager::Tie (const string &name, bool *pointer, bool useDefault) void FGPropertyManager::Tie (const string &name, int *pointer, bool useDefault ) { + tied_properties.push_back(name); if (!tie(name.c_str(), SGRawValuePointer<int>(pointer), useDefault)) cerr << "Failed to tie property " << name << " to a pointer" << endl; else if (debug_lvl & 0x20) @@ -323,6 +338,7 @@ void FGPropertyManager::Tie (const string &name, int *pointer, void FGPropertyManager::Tie (const string &name, long *pointer, bool useDefault ) { + tied_properties.push_back(name); if (!tie(name.c_str(), SGRawValuePointer<long>(pointer), useDefault)) cerr << "Failed to tie property " << name << " to a pointer" << endl; else if (debug_lvl & 0x20) @@ -334,6 +350,7 @@ void FGPropertyManager::Tie (const string &name, long *pointer, void FGPropertyManager::Tie (const string &name, float *pointer, bool useDefault ) { + tied_properties.push_back(name); if (!tie(name.c_str(), SGRawValuePointer<float>(pointer), useDefault)) cerr << "Failed to tie property " << name << " to a pointer" << endl; else if (debug_lvl & 0x20) @@ -344,6 +361,7 @@ void FGPropertyManager::Tie (const string &name, float *pointer, void FGPropertyManager::Tie (const string &name, double *pointer, bool useDefault) { + tied_properties.push_back(name); if (!tie(name.c_str(), SGRawValuePointer<double>(pointer), useDefault)) cerr << "Failed to tie property " << name << " to a pointer" << endl; else if (debug_lvl & 0x20) diff --git a/src/FDM/JSBSim/input_output/FGPropertyManager.h b/src/FDM/JSBSim/input_output/FGPropertyManager.h index c29b5a412..54ea91874 100644 --- a/src/FDM/JSBSim/input_output/FGPropertyManager.h +++ b/src/FDM/JSBSim/input_output/FGPropertyManager.h @@ -77,6 +77,7 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase { private: static bool suppress_warning; + static std::vector<std::string> tied_properties; public: /// Constructor FGPropertyManager(void) {suppress_warning = false;} @@ -399,6 +400,13 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase */ void Untie (const std::string &name); + /** + * Unbind all properties bound by this manager to an external data source. + * + * Classes should use this function to release control of any + * properties they have bound using this property manager. + */ + void unbind (void); // Templates cause ambiguity here From ac717783197dace28bd4f9946f757fc22c26085a Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Sun, 6 Feb 2011 15:16:58 +0100 Subject: [PATCH 21/25] Bertrand Coconnier: updated fix for #204 and #222: JSBSim reset Use shared property pointers instead of path strings, adapt method names to JSBSim style, catch all property ties, proper error handling when tieing failed. --- src/FDM/JSBSim/FGFDMExec.cpp | 18 +-------- src/FDM/JSBSim/FGFDMExec.h | 2 +- src/FDM/JSBSim/JSBSim.cxx | 2 +- .../JSBSim/input_output/FGPropertyManager.cpp | 37 +++++++++++-------- .../JSBSim/input_output/FGPropertyManager.h | 26 ++++++++----- 5 files changed, 41 insertions(+), 44 deletions(-) diff --git a/src/FDM/JSBSim/FGFDMExec.cpp b/src/FDM/JSBSim/FGFDMExec.cpp index ab0bf8a9a..25c5bdd17 100644 --- a/src/FDM/JSBSim/FGFDMExec.cpp +++ b/src/FDM/JSBSim/FGFDMExec.cpp @@ -78,22 +78,6 @@ static const char *IdHdr = ID_FDMEXEC; CLASS IMPLEMENTATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -void checkTied ( FGPropertyManager *node ) -{ - int N = node->nChildren(); - string name; - - for (int i=0; i<N; i++) { - if (node->getChild(i)->nChildren() ) { - checkTied( (FGPropertyManager*)node->getChild(i) ); - } - if ( node->getChild(i)->isTied() ) { - name = ((FGPropertyManager*)node->getChild(i))->GetFullyQualifiedName(); - node->Untie(name); - } - } -} - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // Constructor @@ -185,7 +169,7 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root, unsigned int* fdmctr) : Root(root) FGFDMExec::~FGFDMExec() { try { - checkTied( instance ); + Unbind(); DeAllocate(); if (IdFDM == 0) { // Meaning this is no child FDM diff --git a/src/FDM/JSBSim/FGFDMExec.h b/src/FDM/JSBSim/FGFDMExec.h index c1038c471..b982654e7 100644 --- a/src/FDM/JSBSim/FGFDMExec.h +++ b/src/FDM/JSBSim/FGFDMExec.h @@ -227,7 +227,7 @@ public: ~FGFDMExec(); /** Unbind all tied JSBSim properties. */ - void unbind(void) {instance->unbind();} + void Unbind(void) {instance->Unbind();} /** This routine places a model into the runlist at the specified rate. The "rate" is not really a clock rate. It represents how many calls to the diff --git a/src/FDM/JSBSim/JSBSim.cxx b/src/FDM/JSBSim/JSBSim.cxx index ba35d6900..0f8d5130a 100644 --- a/src/FDM/JSBSim/JSBSim.cxx +++ b/src/FDM/JSBSim/JSBSim.cxx @@ -426,7 +426,7 @@ void FGJSBsim::init() void FGJSBsim::unbind() { - fdmex->unbind(); + fdmex->Unbind(); FGInterface::unbind(); } diff --git a/src/FDM/JSBSim/input_output/FGPropertyManager.cpp b/src/FDM/JSBSim/input_output/FGPropertyManager.cpp index 899565ed2..c0218ec20 100755 --- a/src/FDM/JSBSim/input_output/FGPropertyManager.cpp +++ b/src/FDM/JSBSim/input_output/FGPropertyManager.cpp @@ -53,7 +53,7 @@ std::vector<std::string> FGPropertyManager::tied_properties; //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void FGPropertyManager::unbind(void) +void FGPropertyManager::Unbind(void) { vector<string>::iterator it; for (it = tied_properties.begin();it < tied_properties.end();it++) @@ -314,11 +314,12 @@ void FGPropertyManager::Untie (const string &name) void FGPropertyManager::Tie (const string &name, bool *pointer, bool useDefault) { - tied_properties.push_back(name); if (!tie(name.c_str(), SGRawValuePointer<bool>(pointer), useDefault)) cerr << "Failed to tie property " << name << " to a pointer" << endl; - else if (debug_lvl & 0x20) - cout << name << endl; + else { + tied_properties.push_back(name); + if (debug_lvl & 0x20) std::cout << name << std::endl; + } } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -326,11 +327,12 @@ void FGPropertyManager::Tie (const string &name, bool *pointer, bool useDefault) void FGPropertyManager::Tie (const string &name, int *pointer, bool useDefault ) { - tied_properties.push_back(name); if (!tie(name.c_str(), SGRawValuePointer<int>(pointer), useDefault)) cerr << "Failed to tie property " << name << " to a pointer" << endl; - else if (debug_lvl & 0x20) - cout << name << endl; + else { + tied_properties.push_back(name); + if (debug_lvl & 0x20) std::cout << name << std::endl; + } } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -338,11 +340,12 @@ void FGPropertyManager::Tie (const string &name, int *pointer, void FGPropertyManager::Tie (const string &name, long *pointer, bool useDefault ) { - tied_properties.push_back(name); if (!tie(name.c_str(), SGRawValuePointer<long>(pointer), useDefault)) cerr << "Failed to tie property " << name << " to a pointer" << endl; - else if (debug_lvl & 0x20) - cout << name << endl; + else { + tied_properties.push_back(name); + if (debug_lvl & 0x20) std::cout << name << std::endl; + } } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -350,22 +353,24 @@ void FGPropertyManager::Tie (const string &name, long *pointer, void FGPropertyManager::Tie (const string &name, float *pointer, bool useDefault ) { - tied_properties.push_back(name); if (!tie(name.c_str(), SGRawValuePointer<float>(pointer), useDefault)) cerr << "Failed to tie property " << name << " to a pointer" << endl; - else if (debug_lvl & 0x20) - cout << name << endl; + else { + tied_properties.push_back(name); + if (debug_lvl & 0x20) std::cout << name << std::endl; + } } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% void FGPropertyManager::Tie (const string &name, double *pointer, bool useDefault) { - tied_properties.push_back(name); if (!tie(name.c_str(), SGRawValuePointer<double>(pointer), useDefault)) cerr << "Failed to tie property " << name << " to a pointer" << endl; - else if (debug_lvl & 0x20) - cout << name << endl; + else { + tied_properties.push_back(name); + if (debug_lvl & 0x20) std::cout << name << std::endl; + } } } // namespace JSBSim diff --git a/src/FDM/JSBSim/input_output/FGPropertyManager.h b/src/FDM/JSBSim/input_output/FGPropertyManager.h index 54ea91874..a08f89681 100644 --- a/src/FDM/JSBSim/input_output/FGPropertyManager.h +++ b/src/FDM/JSBSim/input_output/FGPropertyManager.h @@ -406,7 +406,7 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase * Classes should use this function to release control of any * properties they have bound using this property manager. */ - void unbind (void); + void Unbind (void); // Templates cause ambiguity here @@ -534,8 +534,10 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase { if (!tie(name.c_str(), SGRawValueFunctions<V>(getter, setter), useDefault)) std::cout << "Failed to tie property " << name << " to functions" << std::endl; - else if (debug_lvl & 0x20) - std::cout << name << std::endl; + else { + tied_properties.push_back(name); + if (debug_lvl & 0x20) std::cout << name << std::endl; + } } @@ -562,8 +564,10 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase { if (!tie(name.c_str(), SGRawValueFunctionsIndexed<V>(index, getter, setter), useDefault)) std::cout << "Failed to tie property " << name << " to indexed functions" << std::endl; - else if (debug_lvl & 0x20) - std::cout << name << std::endl; + else { + tied_properties.push_back(name); + if (debug_lvl & 0x20) std::cout << name << std::endl; + } } @@ -592,8 +596,10 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase { if (!tie(name.c_str(), SGRawValueMethods<T,V>(*obj, getter, setter), useDefault)) std::cout << "Failed to tie property " << name << " to object methods" << std::endl; - else if (debug_lvl & 0x20) - std::cout << name << std::endl; + else { + tied_properties.push_back(name); + if (debug_lvl & 0x20) std::cout << name << std::endl; + } } /** @@ -621,8 +627,10 @@ class FGPropertyManager : public SGPropertyNode, public FGJSBBase { if (!tie(name.c_str(), SGRawValueMethodsIndexed<T,V>(*obj, index, getter, setter), useDefault)) std::cout << "Failed to tie property " << name << " to indexed object methods" << std::endl; - else if (debug_lvl & 0x20) - std::cout << name << std::endl; + else { + tied_properties.push_back(name); + if (debug_lvl & 0x20) std::cout << name << std::endl; + } } }; } From 591ef4ab0157f79d35486a5c7ac1e16147cda7af Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Sun, 6 Feb 2011 16:46:36 +0100 Subject: [PATCH 22/25] Fixed incomplete merge of JSBSim.cxx Commit 287cc74965e11ff3888117a9d9b88ed2bdbb9252 wasn't merged to release/2.2.0 properly by Commit b649f97b19b60ae273bf18e25b9539363b3d1c9a. --- src/FDM/JSBSim/JSBSim.cxx | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/FDM/JSBSim/JSBSim.cxx b/src/FDM/JSBSim/JSBSim.cxx index 0f8d5130a..8b693bcab 100644 --- a/src/FDM/JSBSim/JSBSim.cxx +++ b/src/FDM/JSBSim/JSBSim.cxx @@ -144,8 +144,6 @@ FGJSBsim::FGJSBsim( double dt ) } } - resetPropertyState(); - fdmex = new FGFDMExec( (FGPropertyManager*)globals->get_props() ); // Register ground callback. @@ -1423,22 +1421,3 @@ void FGJSBsim::update_external_forces(double t_off) fgSetDouble("/fdm/jsbsim/systems/hook/tailhook-pos-deg", fi); } - -void FGJSBsim::resetPropertyState() -{ -// this code works-around bug #222: -// http://code.google.com/p/flightgear-bugs/issues/detail?id=222 -// for whatever reason, having an existing value for the WOW -// property causes the NaNs. Should that be fixed, this code can die - SGPropertyNode* gear = fgGetNode("/fdm/jsbsim/gear", false); - if (!gear) { - return; - } - - int index = 0; - SGPropertyNode* unitNode = NULL; - for (; (unitNode = gear->getChild("unit", index)) != NULL; ++index) { - unitNode->removeChild("WOW", 0, false); - } -} - From a4ebec667da0f849bcbf0be3fed1df3bca7d1db9 Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Fri, 11 Feb 2011 18:53:35 +0100 Subject: [PATCH 23/25] Ivan Ngeow: Fixed compile for FreeBSD platforms. --- utils/TerraSync/terrasync.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/TerraSync/terrasync.cxx b/utils/TerraSync/terrasync.cxx index f1a2cc46b..d15078d9a 100644 --- a/utils/TerraSync/terrasync.cxx +++ b/utils/TerraSync/terrasync.cxx @@ -290,7 +290,7 @@ void sync_tree(const char* dir) { #if defined(_MSC_VER) || defined(__MINGW32__) typedef void (__cdecl * sighandler_t)(int); -#elif defined( __APPLE__ ) +#elif defined( __APPLE__ ) || defined (__FreeBSD__) typedef sig_t sighandler_t; #endif From 526cd9fa6e5b89522c528d4a7f5f7b2cafb9095e Mon Sep 17 00:00:00 2001 From: ThorstenB <brehmt@gmail.com> Date: Sun, 13 Feb 2011 16:50:23 +0100 Subject: [PATCH 24/25] Avoid crash and/or long delay on shutdown in METAR loader. Catching loader thread on subsystem destruction is too late, since it depends on other subsystems (which are destroyed earlier). => Need to stop & join thread during subsystem shutdown. Also changed loader sleep logic - to avoid excessive delays (up to 30 seconds) on shutdown. (Issues mostly happened when running offline with realwx enabled.) --- src/Environment/realwx_ctrl.cxx | 48 ++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/src/Environment/realwx_ctrl.cxx b/src/Environment/realwx_ctrl.cxx index a547ef7e5..71f52d7ba 100644 --- a/src/Environment/realwx_ctrl.cxx +++ b/src/Environment/realwx_ctrl.cxx @@ -191,6 +191,7 @@ public: NoaaMetarRealWxController( SGPropertyNode_ptr rootNode ); virtual ~NoaaMetarRealWxController(); virtual void update (bool first, double delta_time_sec); + virtual void shutdown (); class MetarLoadRequest { public: @@ -234,14 +235,17 @@ private: class MetarLoadThread : public OpenThreads::Thread { public: MetarLoadThread( long maxAge ); + virtual ~MetarLoadThread( ) { stop(); } void requestMetar( const MetarLoadRequest & metarRequest, bool background = true ); bool hasMetar() { return _responseQueue.size() > 0; } MetarLoadResponse getMetar() { return _responseQueue.pop(); } virtual void run(); + void stop(); private: void fetch( const MetarLoadRequest & ); long _maxAge; long _minRequestInterval; + volatile bool _stop; SGBlockingQueue <MetarLoadRequest> _requestQueue; SGBlockingQueue <MetarLoadResponse> _responseQueue; }; @@ -261,18 +265,20 @@ NoaaMetarRealWxController::NoaaMetarRealWxController( SGPropertyNode_ptr rootNod #endif } -NoaaMetarRealWxController::~NoaaMetarRealWxController() +void NoaaMetarRealWxController::shutdown() { #if defined(ENABLE_THREADS) if( _metarLoadThread ) { - MetarLoadRequest request(""); - _metarLoadThread->requestMetar(request); - _metarLoadThread->join(); delete _metarLoadThread; + _metarLoadThread = NULL; } #endif // ENABLE_THREADS } +NoaaMetarRealWxController::~NoaaMetarRealWxController() +{ +} + void NoaaMetarRealWxController::update( bool first, double dt ) { _positionTimeToLive -= dt; @@ -319,7 +325,7 @@ void NoaaMetarRealWxController::update( bool first, double dt ) "NoaaMetarRealWxController::update(): spawning load request for station-id '" << stationId << "'" ); MetarLoadRequest request( stationId ); - // load the metar for the neares airport in the foreground if the fdm is uninitialized + // load the metar for the nearest airport in the foreground if the fdm is uninitialized // to make sure a metar is received // before the automatic runway selection code runs. All subsequent calls // run in the background @@ -348,7 +354,8 @@ void NoaaMetarRealWxController::update( bool first, double dt ) #if defined(ENABLE_THREADS) NoaaMetarRealWxController::MetarLoadThread::MetarLoadThread( long maxAge ) : _maxAge(maxAge), - _minRequestInterval(2000) + _minRequestInterval(2000), + _stop(false) { } @@ -368,24 +375,41 @@ void NoaaMetarRealWxController::MetarLoadThread::requestMetar( const MetarLoadRe } } +void NoaaMetarRealWxController::MetarLoadThread::stop() +{ + // set stop flag and wake up the thread with an empty request + _stop = true; + MetarLoadRequest request(""); + requestMetar(request); + join(); +} + void NoaaMetarRealWxController::MetarLoadThread::run() { SGTimeStamp lastRun = SGTimeStamp::fromSec(0); for( ;; ) { SGTimeStamp dt = SGTimeStamp::now() - lastRun; - if( dt.getSeconds() * 1000 < _minRequestInterval ) - microSleep( (_minRequestInterval - dt.getSeconds() * 1000 ) * 1000 ); - - lastRun = SGTimeStamp::now(); + long delayMs = _minRequestInterval - dt.getSeconds() * 1000; + while (( delayMs > 0 ) && !_stop) + { + // sleep no more than 3 seconds at a time, otherwise shutdown response is too slow + long sleepMs = (delayMs>3000) ? 3000 : delayMs; + microSleep( sleepMs * 1000 ); + delayMs -= sleepMs; + } + if (_stop) + break; + + lastRun = SGTimeStamp::now(); + const MetarLoadRequest request = _requestQueue.pop(); - if( request._stationId.size() == 0 ) + if (( request._stationId.size() == 0 ) || _stop) break; fetch( request ); - } } From c5366cceb6d345d3526ab013b04eb815fe0a6845 Mon Sep 17 00:00:00 2001 From: Tim Moore <timoore33@gmail.com> Date: Tue, 15 Feb 2011 12:30:56 +0100 Subject: [PATCH 25/25] accomodate changes to osgDB::DatabasePager interface The change was introduced in OSG SVN revision 12080. Note: that revision has a bug that causes fgfs to crash. The bug is fixed in revision 12170. --- src/Scenery/SceneryPager.cxx | 39 ++++++++++++++++++++++++++++++------ src/Scenery/SceneryPager.hxx | 19 +++++------------- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/Scenery/SceneryPager.cxx b/src/Scenery/SceneryPager.cxx index 183511361..9328973ef 100644 --- a/src/Scenery/SceneryPager.cxx +++ b/src/Scenery/SceneryPager.cxx @@ -44,15 +44,12 @@ SceneryPager::~SceneryPager() { } +#if SG_PAGEDLOD_HAS_OPTIONS +#else void SceneryPager::requestNodeFile(const std::string& fileName, Group* group, float priority, const FrameStamp* framestamp, ref_ptr<Referenced>& databaseRequest, -#if SG_OSG_MIN_VERSION_REQUIRED(2,9,5) - const osg::Referenced* options -#else - osgDB::ReaderWriter::Options* options -#endif - ) + osgDB::ReaderWriter::Options* options) { simgear::SGPagedLOD *sgplod = dynamic_cast<simgear::SGPagedLOD*>(group); if(sgplod) @@ -64,6 +61,7 @@ void SceneryPager::requestNodeFile(const std::string& fileName, Group* group, databaseRequest, options); } +#endif void SceneryPager::queueRequest(const std::string& fileName, Group* group, float priority, FrameStamp* frameStamp, @@ -81,6 +79,35 @@ void SceneryPager::queueDeleteRequest(osg::ref_ptr<osg::Object>& objptr) _deleteRequests.push_back(objptr); objptr = 0; } + +// Work around interface change in +// osgDB::DatabasePager::requestNodeFile +namespace +{ +struct NodePathProxy +{ + NodePathProxy(NodePath& nodePath) + : _nodePath(nodePath) + { + } + operator Group* () { return static_cast<Group*>(_nodePath.back()); } + operator NodePath& () { return _nodePath; } + NodePath& _nodePath; +}; +} + +void SceneryPager::PagerRequest::doRequest(SceneryPager* pager) +{ + if (_group->getNumChildren() == 0) { + NodePath path; + path.push_back(_group.get()); + pager->requestNodeFile(_fileName, NodePathProxy(path), _priority, + _frameStamp.get(), + *_databaseRequest, + _options.get()); + } +} + void SceneryPager::signalEndFrame() { using namespace std; diff --git a/src/Scenery/SceneryPager.hxx b/src/Scenery/SceneryPager.hxx index ba018993c..04e6ef5c4 100644 --- a/src/Scenery/SceneryPager.hxx +++ b/src/Scenery/SceneryPager.hxx @@ -28,6 +28,7 @@ #include <osgDB/DatabasePager> #include <simgear/structure/OSGVersion.hxx> +#include <simgear/scene/model/SGPagedLOD.hxx> namespace flightgear { @@ -39,16 +40,14 @@ public: // Unhide DatabasePager::requestNodeFile using osgDB::DatabasePager::requestNodeFile; // reimplement to add readerWriterOptions from SGPagedLOD +#if SG_PAGEDLOD_HAS_OPTIONS +#else virtual void requestNodeFile(const std::string& fileName, osg::Group* group, float priority, const osg::FrameStamp* framestamp, osg::ref_ptr<osg::Referenced>& databaseRequest, -#if SG_OSG_MIN_VERSION_REQUIRED(2,9,5) - const osg::Referenced* options -#else - osgDB::ReaderWriter::Options* options + osgDB::ReaderWriter::Options* options); #endif - ); void queueRequest(const std::string& fileName, osg::Group* node, float priority, osg::FrameStamp* frameStamp, osg::ref_ptr<osg::Referenced>& databaseRequest, @@ -77,15 +76,7 @@ protected: _databaseRequest(&databaseRequest) {} - void doRequest(SceneryPager* pager) - { - if (_group->getNumChildren() == 0) - pager->requestNodeFile(_fileName, _group.get(), _priority, - _frameStamp.get(), - *_databaseRequest, - _options.get()); - } - + void doRequest(SceneryPager* pager); std::string _fileName; osg::ref_ptr<osg::Group> _group; float _priority;