MCPcopy Index your code
hub / github.com/INTO-CPS-Association/unifmu

github.com/INTO-CPS-Association/unifmu @v0.14.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.14.0 ↗ · + Follow
781 symbols 2,053 edges 57 files 92 documented · 12%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

UniFMU - Universal Functional Mock-Up Units

The Functional Mock-Up Interface (FMI) defines an exchange format that allows models, referred to as Functional Mock-Up Unit (FMU), to be shared between tools supporting the standard. In general, an FMU must be implemented in a programming language that can produce binaries that can be called from C, such as C itself or C++. While this allows efficient execution of a simulation, it is a significant limitation when prototyping models.

UniFMU is a command line tool that facilitates the implementation of FMUs in other popular languages that would otherwise not be able to produce C-compatible binaries. It does this by providing a precompiled binary that is C-compatible, which then dispatches calls to the implementation of the model in the target language.

Specification Version FMU Interface Languages Binaries
FMI3 Co-Simulation Python, C#, Java win64, linux64, darwin64
FMI2 Co-Simulation Python, C#, Java win64, linux64, darwin64
FMI1 x x x

Examples of generated FMUs can be found in the unifmu_examples repo.

Getting the tool

The tool can be downloaded from releases tab of the repository. It is a single executable that bundles all assets used during FMU generation as part of the binary.

Getting help

Claudio Gomes is currently responsible for tool maintenance. Feel free to reach out for help.

How to use the command line interface

To display the synopsis use the --help flag.

unifmu 0.14.0

Implement Functional Mock-up units (FMUs) in various source languages.

* Source:   https://github.com/INTO-CPS-Association/unifmu
* Examples: https://github.com/INTO-CPS-Association/unifmu_examples

USAGE:
    unifmu <SUBCOMMAND>

COMMANDS:
    generate              Create a new FMU using the specified source language
    generate-distributed  Generates a pair of FMU/private folder for distributed co-simulation, where the FMU works as the proxy and the folder as the model
    help                  Print this message or the help of the given subcommand(s)

OPTIONS:
    -h, --help       Print help information
    -V, --version    Print version information

The command uses git-style subcommands. Help for the individual commands can be inquired by appending the --help after the name of the subcommand.

Help for the command generate:

Create a new FMU using the specified source language

Usage: unifmu generate [OPTIONS] <LANGUAGE> <OUTPATH> [FMU_VERSION]

Arguments:
  <LANGUAGE>     Source language of the generated FMU [possible values: python, c-sharp, java]
  <OUTPATH>      Output directory or name of the FMU archive if "--zipped" is passed
  [FMU_VERSION]  Version of the FMI specification to target [default: fmi2] [possible values: fmi2, fmi3]

Options:
  -z, --zipped  Compress the generated FMU as a zip-archive and store with '.fmu' extension
  -h, --help    Print help

The generate command can be used to create a new FMU:

unifmu generate python model

The command generates a placeholder FMU implemented in the specific language. For example the tree below shows the placeholder FMU generated when implementing an FMU in python using UniFMU:

📦model
 ┣ 📂binaries
 ┃ ┣ 📂darwin64
 ┃ ┃ ┗ 📜unifmu.dylib
 ┃ ┣ 📂linux64
 ┃ ┃ ┗ 📜unifmu.so
 ┃ ┗ 📂win64
 ┃ ┃ ┗ 📜unifmu.dll
 ┣ 📂resources
 ┃ ┣ 📂compilation_resources
 ┃ ┃ ┃ 📜launch_with_pyinstaller.toml
 ┃ ┃ ┃ 📜unifmu_pyinstaller_build_script.bat
 ┃ ┃ ┗ 📜unifmu_pyinstaller_build_script.sh
 ┃ ┣ 📂schemas
 ┃ ┃ ┃ 📜fmi2_messages_pb2.py
 ┃ ┃ ┗ 📜unifmu_handshake_pb2.py
 ┃ ┣ 📜abstract_backend.py
 ┃ ┣ 📜backend.py
 ┃ ┣ 📜launch.toml
 ┃ ┣ 📜main.py
 ┃ ┣ 📜model.py
 ┃ ┣ 📜README.md
 ┃ ┗ 📜requirements.txt
 ┗ 📜modelDescription.xml

