Skip to content

Commit 4494333

Browse files
authored
FMI3 support (#35)
1 parent 68408df commit 4494333

30 files changed

Lines changed: 2698 additions & 374 deletions

CMakeLists.txt

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,14 @@ option(FMU4CPP_BUILD_TESTS "Build internal tests" OFF)
1414
set(CMAKE_CXX_STANDARD 17)
1515

1616

17-
############modelIdentifier###################
17+
############modelIdentifier and export version###########
1818

1919
set(modelIdentifier identity) # <-- CHANGE ME
20+
set(fmi_version "fmi2") # fmi2 and fmi3 is supported
2021

21-
################################################
22+
########################################################
2223

2324
include("cmake/generate_fmu.cmake")
2425

25-
if ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
26-
set(BITNESS 64)
27-
else ()
28-
set(BITNESS 32)
29-
endif ()
30-
31-
if (WIN32)
32-
set(TARGET_PLATFORM win${BITNESS})
33-
elseif (APPLE)
34-
set(TARGET_PLATFORM darwin${BITNESS})
35-
else ()
36-
set(TARGET_PLATFORM linux${BITNESS})
37-
endif ()
38-
3926
add_subdirectory(export)
4027
add_subdirectory(src)

README.md

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
# FMU4cpp
22

33
FMU4cpp is a GitHub template repository that allows you to easily create cross-platform FMUs
4-
compatible with [FMI 2.0](https://fmi-standard.org/downloads/) for Co-simulation using CMake and C++.
4+
compatible with [FMI 2.0](https://fmi-standard.org/downloads/) & [FMI 3.0](https://fmi-standard.org/docs/3.0/) for Co-simulation using CMake and C++.
55

66
The framework generates the required `modelDescription.xml` and further packages
77
the necessary content into a ready-to-use FMU archive.
88

99
### How do I get started?
1010

1111
1. Change the value of the `modelIdentifier` variable in `CMakeLists.txt` to something more appropriate.
12-
2. Edit the content of [model.cpp](src/model.cpp).
13-
3. Build.
12+
2. Select between FMI 2 or FMI 3 export.
13+
3. Edit the content of [model.cpp](src/model.cpp).
14+
4. Build.
1415

1516
An FMU named `<modelIdentifier>.fmu` is now located in a folder `\<modelIdentifier>` within your build folder.
1617

@@ -25,14 +26,15 @@ using namespace fmu4cpp;
2526
class BouncingBall : public fmu_base {
2627

2728
public:
28-
BouncingBall(const std::string &instanceName, const std::string &resources)
29-
: fmu_base(instanceName, resources) {
29+
BouncingBall(const fmu_data& data)
30+
: fmu_base(data) {
3031

3132
register_variable(
3233
real(
3334
"height", &height)
3435
.setCausality(causality_t::OUTPUT)
35-
.setVariability(variability_t::CONTINUOUS));
36+
.setVariability(variability_t::CONTINUOUS))
37+
.setInitial(initial_t::EXACT));
3638

3739
register_variable(
3840
real(
@@ -56,7 +58,7 @@ public:
5658
BouncingBall::reset();
5759
}
5860

59-
bool do_step(double currentTime, double dt) override {
61+
bool do_step(double dt) override {
6062
// Update velocity with gravity
6163
velocity += gravity * dt;
6264
// Update height with current velocity
@@ -79,10 +81,10 @@ public:
7981
}
8082

8183
private:
82-
double height; // Current height of the ball
83-
double velocity; // Current velocity of the ball
84-
double gravity; // Acceleration due to gravity
85-
double bounceFactor;// Factor to reduce velocity on bounce
84+
double height{}; // Current height of the ball
85+
double velocity{}; // Current velocity of the ball
86+
double gravity{}; // Acceleration due to gravity
87+
double bounceFactor{};// Factor to reduce velocity on bounce
8688
};
8789

8890
model_info fmu4cpp::get_model_info() {

cmake/generate_fmu.cmake

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,58 @@
11

2-
function(generateFMU modelIdentifier resourceFolder)
2+
function(generateFMU modelIdentifier fmiVersion)
3+
4+
set(options)
5+
set(oneValueArgs RESOURCE_FOLDER)
6+
set(multiValueArgs)
7+
cmake_parse_arguments(FMU "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
8+
9+
if (NOT FMU_RESOURCE_FOLDER)
10+
set(FMU_RESOURCE_FOLDER "")
11+
endif()
12+
13+
target_sources(${modelIdentifier} PRIVATE "$<TARGET_OBJECTS:fmu4cpp_base>")
14+
15+
set(TARGET_PLATFORM)
16+
if (fmiVersion STREQUAL "fmi2")
17+
18+
if ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
19+
set(BITNESS 64)
20+
else ()
21+
set(BITNESS 32)
22+
endif ()
23+
24+
if (WIN32)
25+
set(TARGET_PLATFORM win${BITNESS})
26+
elseif (APPLE)
27+
set(TARGET_PLATFORM darwin${BITNESS})
28+
else ()
29+
set(TARGET_PLATFORM linux${BITNESS})
30+
endif ()
31+
32+
target_compile_definitions("${modelIdentifier}" PRIVATE FMI2)
33+
target_sources(${modelIdentifier} PRIVATE "$<TARGET_OBJECTS:fmu4cpp_fmi2>")
34+
elseif (fmiVersion STREQUAL "fmi3")
35+
36+
set(TARGET_PLATFORM "x86")
37+
if ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
38+
set(TARGET_PLATFORM "${TARGET_PLATFORM}_64")
39+
endif ()
40+
41+
if (WIN32)
42+
set(TARGET_PLATFORM ${TARGET_PLATFORM}-windows)
43+
elseif (APPLE)
44+
set(TARGET_PLATFORM ${TARGET_PLATFORM}-darwin)
45+
else ()
46+
set(TARGET_PLATFORM ${TARGET_PLATFORM}-linux)
47+
endif ()
48+
49+
target_compile_definitions("${modelIdentifier}" PRIVATE FMI3)
50+
target_sources(${modelIdentifier} PRIVATE "$<TARGET_OBJECTS:fmu4cpp_fmi3>")
51+
52+
else ()
53+
message(FATAL_ERROR "Unknown FMI version: ${fmiVersion}. Supported versions are 'fmi2' and 'fmi3'.")
54+
endif ()
355

4-
target_sources(${modelIdentifier} PRIVATE "$<TARGET_OBJECTS:fmu4cpp>")
556
target_include_directories("${modelIdentifier}" PRIVATE "${PROJECT_SOURCE_DIR}/export/include")
657
target_compile_definitions("${modelIdentifier}" PRIVATE FMU4CPP_MODEL_IDENTIFIER="${modelIdentifier}")
758

@@ -26,17 +77,17 @@ function(generateFMU modelIdentifier resourceFolder)
2677
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
2778
COMMAND descriptionGenerator ${modelIdentifier} "${outputDir}/$<TARGET_FILE_NAME:${modelIdentifier}>")
2879

29-
if (resourceFolder STREQUAL "")
80+
if (FMU_RESOURCE_FOLDER STREQUAL "")
3081
add_custom_command(TARGET ${modelIdentifier} POST_BUILD
3182
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/${modelIdentifier}"
3283
COMMAND ${CMAKE_COMMAND} -E tar "c" "${modelIdentifier}.fmu" --format=zip
3384
"${CMAKE_BINARY_DIR}/${modelIdentifier}/binaries"
3485
"${CMAKE_BINARY_DIR}/${modelIdentifier}/modelDescription.xml")
3586

3687
else ()
37-
message("[generateFMU] Using resourceFolder=${resourceFolder} for model with identifier='${modelIdentifier}'")
88+
message("[generateFMU] Using resourceFolder=${FMU_RESOURCE_FOLDER} for model with identifier='${modelIdentifier}'")
3889

39-
file(COPY "${resourceFolder}/" DESTINATION "${CMAKE_BINARY_DIR}/${modelIdentifier}/resources")
90+
file(COPY "${FMU_RESOURCE_FOLDER}/" DESTINATION "${CMAKE_BINARY_DIR}/${modelIdentifier}/resources")
4091

4192
add_custom_command(TARGET ${modelIdentifier} POST_BUILD
4293
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/${modelIdentifier}"

export/examples/BouncingBall/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ add_library(bouncing_ball SHARED
33
"bouncing_ball.cpp"
44
)
55

6-
generateFMU("bouncing_ball" "")
6+
generateFMU("bouncing_ball" "fmi3")

export/examples/BouncingBall/bouncing_ball.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11

22
#include <fmu4cpp/fmu_base.hpp>
33

4+
#include <iomanip>
5+
#include <sstream>
6+
47
using namespace fmu4cpp;
58

69

710
class BouncingBall : public fmu_base {
811

912
public:
10-
BouncingBall(const std::string &instanceName, const std::filesystem::path &resources)
11-
: fmu_base(instanceName, resources) {
13+
explicit BouncingBall(const fmu_data &data) : fmu_base(data) {
1214

1315
register_variable(
1416
real(
@@ -35,11 +37,10 @@ class BouncingBall : public fmu_base {
3537
.setCausality(causality_t::PARAMETER)
3638
.setVariability(variability_t::FIXED));
3739

38-
3940
BouncingBall::reset();
4041
}
4142

42-
bool do_step(double currentTime, double dt) override {
43+
bool do_step(double dt) override {
4344
// Update velocity with gravity
4445
velocity_ += gravity_ * dt;
4546
// Update height with current velocity
@@ -51,6 +52,13 @@ class BouncingBall : public fmu_base {
5152
velocity_ = -velocity_ * bounceFactor_;// Reverse velocity and apply bounce factor
5253
}
5354

55+
std::ostringstream oss;
56+
oss << std::fixed << std::setprecision(2)
57+
<< "Current height: " << height_
58+
<< ", Current velocity: " << velocity_;
59+
60+
log(fmiOK, oss.str());
61+
5462
return true;
5563
}
5664

@@ -62,10 +70,10 @@ class BouncingBall : public fmu_base {
6270
}
6371

6472
private:
65-
double height_; // Current height of the ball
66-
double velocity_; // Current velocity of the ball
67-
double gravity_; // Acceleration due to gravity
68-
double bounceFactor_;// Factor to reduce velocity on bounce
73+
double height_{}; // Current height of the ball
74+
double velocity_{}; // Current velocity of the ball
75+
double gravity_{}; // Acceleration due to gravity
76+
double bounceFactor_{};// Factor to reduce velocity on bounce
6977
};
7078

7179
model_info fmu4cpp::get_model_info() {

export/examples/Resource/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ add_library(resource SHARED
33
"resource.cpp"
44
)
55

6-
generateFMU("resource" "${CMAKE_CURRENT_SOURCE_DIR}/resources")
6+
generateFMU("resource" "fmi2" RESOURCE_FOLDER "${CMAKE_CURRENT_SOURCE_DIR}/resources")

export/examples/Resource/resource.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@ using namespace fmu4cpp;
1010
class Resource : public fmu_base {
1111

1212
public:
13-
Resource(const std::string &instanceName, const std::filesystem::path &resources)
14-
: fmu_base(instanceName, resources) {
13+
explicit Resource(const fmu_data &data) : fmu_base(data) {
1514

16-
std::ifstream ifs(resources / "file.txt");
15+
std::ifstream ifs(resourceLocation() / "file.txt");
1716

1817
std::getline(ifs, content_);
1918

@@ -26,9 +25,9 @@ class Resource : public fmu_base {
2625
Resource::reset();
2726
}
2827

29-
bool do_step(double currentTime, double dt) override {
28+
bool do_step(double dt) override {
3029

31-
log(fmi2OK, get_string_variable("content")->get());
30+
log(fmiOK, get_string_variable("content")->get());
3231
return true;
3332
}
3433

@@ -38,7 +37,6 @@ class Resource : public fmu_base {
3837

3938
private:
4039
std::string content_;
41-
4240
};
4341

4442
model_info fmu4cpp::get_model_info() {

export/examples/SimplePendulum/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ add_library(simple_pendulum SHARED
33
"simple_pendulum.cpp"
44
)
55

6-
generateFMU(simple_pendulum "")
6+
generateFMU(simple_pendulum "fmi2")

export/examples/SimplePendulum/simple_pendulum.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ using namespace fmu4cpp;
88
constexpr double pi = 3.14159265358979323846;
99

1010
class SimplePendulum : public fmu_base {
11+
1112
public:
12-
SimplePendulum(const std::string &instanceName, const std::filesystem::path &resources)
13-
: fmu_base(instanceName, resources) {
13+
explicit SimplePendulum(const fmu_data &data) : fmu_base(data) {
1414

1515
register_variable(real("angle", &angle_)
1616
.setCausality(causality_t::OUTPUT)
@@ -36,7 +36,7 @@ class SimplePendulum : public fmu_base {
3636
SimplePendulum::reset();
3737
}
3838

39-
bool do_step(double currentTime, double dt) override {
39+
bool do_step(double dt) override {
4040
angularVelocity_ += (-gravity_ / length_) * std::sin(angle_) * dt - damping_ * angularVelocity_ * dt;
4141
angle_ += angularVelocity_ * dt;
4242
return true;
@@ -51,11 +51,11 @@ class SimplePendulum : public fmu_base {
5151
}
5252

5353
private:
54-
double angle_; // Current angle of the pendulum
55-
double angularVelocity_;// Current angular velocity
56-
double gravity_; // Acceleration due to gravity
57-
double length_; // Length of the pendulum
58-
double damping_; // Damping factor
54+
double angle_{}; // Current angle of the pendulum
55+
double angularVelocity_{};// Current angular velocity
56+
double gravity_{}; // Acceleration due to gravity
57+
double length_{}; // Length of the pendulum
58+
double damping_{}; // Damping factor
5959
};
6060

6161

0 commit comments

Comments
 (0)