From 206472c1f552facfa48bd35724d3f132af3566f2 Mon Sep 17 00:00:00 2001 From: Christophe Prud'homme Date: Tue, 4 Jan 2022 10:10:22 +0100 Subject: [PATCH 1/8] enable fmi4cpp as subproject --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1b2dc01..9196088 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ -set(publicHeaderDir ${CMAKE_SOURCE_DIR}/include) +set(publicHeaderDir ${PROJECT_SOURCE_DIR}/include) set(publicHeaders From 7c24cb8dd91f721909b091ee560137b03f0d6c30 Mon Sep 17 00:00:00 2001 From: Christophe Prud'homme Date: Tue, 4 Jan 2022 10:38:01 +0100 Subject: [PATCH 2/8] fix compilation error with clang an alternative would be to delete the default constructor instead --- include/fmi4cpp/fmi2/xml/model_variables.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fmi4cpp/fmi2/xml/model_variables.hpp b/include/fmi4cpp/fmi2/xml/model_variables.hpp index 78ae8e1..1039e4f 100644 --- a/include/fmi4cpp/fmi2/xml/model_variables.hpp +++ b/include/fmi4cpp/fmi2/xml/model_variables.hpp @@ -15,7 +15,7 @@ class model_variables { private: - const std::vector variables_; + const std::vector variables_ = {}; public: model_variables(); From 616898e27b2acd79f5bc74232707e8b6136e0303 Mon Sep 17 00:00:00 2001 From: Christophe Prud'homme Date: Tue, 4 Jan 2022 10:38:17 +0100 Subject: [PATCH 3/8] fix compiler warning (order of initialization) --- include/fmi4cpp/fmu_instance_base.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/fmi4cpp/fmu_instance_base.hpp b/include/fmi4cpp/fmu_instance_base.hpp index 91cf6e0..e1e2969 100644 --- a/include/fmi4cpp/fmu_instance_base.hpp +++ b/include/fmi4cpp/fmu_instance_base.hpp @@ -31,8 +31,8 @@ class fmu_instance_base : public virtual fmu_instance std::shared_ptr resource, const std::shared_ptr& library, const std::shared_ptr& modelDescription) - : c_(c) - , resource_(std::move(resource)) + : resource_(std::move(resource)) + , c_(c) , library_(library) , modelDescription_(modelDescription) {} From 3c99b262e42784faca373a111d6f31caaac4b6cd Mon Sep 17 00:00:00 2001 From: Christophe Prud'homme Date: Thu, 6 Jan 2022 10:27:31 +0100 Subject: [PATCH 4/8] --warning, add override --- include/fmi4cpp/fmi2/me_fmu.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fmi4cpp/fmi2/me_fmu.hpp b/include/fmi4cpp/fmi2/me_fmu.hpp index fa8de28..5302acf 100644 --- a/include/fmi4cpp/fmi2/me_fmu.hpp +++ b/include/fmi4cpp/fmi2/me_fmu.hpp @@ -26,7 +26,7 @@ class me_fmu : public virtual me_fmu_base [[nodiscard]] std::shared_ptr get_model_description() const override; - std::unique_ptr new_instance(bool visible = false, bool loggingOn = false); + std::unique_ptr new_instance(bool visible = false, bool loggingOn = false) override; }; } // namespace fmi4cpp::fmi2 From dfd827d052856c70cac86bbd3920b741524d3aea Mon Sep 17 00:00:00 2001 From: Christophe Prud'homme Date: Thu, 6 Jan 2022 16:34:49 +0100 Subject: [PATCH 5/8] fix installation of FindLIBZIP.cmake enable fmi4cpp as subproject #122 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d7059dc..5e216a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -138,7 +138,7 @@ install(FILES "${versionFile}" DESTINATION "${FMI4CPP_CMAKE_INSTALL_DIR}") # Install custom find modules install(FILES - ${CMAKE_SOURCE_DIR}/cmake/FindLIBZIP.cmake + ${PROJECT_SOURCE_DIR}/cmake/FindLIBZIP.cmake DESTINATION ${FMI4CPP_CMAKE_INSTALL_DIR} ) From c3670c8e28cf5b9ece8fa19f0b551606f74301cc Mon Sep 17 00:00:00 2001 From: Christophe Prud'homme Date: Thu, 6 Jan 2022 18:06:19 +0100 Subject: [PATCH 6/8] up enable fmi4cpp as subproject allow customization from parent project use GNUInstalldirs to customize with the default values corresponding the to ones as before --- CMakeLists.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e216a1..c3da68b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,10 +61,11 @@ if (MSVC) #https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-3-c4996?view=vs-2017 endif () +include(GNUInstallDirs) -set(FMI4CPP_HEADER_INSTALL_DIR "include") -set(FMI4CPP_CMAKE_INSTALL_DIR "share/${PROJECT_NAME}") -set(FMI4CPP_DOC_INSTALL_DIR "share/doc/${PROJECT_NAME}") +set(FMI4CPP_HEADER_INSTALL_DIR "${CMAKE_INSTALL_INCLUDEDIR}") +set(FMI4CPP_CMAKE_INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}" ) +set(FMI4CPP_DOC_INSTALL_DIR "${CMAKE_INSTALL_DOCDIR}") set(FMI4CPP_INSTALL_DESTINATIONS ARCHIVE DESTINATION "lib" From 292ee75112348b92dbcf696f8328fe0d4b65692e Mon Sep 17 00:00:00 2001 From: Christophe Prud'homme Date: Sat, 2 Dec 2023 02:03:43 +0100 Subject: [PATCH 7/8] #1 enhance fmu constructor for moi environment /cc @vincentchabannes --- include/fmi4cpp/fmi2/fmu.hpp | 2 +- src/fmi4cpp/fmi2/fmu.cpp | 56 ++++++++++++++------------ tests/CMakeLists.txt | 3 +- tests/test_controlled_temperature.cpp | 57 +++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 28 deletions(-) diff --git a/include/fmi4cpp/fmi2/fmu.hpp b/include/fmi4cpp/fmi2/fmu.hpp index 7526486..54fe8bb 100644 --- a/include/fmi4cpp/fmi2/fmu.hpp +++ b/include/fmi4cpp/fmi2/fmu.hpp @@ -26,7 +26,7 @@ class fmu : public virtual fmu_provider std::shared_ptr modelDescription_; public: - explicit fmu(const fs::path& fmuPath); + explicit fmu(const fs::path& fmuPath, bool unzipFmu = true); [[nodiscard]] std::string get_model_description_xml() const; [[nodiscard]] std::shared_ptr get_model_description() const override; diff --git a/src/fmi4cpp/fmi2/fmu.cpp b/src/fmi4cpp/fmi2/fmu.cpp index ae4ed46..6267af8 100644 --- a/src/fmi4cpp/fmi2/fmu.cpp +++ b/src/fmi4cpp/fmi2/fmu.cpp @@ -11,34 +11,38 @@ using namespace fmi4cpp; using namespace fmi4cpp::fmi2; -fmu::fmu(const fs::path& fmuPath) +fmu::fmu(const fs::path& fmuPath, bool unzipFmu) { - - if (!exists(fmuPath)) { - const auto err = "No such file '" + absolute(fmuPath).string() + "'!"; - MLOG_FATAL(err); - throw std::runtime_error(err); - } - - const std::string fmuName = fmuPath.stem().string(); - fs::path tmpPath(fs::temp_directory_path() /= fs::path("fmi4cpp_" + fmuName + "_" + generate_simple_id(8))); - - if (!create_directories(tmpPath)) { - const auto err = "Failed to create temporary directory '" + tmpPath.string() + "' !"; - MLOG_FATAL(err); - throw std::runtime_error(err); + if (unzipFmu) { + if (!exists(fmuPath)) { + const auto err = "No such file '" + absolute(fmuPath).string() + "'!"; + MLOG_FATAL(err); + throw std::runtime_error(err); + } + + const std::string fmuName = fmuPath.stem().string(); + fs::path tmpPath(fs::temp_directory_path() /= fs::path("fmi4cpp_" + fmuName + "_" + generate_simple_id(8))); + + if (!create_directories(tmpPath)) { + const auto err = "Failed to create temporary directory '" + tmpPath.string() + "' !"; + MLOG_FATAL(err); + throw std::runtime_error(err); + } + + MLOG_DEBUG("Created temporary directory '" << tmpPath.string()); + + if (!unzip(fmuPath, tmpPath.string())) { + const auto err = "Failed to extract FMU '" + absolute(fmuPath).string() + "'!"; + MLOG_FATAL(err); + throw std::runtime_error(err); + } + + resource_ = std::make_shared(tmpPath); + modelDescription_ = std::move(parse_model_description(resource_->model_description_path())); + } else { + resource_ = std::make_shared(fmuPath); + modelDescription_ = std::move(parse_model_description(resource_->model_description_path())); } - - MLOG_DEBUG("Created temporary directory '" << tmpPath.string()); - - if (!unzip(fmuPath, tmpPath.string())) { - const auto err = "Failed to extract FMU '" + absolute(fmuPath).string() + "'!"; - MLOG_FATAL(err); - throw std::runtime_error(err); - } - - resource_ = std::make_shared(tmpPath); - modelDescription_ = std::move(parse_model_description(resource_->model_description_path())); } std::string fmu::get_model_description_xml() const diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6e8ad93..3fd03c6 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,7 +1,8 @@ add_executable(test_controlled_temperature test_controlled_temperature.cpp) -target_link_libraries(test_controlled_temperature PRIVATE fmi4cpp::fmi4cpp Catch2::Catch2) +target_link_libraries(test_controlled_temperature PRIVATE fmi4cpp::fmi4cpp Catch2::Catch2 libzip::libzip) add_test(NAME test_controlled_temperature COMMAND test_controlled_temperature) +target_include_directories(test_controlled_temperature PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../src) add_executable(test_model_description1 test_modeldescription1.cpp) target_link_libraries(test_model_description1 PRIVATE fmi4cpp::fmi4cpp Catch2::Catch2) diff --git a/tests/test_controlled_temperature.cpp b/tests/test_controlled_temperature.cpp index f8f4cdd..b015de0 100644 --- a/tests/test_controlled_temperature.cpp +++ b/tests/test_controlled_temperature.cpp @@ -1,5 +1,10 @@ #include +#include +#include +#include +#include +#include #define CATCH_CONFIG_MAIN #include @@ -37,5 +42,57 @@ TEST_CASE("ControlledTemperature_test1") CHECK(298.15 == Approx(ref)); + CHECK(slave->terminate()); +} + + +TEST_CASE("ControlledTemperature_test2") +{ + const std::string fmu_path = "../resources/fmus/2.0/cs/20sim/4.6.4.8004/" + "ControlledTemperature/ControlledTemperature.fmu"; + namespace fs = std::filesystem; + if (!fs::exists(fmu_path)) { + const auto err = "No such file '" + fs::absolute(fmu_path).string() + "'!"; + MLOG_FATAL(err); + throw std::runtime_error(err); + } + + const std::string fmuName = fs::path(fmu_path).stem().string(); + fs::path tmpPath(fs::temp_directory_path() /= fs::path("fmi4cpp_" + fmuName + "_" + generate_simple_id(8))); + + if (!fs::create_directories(tmpPath)) { + const auto err = "Failed to create temporary directory '" + tmpPath.string() + "' !"; + MLOG_FATAL(err); + throw std::runtime_error(err); + } + + MLOG_DEBUG("Created temporary directory '" << tmpPath.string()); + + if (!unzip(fmu_path, tmpPath.string())) { + const auto err = "Failed to extract FMU '" + fs::absolute(fs::path(fmu_path)).string() + "'!"; + MLOG_FATAL(err); + throw std::runtime_error(err); + } + auto fmu = fmi2::fmu(tmpPath,false).as_cs_fmu(); + + size_t numOutputs = 0; + for (const auto& v : *fmu->get_model_description()->model_variables) { + if (v.causality == fmi2::causality::output) { + numOutputs++; + } + } + CHECK(2 == numOutputs); + + auto slave = fmu->new_instance(); + CHECK(slave->setup_experiment()); + CHECK(slave->enter_initialization_mode()); + CHECK(slave->exit_initialization_mode()); + + double ref; + CHECK(slave->step(step_size)); + CHECK(slave->read_real(vr, ref)); + + CHECK(298.15 == Approx(ref)); + CHECK(slave->terminate()); } \ No newline at end of file From 82f59e027492b1337fd41dd9c0759d18db4986fc Mon Sep 17 00:00:00 2001 From: Christophe Prud'homme Date: Mon, 4 Dec 2023 13:05:17 +0100 Subject: [PATCH 8/8] check if the fmuPath is a directory and modelDescription.xml exists #1 --- src/fmi4cpp/fmi2/fmu.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/fmi4cpp/fmi2/fmu.cpp b/src/fmi4cpp/fmi2/fmu.cpp index 6267af8..49a19ee 100644 --- a/src/fmi4cpp/fmi2/fmu.cpp +++ b/src/fmi4cpp/fmi2/fmu.cpp @@ -13,6 +13,10 @@ using namespace fmi4cpp::fmi2; fmu::fmu(const fs::path& fmuPath, bool unzipFmu) { + if ( fs::is_directory(fmuPath) && fs::exists(fmuPath / "modelDescription.xml") ) { + MLOG_DEBUG("fmuPath is a directory, assuming it is an unzipped FMU"); + unzipFmu = false; + } if (unzipFmu) { if (!exists(fmuPath)) { const auto err = "No such file '" + absolute(fmuPath).string() + "'!";