Help for the command generate-distributed:

Generates a pair of FMU/private folder for distributed co-simulation, where the FMU works as the proxy and the folder as the model

Usage: unifmu generate-distributed [OPTIONS] <LANGUAGE> <OUTPATH> [FMU_VERSION]

Arguments:
  <LANGUAGE>     Source language of the generated FMU [possible values: python, c-sharp, java]
  <OUTPATH>      Output directory or name of the FMU archive if "--zipped" is passed
  [FMU_VERSION]  Version of the FMI specification to target [default: fmi2] [possible values: fmi2, fmi3]

Options:
  -e, --endpoint <ENDPOINT>  IP address of the host running the proxy FMU [default: 127.0.0.1]
  -z, --zipped               Compress the generated FMU as a zip-archive and store with '.fmu' extension
  -b, --black-box-fmu        Additional feature to handle when the private model is an existing black-box FMU with '.fmu' extension. In this case, the private backend always uses Python and its inner FMU requires to have the same name as the output directory or name of the FMU archive
  -h, --help                 Print help

The generate-distributed command can be used to create a new pair FMU (proxy) / folder (model) for distributed co-simulations (FMI2 only):

unifmu generate-distributed python model_distributed

The command generates a proxy FMU suffixed with _proxy and a private model folder suffixed with _private in the specific language. The proxy FMU differs from the FMU created with the generate command as it does not contain the model file and its dependencies. For example the trees below show the proxy FMU and folder generated when using the generate-distributed command with python as the language:

📦model_distributed_proxy
 ┣ 📂binaries
 ┣ 📂resources
 ┃ ┣ 📜launch.toml
 ┃ ┗ 📜README.md
 ┗ 📜modelDescription.xml

whereas its fellow private model folder contains the model file, the dependencies, and the endpoint.toml file for the connection with the proxy FMU, as follows (NOTE: This is not an FMU):

📦model_distributed_private
 ┣ 📂schemas
 ┃ ┃ 📜fmi2_messages_pb2.py
 ┃ ┗ 📜unifmu_handshake_pb2.py
 ┣ 📜abstract_backend.py
 ┣ 📜backend.py
 ┣ 📜endpoint.toml
 ┣ 📜launch.toml
 ┣ 📜main.py
 ┣ 📜model.py
 ┣ 📜README.md
 ┗ 📜requirements.txt

In order for the distributed co-simulation to work, the proxy FMU shall be executed first with a co-simulation master algorithm, and then, the private model shall be executed externally, using the IP address provided in endpoint.toml and the port opened by the proxy FMU as an argument (or after executing as a console input) for example (NOTE: The port number is logged by the proxy FMU after initializing it). To change the default IP address, either run the command generate-distributed with the option --endpoint=IP_ADDRESS or update the endpoint.toml file directly.

In case the model in the private backend is an existing FMU, use the option --black-box-fmu. This will generate a private folder that interacts with the existing FMU using FMPy and UniFMU's existing capabilities. The FMU in the private folder should have the same name of the private folder without the suffix _private. In this example, the FMU should be called model_distributed.fmu and should be located in path/to/model_distributed_private/.

The private backend can be executed using the launch.toml, which defines the command to execute the model; in the case of python, it would look like:

python path/to/model_distributed_private/backend.py PORT_NUMBER

(Note: the argument PORT_NUMBER is used to pass the port of the proxy directly to the process running the private model)

Language specific documentation and backend development

Like the file structure, the workflow for modifying FMUs varies depending on the implementation language. Depending on the language a README.md is placed in the root of the generated FMU, which serves as documentation for the particular language. The readme file, as well as other source files for each backend are in the respective folder: - Python - Csharp - Java - Matlab - This backend is not supported, but documentation is left in case you wish to implement it.

Supported Features

FMI2

