From 2722cb26db3dc1e62579ecf30c7b0303d8cfabf7 Mon Sep 17 00:00:00 2001 From: Lars Ivar Hatledal Date: Fri, 8 Nov 2024 14:36:54 +0100 Subject: [PATCH] add pendulum example and some other changes --- CMakeLists.txt | 6 +- cmake/generate_fmu.cmake | 5 + export/CMakeLists.txt | 2 +- export/examples/BouncingBall/CMakeLists.txt | 5 +- export/examples/CMakeLists.txt | 3 +- export/examples/SimplePendulum/CMakeLists.txt | 6 ++ .../SimplePendulum/simple_pendulum.cpp | 78 ++++++++++++++++ src/CMakeLists.txt | 10 +- src/model.cpp | 92 +++++++++---------- 9 files changed, 144 insertions(+), 63 deletions(-) create mode 100644 export/examples/SimplePendulum/CMakeLists.txt create mode 100644 export/examples/SimplePendulum/simple_pendulum.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 35d7c79..c5eca90 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,10 +4,12 @@ project(fmu4cpp-template VERSION ${projectVersion}) option(FMU4CPP_BUILD_TESTS "Build tests" OFF) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) -set(modelIdentifier identity) +set(modelIdentifier identity) # <-- CHANGE ME + +include("cmake/generate_fmu.cmake") if (MSVC) # link statically against the the Visual C runtime diff --git a/cmake/generate_fmu.cmake b/cmake/generate_fmu.cmake index 02e1633..b45d228 100644 --- a/cmake/generate_fmu.cmake +++ b/cmake/generate_fmu.cmake @@ -1,6 +1,11 @@ function(generateFMU modelIdentifier) + target_sources(${modelIdentifier} PRIVATE "$") + target_include_directories("${modelIdentifier}" PRIVATE "${PROJECT_SOURCE_DIR}/export/include") + target_compile_definitions("${modelIdentifier}" PRIVATE FMU4CPP_MODEL_IDENTIFIER="${modelIdentifier}") + + set(outputDir "$<1:${CMAKE_BINARY_DIR}/${modelIdentifier}/binaries/${TARGET_PLATFORM}>") if (WIN32) diff --git a/export/CMakeLists.txt b/export/CMakeLists.txt index 6f61c8b..645d5ca 100644 --- a/export/CMakeLists.txt +++ b/export/CMakeLists.txt @@ -1,7 +1,7 @@ add_subdirectory(src) add_subdirectory(examples) -add_executable(descriptionGenerator descriptionGenerator.cpp) +add_executable(descriptionGenerator "descriptionGenerator.cpp") if (UNIX) target_link_libraries(descriptionGenerator PRIVATE dl) endif() diff --git a/export/examples/BouncingBall/CMakeLists.txt b/export/examples/BouncingBall/CMakeLists.txt index 26f09e6..e252b7d 100644 --- a/export/examples/BouncingBall/CMakeLists.txt +++ b/export/examples/BouncingBall/CMakeLists.txt @@ -1,9 +1,6 @@ add_library(bouncing_ball SHARED - bouncing_ball.cpp - "$" + "bouncing_ball.cpp" ) -target_include_directories(bouncing_ball PRIVATE "../../include") -target_compile_definitions(bouncing_ball PRIVATE FMU4CPP_MODEL_IDENTIFIER="bouncing_ball") generateFMU("bouncing_ball") diff --git a/export/examples/CMakeLists.txt b/export/examples/CMakeLists.txt index 510d944..d0eb5fa 100644 --- a/export/examples/CMakeLists.txt +++ b/export/examples/CMakeLists.txt @@ -1,4 +1,3 @@ -include("${PROJECT_SOURCE_DIR}/cmake/generate_fmu.cmake") - add_subdirectory(BouncingBall) +add_subdirectory(SimplePendulum) diff --git a/export/examples/SimplePendulum/CMakeLists.txt b/export/examples/SimplePendulum/CMakeLists.txt new file mode 100644 index 0000000..d357a95 --- /dev/null +++ b/export/examples/SimplePendulum/CMakeLists.txt @@ -0,0 +1,6 @@ + +add_library(simple_pendulum SHARED + "simple_pendulum.cpp" +) + +generateFMU(simple_pendulum) diff --git a/export/examples/SimplePendulum/simple_pendulum.cpp b/export/examples/SimplePendulum/simple_pendulum.cpp new file mode 100644 index 0000000..420cfcb --- /dev/null +++ b/export/examples/SimplePendulum/simple_pendulum.cpp @@ -0,0 +1,78 @@ + +#include + +#include + +using namespace fmu4cpp; + + +class SimplePendulum : public fmu_base { +public: + SimplePendulum(const std::string &instanceName, const std::string &resources) + : fmu_base(instanceName, resources) { + + register_variable(real("angle", + [this] { return angle_; }) + .setCausality(causality_t::OUTPUT) + .setVariability(variability_t::CONTINUOUS)); + + register_variable(real("angularVelocity", + [this] { return angularVelocity_; }) + .setCausality(causality_t::LOCAL) + .setVariability(variability_t::CONTINUOUS)); + register_variable(real( + "gravity", + [this] { return gravity_; }, + [this](double input) { gravity_ = input; }) + .setCausality(causality_t::PARAMETER) + .setVariability(variability_t::FIXED)); + register_variable(real( + "length", + [this] { return length_; }, + [this](double input) { length_ = input; }) + .setCausality(causality_t::PARAMETER) + .setVariability(variability_t::FIXED)); + register_variable(real( + "damping", + [this] { return damping_; }, + [this](double input) { damping_ = input; }) + .setCausality(causality_t::PARAMETER) + .setVariability(variability_t::FIXED)); + + SimplePendulum::reset(); + } + + bool do_step(double currentTime, double dt) override { + angularVelocity_ += (-gravity_ / length_) * sin(angle_) * dt - damping_ * angularVelocity_ * dt; + angle_ += angularVelocity_ * dt; + return true; + } + + void reset() override { + angle_ = std::numbers::pi / 4;// 45 degrees + angularVelocity_ = 0; + gravity_ = -9.81; + length_ = 1.0; + damping_ = 0.1; + } + +private: + double angle_; // Current angle of the pendulum + double angularVelocity_;// Current angular velocity + double gravity_; // Acceleration due to gravity + double length_; // Length of the pendulum + double damping_; // Damping factor +}; + + +model_info fmu4cpp::get_model_info() { + model_info info; + info.modelName = "SimplePendulum"; + info.description = "A simple pendulum model"; + info.modelIdentifier = FMU4CPP_MODEL_IDENTIFIER; + return info; +} + +std::unique_ptr fmu4cpp::createInstance(const std::string &instanceName, const std::string &fmuResourceLocation) { + return std::make_unique(instanceName, fmuResourceLocation); +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1343d6b..e783b88 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,15 +1,11 @@ -include("${PROJECT_SOURCE_DIR}/cmake/generate_fmu.cmake") + add_library(${modelIdentifier} SHARED - model.cpp - "$") -target_include_directories(${modelIdentifier} PRIVATE ${PROJECT_SOURCE_DIR}/export/include) -target_compile_definitions(${modelIdentifier} PRIVATE FMU4CPP_MODEL_IDENTIFIER="${modelIdentifier}") + "model.cpp" +) # Generate FMU generateFMU("${modelIdentifier}") set(OUTPUT_FILE "${CMAKE_BINARY_DIR}/model.txt") file(WRITE ${OUTPUT_FILE} "${modelIdentifier}") - -#generateFMU("model" "${modelIdentifier}") diff --git a/src/model.cpp b/src/model.cpp index 8fa8d77..9e90460 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -14,59 +14,56 @@ class Model : public fmu_base { Model(const std::string &instanceName, const std::string &resources) : fmu_base(instanceName, resources) { - register_variable( - integer( - "integerIn", [this] { return integer_; }, [this](int value) { integer_ = value; }) - .setCausality(causality_t::INPUT) - .setVariability(variability_t::DISCRETE) - .setInitial(initial_t::EXACT)); + register_variable(integer( + "integerIn", [this] { return integer_; }, + [this](int value) { integer_ = value; }) + .setCausality(causality_t::INPUT) + .setVariability(variability_t::DISCRETE) + .setInitial(initial_t::EXACT)); register_variable( real( "realIn", [this] { return real_; }, [this](double value) { real_ = value; }) .setCausality(causality_t::INPUT) .setVariability(variability_t::DISCRETE) .setInitial(initial_t::EXACT)); - register_variable( - boolean( - "booleanIn", [this] { return boolean_; }, [this](bool value) { boolean_ = value; }) - .setCausality(causality_t::INPUT) - .setVariability(variability_t::DISCRETE) - .setInitial(initial_t::EXACT)); - register_variable( - string( - "stringIn", [this] { return string_; }, [this](std::string value) { string_ = std::move(value); }) - .setCausality(causality_t::INPUT) - .setVariability(variability_t::DISCRETE) - .setInitial(initial_t::EXACT)); - register_variable( - integer( - "integerOut", [this] { return integer_; }) - .setCausality(causality_t::OUTPUT) - .setVariability(variability_t::DISCRETE) - .setInitial(initial_t::CALCULATED) - .setDependencies({get_int_variable("integerIn")->index()})); - register_variable( - real( - "realOut", [this] { return real_; }) - .setCausality(causality_t::OUTPUT) - .setVariability(variability_t::DISCRETE) - .setInitial(initial_t::CALCULATED) - .setDependencies({get_real_variable("realIn")->index()})); - register_variable( - boolean( - "booleanOut", [this] { return boolean_; }) - .setCausality(causality_t::OUTPUT) - .setVariability(variability_t::DISCRETE) - .setInitial(initial_t::CALCULATED) - .setDependencies({get_bool_variable("booleanIn")->index()})); - register_variable( - string( - "stringOut", [this] { return string_; }) - .setCausality(causality_t::OUTPUT) - .setVariability(variability_t::DISCRETE) - .setInitial(initial_t::CALCULATED) - .setDependencies({get_string_variable("stringIn")->index()})); + register_variable(boolean( + "booleanIn", [this] { return boolean_; }, + [this](bool value) { boolean_ = value; }) + .setCausality(causality_t::INPUT) + .setVariability(variability_t::DISCRETE) + .setInitial(initial_t::EXACT)); + + register_variable(string( + "stringIn", [this] { return string_; }, + [this](std::string value) { string_ = std::move(value); }) + .setCausality(causality_t::INPUT) + .setVariability(variability_t::DISCRETE) + .setInitial(initial_t::EXACT)); + + register_variable(integer("integerOut", [this] { return integer_; }) + .setCausality(causality_t::OUTPUT) + .setVariability(variability_t::DISCRETE) + .setInitial(initial_t::CALCULATED) + .setDependencies({get_int_variable("integerIn")->index()})); + + register_variable(real("realOut", [this] { return real_; }) + .setCausality(causality_t::OUTPUT) + .setVariability(variability_t::DISCRETE) + .setInitial(initial_t::CALCULATED) + .setDependencies({get_real_variable("realIn")->index()})); + + register_variable(boolean("booleanOut", [this] { return boolean_; }) + .setCausality(causality_t::OUTPUT) + .setVariability(variability_t::DISCRETE) + .setInitial(initial_t::CALCULATED) + .setDependencies({get_bool_variable("booleanIn")->index()})); + + register_variable(string("stringOut", [this] { return string_; }) + .setCausality(causality_t::OUTPUT) + .setVariability(variability_t::DISCRETE) + .setInitial(initial_t::CALCULATED) + .setDependencies({get_string_variable("stringIn")->index()})); Model::reset(); } @@ -98,6 +95,7 @@ model_info fmu4cpp::get_model_info() { return info; } -std::unique_ptr fmu4cpp::createInstance(const std::string &instanceName, const std::string &fmuResourceLocation) { +std::unique_ptr fmu4cpp::createInstance(const std::string &instanceName, + const std::string &fmuResourceLocation) { return std::make_unique(instanceName, fmuResourceLocation); }