Skip to content

Commit 81f32f4

Browse files
committed
feat (node-fmu): New node fmu using FMI3.0
Signed-off-by: Ritesh.K <riteshkarki6@gmail.com>
1 parent 5ab933a commit 81f32f4

File tree

8 files changed

+633
-0
lines changed

8 files changed

+633
-0
lines changed

CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ find_package(Criterion)
9191
find_package(OpalOrchestra)
9292
find_package(LibXml2)
9393
find_package(OpalAsyncApi)
94+
find_package(FMI)
9495

9596
# Check for tools
9697
find_program(PROTOBUFC_COMPILER NAMES protoc-c)
@@ -199,6 +200,7 @@ cmake_dependent_option(WITH_NODE_ETHERCAT "Build with ethercat node-type"
199200
cmake_dependent_option(WITH_NODE_EXAMPLE "Build with example node-type" "${WITH_DEFAULTS}" "" OFF)
200201
cmake_dependent_option(WITH_NODE_EXEC "Build with exec node-type" "${WITH_DEFAULTS}" "" OFF)
201202
cmake_dependent_option(WITH_NODE_FILE "Build with file node-type" "${WITH_DEFAULTS}" "" OFF)
203+
cmake_dependent_option(WITH_NODE_FMU "Build with fmu node-type" "${WITH_DEFAULTS}" "FMI_FOUND" OFF)
202204
cmake_dependent_option(WITH_NODE_FPGA "Build with fpga node-type" "${WITH_DEFAULTS}" "WITH_FPGA" OFF)
203205
cmake_dependent_option(WITH_NODE_IEC60870 "Build with iec60870 node-types" "${WITH_DEFAULTS}" "LIB60870_FOUND; NOT WITHOUT_GPL" OFF)
204206
cmake_dependent_option(WITH_NODE_IEC61850 "Build with iec61850 node-types" "${WITH_DEFAULTS}" "LIBIEC61850_FOUND; NOT WITHOUT_GPL" OFF)
@@ -309,6 +311,7 @@ add_feature_info(NODE_ETHERCAT WITH_NODE_ETHERCAT "Build with
309311
add_feature_info(NODE_EXAMPLE WITH_NODE_EXAMPLE "Build with example node-type")
310312
add_feature_info(NODE_EXEC WITH_NODE_EXEC "Build with exec node-type")
311313
add_feature_info(NODE_FILE WITH_NODE_FILE "Build with file node-type")
314+
add_feature_info(NODE_FMU WITH_NODE_FMU "Build with fmu node-type")
312315
add_feature_info(NODE_FPGA WITH_NODE_FPGA "Build with fpga node-type")
313316
add_feature_info(NODE_IEC60870 WITH_NODE_IEC60870 "Build with iec60870 node-types")
314317
add_feature_info(NODE_IEC61850 WITH_NODE_IEC61850 "Build with iec61850 node-types")

cmake/FindFMI.cmake

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
3+
find_path(FMI_INCLUDE_DIR
4+
NAMES fmilib.h
5+
)
6+
7+
find_library(FMI_LIBRARY fmilib
8+
PATHS /usr/local/lib /usr/local/lib64
9+
)
10+
11+
include(FindPackageHandleStandardArgs)
12+
find_package_handle_standard_args(FMI DEFAULT_MSG FMI_LIBRARY FMI_INCLUDE_DIR)
13+
14+
mark_as_advanced(FMI_INCLUDE_DIR FMI_LIBRARY)
15+
16+
if(FMI_FOUND)
17+
add_library(FMI SHARED IMPORTED)
18+
set_target_properties(FMI PROPERTIES
19+
IMPORTED_LOCATION "${FMI_LIBRARY}"
20+
INTERFACE_INCLUDE_DIRECTORIES "${FMI_INCLUDE_DIR}"
21+
)
22+
endif()

etc/examples/nodes/fmu.conf

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# SPDX-FileCopyrightText: 2014-2023 Institute for Automation of Complex Power Systems, RWTH Aachen University
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
nodes = {
5+
file_output = {
6+
type = "file"
7+
# format = "csv"
8+
uri = "/workspaces/node/fmu_temp/output.dat"
9+
out = {
10+
11+
}
12+
},
13+
14+
signal_node = {
15+
type = "signal.v2"
16+
rate = 100.0
17+
realtime = true
18+
19+
limit = 100
20+
21+
in = {
22+
signals = (
23+
{ name = "sine1", signal = "sine", amplitude = 1, frequency = 100 },
24+
# { name = "in2", signal = "constant", amplitude = 1 },
25+
)
26+
}
27+
},
28+
fmu_node = {
29+
type = "fmu"
30+
# Path to fmu file
31+
fmu_path = "/workspaces/node/fmu_temp/asine.fmu"
32+
fmu_unpack_path = "/workspaces/node/fmu_temp/fmu_asine"
33+
fmu_writefirst = true
34+
stopTime = 10.0
35+
startTime = 0.0
36+
stepSize = 0.2
37+
38+
in = {
39+
signals = (
40+
{name = "In1", type = "float"}
41+
)
42+
}
43+
44+
out = {
45+
signals = (
46+
{name = "Out1", type = "float"},
47+
)
48+
}
49+
}
50+
}
51+
52+
paths = (
53+
{
54+
in = "signal_node",
55+
out = "fmu_node"
56+
},
57+
{
58+
in = "fmu_node",
59+
out = "file_output"
60+
},
61+
)

include/villas/nodes/fmu.hpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/* Node type: Functional Mock-up unit.
2+
*
3+
* Author: Jitpanu Maneeratpongsuk <jitpanu.maneeratpongsuk@rwth-aachen.de>
4+
* SPDX-FileCopyrightText: 2025 Institute for Automation of Complex Power Systems, RWTH Aachen University
5+
* SPDX-License-Identifier: Apache-2.0
6+
*/
7+
#pragma once
8+
9+
#include <string>
10+
#include <vector>
11+
12+
#include <fmilib.h>
13+
14+
#include <villas/format.hpp>
15+
#include <villas/node.hpp>
16+
17+
namespace villas {
18+
namespace node {
19+
20+
// Forward declarations
21+
struct Sample;
22+
23+
class FmuNode : public Node {
24+
protected:
25+
int parse(json_t *json) override;
26+
27+
int _read(struct Sample *smps[], unsigned cnt) override;
28+
int _write(struct Sample *smps[], unsigned cnt) override;
29+
30+
bool writingTurn = true;
31+
const char *path;
32+
const char *unpack_path;
33+
34+
timespec ts;
35+
pthread_mutex_t mutex;
36+
pthread_cond_t cv;
37+
38+
fmi3_import_t *fmu;
39+
jm_callbacks callbacks;
40+
fmi_import_context_t *context;
41+
42+
public:
43+
FmuNode(const uuid_t &id = {}, const std::string &name = "");
44+
struct fmu_signal {
45+
unsigned int ref = 0;
46+
fmi3_base_type_enu_t type = fmi3_base_type_enu_t::fmi3_base_type_float64;
47+
std::string name;
48+
};
49+
50+
std::vector<fmu_signal> signalIn;
51+
std::vector<fmu_signal> signalOut;
52+
53+
int prepare() override;
54+
55+
int check() override;
56+
57+
int start() override;
58+
59+
int stop() override;
60+
61+
// ~FmuNode();
62+
63+
private:
64+
void parse_signal(json_t *json, bool in);
65+
double currentTime = 0;
66+
double stepSize = 0.1;
67+
double stopTime = 0;
68+
double startTime = 0;
69+
bool stopTimeDef = false;
70+
double nextTime = 0.0;
71+
void get_vr(const char *var_name, fmi3_value_reference_t &ref,
72+
fmi3_base_type_enu_t &type);
73+
};
74+
75+
} // namespace node
76+
} // namespace villas

lib/nodes/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,12 @@ if(WITH_NODE_WEBRTC)
202202
list(APPEND LIBRARIES LibDataChannel::LibDataChannel)
203203
endif()
204204

205+
# Enable FMU node-type support
206+
if(WITH_NODE_FMU)
207+
list(APPEND NODE_SRC fmu.cpp)
208+
list(APPEND LIBRARIES FMI)
209+
endif()
210+
205211
add_library(nodes STATIC ${NODE_SRC})
206212
target_include_directories(nodes PUBLIC ${INCLUDE_DIRS})
207213
target_link_libraries(nodes PUBLIC ${LIBRARIES})

0 commit comments

Comments
 (0)