Name Supported Notes
fmi2GetTypesPlatform
fmi2GetVersion
fmi2SetDebugLogging
fmi2Instantiate
fmi2FreeInstance
fmi2SetupExperiment
fmi2EnterInitializationMode
fmi2ExitInitializationMode
fmi2Terminate
fmi2Reset
fmi2GetReal
fmi2GetInteger
fmi2GetBoolean
fmi2GetString
fmi2SetReal
fmi2SetInteger
fmi2SetBoolean
fmi2SetString
fmi2GetFMUstate
fmi2SetFMUstate
fmi2FreeFMUstate
fmi2SerializedFMUstateSize
fmi2SerializeFMUstate
fmi2DeSerializeFMUstate
fmi2GetDirectionalDerivative x
fmi2EnterEventMode x
fmi2NewDiscreteStates x
fmi2EnterContinuousTimeMode x
fmi2CompletedIntegratorStep x
fmi2SetTime x
fmi2SetContinuousStates x
fmi2GetDerivatives x
fmi2GetEventIndicators x
fmi2GetContinuousStates x
fmi2GetNominalsOfContinuousStates x
fmi2SetRealInputDerivatives x
fmi2GetRealOutputDerivatives x
fmi2DoStep
fmi2CancelStep x
fmi2GetStatus x
fmi2GetRealStatus x
fmi2GetIntegerStatus x
fmi2GetBooleanStatus x
fmi2GetStringStatus x

FMI3 (in progress)

Name Supported Notes
fmi3GetVersion
fmi3SetDebugLogging
fmi3InstantiateModelExchange x
fmi3InstantiateCoSimulation
fmi3InstantiateScheduledExecution x
fmi3FreeInstance
fmi3EnterInitializationMode
fmi3ExitInitializationMode
fmi3EnterEventMode
fmi3Terminate
fmi3Reset
fmi3GetFloat32
fmi3GetFloat64
fmi3GetInt8
fmi3GetUInt8
fmi3GetInt16
fmi3GetUInt16
fmi3GetInt32
fmi3GetUInt32
fmi3GetInt64

Extension points exported contracts — how you extend this code

BasicFmu (Interface)
Behaviour shared by all FMUs. [5 implementers]
cli/tests/common/mod.rs
Dispatch (Interface)
Must be implemented by all Dispatchers. Ensures that FMI commands can be dispatched. Gives the await_handshake() functio [3 …
fmiapi/src/common/dispatcher/mod.rs
NonScalar (Interface)
(no doc) [1 implementers]
assets/java/src/fmi3/java/Model.java
INonScalar (Interface)
(no doc)
assets/csharp/fmi3/model.cs
ZippedTestableFmu (Interface)
Behaviour for zipped FMUs. [3 implementers]
cli/tests/common/mod.rs
Logger (Interface)
A `Logger` can send log events with LogCategories and LogStatuses to the importer, and to the environment if the module [2 …
fmiapi/src/common/logger/mod.rs
ISerializeable (Interface)
(no doc)
assets/csharp/fmi3/model.cs
DistributedFileStructure (Interface)
Functionality for accessing the underlying file structure of distributed FMUs [3 implementers]
cli/tests/common/mod.rs

Core symbols most depended-on inside this repo

error
called by 80
fmiapi/src/fmi3/fmi3_types.rs
status_reply
called by 57
assets/python/fmi3/abstract_backend.py
send_reply
called by 53
assets/python/fmi3/abstract_backend.py
error
called by 49
fmiapi/src/fmi2/fmi2_types.rs
escalate_status
called by 46
fmiapi/src/fmi3/fmi3_types.rs
get
called by 36
assets/java/src/fmi3/java/Model.java
sendStatusReply
called by 28
assets/java/src/fmi3/java/AbstractBackend.java
send_cmd_recv_status
called by 28
fmiapi/src/fmi3/mod.rs

Shape

Method 497
Function 173
Class 64
Enum 33
Interface 14

Languages

Rust44%
Python22%
Java18%
C#16%

Modules by API surface

assets/java/src/fmi3/java/Model.java90 symbols
fmiapi/src/fmi3/mod.rs77 symbols
assets/csharp/fmi3/model.cs77 symbols
cli/tests/common/mod.rs65 symbols
assets/python/fmi3/model.py61 symbols
fmiapi/src/fmi2/mod.rs36 symbols
assets/java/src/fmi2/java/Model.java29 symbols
unifmu_macros/src/lib.rs24 symbols
assets/python/fmi2/model.py24 symbols
assets/csharp/fmi2/model.cs24 symbols
cli/tests/python_tests/fmu_tests.py19 symbols
fmiapi/src/fmi2/fmi2_types.rs18 symbols

For agents

$ claude mcp add unifmu \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page