Skip to content

Commit

Permalink
Merge pull request #46 from INTO-CPS-Association/#44
Browse files Browse the repository at this point in the history
  • Loading branch information
clegaard authored Jan 27, 2022
2 parents 23dcdfa + 21a2c08 commit 340d77a
Show file tree
Hide file tree
Showing 7 changed files with 204 additions and 441 deletions.
93 changes: 14 additions & 79 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,31 @@
# UniFMU - Universal Functional Mock-Up Units

The [_Functional Mock-Up Interface_](https://fmi-standard.org/) _(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.

Traditionally, an FMU must be implemented in a programming language that is compatible with C's binary interface such as C itself or C++.
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.

UniFMU is a command line tool that facilitates the implementation of FMUs in languages in several languages, such as:
| Specification Version | FMU Types | Languages |
| --------------------- | ------------ | ---------- |
| FMI3 | | |
| FMI2 | cosimulation | Python, C# |
| FMI1 | | |

- Python
- C#
Examples of generated FMUs can be found in the [unifmu_examples](https://github.com/INTO-CPS-Association/unifmu_examples) repo.

This is made possible by providing a generic binary that dispatches calls to the users implementation using _remote procedure call_ _(RPC)_.
## Getting the tool

## Installing the tool

The current and revious versions of the tool can be downloaded from the releases tab of the repository.

For convenience the tool can be copied to a directory that is in the systems path such as `/usr/bin/` for most Linux distributions.
The tool can be downloaded from [releases](https://github.com/INTO-CPS-Association/unifmu/releases) tab of the repository.
It is a single executable that bundles all assets used during FMU generation as part of the binary.

## How to use the command line interface?

To display the synopsis use the `--help` flag.

```
UniFMU 0.0.4
UniFMU 0.0.6
Implement 'Functional Mock-up units' (FMUs) in various source languages.
USAGE:
Expand Down Expand Up @@ -93,74 +96,6 @@ Like the file structure, the workflow for modifying FMUs varies depending on the
Depending on the language a `README.md` is placed in the root of the generated FMU, which serves as documentation for the particular language.
For reference the `README.md` copied into Python FMUs looks like [README.md](tool/unifmu/resources/backends/python/README.md).

## Building and Testing

Build the cross compilation image from the dockerfile stored in `docker-build` folder:

```
docker build -t unifmu-build docker-build
```

**Note: This process may take a long time 10-30 minutes, but must only be done once.**

Start a container with the name `builder` from the cross-compilation image `unifmu-build`:

```bash
docker run --name builder -it -v $(pwd):/workdir unifmu-build # bash
```

```powershell
$pwd = (pwd).Path
docker run --name builder -it -v ${pwd}:/workdir unifmu-build # powershell
```

**Note: On windows you may have to enable the use of shared folders through the dockers interface, otherwise the container fails to start.**

To build the code invoke the script `docker-build/build_all.sh` in the `workdir` of the container:

``` bash
bash ./docker-build/build_all.sh
```

This generates and copies all relevant build artifacts into the `assets/auto_generated` directory:

```
📦auto_generated
┣ 📜.gitkeep
┣ 📜unifmu.dll
┣ 📜unifmu.dylib
┣ 📜unifmu.so
┣ 📜UnifmuFmi2.cs
┗ 📜unifmu_fmi2_pb2.py
```

**Note: On windows Git may be configured to replace LF line-endings with CRLF, which are not compatible with bash.**

Following this the cli is compiled for each platform, including the assets that were just compiled.
The final standalone executables can be found in the target folder, under the host tripple:

- linux: unifmu-x86_64-unknown-linux-gnu-0.0.4.zip
- windows: unifmu-x86_64-pc-windows-gnu-0.0.4.zip
- macOS: unifmu-x86_64-apple-darwin-0.0.4.zip

## Environment Variables

In addition to the systems environment variables, UniFMU defines the following variables in the process created during instantiation of a slave.
These can be accessed during execution by the model implementation or the backend.

| Variable | Description | Example |
| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- |
| UNIFMU_GUID | The global unique identifier, passed as an argument to fmi2Instantiate | 77236337-210e-4e9c-8f2c-c1a0677db21b |
| UNIFMU_INSTANCE_NAME | Name of the slave instance, passed as an argument to fmi2Instantiate | left_wheel_motor |
| UNIFMU_VISIBLE | Flag used to indicating if the instance should run in visible mode, passed as an argument to fmi2Instantiate | {true, false} |
| UNIFMU_LOGGING_ON | Flag used to indicating if the instance should run with logging, passed as an argument to fmi2Instantiate | {true, false} |
| UNIFMU_FMU_TYPE | Flag used to indicating if the instance is running in co-sim or model exchange mode, passed as an argument to fmi2Instantiate | {fmi2ModelExchange, fmi2CoSimulation} |
| UNIFMU_DISPATCHER_ENDPOINT | Endpoint bound by the zmq socket of the binary | tcp://127.0.0.1/5000 |
| UNIFMU_DISPATCHER_ENDPOINT_PORT | Port component of UNIFMU_DISPATCHER_ENDPOINT | 5000 |
| UNIFMU_REFS_TO_ATTRS | Mapping from value references to variable names encoded as a JSON dictionary\*. | {"0": "my_input", "1" : "my_output"} |

\* This variable is only defined if the modelDescription.xml is present in the parent directory of the resources folder passed to fmi2Instantiate.

## Citing the tool

When citing the tool, please cite the following paper:
Expand Down
27 changes: 14 additions & 13 deletions assets/csharp/model.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
using System.IO;
using System.Reflection;


using Newtonsoft.Json;
using System.Linq;
using Fmi2Proto;

Expand All @@ -28,18 +26,21 @@ public class Model

public Model()
{
// Populate map from value reference to attributes of the model.
string references_to_values = System.Environment.GetEnvironmentVariable("UNIFMU_REFS_TO_ATTRS");
if (references_to_values == null)
{
Console.WriteLine("the environment variable 'UNIFMU_REFS_TO_ATTRS' was not set");
Environment.Exit(-1);
}
var dict = JsonConvert.DeserializeObject<Dictionary<uint, String>>(references_to_values);
foreach (var (vref, variable) in dict)
this.reference_to_attributes = new Dictionary<uint, PropertyInfo>
{
this.reference_to_attributes.Add(vref, this.GetType().GetProperty(variable));
}
{ 0, this.GetType().GetProperty("real_a") },
{ 1, this.GetType().GetProperty("real_b") },
{ 2, this.GetType().GetProperty("real_c") },
{ 3, this.GetType().GetProperty("integer_a") },
{ 4, this.GetType().GetProperty("integer_b") },
{ 5, this.GetType().GetProperty("integer_c") },
{ 6, this.GetType().GetProperty("boolean_a") },
{ 7, this.GetType().GetProperty("boolean_b") },
{ 8, this.GetType().GetProperty("boolean_c") },
{ 9, this.GetType().GetProperty("string_a") },
{ 10, this.GetType().GetProperty("string_b") },
{ 11, this.GetType().GetProperty("string_c") },
};

}
public Fmi2Status Fmi2DoStep(double currentTime, double stepSize, bool noStepPrior)
Expand Down
Loading

0 comments on commit 340d77a

Please sign in to comment.