diff --git a/configure.ac b/configure.ac index e1725ce50..25e73b4e3 100644 --- a/configure.ac +++ b/configure.ac @@ -263,29 +263,30 @@ if test "x$with_rti13" != "xno"; then AC_MSG_CHECKING([for simgear HLA/RTI support]) AC_LANG_PUSH(C++) AC_TRY_COMPILE([ - #include + #include ],[ - new simgear::HLA13Federate; + new simgear::HLAFederate; ], simgear_hla=yes, simgear_hla=no) AC_MSG_RESULT($simgear_hla) if test "x$simgear_hla" = "xyes" ; then AC_MSG_CHECKING([for hla libraries]) saved_LIBS="$LIBS" saved_LDFLAGS="$LDFLAGS" + have_rti13=no for rti13libs in "-lRTI-NG -lFedTime" "-lRTI-NGd -lFedTimed" ; do if test "x$hla_libs" = "x" ; then - LIBS="-lsghla13 -lsghla -lsgxml -lsgstructure -lsgmath -lsgdebug -lsgtiming $rti13libs -lrt $saved_LIBS" + LIBS="-lsghla -lsgrti13 -lsgrti -lsgxml -lsgstructure -lsgmath -lsgdebug -lsgtiming $rti13libs -lrt $saved_LIBS" LDFLAGS="$HLA_LDFLAGS $saved_LDFLAGS" AC_TRY_LINK([ - #include + #include ],[ - new simgear::HLA13Federate; + new simgear::HLAFederate; ], [hla_libs="$rti13libs"; have_rti13=yes],) fi done LIBS="$saved_LIBS" LDFLAGS="$saved_LDFLAGS" - AC_MSG_RESULT($hla_libs) + AC_MSG_RESULT($have_rti13) fi AC_LANG_POP() fi @@ -293,7 +294,7 @@ dnl Currently only the rti13 variant, but in the future also rti1516 AM_CONDITIONAL(WITH_HLA, test "x$have_rti13" = "xyes") if test "x$have_rti13" = "xyes" ; then AC_DEFINE([FG_HAVE_HLA], 1, [Define if HLA/RTI is available.]) - AC_SUBST(HLA_LIBS, "-lsghla13 -lsghla $hla_libs") + AC_SUBST(HLA_LIBS, "-lsghla -lsgrti13 -lsgrti $hla_libs") fi dnl EXPERIMENTAL fgpanel application diff --git a/src/AIModel/AIBallistic.cxx b/src/AIModel/AIBallistic.cxx index 4336fa14c..80778f84c 100644 --- a/src/AIModel/AIBallistic.cxx +++ b/src/AIModel/AIBallistic.cxx @@ -859,7 +859,7 @@ void FGAIBallistic::Run(double dt) { hs = 0; // adjust vertical speed for acceleration of gravity, buoyancy, and vertical force - double gravity = Environment::Gravity::instance()->getGravity(pos); + double gravity = SG_METER_TO_FEET * (Environment::Gravity::instance()->getGravity(pos)); vs -= (gravity - _buoyancy - v_force_acc_fpss - normal_force_fpss) * dt; if (vs <= 0.00001 && vs >= -0.00001) diff --git a/src/FDM/CMakeLists.txt b/src/FDM/CMakeLists.txt index 74d695f50..8153b4461 100644 --- a/src/FDM/CMakeLists.txt +++ b/src/FDM/CMakeLists.txt @@ -5,6 +5,7 @@ set(SP_FDM_SOURCES SP/ACMS.cxx SP/ADA.cxx SP/Balloon.cxx + SP/BalloonSim.cpp SP/MagicCarpet.cxx ) endif() diff --git a/src/Main/CMakeLists.txt b/src/Main/CMakeLists.txt index 2f80a23f6..5818335d3 100644 --- a/src/Main/CMakeLists.txt +++ b/src/Main/CMakeLists.txt @@ -61,24 +61,25 @@ get_property(FG_LIBS GLOBAL PROPERTY FG_LIBS) #message(STATUS "SG libs ${SIMGEAR_LIBRARIES}") if(RTI_FOUND) - find_sg_component(hla13 SIMGEAR_LIBRARIES) find_sg_component(hla SIMGEAR_LIBRARIES) + find_sg_component(rti13 SIMGEAR_LIBRARIES) + find_sg_component(rti SIMGEAR_LIBRARIES) set(HLA_LIBRARIES ${RTI_LIBRARIES}) else() set(HLA_LIBRARIES "") endif() -target_link_libraries(fgfs +target_link_libraries(fgfs ${FG_LIBS} ${HLA_LIBRARIES} ${SIMGEAR_LIBRARIES} - ${OPENSCENEGRAPH_LIBRARIES} - ${OPENAL_LIBRARY} + ${OPENSCENEGRAPH_LIBRARIES} + ${OPENAL_LIBRARY} ${OPENGL_LIBRARIES} - ${ALUT_LIBRARY} + ${ALUT_LIBRARY} ${ZLIB_LIBRARIES} ${PLIB_LIBRARIES} ${LIBSVN_LIBRARIES} ${RT_LIBRARY}) - + install(TARGETS fgfs RUNTIME DESTINATION bin) diff --git a/src/Main/fg_props.hxx b/src/Main/fg_props.hxx index 41772ff35..8f2e95f0f 100644 --- a/src/Main/fg_props.hxx +++ b/src/Main/fg_props.hxx @@ -85,6 +85,18 @@ extern bool fgLoadProps (const char * path, SGPropertyNode * props, */ extern SGPropertyNode * fgGetNode (const char * path, bool create = false); +/** + * Get a property node. + * + * @param path The path of the node, relative to root. + * @param create true to create the node if it doesn't exist. + * @return The node, or 0 if none exists and none was created. + */ +inline SGPropertyNode * fgGetNode (const std::string & path, bool create = false) +{ + return fgGetNode(path.c_str(), create ); +} + /** * Get a property node with separate index. @@ -103,6 +115,26 @@ extern SGPropertyNode * fgGetNode (const char * path, bool create = false); extern SGPropertyNode * fgGetNode (const char * path, int index, bool create = false); +/** + * Get a property node with separate index. + * + * This method separates the index from the path string, to make it + * easier to iterate through multiple components without using sprintf + * to add indices. For example, fgGetNode("foo[1]/bar", 3) will + * return the same result as fgGetNode("foo[1]/bar[3]"). + * + * @param path The path of the node, relative to root. + * @param index The index for the last member of the path (overrides + * any given in the string). + * @param create true to create the node if it doesn't exist. + * @return The node, or 0 if none exists and none was created. + */ +inline SGPropertyNode * fgGetNode (const std::string & path, + int index, bool create = false) +{ + return fgGetNode(path.c_str(), index, create ); +} + /** * Test whether a given node exists. @@ -112,6 +144,17 @@ extern SGPropertyNode * fgGetNode (const char * path, */ extern bool fgHasNode (const char * path); +/** + * Test whether a given node exists. + * + * @param path The path of the node, relative to root. + * @return true if the node exists, false otherwise. + */ +inline bool fgHasNode (const std::string & path) +{ + return fgHasNode( path.c_str() ); +} + /** * Add a listener to a node. @@ -124,6 +167,20 @@ extern bool fgHasNode (const char * path); extern void fgAddChangeListener (SGPropertyChangeListener * listener, const char * path); +/** + * Add a listener to a node. + * + * @param listener The listener to add to the node. + * @param path The path of the node, relative to root. + * @param index The index for the last member of the path (overrides + * any given in the string). + */ +inline void fgAddChangeListener (SGPropertyChangeListener * listener, + const std::string & path) +{ + fgAddChangeListener( listener, path.c_str() ); +} + /** * Add a listener to a node. @@ -136,6 +193,20 @@ extern void fgAddChangeListener (SGPropertyChangeListener * listener, extern void fgAddChangeListener (SGPropertyChangeListener * listener, const char * path, int index); +/** + * Add a listener to a node. + * + * @param listener The listener to add to the node. + * @param path The path of the node, relative to root. + * @param index The index for the last member of the path (overrides + * any given in the string). + */ +inline void fgAddChangeListener (SGPropertyChangeListener * listener, + const std::string & path, int index) +{ + fgAddChangeListener( listener, path.c_str(), index ); +} + /** * Get a bool value for a property. @@ -153,6 +224,25 @@ extern void fgAddChangeListener (SGPropertyChangeListener * listener, */ extern bool fgGetBool (const char * name, bool defaultValue = false); +/** + * Get a bool value for a property. + * + * This method is convenient but inefficient. It should be used + * infrequently (i.e. for initializing, loading, saving, etc.), + * not in the main loop. If you need to get a value frequently, + * it is better to look up the node itself using fgGetNode and then + * use the node's getBoolValue() method, to avoid the lookup overhead. + * + * @param name The property name. + * @param defaultValue The default value to return if the property + * does not exist. + * @return The property's value as a bool, or the default value provided. + */ +inline bool fgGetBool (const std::string & name, bool defaultValue = false) +{ + return fgGetBool( name.c_str(), defaultValue ); +} + /** * Get an int value for a property. @@ -170,6 +260,25 @@ extern bool fgGetBool (const char * name, bool defaultValue = false); */ extern int fgGetInt (const char * name, int defaultValue = 0); +/** + * Get an int value for a property. + * + * This method is convenient but inefficient. It should be used + * infrequently (i.e. for initializing, loading, saving, etc.), + * not in the main loop. If you need to get a value frequently, + * it is better to look up the node itself using fgGetNode and then + * use the node's getIntValue() method, to avoid the lookup overhead. + * + * @param name The property name. + * @param defaultValue The default value to return if the property + * does not exist. + * @return The property's value as an int, or the default value provided. + */ +inline int fgGetInt (const std::string & name, int defaultValue = 0) +{ + return fgGetInt( name.c_str(), defaultValue ); +} + /** * Get a long value for a property. @@ -187,6 +296,25 @@ extern int fgGetInt (const char * name, int defaultValue = 0); */ extern int fgGetLong (const char * name, long defaultValue = 0L); +/** + * Get a long value for a property. + * + * This method is convenient but inefficient. It should be used + * infrequently (i.e. for initializing, loading, saving, etc.), + * not in the main loop. If you need to get a value frequently, + * it is better to look up the node itself using fgGetNode and then + * use the node's getLongValue() method, to avoid the lookup overhead. + * + * @param name The property name. + * @param defaultValue The default value to return if the property + * does not exist. + * @return The property's value as a long, or the default value provided. + */ +inline int fgGetLong (const std::string & name, long defaultValue = 0L) +{ + return fgGetLong( name.c_str(), defaultValue ); +} + /** * Get a float value for a property. @@ -204,6 +332,25 @@ extern int fgGetLong (const char * name, long defaultValue = 0L); */ extern float fgGetFloat (const char * name, float defaultValue = 0.0); +/** + * Get a float value for a property. + * + * This method is convenient but inefficient. It should be used + * infrequently (i.e. for initializing, loading, saving, etc.), + * not in the main loop. If you need to get a value frequently, + * it is better to look up the node itself using fgGetNode and then + * use the node's getFloatValue() method, to avoid the lookup overhead. + * + * @param name The property name. + * @param defaultValue The default value to return if the property + * does not exist. + * @return The property's value as a float, or the default value provided. + */ +inline float fgGetFloat (const std::string & name, float defaultValue = 0.0) +{ + return fgGetFloat( name.c_str(), defaultValue ); +} + /** * Get a double value for a property. @@ -221,6 +368,25 @@ extern float fgGetFloat (const char * name, float defaultValue = 0.0); */ extern double fgGetDouble (const char * name, double defaultValue = 0.0); +/** + * Get a double value for a property. + * + * This method is convenient but inefficient. It should be used + * infrequently (i.e. for initializing, loading, saving, etc.), + * not in the main loop. If you need to get a value frequently, + * it is better to look up the node itself using fgGetNode and then + * use the node's getDoubleValue() method, to avoid the lookup overhead. + * + * @param name The property name. + * @param defaultValue The default value to return if the property + * does not exist. + * @return The property's value as a double, or the default value provided. + */ +inline double fgGetDouble (const std::string & name, double defaultValue = 0.0) +{ + return fgGetDouble( name.c_str(), defaultValue ); +} + /** * Get a string value for a property. @@ -239,6 +405,26 @@ extern double fgGetDouble (const char * name, double defaultValue = 0.0); extern const char * fgGetString (const char * name, const char * defaultValue = ""); +/** + * Get a string value for a property. + * + * This method is convenient but inefficient. It should be used + * infrequently (i.e. for initializing, loading, saving, etc.), + * not in the main loop. If you need to get a value frequently, + * it is better to look up the node itself using fgGetNode and then + * use the node's getStringValue() method, to avoid the lookup overhead. + * + * @param name The property name. + * @param defaultValue The default value to return if the property + * does not exist. + * @return The property's value as a string, or the default value provided. + */ +inline const char * fgGetString (const std::string & name, + const std::string & defaultValue = string("")) +{ + return fgGetString( name.c_str(), defaultValue.c_str() ); +} + /** * Set a bool value for a property. @@ -255,6 +441,24 @@ extern const char * fgGetString (const char * name, */ extern bool fgSetBool (const char * name, bool val); +/** + * Set a bool value for a property. + * + * Assign a bool value to a property. If the property does not + * yet exist, it will be created and its type will be set to + * BOOL; if it has a type of UNKNOWN, the type will also be set to + * BOOL; otherwise, the bool value will be converted to the property's + * type. + * + * @param name The property name. + * @param val The new value for the property. + * @return true if the assignment succeeded, false otherwise. + */ +inline bool fgSetBool (const std::string & name, bool val) +{ + return fgSetBool( name.c_str(), val ); +} + /** * Set an int value for a property. @@ -271,6 +475,23 @@ extern bool fgSetBool (const char * name, bool val); */ extern bool fgSetInt (const char * name, int val); +/** + * Set an int value for a property. + * + * Assign an int value to a property. If the property does not + * yet exist, it will be created and its type will be set to + * INT; if it has a type of UNKNOWN, the type will also be set to + * INT; otherwise, the bool value will be converted to the property's + * type. + * + * @param name The property name. + * @param val The new value for the property. + * @return true if the assignment succeeded, false otherwise. + */ +inline bool fgSetInt (const std::string & name, int val) +{ + return fgSetInt( name.c_str(), val ); +} /** * Set a long value for a property. @@ -287,6 +508,24 @@ extern bool fgSetInt (const char * name, int val); */ extern bool fgSetLong (const char * name, long val); +/** + * Set a long value for a property. + * + * Assign a long value to a property. If the property does not + * yet exist, it will be created and its type will be set to + * LONG; if it has a type of UNKNOWN, the type will also be set to + * LONG; otherwise, the bool value will be converted to the property's + * type. + * + * @param name The property name. + * @param val The new value for the property. + * @return true if the assignment succeeded, false otherwise. + */ +inline bool fgSetLong (const std::string & name, long val) +{ + return fgSetLong( name.c_str(), val ); +} + /** * Set a float value for a property. @@ -303,6 +542,24 @@ extern bool fgSetLong (const char * name, long val); */ extern bool fgSetFloat (const char * name, float val); +/** + * Set a float value for a property. + * + * Assign a float value to a property. If the property does not + * yet exist, it will be created and its type will be set to + * FLOAT; if it has a type of UNKNOWN, the type will also be set to + * FLOAT; otherwise, the bool value will be converted to the property's + * type. + * + * @param name The property name. + * @param val The new value for the property. + * @return true if the assignment succeeded, false otherwise. + */ +inline bool fgSetFloat (const std::string & name, float val) +{ + return fgSetFloat( name.c_str(), val ); +} + /** * Set a double value for a property. @@ -319,6 +576,24 @@ extern bool fgSetFloat (const char * name, float val); */ extern bool fgSetDouble (const char * name, double val); +/** + * Set a double value for a property. + * + * Assign a double value to a property. If the property does not + * yet exist, it will be created and its type will be set to + * DOUBLE; if it has a type of UNKNOWN, the type will also be set to + * DOUBLE; otherwise, the double value will be converted to the property's + * type. + * + * @param name The property name. + * @param val The new value for the property. + * @return true if the assignment succeeded, false otherwise. + */ +inline bool fgSetDouble (const std::string & name, double val) +{ + return fgSetDouble( name.c_str(), val ); +} + /** * Set a string value for a property. @@ -335,6 +610,24 @@ extern bool fgSetDouble (const char * name, double val); */ extern bool fgSetString (const char * name, const char * val); +/** + * Set a string value for a property. + * + * Assign a string value to a property. If the property does not + * yet exist, it will be created and its type will be set to + * STRING; if it has a type of UNKNOWN, the type will also be set to + * STRING; otherwise, the string value will be converted to the property's + * type. + * + * @param name The property name. + * @param val The new value for the property. + * @return true if the assignment succeeded, false otherwise. + */ +inline bool fgSetString (const std::string & name, const std::string & val) +{ + return fgSetString( name.c_str(), val.c_str() ); +} + //////////////////////////////////////////////////////////////////////// diff --git a/src/Network/HLA/hla.cxx b/src/Network/HLA/hla.cxx index cf6af5eff..8d6b696a8 100644 --- a/src/Network/HLA/hla.cxx +++ b/src/Network/HLA/hla.cxx @@ -37,7 +37,7 @@ #include #include -#include +#include #include #include #include @@ -77,7 +77,7 @@ public: HLAVersion getRTIVersion() const { return _rtiVersion; } - const std::vector& getRTIArguments() const + const std::list& getRTIArguments() const { return _rtiArguments; } struct DataElement { @@ -318,7 +318,7 @@ private: std::string _federateObjectModel; HLAVersion _rtiVersion; - std::vector _rtiArguments; + std::list _rtiArguments; ObjectClassConfigList _objectClassConfigList; }; @@ -818,7 +818,8 @@ private: sg::HLADataElement::IndexPathPair _mpPropertiesIndexPathPair; }; -FGHLA::FGHLA(const std::vector& tokens) +FGHLA::FGHLA(const std::vector& tokens) : + _hlaFederate(new simgear::HLAFederate) { if (1 < tokens.size() && !tokens[1].empty()) set_direction(tokens[1]); @@ -919,14 +920,23 @@ FGHLA::open() // We need that to communicate to the rti switch (configReader.getRTIVersion()) { case RTI13: - _hlaFederate = new simgear::HLA13Federate; + if (!_hlaFederate->connect(simgear::HLAFederate::RTI13, configReader.getRTIArguments())) { + SG_LOG(SG_IO, SG_ALERT, "Could not connect to RTI13 federation."); + return false; + } break; case RTI1516: - SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516 not yet(!?) supported."); - return false; + if (!_hlaFederate->connect(simgear::HLAFederate::RTI1516, configReader.getRTIArguments())) { + SG_LOG(SG_IO, SG_ALERT, "Could not connect to RTI1516 federation."); + return false; + } + break; case RTI1516E: - SG_LOG(SG_IO, SG_ALERT, "HLA version RTI1516E not yet(!?) supported."); - return false; + if (!_hlaFederate->connect(simgear::HLAFederate::RTI1516E, configReader.getRTIArguments())) { + SG_LOG(SG_IO, SG_ALERT, "Could not connect to RTI1516E federation."); + return false; + } + break; } // Try to create a new federation execution @@ -1264,7 +1274,7 @@ FGHLA::close() _hlaFederate->destroyFederationExecution(_federation); // throw away the HLAFederate - _hlaFederate = 0; + _hlaFederate->disconnect(); set_enabled(false); diff --git a/utils/GPSsmooth/CMakeLists.txt b/utils/GPSsmooth/CMakeLists.txt index 56ed1b463..453e2369c 100644 --- a/utils/GPSsmooth/CMakeLists.txt +++ b/utils/GPSsmooth/CMakeLists.txt @@ -15,6 +15,7 @@ target_link_libraries(GPSsmooth ${WINMM_LIBRARY} ${WINSOCK_LIBRARY} ${ZLIB_LIBRARIES} + ${OPENTHREADS_LIBRARIES} ${RT_LIBRARY} ) @@ -25,6 +26,7 @@ target_link_libraries(MIDGsmooth ${SIMGEAR_STRUCTURE_LIBRARY} ${SIMGEAR_TIMING_LIBRARY} ${SIMGEAR_DEBUG_LIBRARY} + ${OPENTHREADS_LIBRARIES} ${PLIB_SG_LIBRARY} ${PLIB_UL_LIBRARY} ${WINMM_LIBRARY} @@ -40,6 +42,7 @@ target_link_libraries(UGsmooth ${SIMGEAR_SERIAL_LIBRARY} ${SIMGEAR_STRUCTURE_LIBRARY} ${SIMGEAR_TIMING_LIBRARY} + ${OPENTHREADS_LIBRARIES} ${PLIB_SG_LIBRARY} ${PLIB_UL_LIBRARY} ${WINMM_LIBRARY} diff --git a/utils/TerraSync/CMakeLists.txt b/utils/TerraSync/CMakeLists.txt index 88b208c16..25c01f084 100644 --- a/utils/TerraSync/CMakeLists.txt +++ b/utils/TerraSync/CMakeLists.txt @@ -4,6 +4,7 @@ add_executable(terrasync terrasync.cxx) target_link_libraries(terrasync ${SIMGEAR_LIBRARIES} + ${OPENTHREADS_LIBRARIES} ${ZLIB_LIBRARIES} ${WINSOCK_LIBRARY}) diff --git a/utils/fgpanel/CMakeLists.txt b/utils/fgpanel/CMakeLists.txt index 8abc896e7..3595bf164 100644 --- a/utils/fgpanel/CMakeLists.txt +++ b/utils/fgpanel/CMakeLists.txt @@ -20,6 +20,7 @@ if(GLUT_FOUND) ${PNG_LIBRARIES} ${GLUT_LIBRARIES} ${SIMGEAR_LIBRARIES} + ${OPENTHREADS_LIBRARIES} ${OPENGL_LIBRARIES} ${ZLIB_LIBRARIES} ${PLIB_LIBRARIES}