From 11146b8d9269c3b139f612047928b3b3da3cb3ba Mon Sep 17 00:00:00 2001 From: Bertrand Coconnier Date: Fri, 1 Sep 2023 21:34:48 +0200 Subject: [PATCH] Maintenance / Minor changes (#952) * Remove useless parameter. * Increase the sleep time to avoid failures with MSVC. * Fix the deprecated method `lookup` from pandas. * A couple of small improvements to `FGPropertyManager::Unbind()`. * Fix the supported versions of the Python language in `README.md` * Improvements to some unit tests. * Fix a number of small details. --- .github/workflows/cpp-python-build.yml | 2 +- README.md | 4 +-- python/jsbsim.pxd | 2 +- python/jsbsim.pyx.in | 8 +++--- src/FGFDMExec.cpp | 2 +- src/JSBSim.cpp | 6 ++++- src/initialization/FGInitialCondition.cpp | 6 ++--- src/initialization/FGInitialCondition.h | 4 +-- src/input_output/FGPropertyManager.cpp | 2 +- src/input_output/FGPropertyManager.h | 20 ++++++++++++--- src/math/FGParameterValue.h | 2 -- src/models/FGInertial.cpp | 2 +- src/models/FGInertial.h | 2 +- tests/CMakeLists.txt | 2 +- tests/JSBSim_utils.py | 5 ++-- tests/TestInputSocket.py | 2 +- tests/unit_tests/FGAtmosphereTest.h | 5 ++-- tests/unit_tests/FGAuxiliaryTest.h | 30 +++++++++++++++-------- tests/unit_tests/FGMSISTest.h | 2 +- 19 files changed, 66 insertions(+), 42 deletions(-) diff --git a/.github/workflows/cpp-python-build.yml b/.github/workflows/cpp-python-build.yml index 42cb93523..1b3b37854 100644 --- a/.github/workflows/cpp-python-build.yml +++ b/.github/workflows/cpp-python-build.yml @@ -737,7 +737,7 @@ jobs: - name: Upload to Codecov uses: codecov/codecov-action@v3 with: - working-directory: build/lcov/data/capture + directory: build/lcov/data/capture files: all_targets.info Rolling-Release: diff --git a/README.md b/README.md index aba82a482..5a854b893 100644 --- a/README.md +++ b/README.md @@ -70,11 +70,11 @@ Debian packages for Ubuntu Linux "Bionic" 18.04 LTS and "Focal" 20.04 LTS for 64 * `JSBSim_1.1.13-986.amd64.deb` which installs the executables `JSBSim` and `aeromatic` * `JSBSim-devel_1.1.13-986.amd64.deb` which installs the development resources (headers and libraries) -* `python3-JSBSim_1.1.13-986.amd64.deb` which installs the Python 3.6 module of JSBSim +* `python3-JSBSim_1.1.13-986.amd64.deb` which installs the Python module of JSBSim ### Python module -JSBSim provides binary wheel packages for its Python module on Windows, Mac OSX and Linux platforms for several Python versions (3.6, 3.7, 3.8, 3.9 and 3.10). These can be installed using either `pip` or `conda`. +JSBSim provides binary wheel packages for its Python module on Windows, Mac OSX and Linux platforms for several Python versions (3.7, 3.8, 3.9, 3.10 and 3.11). These can be installed using either `pip` or `conda`. #### Installation with `pip` diff --git a/python/jsbsim.pxd b/python/jsbsim.pxd index ad2c16c46..6093c0906 100644 --- a/python/jsbsim.pxd +++ b/python/jsbsim.pxd @@ -38,7 +38,7 @@ cdef extern from "ExceptionManagement.h": cdef extern from "initialization/FGInitialCondition.h" namespace "JSBSim": cdef cppclass c_FGInitialCondition "JSBSim::FGInitialCondition": c_FGInitialCondition(c_FGInitialCondition* ic) - bool Load(const c_SGPath& rstfile, bool useStoredPath) + bool Load(const c_SGPath& rstfile, bool useAircraftPath) cdef extern from "initialization/FGLinearization.h" namespace "JSBSim": cdef cppclass c_FGLinearization "JSBSim::FGLinearization": diff --git a/python/jsbsim.pyx.in b/python/jsbsim.pyx.in index e73320142..4a8c2144f 100644 --- a/python/jsbsim.pyx.in +++ b/python/jsbsim.pyx.in @@ -752,7 +752,7 @@ cdef class FGFDMExec(FGJSBBase): model.encode(), add_model_to_path) def load_script(self, script: str, delta_t: float = 0.0, initfile:str = "") -> bool: - """@Dox(JSBSim::FGFDMExec::LoadScript) """ + """@Dox(JSBSim::FGFDMExec::LoadScript)""" scriptfile = os.path.join(self.get_root_dir(), script) if not os.path.exists(scriptfile): raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), @@ -951,15 +951,15 @@ cdef class FGFDMExec(FGJSBBase): """@Dox(JSBSim::FGFDMExec::GetDebugLevel) """ return self.thisptr.GetDebugLevel() - def load_ic(self, rstfile: str, useStoredPath: bool) -> bool: + def load_ic(self, rstfile: str, useAircraftPath: bool) -> bool: reset_file = _append_xml(rstfile) - if useStoredPath and not os.path.isabs(reset_file): + if useAircraftPath and not os.path.isabs(reset_file): reset_file = os.path.join(self.get_full_aircraft_path(), reset_file) if not os.path.exists(reset_file): raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), reset_file) return deref(self.thisptr.GetIC()).Load(c_SGPath(rstfile.encode(), NULL), - useStoredPath) + useAircraftPath) def get_propagate(self) -> FGPropagate: """@Dox(JSBSim::FGFDMExec::GetPropagate)""" diff --git a/src/FGFDMExec.cpp b/src/FGFDMExec.cpp index f5ba6a6b1..60bfb17c1 100644 --- a/src/FGFDMExec.cpp +++ b/src/FGFDMExec.cpp @@ -796,7 +796,7 @@ bool FGFDMExec::LoadPlanet(Element* element) string model = atm_element->GetAttributeValue("model"); if (model == "MSIS") { // Replace the existing atmosphere model - instance->Unbind(Models[eAtmosphere].get()); + instance->Unbind(Models[eAtmosphere]); Models[eAtmosphere] = std::make_shared(this); Atmosphere = static_cast(Models[eAtmosphere].get()); diff --git a/src/JSBSim.cpp b/src/JSBSim.cpp index 09090efbf..18226301b 100644 --- a/src/JSBSim.cpp +++ b/src/JSBSim.cpp @@ -300,6 +300,10 @@ int main(int argc, char* argv[]) std::cerr << "FATAL ERROR: JSBSim terminated with an exception." << std::endl << "The message was: " << msg << std::endl; return 1; + } catch (const JSBSim::BaseException& e) { + std::cerr << "FATAL ERROR: JSBSim terminated with an exception." + << std::endl << "The message was: " << e.what() << std::endl; + return 1; } catch (...) { std::cerr << "FATAL ERROR: JSBSim terminated with an unknown exception." << std::endl; @@ -794,7 +798,7 @@ void PrintHelp(void) cout << " --nice specifies to run at lower CPU usage" << endl; cout << " --nohighlight specifies that console output should be pure text only (no color)" << endl; cout << " --suspend specifies to suspend the simulation after initialization" << endl; - cout << " --initfile= specifies an initilization file" << endl; + cout << " --initfile= specifies an initialization file" << endl; cout << " --planet= specifies a planet definition file" << endl; cout << " --catalog specifies that all properties for this aircraft model should be printed" << endl; cout << " (catalog=aircraftname is an optional format)" << endl; diff --git a/src/initialization/FGInitialCondition.cpp b/src/initialization/FGInitialCondition.cpp index 71125ae5e..e9f909446 100644 --- a/src/initialization/FGInitialCondition.cpp +++ b/src/initialization/FGInitialCondition.cpp @@ -1002,10 +1002,10 @@ double FGInitialCondition::GetBodyVelFpsIC(int idx) const //****************************************************************************** -bool FGInitialCondition::Load(const SGPath& rstfile, bool useStoredPath) +bool FGInitialCondition::Load(const SGPath& rstfile, bool useAircraftPath) { SGPath init_file_name; - if(useStoredPath && rstfile.isRelative()) { + if(useAircraftPath && rstfile.isRelative()) { init_file_name = fdmex->GetFullAircraftPath()/rstfile.utf8Str(); } else { init_file_name = rstfile; @@ -1022,7 +1022,7 @@ bool FGInitialCondition::Load(const SGPath& rstfile, bool useStoredPath) throw BaseException(s.str()); } - if (document->GetName() != string("initialize")) { + if (document->GetName() != "initialize") { stringstream s; s << "File: " << init_file_name << " is not a reset file."; cerr << s.str() << endl; diff --git a/src/initialization/FGInitialCondition.h b/src/initialization/FGInitialCondition.h index cc65f4236..36065f7a7 100644 --- a/src/initialization/FGInitialCondition.h +++ b/src/initialization/FGInitialCondition.h @@ -667,9 +667,9 @@ class JSBSIM_API FGInitialCondition : public FGJSBBase /** Loads the initial conditions. @param rstname The name of an initial conditions file - @param useStoredPath true if the stored path to the IC file should be used + @param useAircraftPath true if path is given relative to the aircraft path. @return true if successful */ - bool Load(const SGPath& rstname, bool useStoredPath = true ); + bool Load(const SGPath& rstname, bool useAircraftPath = true ); /** Is an engine running ? @param index of the engine to be checked diff --git a/src/input_output/FGPropertyManager.cpp b/src/input_output/FGPropertyManager.cpp index 32cf5d20e..927a33c33 100644 --- a/src/input_output/FGPropertyManager.cpp +++ b/src/input_output/FGPropertyManager.cpp @@ -61,7 +61,7 @@ void FGPropertyManager::Unbind(void) //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -void FGPropertyManager::Unbind(void* instance) +void FGPropertyManager::Unbind(const void* instance) { auto it = tied_properties.begin(); diff --git a/src/input_output/FGPropertyManager.h b/src/input_output/FGPropertyManager.h index 6aebd236b..07271f8cd 100644 --- a/src/input_output/FGPropertyManager.h +++ b/src/input_output/FGPropertyManager.h @@ -43,6 +43,7 @@ INCLUDES #include #include +#include #include "simgear/props/props.hxx" #if !PROPS_STANDALONE # include "simgear/math/SGMath.hxx" @@ -437,8 +438,21 @@ class JSBSIM_API FGPropertyManager * * Classes should use this function to release control of any * properties they have bound using this property manager. + * @param instance The instance which properties shall be unbound. */ - void Unbind(void* instance); + void Unbind(const void* instance); + + /** + * Unbind all properties bound by this manager to an instance. + * + * Classes should use this function to release control of any + * properties they have bound using this property manager. + * Helper function for shared_ptr + * @see Unbind(const void*) + */ + template void Unbind(const std::shared_ptr& instance) { + Unbind(instance.get()); + } /** * Tie a property to an external variable. @@ -615,10 +629,10 @@ class JSBSIM_API FGPropertyManager private: struct PropertyState { SGPropertyNode_ptr node; - void* BindingInstance = nullptr; + const void* BindingInstance = nullptr; bool WriteAttribute = true; bool ReadAttribute = true; - PropertyState(SGPropertyNode* property, void* instance) + PropertyState(SGPropertyNode* property, const void* instance) : node(property), BindingInstance(instance) { WriteAttribute = node->getAttribute(SGPropertyNode::WRITE); ReadAttribute = node->getAttribute(SGPropertyNode::READ); diff --git a/src/math/FGParameterValue.h b/src/math/FGParameterValue.h index ffdf3f5ab..2b38abcca 100644 --- a/src/math/FGParameterValue.h +++ b/src/math/FGParameterValue.h @@ -34,8 +34,6 @@ INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ -#include - #include "math/FGRealValue.h" #include "math/FGPropertyValue.h" #include "input_output/FGXMLElement.h" diff --git a/src/models/FGInertial.cpp b/src/models/FGInertial.cpp index dd3c43ffd..b8c3c5941 100644 --- a/src/models/FGInertial.cpp +++ b/src/models/FGInertial.cpp @@ -292,7 +292,7 @@ void FGInertial::Debug(int from) cout << " Semi minor axis: " << b << endl; cout << " Rotation rate : " << scientific << vOmegaPlanet(eZ) << endl; cout << " GM : " << GM << endl; - cout << " J2 : " << J2 << endl << defaultfloat; + cout << " J2 : " << J2 << endl << defaultfloat << endl; } } if (debug_lvl & 2 ) { // Instantiation/Destruction notification diff --git a/src/models/FGInertial.h b/src/models/FGInertial.h index 2c748fc4e..08f0e23c0 100644 --- a/src/models/FGInertial.h +++ b/src/models/FGInertial.h @@ -133,7 +133,7 @@ class JSBSIM_API FGInertial : public FGModel { } /** Set the simulation time. - The elapsed time can be used by the ground callbck to assess the planet + The elapsed time can be used by the ground callback to assess the planet rotation or the movement of objects. @param time elapsed time in seconds since the simulation started. */ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9a5ac9843..176527de0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -54,5 +54,5 @@ set(PYTHON_TESTS ResetOutputFiles foreach(test ${PYTHON_TESTS}) add_test(NAME ${test} - COMMAND ${Python3_EXECUTABLE} -B ${CMAKE_CURRENT_SOURCE_DIR}/${test}.py) + COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/${test}.py) endforeach() diff --git a/tests/JSBSim_utils.py b/tests/JSBSim_utils.py index a663b3c5b..f1379d01d 100644 --- a/tests/JSBSim_utils.py +++ b/tests/JSBSim_utils.py @@ -266,9 +266,8 @@ def FindDifferences(ref, other, tol): delta = np.abs(ref - other) idxmax = delta.idxmax() - ref_max = pd.Series(ref.lookup(idxmax, ref.columns), index=ref.columns) - other_max = pd.Series(other.lookup(idxmax, other.columns), - index=other.columns) + ref_max = pd.Series(np.diag(ref.loc[idxmax]), index=ref.columns) + other_max = pd.Series(np.diag(other.loc[idxmax]), index=other.columns) diff = pd.concat([idxmax, delta.max(), ref_max, other_max], axis=1) diff.columns = ['Time', 'delta', 'ref value', 'value'] return diff[diff['delta'] > tol] diff --git a/tests/TestInputSocket.py b/tests/TestInputSocket.py index 04ce4faef..c4762ac07 100644 --- a/tests/TestInputSocket.py +++ b/tests/TestInputSocket.py @@ -45,7 +45,7 @@ def sendCommand(self, command): return self.getOutput() def getOutput(self): - time.sleep(0.5) # Wait for the socket to process all the data. + time.sleep(1.0) # Wait for the socket to process all the data. return self.tn.read_very_eager().decode() def getPropertyValue(self, property): diff --git a/tests/unit_tests/FGAtmosphereTest.h b/tests/unit_tests/FGAtmosphereTest.h index e2a75d282..25ada7598 100644 --- a/tests/unit_tests/FGAtmosphereTest.h +++ b/tests/unit_tests/FGAtmosphereTest.h @@ -34,7 +34,6 @@ class DummyAtmosphere : public FGAtmosphere } // Getters for the protected members static constexpr double GetR(void) { return Reng0; } - static constexpr double GetGamma(void) { return SHRatio; } static constexpr double GetBeta(void) { return Beta; } static constexpr double GetSutherlandConstant(void) { return SutherlandConstant; } static constexpr double GetPSFtoPa(void) { return psftopa; } @@ -44,7 +43,7 @@ class DummyAtmosphere : public FGAtmosphere }; constexpr double R = DummyAtmosphere::GetR(); -constexpr double gama = DummyAtmosphere::GetGamma(); +constexpr double gama = FGAtmosphere::SHRatio; constexpr double beta = DummyAtmosphere::GetBeta(); constexpr double k = DummyAtmosphere::GetSutherlandConstant(); constexpr double psftopa = DummyAtmosphere::GetPSFtoPa(); @@ -58,7 +57,7 @@ class FGAtmosphereTest : public CxxTest::TestSuite FGAtmosphereTest() { auto atm = fdmex.GetAtmosphere(); - fdmex.GetPropertyManager()->Unbind(atm.get()); + fdmex.GetPropertyManager()->Unbind(atm); } void testDefaultValuesBeforeInit() diff --git a/tests/unit_tests/FGAuxiliaryTest.h b/tests/unit_tests/FGAuxiliaryTest.h index 1d4547ba7..df5840932 100644 --- a/tests/unit_tests/FGAuxiliaryTest.h +++ b/tests/unit_tests/FGAuxiliaryTest.h @@ -20,16 +20,24 @@ class DummyAtmosphere : public FGAtmosphere constexpr double R = DummyAtmosphere::GetR(); -class FGAtmosphereTest : public CxxTest::TestSuite +class FGAuxiliaryTest : public CxxTest::TestSuite { public: static constexpr double gama = FGAtmosphere::SHRatio; + FGFDMExec fdmex; + std::shared_ptr atm; + + FGAuxiliaryTest() { + auto aux = fdmex.GetAuxiliary(); + atm = fdmex.GetAtmosphere(); + atm->InitModel(); + fdmex.GetPropertyManager()->Unbind(aux); + } + void testPitotTotalPressure() { - FGFDMExec fdmex; - auto atm = fdmex.GetAtmosphere(); auto aux = FGAuxiliary(&fdmex); - atm->InitModel(); + aux.in.vLocation = fdmex.GetAuxiliary()->in.vLocation; // Ambient conditions far upstream (i.e. upstream the normal schock // in supersonic flight) @@ -64,13 +72,13 @@ class FGAtmosphereTest : public CxxTest::TestSuite // energy conservation TS_ASSERT_DELTA(Cp*t1+0.5*u1*u1, Cp*t2+0.5*u2*u2, epsilon); } + + fdmex.GetPropertyManager()->Unbind(&aux); } void testMachFromImpactPressure() { - FGFDMExec fdmex; - auto atm = fdmex.GetAtmosphere(); auto aux = FGAuxiliary(&fdmex); - atm->InitModel(); + aux.in.vLocation = fdmex.GetAuxiliary()->in.vLocation; // Ambient conditions far upstream (i.e. upstream the normal schock // in supersonic flight) @@ -112,14 +120,14 @@ class FGAtmosphereTest : public CxxTest::TestSuite TS_ASSERT_DELTA(mach1, M1, 1e-7); TS_ASSERT_DELTA(mach2, M2, 1e-7); } + + fdmex.GetPropertyManager()->Unbind(&aux); } void testCASConversion() { - FGFDMExec fdmex; - auto atm = fdmex.GetAtmosphere(); auto aux = FGAuxiliary(&fdmex); - atm->InitModel(); aux.in.StdDaySLsoundspeed = atm->StdDaySLsoundspeed; + aux.in.vLocation = fdmex.GetAuxiliary()->in.vLocation; // Ambient conditions far upstream (i.e. upstream the normal schock // in supersonic flight) @@ -176,5 +184,7 @@ class FGAtmosphereTest : public CxxTest::TestSuite TS_ASSERT_DELTA(aux.VcalibratedFromMach(M1, p1)/(mach*asl), 1.0, 1e-8); } + + fdmex.GetPropertyManager()->Unbind(&aux); } }; diff --git a/tests/unit_tests/FGMSISTest.h b/tests/unit_tests/FGMSISTest.h index 658113a3b..a47036a77 100644 --- a/tests/unit_tests/FGMSISTest.h +++ b/tests/unit_tests/FGMSISTest.h @@ -58,7 +58,7 @@ class FGMSISTest : public CxxTest::TestSuite, FGJSBBase FGMSISTest() { std_atm = fdmex.GetAtmosphere(); - fdmex.GetPropertyManager()->Unbind(std_atm.get()); + fdmex.GetPropertyManager()->Unbind(std_atm); const double species_mmol[8] {28.0134, 31.9988, 31.9988/2.0, 4.0, 1.0, 39.948, 28.0134/2.0, 31.9988/2.0};