diff --git a/projects/VC100/FlightGear/FlightGear.vcxproj b/projects/VC100/FlightGear/FlightGear.vcxproj
index dffa08cb4..fa563816b 100644
--- a/projects/VC100/FlightGear/FlightGear.vcxproj
+++ b/projects/VC100/FlightGear/FlightGear.vcxproj
@@ -174,7 +174,7 @@
.\Release/FlightGear.tlb
- OnlyExplicitInline
+ AnySuitable
..\..\..\src;..\..\..\src\include;..\..\..\src\FDM\JSBSim;..\..\..\..\SimGear;..\..\..\..\install\msvc100\OpenSceneGraph\include;..\..\..\..\3rdParty\include;..\..\..\..\boost_1_43_0;%(AdditionalIncludeDirectories)
NDEBUG;WIN32;_CONSOLE;HAVE_CONFIG_H;FGFS;ENABLE_AUDIO_SUPPORT;_FG_NDEBUG;ENABLE_THREADS=1;FG_ENABLE_MULTIPASS_CLOUDS;ENABLE_SP_FMDS;_USE_MATH_DEFINES;FG_JPEG_SERVER;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)
true
diff --git a/projects/VC100/GPSsmooth/GPSsmooth.vcxproj b/projects/VC100/GPSsmooth/GPSsmooth.vcxproj
index 501151db0..01e9faee7 100644
--- a/projects/VC100/GPSsmooth/GPSsmooth.vcxproj
+++ b/projects/VC100/GPSsmooth/GPSsmooth.vcxproj
@@ -149,6 +149,7 @@
Level3
ProgramDatabase
+ AnySuitable
sg.lib;net.lib;ul.lib;ws2_32.lib;winmm.lib;zlib.lib;%(AdditionalDependencies)
diff --git a/projects/VC100/MIDGsmooth/MIDGsmooth.vcxproj b/projects/VC100/MIDGsmooth/MIDGsmooth.vcxproj
index 3e3ae732a..4c52c0bac 100644
--- a/projects/VC100/MIDGsmooth/MIDGsmooth.vcxproj
+++ b/projects/VC100/MIDGsmooth/MIDGsmooth.vcxproj
@@ -151,6 +151,7 @@
Level3
ProgramDatabase
+ AnySuitable
sg.lib;net.lib;ul.lib;ws2_32.lib;winmm.lib;%(AdditionalDependencies)
diff --git a/projects/VC100/UGsmooth/UGsmooth.vcxproj b/projects/VC100/UGsmooth/UGsmooth.vcxproj
index 4e100688e..44d5a52d7 100644
--- a/projects/VC100/UGsmooth/UGsmooth.vcxproj
+++ b/projects/VC100/UGsmooth/UGsmooth.vcxproj
@@ -151,6 +151,7 @@
Level3
ProgramDatabase
+ AnySuitable
sg.lib;net.lib;ul.lib;ws2_32.lib;winmm.lib;zlib.lib;%(AdditionalDependencies)
diff --git a/projects/VC100/fgadmin/fgadmin.vcxproj b/projects/VC100/fgadmin/fgadmin.vcxproj
index 3b7795bdc..c7c59e4ec 100644
--- a/projects/VC100/fgadmin/fgadmin.vcxproj
+++ b/projects/VC100/fgadmin/fgadmin.vcxproj
@@ -142,7 +142,7 @@
MaxSpeed
- OnlyExplicitInline
+ AnySuitable
true
..\..\..\..\SimGear;..\..\..\..\install\msvc100\OpenSceneGraph\include;..\..\..\..\3rdParty\include;%(AdditionalIncludeDirectories)
WIN32;NDEBUG;_CONSOLE;HAVE_ZLIB;NOMINMAX;_USE_MATH_DEFINES;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)
diff --git a/projects/VC100/fgjs/fgjs.vcxproj b/projects/VC100/fgjs/fgjs.vcxproj
index e34b9b53c..f9b1b2e4f 100644
--- a/projects/VC100/fgjs/fgjs.vcxproj
+++ b/projects/VC100/fgjs/fgjs.vcxproj
@@ -151,6 +151,7 @@
Level3
ProgramDatabase
+ AnySuitable
sg.lib;js.lib;ul.lib;zlib.lib;winmm.lib;ws2_32.lib;OpenThreads.lib;%(AdditionalDependencies)
diff --git a/projects/VC100/fgviewer/fgviewer.vcxproj b/projects/VC100/fgviewer/fgviewer.vcxproj
index a981fce78..4c37c4d30 100644
--- a/projects/VC100/fgviewer/fgviewer.vcxproj
+++ b/projects/VC100/fgviewer/fgviewer.vcxproj
@@ -151,6 +151,7 @@
Level3
ProgramDatabase
+ AnySuitable
opengl32.lib;osg.lib;osgDB.lib;osgViewer.lib;osgGA.lib;openthreads.lib;osgParticle.lib;osgUtil.lib;osgText.lib;ul.lib;sg.lib;zlib.lib;%(AdditionalDependencies)
diff --git a/projects/VC100/metar/metar.vcxproj b/projects/VC100/metar/metar.vcxproj
index 5102d960c..d40361f04 100644
--- a/projects/VC100/metar/metar.vcxproj
+++ b/projects/VC100/metar/metar.vcxproj
@@ -148,6 +148,7 @@
Level3
ProgramDatabase
+ AnySuitable
sg.lib;ul.lib;net.lib;ws2_32.lib;%(AdditionalDependencies)
diff --git a/projects/VC100/terrasync/terrasync.vcxproj b/projects/VC100/terrasync/terrasync.vcxproj
index 9107c115e..2edb4903e 100644
--- a/projects/VC100/terrasync/terrasync.vcxproj
+++ b/projects/VC100/terrasync/terrasync.vcxproj
@@ -151,6 +151,7 @@
Level3
ProgramDatabase
+ AnySuitable
ul.lib;sg.lib;net.lib;ws2_32.lib;libsvn_client-1.lib;libsvn_diff-1.lib;libsvn_delta-1.lib;libsvn_ra-1.lib;libsvn_subr-1.lib;libsvn_wc-1.lib;libapr-1.lib;%(AdditionalDependencies)
diff --git a/projects/VC100/xmlgrep/xmlgrep.vcxproj b/projects/VC100/xmlgrep/xmlgrep.vcxproj
index d12aecfea..f2894ce6f 100644
--- a/projects/VC100/xmlgrep/xmlgrep.vcxproj
+++ b/projects/VC100/xmlgrep/xmlgrep.vcxproj
@@ -142,6 +142,7 @@
Level3
ProgramDatabase
+ AnySuitable
true
diff --git a/projects/VC100/yasim/yasim.vcxproj b/projects/VC100/yasim/yasim.vcxproj
index 9a8b1047f..cb3477d7b 100644
--- a/projects/VC100/yasim/yasim.vcxproj
+++ b/projects/VC100/yasim/yasim.vcxproj
@@ -151,6 +151,7 @@
Level3
ProgramDatabase
+ AnySuitable
sg.lib;ul.lib;OpenThreads.lib;%(AdditionalDependencies)
diff --git a/src/AIModel/AIBallistic.cxx b/src/AIModel/AIBallistic.cxx
index 5f67d88e4..0306c3ec5 100644
--- a/src/AIModel/AIBallistic.cxx
+++ b/src/AIModel/AIBallistic.cxx
@@ -940,7 +940,7 @@ void FGAIBallistic::handle_impact() {
invisible = true;
} else if (_subID == 0) // kill the AIObject if there is no subsubmodel
setDie(true);
- }
+ }
}
void FGAIBallistic::handle_expiry() {
diff --git a/src/AIModel/AIBallistic.hxx b/src/AIModel/AIBallistic.hxx
index 6ce9c13d8..c9613de89 100644
--- a/src/AIModel/AIBallistic.hxx
+++ b/src/AIModel/AIBallistic.hxx
@@ -15,7 +15,7 @@
// 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
+// 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.
diff --git a/src/AIModel/AIBase.cxx b/src/AIModel/AIBase.cxx
index ac8c4fb57..517b91b1d 100644
--- a/src/AIModel/AIBase.cxx
+++ b/src/AIModel/AIBase.cxx
@@ -236,7 +236,7 @@ void FGAIBase::initModel(osg::Node *node)
SG_LOG(SG_INPUT, SG_WARN, "AIBase: Could not load model " << model_path);
}
- //props->setStringValue("submodels/path", _path.c_str());
+ //props->setStringValue("submodels/path", _path.c_str());
setDie(false);
}
diff --git a/src/AIModel/AIBase.hxx b/src/AIModel/AIBase.hxx
index 20bca1d9c..4c2c591af 100644
--- a/src/AIModel/AIBase.hxx
+++ b/src/AIModel/AIBase.hxx
@@ -1,7 +1,7 @@
// FGAIBase.hxx - abstract base class for AI objects
// Written by David Culp, started Nov 2003, based on
// David Luff's FGAIEntity class.
-// - davidculp2@comcast.net
+// - davidculp2@comcast.net
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
diff --git a/src/AIModel/AIManager.cxx b/src/AIModel/AIManager.cxx
index 1c83ca479..4255709ab 100644
--- a/src/AIModel/AIManager.cxx
+++ b/src/AIModel/AIManager.cxx
@@ -2,7 +2,7 @@
// - a global management type for AI objects
//
// Written by David Culp, started October 2003.
-// - davidculp2@comcast.net
+// - davidculp2@comcast.net
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
diff --git a/src/AIModel/AIWingman.cxx b/src/AIModel/AIWingman.cxx
index 0ed84e85a..39c20bbc6 100644
--- a/src/AIModel/AIWingman.cxx
+++ b/src/AIModel/AIWingman.cxx
@@ -1,7 +1,7 @@
// FGAIWingman - FGAIBllistic-derived class creates an AI Wingman
//
// Written by Vivian Meazza, started February 2008.
-// - vivian.meazza at lineone.net
+// - vivian.meazza at lineone.net
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
diff --git a/src/AIModel/submodel.cxx b/src/AIModel/submodel.cxx
index 7f9f80c02..471b45dd1 100644
--- a/src/AIModel/submodel.cxx
+++ b/src/AIModel/submodel.cxx
@@ -896,7 +896,7 @@ void FGSubmodelMgr::setParentNode(int id) {
if (!model)
continue;
- }// end for loop
+ }// end for loop
if (_selected_ac != 0){
diff --git a/src/AIModel/submodel.hxx b/src/AIModel/submodel.hxx
index e6c9f9e1f..2abff45ce 100644
--- a/src/AIModel/submodel.hxx
+++ b/src/AIModel/submodel.hxx
@@ -20,7 +20,7 @@
#include
using std::vector;
-using std::string;
+using std::string;
using std::list;
class FGAIBase;
diff --git a/src/Airports/pavement.cxx b/src/Airports/pavement.cxx
index 7e5f60763..4f06a9a1d 100755
--- a/src/Airports/pavement.cxx
+++ b/src/Airports/pavement.cxx
@@ -25,8 +25,9 @@
#include "pavement.hxx"
FGPavement::FGPavement(const std::string& aIdent, const SGGeod& aPos) :
- FGPositioned(PAVEMENT, aIdent, aPos, false)
+ FGPositioned(PAVEMENT, aIdent, aPos)
{
+ init(false); // FGPositioned::init
}
void FGPavement::addNode(const SGGeod &aPos, bool aClose)
diff --git a/src/Airports/runwaybase.cxx b/src/Airports/runwaybase.cxx
index fd82406ad..1131e22a0 100644
--- a/src/Airports/runwaybase.cxx
+++ b/src/Airports/runwaybase.cxx
@@ -51,12 +51,14 @@ FGRunwayBase::FGRunwayBase(Type aTy, const string& aIdent,
const double width,
const int surface_code,
bool index) :
- FGPositioned(aTy, aIdent, aGeod, index)
+ FGPositioned(aTy, aIdent, aGeod)
{
_heading = heading;
_length = length;
_width = width;
_surface_code = surface_code;
+
+ init(index);
}
SGGeod FGRunwayBase::pointOnCenterline(double aOffset) const
diff --git a/src/Airports/simple.cxx b/src/Airports/simple.cxx
index 249e5a72b..a418bd414 100644
--- a/src/Airports/simple.cxx
+++ b/src/Airports/simple.cxx
@@ -63,6 +63,7 @@ FGAirport::FGAirport(const string &id, const SGGeod& location, const SGGeod& tow
mRunwaysLoaded(false),
mTaxiwaysLoaded(true)
{
+ init(true); // init FGPositioned
}
diff --git a/src/Autopilot/autopilot.cxx b/src/Autopilot/autopilot.cxx
index 809001d61..e8bb91b02 100644
--- a/src/Autopilot/autopilot.cxx
+++ b/src/Autopilot/autopilot.cxx
@@ -97,11 +97,11 @@ void Autopilot::add_component( Component * component )
std::string name = component->get_name();
for( unsigned i = 0; get_subsystem( name.c_str() ) != NULL; i++ ) {
ostringstream buf;
- buf << name << "_" << i;
+ buf << component->get_name() << "_" << i;
name = buf.str();
}
if( name != component->get_name() )
- SG_LOG( SG_ALL, SG_ALERT, "Duplicate autopilot component " << component->get_name() << ", renamed to " << name );
+ SG_LOG( SG_ALL, SG_WARN, "Duplicate autopilot component " << component->get_name() << ", renamed to " << name );
set_subsystem( name.c_str(), component );
}
diff --git a/src/Autopilot/autopilotgroup.cxx b/src/Autopilot/autopilotgroup.cxx
index e5bb6d03c..347a39e0e 100644
--- a/src/Autopilot/autopilotgroup.cxx
+++ b/src/Autopilot/autopilotgroup.cxx
@@ -28,117 +28,35 @@
#include "autopilot.hxx"
#include "autopilotgroup.hxx"
+#include
+#include
+
+#include
+#include
#include
-#include
-#include
-#include
-#include
-#include
-
-using std::cout;
-using std::endl;
using simgear::PropertyList;
-FGXMLAutopilotGroup::FGXMLAutopilotGroup() :
- SGSubsystemGroup()
-#ifdef XMLAUTO_USEHELPER
- ,average(0.0), // average/filtered prediction
- v_last(0.0), // last velocity
- last_static_pressure(0.0),
- vel(fgGetNode( "/velocities/airspeed-kt", true )),
- // Estimate speed in 5,10 seconds
- lookahead5(fgGetNode( "/autopilot/internal/lookahead-5-sec-airspeed-kt", true )),
- lookahead10(fgGetNode( "/autopilot/internal/lookahead-10-sec-airspeed-kt", true )),
- bug(fgGetNode( "/autopilot/settings/heading-bug-deg", true )),
- mag_hdg(fgGetNode( "/orientation/heading-magnetic-deg", true )),
- bug_error(fgGetNode( "/autopilot/internal/heading-bug-error-deg", true )),
- fdm_bug_error(fgGetNode( "/autopilot/internal/fdm-heading-bug-error-deg", true )),
- target_true(fgGetNode( "/autopilot/settings/true-heading-deg", true )),
- true_hdg(fgGetNode( "/orientation/heading-deg", true )),
- true_error(fgGetNode( "/autopilot/internal/true-heading-error-deg", true )),
- target_nav1(fgGetNode( "/instrumentation/nav[0]/radials/target-auto-hdg-deg", true )),
- true_nav1(fgGetNode( "/autopilot/internal/nav1-heading-error-deg", true )),
- true_track_nav1(fgGetNode( "/autopilot/internal/nav1-track-error-deg", true )),
- nav1_course_error(fgGetNode( "/autopilot/internal/nav1-course-error", true )),
- nav1_selected_course(fgGetNode( "/instrumentation/nav[0]/radials/selected-deg", true )),
- vs_fps(fgGetNode( "/velocities/vertical-speed-fps", true )),
- vs_fpm(fgGetNode( "/autopilot/internal/vert-speed-fpm", true )),
- static_pressure(fgGetNode( "/systems/static[0]/pressure-inhg", true )),
- pressure_rate(fgGetNode( "/autopilot/internal/pressure-rate", true )),
- track(fgGetNode( "/orientation/track-deg", true ))
-#endif
+class FGXMLAutopilotGroupImplementation : public FGXMLAutopilotGroup
{
-}
+public:
+ void init();
+ void reinit();
+ void update( double dt );
+private:
+ void initFrom( SGPropertyNode_ptr rootNode, const char * childName );
+ vector _autopilotNames;
-void FGXMLAutopilotGroup::update( double dt )
+};
+
+void FGXMLAutopilotGroupImplementation::update( double dt )
{
// update all configured autopilots
SGSubsystemGroup::update( dt );
-#ifdef XMLAUTO_USEHELPER
- // update helper values
- double v = vel->getDoubleValue();
- double a = 0.0;
- if ( dt > 0.0 ) {
- a = (v - v_last) / dt;
-
- if ( dt < 1.0 ) {
- average = (1.0 - dt) * average + dt * a;
- } else {
- average = a;
- }
-
- lookahead5->setDoubleValue( v + average * 5.0 );
- lookahead10->setDoubleValue( v + average * 10.0 );
- v_last = v;
- }
-
- // Calculate heading bug error normalized to +/- 180.0
- double diff = bug->getDoubleValue() - mag_hdg->getDoubleValue();
- SG_NORMALIZE_RANGE(diff, -180.0, 180.0);
- bug_error->setDoubleValue( diff );
-
- fdm_bug_error->setDoubleValue( diff );
-
- // Calculate true heading error normalized to +/- 180.0
- diff = target_true->getDoubleValue() - true_hdg->getDoubleValue();
- SG_NORMALIZE_RANGE(diff, -180.0, 180.0);
- true_error->setDoubleValue( diff );
-
- // Calculate nav1 target heading error normalized to +/- 180.0
- diff = target_nav1->getDoubleValue() - true_hdg->getDoubleValue();
- SG_NORMALIZE_RANGE(diff, -180.0, 180.0);
- true_nav1->setDoubleValue( diff );
-
- // Calculate true groundtrack
- diff = target_nav1->getDoubleValue() - track->getDoubleValue();
- SG_NORMALIZE_RANGE(diff, -180.0, 180.0);
- true_track_nav1->setDoubleValue( diff );
-
- // Calculate nav1 selected course error normalized to +/- 180.0
- diff = nav1_selected_course->getDoubleValue() - mag_hdg->getDoubleValue();
- SG_NORMALIZE_RANGE( diff, -180.0, 180.0 );
- nav1_course_error->setDoubleValue( diff );
-
- // Calculate vertical speed in fpm
- vs_fpm->setDoubleValue( vs_fps->getDoubleValue() * 60.0 );
-
-
- // Calculate static port pressure rate in [inhg/s].
- // Used to determine vertical speed.
- if ( dt > 0.0 ) {
- double current_static_pressure = static_pressure->getDoubleValue();
- double current_pressure_rate =
- ( current_static_pressure - last_static_pressure ) / dt;
-
- pressure_rate->setDoubleValue(current_pressure_rate);
- last_static_pressure = current_static_pressure;
- }
-#endif
}
-void FGXMLAutopilotGroup::reinit()
+void FGXMLAutopilotGroupImplementation::reinit()
{
SGSubsystemGroup::unbind();
@@ -152,18 +70,29 @@ void FGXMLAutopilotGroup::reinit()
init();
}
-void FGXMLAutopilotGroup::init()
+void FGXMLAutopilotGroupImplementation::init()
{
- PropertyList autopilotNodes = fgGetNode( "/sim/systems", true )->getChildren("autopilot");
- if( autopilotNodes.size() == 0 ) {
- SG_LOG( SG_ALL, SG_WARN, "No autopilot configuration specified for this model!");
- return;
- }
+ static const char * nodeNames[] = {
+ "autopilot",
+ "property-rule"
+ };
+ for( unsigned i = 0; i < sizeof(nodeNames)/sizeof(nodeNames[0]); i++ )
+ initFrom( fgGetNode( "/sim/systems" ), nodeNames[i] );
+ SGSubsystemGroup::bind();
+ SGSubsystemGroup::init();
+}
+
+void FGXMLAutopilotGroupImplementation::initFrom( SGPropertyNode_ptr rootNode, const char * childName )
+{
+ if( rootNode == NULL )
+ return;
+
+ PropertyList autopilotNodes = rootNode->getChildren(childName);
for( PropertyList::size_type i = 0; i < autopilotNodes.size(); i++ ) {
SGPropertyNode_ptr pathNode = autopilotNodes[i]->getNode( "path" );
if( pathNode == NULL ) {
- SG_LOG( SG_ALL, SG_WARN, "No autopilot configuration file specified for this autopilot!");
+ SG_LOG( SG_ALL, SG_WARN, "No configuration file specified for this property-rule!");
continue;
}
@@ -182,40 +111,36 @@ void FGXMLAutopilotGroup::init()
string name = apName;
for( unsigned i = 0; get_subsystem( apName.c_str() ) != NULL; i++ ) {
ostringstream buf;
- buf << apName << "_" << i;
+ buf << name << "_" << i;
apName = buf.str();
}
if( apName != name )
- SG_LOG( SG_ALL, SG_ALERT, "Duplicate autopilot component " << name << ", renamed to " << apName );
+ SG_LOG( SG_ALL, SG_WARN, "Duplicate property-rule configuration name " << name << ", renamed to " << apName );
}
- if( get_subsystem( apName.c_str() ) != NULL ) {
- SG_LOG( SG_ALL, SG_ALERT, "Duplicate autopilot configuration name " << apName << " ignored" );
- continue;
- }
+ SGPath config = globals->resolve_maybe_aircraft_path(pathNode->getStringValue());
- SGPath config = globals->resolve_aircraft_path(pathNode->getStringValue());
-
- SG_LOG( SG_ALL, SG_INFO, "Reading autopilot configuration from " << config.str() );
+ SG_LOG( SG_ALL, SG_INFO, "Reading property-rule configuration from " << config.str() );
try {
SGPropertyNode_ptr root = new SGPropertyNode();
readProperties( config.str(), root );
- SG_LOG( SG_AUTOPILOT, SG_INFO, "adding autopilot subsystem " << apName );
+ SG_LOG( SG_AUTOPILOT, SG_INFO, "adding property-rule subsystem " << apName );
FGXMLAutopilot::Autopilot * ap = new FGXMLAutopilot::Autopilot( autopilotNodes[i], root );
ap->set_name( apName );
set_subsystem( apName, ap );
_autopilotNames.push_back( apName );
} catch (const sg_exception& e) {
- SG_LOG( SG_AUTOPILOT, SG_ALERT, "Failed to load autopilot configuration: "
+ SG_LOG( SG_AUTOPILOT, SG_ALERT, "Failed to load property-rule configuration: "
<< config.str() << ":" << e.getMessage() );
continue;
}
}
-
- SGSubsystemGroup::bind();
- SGSubsystemGroup::init();
}
+FGXMLAutopilotGroup * FGXMLAutopilotGroup::createInstance()
+{
+ return new FGXMLAutopilotGroupImplementation();
+}
diff --git a/src/Autopilot/autopilotgroup.hxx b/src/Autopilot/autopilotgroup.hxx
index e27a6b16d..1ccb0be76 100644
--- a/src/Autopilot/autopilotgroup.hxx
+++ b/src/Autopilot/autopilotgroup.hxx
@@ -24,11 +24,6 @@
#ifndef _XMLAUTO_HXX
#define _XMLAUTO_HXX 1
-#include
-#include
-
-#include
-#include
/**
* @brief Model an autopilot system by implementing a SGSubsystemGroup
@@ -37,12 +32,9 @@
class FGXMLAutopilotGroup : public SGSubsystemGroup
{
public:
- FGXMLAutopilotGroup();
- void init();
- void reinit();
- void update( double dt );
-private:
- std::vector _autopilotNames;
+ static FGXMLAutopilotGroup * createInstance();
+protected:
+ FGXMLAutopilotGroup() : SGSubsystemGroup() {}
};
diff --git a/src/Cockpit/cockpit.cxx b/src/Cockpit/cockpit.cxx
index 54ccd2a23..a2f542cbc 100644
--- a/src/Cockpit/cockpit.cxx
+++ b/src/Cockpit/cockpit.cxx
@@ -26,6 +26,7 @@
#endif
#include
+#include
#include
#include
@@ -245,7 +246,8 @@ float get_climb_rate( void )
float get_view_direction( void )
{
double view_off = 360.0 - globals->get_current_view()->getHeadingOffset_deg();
- double view = SGMiscd::normalizeAngle(fgGetDouble("/orientation/heading-deg") + view_off);
+ double view = fgGetDouble("/orientation/heading-deg") + view_off;
+ SG_NORMALIZE_RANGE(view, 0.0, 360.0);
return view;
}
diff --git a/src/Environment/environment_ctrl.cxx b/src/Environment/environment_ctrl.cxx
index 74f1d82ea..0cc434e69 100644
--- a/src/Environment/environment_ctrl.cxx
+++ b/src/Environment/environment_ctrl.cxx
@@ -135,7 +135,9 @@ FGInterpolateEnvironmentCtrl::init ()
read_table( boundary_n, _boundary_table);
// pass in a pointer to the environment of the last bondary layer as
// a starting point
- read_table( aloft_n, _aloft_table, &(*(_boundary_table.end()-1))->environment);
+ read_table( aloft_n, _aloft_table,
+ _boundary_table.size() > 0 ?
+ &(*(_boundary_table.end()-1))->environment : NULL );
}
void
diff --git a/src/Environment/environment_mgr.cxx b/src/Environment/environment_mgr.cxx
index 98184acf9..c81022258 100644
--- a/src/Environment/environment_mgr.cxx
+++ b/src/Environment/environment_mgr.cxx
@@ -41,6 +41,7 @@
#include "environment_ctrl.hxx"
#include "fgclouds.hxx"
#include "precipitation_mgr.hxx"
+#include "ridge_lift.hxx"
class SGSky;
extern SGSky *thesky;
@@ -65,10 +66,18 @@ FGEnvironmentMgr::FGEnvironmentMgr ()
_precipitationManager = new FGPrecipitationMgr;
set_subsystem("precipitation", _precipitationManager);
+
+ set_subsystem("ridgelift", new FGRidgeLift);
}
FGEnvironmentMgr::~FGEnvironmentMgr ()
{
+ SGSubsystem * subsys;
+
+ subsys = get_subsystem( "ridgelift" );
+ remove_subsystem( "ridgelift" );
+ delete subsys;
+
remove_subsystem("precipitation");
delete _precipitationManager;
diff --git a/src/Environment/terrainsampler.cxx b/src/Environment/terrainsampler.cxx
new file mode 100644
index 000000000..276c8ffb1
--- /dev/null
+++ b/src/Environment/terrainsampler.cxx
@@ -0,0 +1,402 @@
+// terrainsampler.cxx --
+//
+// Written by Torsten Dreyer, started July 2010
+// Based on local weather implementation in nasal from
+// Thorsten Renk
+//
+// Copyright (C) 2010 Curtis Olson
+//
+// 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
+#endif
+
+#include
+#include
+#include
+#include
+
+#include "terrainsampler.hxx"
+using simgear::PropertyList;
+
+#include "tiedpropertylist.hxx"
+
+namespace Environment {
+/**
+ * @brief Class for presampling the terrain roughness
+ */
+class AreaSampler : public SGSubsystem {
+public:
+ AreaSampler( SGPropertyNode_ptr rootNode );
+ virtual ~AreaSampler();
+ void update( double dt );
+ void bind();
+ void unbind();
+ void init();
+ void reinit();
+
+ int getElevationHistogramStep() const { return _elevationHistogramStep; }
+ void setElevationHistograpStep( int value ) {
+ _elevationHistogramStep = value > 0 ? value : 500;
+ _elevationHistogramCount = _elevationHistogramMax / _elevationHistogramStep;
+ }
+
+ int getElevationHistogramMax() const { return _elevationHistogramMax; }
+ void setElevationHistograpMax( int value ) {
+ _elevationHistogramMax = value > 0 ? value : 10000;
+ _elevationHistogramCount = _elevationHistogramMax / _elevationHistogramStep;
+ }
+
+ int getElevationHistogramCount() const { return _elevationHistogramCount; }
+
+private:
+ void analyse();
+
+ SGPropertyNode_ptr _rootNode;
+
+ bool _enabled;
+ bool _useAircraftPosition;
+ double _heading_deg;
+ double _speed_kt;
+ int _radius;
+ double _max_computation_time_norm;
+ int _max_samples; // keep xx samples in queue for analysis
+ double _reuse_samples_norm;
+ double _recalc_distance_norm;
+ int _elevationHistogramMax;
+ int _elevationHistogramStep;
+ int _elevationHistogramCount;
+ SGGeod _inputPosition;
+
+ double _altOffset;
+ double _altMedian;
+ double _altMin;
+ double _altLayered;
+ double _altMean;
+ SGGeod _outputPosition;
+
+ SGPropertyNode_ptr _signalNode;
+ SGPropertyNode_ptr _positionLatitudeNode;
+ SGPropertyNode_ptr _positionLongitudeNode;
+
+ deque _elevations;
+ TiedPropertyList _tiedProperties;
+};
+
+AreaSampler::AreaSampler( SGPropertyNode_ptr rootNode ) :
+ _rootNode(rootNode),
+ _enabled(true),
+ _useAircraftPosition(false),
+ _heading_deg(0.0),
+ _speed_kt(0.0),
+ _radius(40000.0),
+ _max_computation_time_norm(0.1),
+ _max_samples(1000),
+ _reuse_samples_norm(0.8),
+ _recalc_distance_norm(0.1),
+ _elevationHistogramMax(10000),
+ _elevationHistogramStep(500),
+ _elevationHistogramCount(_elevationHistogramMax/_elevationHistogramStep),
+ _altOffset(0),
+ _altMedian(0),
+ _altMin(0),
+ _altLayered(0),
+ _altMean(0),
+ _signalNode(rootNode->getNode("output/valid", true )),
+ _positionLatitudeNode(fgGetNode( "/position/latitude-deg", true )),
+ _positionLongitudeNode(fgGetNode( "/position/longitude-deg", true ))
+{
+ _inputPosition.setElevationM( SG_MAX_ELEVATION_M );
+}
+
+AreaSampler::~AreaSampler()
+{
+}
+
+
+void AreaSampler::bind()
+{
+ _tiedProperties.setRoot( _rootNode );
+ _tiedProperties.Tie( "enabled", &_enabled );
+
+ _tiedProperties.setRoot( _rootNode->getNode( "input", true ) );
+ _tiedProperties.Tie( "use-aircraft-position", &_useAircraftPosition );
+ _tiedProperties.Tie( "latitude-deg", &_inputPosition, &SGGeod::getLatitudeDeg, &SGGeod::setLatitudeDeg );
+ _tiedProperties.Tie( "longitude-deg", &_inputPosition, &SGGeod::getLongitudeDeg, &SGGeod::setLongitudeDeg );
+ _tiedProperties.Tie( "heading-deg", &_heading_deg );
+ _tiedProperties.Tie( "speed-kt", &_speed_kt );
+ _tiedProperties.Tie( "radius-m", &_radius );
+ _tiedProperties.Tie( "max-computation-time-norm", &_max_computation_time_norm );
+ _tiedProperties.Tie( "max-samples", &_max_samples );
+ _tiedProperties.Tie( "reuse-samples-norm", &_reuse_samples_norm );
+ _tiedProperties.Tie( "recalc-distance-norm", &_recalc_distance_norm );
+ _tiedProperties.Tie( "elevation-histogram-max-ft", this, &AreaSampler::getElevationHistogramMax, &AreaSampler::setElevationHistograpMax );
+ _tiedProperties.Tie( "elevation-histogram-step-ft", this, &AreaSampler::getElevationHistogramStep, &AreaSampler::setElevationHistograpStep );
+ _tiedProperties.Tie( "elevation-histogram-count", this, &AreaSampler::getElevationHistogramCount );
+
+ _tiedProperties.setRoot( _rootNode->getNode( "output", true ) );
+ _tiedProperties.Tie( "alt-offset-ft", &_altOffset );
+ _tiedProperties.Tie( "alt-median-ft", &_altMedian );
+ _tiedProperties.Tie( "alt-min-ft", &_altMin );
+ _tiedProperties.Tie( "alt-layered-ft", &_altLayered );
+ _tiedProperties.Tie( "alt-mean-ft", &_altMean );
+ _tiedProperties.Tie( "longitude-deg", &_outputPosition, &SGGeod::getLongitudeDeg );
+ _tiedProperties.Tie( "latitude-deg", &_outputPosition, &SGGeod::getLatitudeDeg );
+
+}
+
+void AreaSampler::unbind()
+{
+ _tiedProperties.Untie();
+}
+
+void AreaSampler::init()
+{
+ _signalNode->setBoolValue(false);
+ _elevations.clear();
+ _altOffset = 0.0;
+ _altMedian = 0.0;
+ _altMin = 0.0;
+ _altLayered = 0.0;
+ _altMean = 0.0;
+}
+
+void AreaSampler::reinit()
+{
+ init();
+}
+
+void AreaSampler::update( double dt )
+{
+ // if not enabled or time has stalled, do nothing
+ if( !(_enabled && dt > SGLimitsd::min()) )
+ return;
+
+ // get the aircraft's position if requested
+ if( _useAircraftPosition && _speed_kt < 0.5 ) {
+ _inputPosition = SGGeod::fromDegM(
+ _positionLongitudeNode->getDoubleValue(),
+ _positionLatitudeNode->getDoubleValue(),
+ SG_MAX_ELEVATION_M );
+ }
+
+ // need geocentric coordinates
+ SGGeoc center = SGGeoc::fromGeod( _inputPosition );
+
+ // if a speed is set, move the input position
+ if( _speed_kt >= 0.5 ) {
+ double distance_m = _speed_kt * dt * SG_NM_TO_METER;
+ center = center.advanceRadM( _heading_deg * SG_DEGREES_TO_RADIANS, distance_m );
+ _inputPosition = SGGeod::fromGeoc( center );
+ }
+
+ if( _signalNode->getBoolValue() ) {
+ // if we had finished the iteration and moved more than 10% of the radius
+ // of the sampling area, drop the oldest samples and continue sampling
+ if( SGGeoc::distanceM( center, SGGeoc::fromGeod(_outputPosition ) ) >= _recalc_distance_norm * _radius ) {
+ _elevations.resize( _max_samples * _reuse_samples_norm );
+ _signalNode->setBoolValue( false );
+ }
+ }
+
+ if( _signalNode->getBoolValue() )
+ return; // nothing to do.
+
+ FGScenery * scenery = globals->get_scenery();
+
+ SGTimeStamp start = SGTimeStamp::now();
+ while( (SGTimeStamp::now() - start).toSecs() < dt * _max_computation_time_norm ) {
+ // sample until we used up all our configured time
+ double distance = sg_random();
+ distance = _radius * (1-distance*distance);
+ double course = sg_random() * 2.0 * SG_PI;
+ SGGeod probe = SGGeod::fromGeoc(center.advanceRadM( course, distance ));
+ double elevation_m = 0.0;
+
+ if (scenery->get_elevation_m( probe, elevation_m, NULL ))
+ _elevations.push_front(elevation_m *= SG_METER_TO_FEET);
+
+ if( _elevations.size() >= (deque::size_type)_max_samples ) {
+ // sampling complete?
+ analyse();
+ _outputPosition = _inputPosition;
+ _signalNode->setBoolValue( true );
+ break;
+ }
+ }
+}
+
+void AreaSampler::analyse()
+{
+ double sum;
+
+ vector histogram(_elevationHistogramCount,0);
+
+ for( deque::size_type i = 0; i < _elevations.size(); i++ ) {
+ int idx = SGMisc::clip( (int)(_elevations[i]/_elevationHistogramStep), 0, histogram.size()-1 );
+ histogram[idx]++;
+ }
+
+ _altMedian = 0.0;
+ sum = 0.0;
+ for( vector::size_type i = 0; i < histogram.size(); i++ ) {
+ sum += histogram[i];
+ if( sum > 0.5 * _elevations.size() ) {
+ _altMedian = i * _elevationHistogramStep;
+ break;
+ }
+ }
+
+ _altOffset = 0.0;
+ sum = 0.0;
+ for( vector::size_type i = 0; i < histogram.size(); i++ ) {
+ sum += histogram[i];
+ if( sum > 0.3 * _elevations.size() ) {
+ _altOffset = i * _elevationHistogramStep;
+ break;
+ }
+ }
+
+ _altMean = 0.0;
+ for( vector::size_type i = 0; i < histogram.size(); i++ ) {
+ _altMean += histogram[i] * i;
+ }
+ _altMean *= _elevationHistogramStep;
+ if( _elevations.size() != 0.0 ) _altMean /= _elevations.size();
+
+ _altMin = 0.0;
+ for( vector::size_type i = 0; i < histogram.size(); i++ ) {
+ if( histogram[i] > 0 ) {
+ _altMin = i * _elevationHistogramStep;
+ break;
+ }
+ }
+
+ double alt_low_min = 0.0;
+ double n_max = 0.0;
+ sum = 0.0;
+ for( vector::size_type i = 0; i < histogram.size()-1; i++ ) {
+ sum += histogram[i];
+ if( histogram[i] > n_max ) n_max = histogram[i];
+ if( n_max > histogram[i+1] && sum > 0.3*_elevations.size()) {
+ alt_low_min = i * _elevationHistogramStep;
+ break;
+ }
+ }
+
+ _altLayered = 0.5 * (_altMin + _altOffset);
+
+#if 0
+append(alt_50_array, alt_med);
+#endif
+}
+
+/* --------------------- End of AreaSampler implementation ------------- */
+
+/* --------------------- TerrainSamplerImplementation -------------------------- */
+
+class TerrainSamplerImplementation : public TerrainSampler
+{
+public:
+ TerrainSamplerImplementation ( SGPropertyNode_ptr rootNode );
+ virtual ~TerrainSamplerImplementation ();
+
+ virtual void init ();
+ virtual void postinit();
+ virtual void reinit ();
+ virtual void bind();
+ virtual void unbind();
+ virtual void update (double delta_time_sec);
+private:
+ inline string areaSubsystemName( unsigned i ) {
+ ostringstream name;
+ name << "area" << i;
+ return name.str();
+ }
+
+ SGPropertyNode_ptr _rootNode;
+ bool _enabled;
+ TiedPropertyList _tiedProperties;
+};
+
+TerrainSamplerImplementation::TerrainSamplerImplementation( SGPropertyNode_ptr rootNode ) :
+ _rootNode( rootNode ),
+ _enabled(true)
+{
+}
+
+TerrainSamplerImplementation::~TerrainSamplerImplementation()
+{
+}
+
+void TerrainSamplerImplementation::init()
+{
+ PropertyList areaNodes = _rootNode->getChildren( "area" );
+
+ for( PropertyList::size_type i = 0; i < areaNodes.size(); i++ )
+ set_subsystem( areaSubsystemName(i), new AreaSampler( areaNodes[i] ) );
+
+ SGSubsystemGroup::init();
+}
+
+void TerrainSamplerImplementation::postinit()
+{
+ SGSubsystemGroup::bind();//
+}
+
+void TerrainSamplerImplementation::reinit()
+{
+ for( unsigned i = 0;; i++ ) {
+ string subsystemName = areaSubsystemName(i);
+ SGSubsystem * subsys = get_subsystem( subsystemName );
+ if( subsys == NULL )
+ break;
+ remove_subsystem( subsystemName );
+ }
+
+ init();
+}
+
+void TerrainSamplerImplementation::bind()
+{
+ SGSubsystemGroup::bind();
+ _tiedProperties.Tie( _rootNode->getNode("enabled",true), &_enabled );
+}
+
+void TerrainSamplerImplementation::unbind()
+{
+ _tiedProperties.Untie();
+ SGSubsystemGroup::unbind();
+}
+
+void TerrainSamplerImplementation::update( double dt )
+{
+ if( !(_enabled && dt > SGLimitsd::min()) )
+ return;
+ SGSubsystemGroup::update(dt);
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* implementation of the TerrainSampler factory to hide the implementation
+ details */
+TerrainSampler * TerrainSampler::createInstance( SGPropertyNode_ptr rootNode )
+{
+ return new TerrainSamplerImplementation( rootNode );
+}
+
+} // namespace
+
diff --git a/src/Environment/terrainsampler.hxx b/src/Environment/terrainsampler.hxx
new file mode 100644
index 000000000..e9fa3c319
--- /dev/null
+++ b/src/Environment/terrainsampler.hxx
@@ -0,0 +1,36 @@
+// terrainsampler.hxx --
+//
+// Written by Torsten Dreyer, started July 2010
+// Based on local weather implementation in nasal from
+// Thorsten Renk
+//
+// Copyright (C) 2010 Curtis Olson
+//
+// 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 _TERRAIN_SAMPLER_HXX
+#define _TERRAIN_SAMPLER_HXX
+
+#include
+
+namespace Environment {
+class TerrainSampler : public SGSubsystemGroup
+{
+public:
+ static TerrainSampler * createInstance( SGPropertyNode_ptr rootNode );
+};
+
+} // namespace
+#endif
diff --git a/src/Environment/tiedpropertylist.hxx b/src/Environment/tiedpropertylist.hxx
new file mode 100644
index 000000000..dbb9cc45a
--- /dev/null
+++ b/src/Environment/tiedpropertylist.hxx
@@ -0,0 +1,80 @@
+#ifndef __TIEDPROPERTYLIST_HXX
+#define __TIEDPROPERTYLIST_HXX
+#include
+using simgear::PropertyList;
+
+// Maybe this goes into SimGear's props.hxx later?
+class TiedPropertyList : PropertyList {
+public:
+ TiedPropertyList() {}
+ TiedPropertyList( SGPropertyNode_ptr root ) { _root = root; }
+
+ void setRoot( SGPropertyNode_ptr root ) { _root = root; }
+ SGPropertyNode_ptr getRoot() const { return _root; }
+
+ template SGPropertyNode_ptr Tie( SGPropertyNode_ptr node, const SGRawValue &rawValue, bool useDefault = true ) {
+ bool success = node->tie( rawValue, useDefault );
+ if( success ) {
+ SG_LOG( SG_ALL, SG_INFO, "Tied " << node->getPath() );
+ push_back( node );
+ } else {
+#if PROPS_STANDALONE
+ cerr << "Failed to tie property " << node->getPath() << endl;
+#else
+ SG_LOG(SG_GENERAL, SG_WARN, "Failed to tie property " << node->getPath() );
+#endif
+ }
+ return node;
+ }
+
+ template SGPropertyNode_ptr Tie( SGPropertyNode_ptr node, V * value, bool useDefault = true ) {
+ return Tie( node, SGRawValuePointer(value), useDefault );
+ }
+
+ template SGPropertyNode_ptr Tie( const char * relative_path, V * value, bool useDefault = true ) {
+ return Tie( _root->getNode(relative_path,true), SGRawValuePointer(value), useDefault );
+ }
+
+ template SGPropertyNode_ptr Tie( SGPropertyNode_ptr node, V (*getter)(), void (*setter)(V) = 0, bool useDefault = true ) {
+ return Tie(node, SGRawValueFunctions(getter, setter), useDefault );
+ }
+
+ template SGPropertyNode_ptr Tie( const char * relative_path, V (*getter)(), void (*setter)(V) = 0, bool useDefault = true ) {
+ return Tie(_root->getNode(relative_path, true), SGRawValueFunctions(getter, setter), useDefault );
+ }
+
+ template SGPropertyNode_ptr Tie( SGPropertyNode_ptr node, int index, V (*getter)(int), void (*setter)(int, V) = 0, bool useDefault = true) {
+ return Tie( node, SGRawValueFunctionsIndexed(index, getter, setter), useDefault );
+ }
+
+ template SGPropertyNode_ptr Tie( const char * relative_path, int index, V (*getter)(int), void (*setter)(int, V) = 0, bool useDefault = true) {
+ return Tie( _root->getNode( relative_path, true ), SGRawValueFunctionsIndexed(index, getter, setter), useDefault );
+ }
+
+ template SGPropertyNode_ptr Tie( SGPropertyNode_ptr node, T * obj, V (T::*getter)() const, void (T::*setter)(V) = 0, bool useDefault = true) {
+ return Tie( node, SGRawValueMethods(*obj, getter, setter), useDefault );
+ }
+
+ template SGPropertyNode_ptr Tie( const char * relative_path, T * obj, V (T::*getter)() const, void (T::*setter)(V) = 0, bool useDefault = true) {
+ return Tie( _root->getNode( relative_path, true), SGRawValueMethods(*obj, getter, setter), useDefault );
+ }
+
+ template SGPropertyNode_ptr Tie( SGPropertyNode_ptr node, T * obj, int index, V (T::*getter)(int) const, void (T::*setter)(int, V) = 0, bool useDefault = true) {
+ return Tie( node, SGRawValueMethodsIndexed(*obj, index, getter, setter), useDefault);
+ }
+
+ template SGPropertyNode_ptr Tie( const char * relative_path, T * obj, int index, V (T::*getter)(int) const, void (T::*setter)(int, V) = 0, bool useDefault = true) {
+ return Tie( _root->getNode( relative_path, true ), SGRawValueMethodsIndexed(*obj, index, getter, setter), useDefault);
+ }
+
+ void Untie() {
+ while( size() > 0 ) {
+ SG_LOG( SG_ALL, SG_INFO, "untie of " << back()->getPath() );
+ back()->untie();
+ pop_back();
+ }
+ }
+private:
+ SGPropertyNode_ptr _root;
+};
+#endif
diff --git a/src/Instrumentation/dclgps.cxx b/src/Instrumentation/dclgps.cxx
index d3da8e828..018e943c4 100644
--- a/src/Instrumentation/dclgps.cxx
+++ b/src/Instrumentation/dclgps.cxx
@@ -1102,7 +1102,8 @@ FGPositioned* DCLGPS::FindTypedFirstById(const string& id, FGPositioned::Type ty
if (exact) {
FGPositioned::List matches =
- FGPositioned::findAllWithIdentSortedByRange(id, SGGeod::fromRad(_lon, _lat), &filter);
+ FGPositioned::findAllWithIdent(id, &filter);
+ FGPositioned::sortByRange(matches, SGGeod::fromRad(_lon, _lat));
multi = (matches.size() > 1);
return matches.empty() ? NULL : matches.front().ptr();
}
diff --git a/src/Instrumentation/gps.cxx b/src/Instrumentation/gps.cxx
index 06647d4ad..71e3becbd 100644
--- a/src/Instrumentation/gps.cxx
+++ b/src/Instrumentation/gps.cxx
@@ -220,7 +220,6 @@ GPS::GPS ( SGPropertyNode *node) :
_mode("init"),
_name(node->getStringValue("name", "gps")),
_num(node->getIntValue("number", 0)),
- _searchResultsCached(false),
_computeTurnData(false),
_anticipateTurn(false),
_inTurn(false)
@@ -333,7 +332,7 @@ GPS::bind()
tie(_gpsNode, "desired-course-deg", SGRawValueMethods
(*this, &GPS::getDesiredCourse, NULL));
- _desiredCourseNode = _gpsNode->getChild("desired-course-deg");
+ _desiredCourseNode = _gpsNode->getChild("desired-course-deg", 0, true);
tieSGGeodReadOnly(_gpsNode, _indicated_pos, "indicated-longitude-deg",
"indicated-latitude-deg", "indicated-altitude-ft");
@@ -1384,9 +1383,6 @@ void GPS::setScratchFromRouteWaypoint(int aIndex)
_scratchValid = true;
_scratchNode->setDoubleValue("course", wp.get_track());
_scratchNode->setIntValue("index", aIndex);
-
- int lastResult = _routeMgr->size() - 1;
- _searchHasNext = (_searchResultIndex < lastResult);
}
void GPS::loadNearest()
@@ -1411,17 +1407,14 @@ void GPS::loadNearest()
_searchResults =
FGPositioned::findClosestN(searchPos, limitCount, cutoffDistance, f.get());
- _searchResultsCached = true;
_searchResultIndex = 0;
_searchIsRoute = false;
- _searchHasNext = false;
if (_searchResults.empty()) {
SG_LOG(SG_INSTR, SG_INFO, "GPS:loadNearest: no matches at all");
return;
}
- _searchHasNext = (_searchResults.size() > 1);
setScratchFromCachedSearchResult();
}
@@ -1478,66 +1471,47 @@ void GPS::search()
}
_searchExact = _scratchNode->getBoolValue("exact", true);
- _searchOrderByRange = _scratchNode->getBoolValue("order-by-distance", true);
_searchResultIndex = 0;
_searchIsRoute = false;
- _searchHasNext = false;
-
- if (_searchExact && _searchOrderByRange) {
- // immediate mode search, get all the results now and cache them
- auto_ptr f(createFilter(_searchType));
- if (_searchNames) {
- _searchResults = FGPositioned::findAllWithNameSortedByRange(_searchQuery, _indicated_pos, f.get());
- } else {
- _searchResults = FGPositioned::findAllWithIdentSortedByRange(_searchQuery, _indicated_pos, f.get());
- }
-
- _searchResultsCached = true;
-
- if (_searchResults.empty()) {
- clearScratch();
- return;
- }
-
- _searchHasNext = (_searchResults.size() > 1);
- setScratchFromCachedSearchResult();
- } else {
- // iterative search, look up result zero
- _searchResultsCached = false;
- performSearch();
- }
-}
-void GPS::performSearch()
-{
auto_ptr f(createFilter(_searchType));
- clearScratch();
-
- FGPositionedRef r;
if (_searchNames) {
- if (_searchOrderByRange) {
- r = FGPositioned::findClosestWithPartialName(_indicated_pos, _searchQuery, f.get(), _searchResultIndex, _searchHasNext);
- } else {
- r = FGPositioned::findWithPartialName(_searchQuery, f.get(), _searchResultIndex, _searchHasNext);
- }
+ _searchResults = FGPositioned::findAllWithName(_searchQuery, f.get());
} else {
- if (_searchOrderByRange) {
- r = FGPositioned::findClosestWithPartialId(_indicated_pos, _searchQuery, f.get(), _searchResultIndex, _searchHasNext);
- } else {
- r = FGPositioned::findWithPartialId(_searchQuery, f.get(), _searchResultIndex, _searchHasNext);
- }
+ _searchResults = FGPositioned::findAllWithIdent(_searchQuery, f.get());
}
- if (!r) {
+ bool orderByRange = _scratchNode->getBoolValue("order-by-distance", true);
+ if (orderByRange) {
+ FGPositioned::sortByRange(_searchResults, _indicated_pos);
+ }
+
+ if (_searchResults.empty()) {
+ clearScratch();
return;
}
- setScratchFromPositioned(r.get(), _searchResultIndex);
+ setScratchFromCachedSearchResult();
+}
+
+bool GPS::getScratchHasNext() const
+{
+ int lastResult;
+ if (_searchIsRoute) {
+ lastResult = _routeMgr->size() - 1;
+ } else {
+ lastResult = (int) _searchResults.size() - 1;
+ }
+
+ if (lastResult < 0) { // search array might be empty
+ return false;
+ }
+
+ return (_searchResultIndex < lastResult);
}
void GPS::setScratchFromCachedSearchResult()
{
- assert(_searchResultsCached);
int index = _searchResultIndex;
if ((index < 0) || (index >= (int) _searchResults.size())) {
@@ -1546,9 +1520,6 @@ void GPS::setScratchFromCachedSearchResult()
}
setScratchFromPositioned(_searchResults[index], index);
-
- int lastResult = (int) _searchResults.size() - 1;
- _searchHasNext = (_searchResultIndex < lastResult);
}
void GPS::setScratchFromPositioned(FGPositioned* aPos, int aIndex)
@@ -1566,9 +1537,7 @@ void GPS::setScratchFromPositioned(FGPositioned* aPos, int aIndex)
}
_scratchValid = true;
- if (_searchResultsCached) {
- _scratchNode->setIntValue("result-count", _searchResults.size());
- }
+ _scratchNode->setIntValue("result-count", _searchResults.size());
switch (aPos->type()) {
case FGPositioned::VOR:
@@ -1652,20 +1621,17 @@ void GPS::selectLegMode()
void GPS::nextResult()
{
- if (!_searchHasNext) {
+ if (!getScratchHasNext()) {
return;
}
clearScratch();
if (_searchIsRoute) {
setScratchFromRouteWaypoint(++_searchResultIndex);
- } else if (_searchResultsCached) {
- ++_searchResultIndex;
- setScratchFromCachedSearchResult();
} else {
++_searchResultIndex;
- performSearch();
- } // of iterative search case
+ setScratchFromCachedSearchResult();
+ }
}
void GPS::previousResult()
@@ -1679,10 +1645,8 @@ void GPS::previousResult()
if (_searchIsRoute) {
setScratchFromRouteWaypoint(_searchResultIndex);
- } else if (_searchResultsCached) {
- setScratchFromCachedSearchResult();
} else {
- performSearch();
+ setScratchFromCachedSearchResult();
}
}
@@ -1701,14 +1665,15 @@ void GPS::defineWaypoint()
// check for duplicate idents
FGPositioned::TypeFilter f(FGPositioned::WAYPOINT);
- FGPositioned::List dups = FGPositioned::findAllWithIdentSortedByRange(ident, _indicated_pos, &f);
+ FGPositioned::List dups = FGPositioned::findAllWithIdent(ident, &f);
if (!dups.empty()) {
SG_LOG(SG_INSTR, SG_WARN, "GPS:defineWaypoint: non-unique waypoint identifier, ho-hum");
}
SG_LOG(SG_INSTR, SG_INFO, "GPS:defineWaypoint: creating waypoint:" << ident);
FGPositionedRef wpt = FGPositioned::createUserWaypoint(ident, _scratchPos);
- _searchResultsCached = false;
+ _searchResults.clear();
+ _searchResults.push_back(wpt);
setScratchFromPositioned(wpt.get(), -1);
}
diff --git a/src/Instrumentation/gps.hxx b/src/Instrumentation/gps.hxx
index cbdca3bc4..d6c3a7069 100644
--- a/src/Instrumentation/gps.hxx
+++ b/src/Instrumentation/gps.hxx
@@ -264,7 +264,7 @@ private:
double getScratchDistance() const;
double getScratchMagBearing() const;
double getScratchTrueBearing() const;
- bool getScratchHasNext() const { return _searchHasNext; }
+ bool getScratchHasNext() const;
double getSelectedCourse() const { return _selectedCourse; }
void setSelectedCourse(double crs);
@@ -394,8 +394,6 @@ private:
std::string _searchQuery;
FGPositioned::Type _searchType;
bool _searchExact;
- bool _searchOrderByRange;
- bool _searchResultsCached;
FGPositioned::List _searchResults;
bool _searchIsRoute; ///< set if 'search' is actually the current route
bool _searchHasNext; ///< is there a result after this one?
diff --git a/src/Instrumentation/instrument_mgr.cxx b/src/Instrumentation/instrument_mgr.cxx
index b85f191ae..2e3f21e3f 100644
--- a/src/Instrumentation/instrument_mgr.cxx
+++ b/src/Instrumentation/instrument_mgr.cxx
@@ -92,6 +92,7 @@ void FGInstrumentMgr::init()
SGPropertyNode_ptr nd(new SGPropertyNode);
nd->setStringValue("name", "gps");
nd->setIntValue("number", 0);
+ _instruments.push_back("gps[0]");
set_subsystem("gps[0]", new GPS(nd));
}
diff --git a/src/Main/fg_commands.cxx b/src/Main/fg_commands.cxx
index c277b6b73..ddeab463b 100644
--- a/src/Main/fg_commands.cxx
+++ b/src/Main/fg_commands.cxx
@@ -1349,6 +1349,10 @@ do_load_xml_to_proptree(const SGPropertyNode * arg)
if (file.extension() != "xml")
file.concat(".xml");
+ if (file.isRelative()) {
+ file = globals->resolve_maybe_aircraft_path(file.str());
+ }
+
if (!fgValidatePath(file.c_str(), false)) {
SG_LOG(SG_IO, SG_ALERT, "loadxml: reading '" << file.str() << "' denied "
"(unauthorized access)");
diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx
index 2db7f32e2..7d1b82fd8 100644
--- a/src/Main/fg_init.cxx
+++ b/src/Main/fg_init.cxx
@@ -109,7 +109,6 @@
#include
#include
-#include
#include "fg_init.hxx"
#include "fg_io.hxx"
@@ -1259,8 +1258,8 @@ bool fgInitGeneral() {
curr->setStringValue(cwd ? cwd : "");
curr->setAttribute(SGPropertyNode::WRITE, false);
- fgSetBool("/sim/startup/stdout-to-terminal", isatty(1));
- fgSetBool("/sim/startup/stderr-to-terminal", isatty(2));
+ fgSetBool("/sim/startup/stdout-to-terminal", isatty(1) != 0 );
+ fgSetBool("/sim/startup/stderr-to-terminal", isatty(2) != 0 );
return true;
}
@@ -1349,13 +1348,6 @@ bool fgInitSubsystems() {
// Initialize the weather modeling subsystem
globals->add_subsystem("environment", new FGEnvironmentMgr);
- ////////////////////////////////////////////////////////////////////
- // Initialize the ridge lift simulation.
- ////////////////////////////////////////////////////////////////////
-
- // Initialize the ridgelift subsystem
- globals->add_subsystem("ridgelift", new FGRidgeLift);
-
////////////////////////////////////////////////////////////////////
// Initialize the aircraft systems and instrumentation (before the
// autopilot.)
@@ -1368,7 +1360,7 @@ bool fgInitSubsystems() {
// Initialize the XML Autopilot subsystem.
////////////////////////////////////////////////////////////////////
- globals->add_subsystem( "xml-autopilot", new FGXMLAutopilotGroup, SGSubsystemMgr::FDM );
+ globals->add_subsystem( "xml-autopilot", FGXMLAutopilotGroup::createInstance(), SGSubsystemMgr::FDM );
globals->add_subsystem( "route-manager", new FGRouteMgr );
////////////////////////////////////////////////////////////////////
diff --git a/src/Main/globals.cxx b/src/Main/globals.cxx
index 35bc8f02d..bfa51f72f 100644
--- a/src/Main/globals.cxx
+++ b/src/Main/globals.cxx
@@ -105,6 +105,7 @@ FGGlobals::FGGlobals() :
airwaynet( NULL ),
multiplayer_mgr( NULL )
{
+
}
@@ -239,7 +240,15 @@ void FGGlobals::append_aircraft_path(const std::string& path)
return;
}
+ unsigned int index = fg_aircraft_dirs.size();
fg_aircraft_dirs.push_back(path);
+
+// make aircraft dirs available to Nasal
+ SGPropertyNode* sim = fgGetNode("/sim", true);
+ sim->removeChild("fg-aircraft", index, false);
+ SGPropertyNode* n = sim->getChild("fg-aircraft", index, true);
+ n->setStringValue(path);
+ n->setAttribute(SGPropertyNode::WRITE, false);
}
void FGGlobals::append_aircraft_paths(const std::string& path)
diff --git a/src/Model/model_panel.cxx b/src/Model/model_panel.cxx
index 8a2ec9b2f..a316243c1 100644
--- a/src/Model/model_panel.cxx
+++ b/src/Model/model_panel.cxx
@@ -30,7 +30,8 @@ using namespace simgear;
osg::Node *
fgLoad3DModelPanel(const std::string &path, SGPropertyNode *prop_root)
{
- osg::Node* node = SGModelLib::loadModel(path, prop_root);
+ bool loadPanels = true;
+ osg::Node* node = SGModelLib::loadModel(path, prop_root, NULL, loadPanels);
if (node)
node->setNodeMask(~SG_NODEMASK_TERRAIN_BIT);
return node;
diff --git a/src/Navaids/fixlist.cxx b/src/Navaids/fixlist.cxx
index 835a2b1b5..50c06ac56 100644
--- a/src/Navaids/fixlist.cxx
+++ b/src/Navaids/fixlist.cxx
@@ -39,6 +39,7 @@
FGFix::FGFix(const std::string& aIdent, const SGGeod& aPos) :
FGPositioned(FIX, aIdent, aPos)
{
+ init(true); // init FGPositioned
}
// Constructor
diff --git a/src/Navaids/markerbeacon.cxx b/src/Navaids/markerbeacon.cxx
index 3a49e3280..651879961 100644
--- a/src/Navaids/markerbeacon.cxx
+++ b/src/Navaids/markerbeacon.cxx
@@ -65,4 +65,5 @@ FGMarkerBeaconRecord::FGMarkerBeaconRecord(Type aTy, FGRunway* aRunway, const SG
FGPositioned(aTy, string(), aPos),
_runway(aRunway)
{
+ init(true); // init FGPositioned
}
diff --git a/src/Navaids/navrecord.cxx b/src/Navaids/navrecord.cxx
index 041c12f1a..a22bebb69 100644
--- a/src/Navaids/navrecord.cxx
+++ b/src/Navaids/navrecord.cxx
@@ -82,6 +82,7 @@ FGNavRecord::FGNavRecord(Type aTy, const std::string& aIdent,
}
}
+ init(true); // init FGPositioned (now position is adjusted)
}
void FGNavRecord::initAirportRelation()
diff --git a/src/Navaids/positioned.cxx b/src/Navaids/positioned.cxx
index 48f284648..917156877 100644
--- a/src/Navaids/positioned.cxx
+++ b/src/Navaids/positioned.cxx
@@ -22,6 +22,8 @@
# include "config.h"
#endif
+#include "positioned.hxx"
+
#include