Skip to content

Commit

Permalink
Version 0.3.0
Browse files Browse the repository at this point in the history
Add support for FMI 3.0 (previously was only 2.0)

Instance must now be started before any variable is read.
  • Loading branch information
Olivier Azeau committed Sep 21, 2024
1 parent 2934fe9 commit 2f58710
Show file tree
Hide file tree
Showing 32 changed files with 996 additions and 430 deletions.
15 changes: 11 additions & 4 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,19 @@ jobs:
with:
submodules: recursive

- name: Generate Reference-FMUs Makefile
run: cmake -S Reference-FMUs -B bin
- name: Generate Reference-FMUs Makefile (FMI 2.0)
run: cmake -S Reference-FMUs -D FMI_VERSION=2 -B bin2
working-directory: FMU
- name: Build Reference-FMUs
- name: Build Reference-FMUs (FMI 2.0)
run: make
working-directory: FMU/bin
working-directory: FMU/bin2

- name: Generate Reference-FMUs Makefile (FMI 3.0)
run: cmake -S Reference-FMUs -D FMI_VERSION=3 -B bin3
working-directory: FMU
- name: Build Reference-FMUs (FMI 3.0)
run: make
working-directory: FMU/bin3

- name: Setup .NET Core
uses: actions/setup-dotnet@v3
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
obj
bin
bin*
.vscode
.ionide
*.nupkg
Expand Down
Binary file removed BouncingBall.gif
Binary file not shown.
Binary file added BouncingBall2.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added BouncingBall3.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion FMU/Reference-FMUs
6 changes: 3 additions & 3 deletions FMU/build-reference-FMUs.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
snap install cmake
cmake -S Reference-FMUs -B bin
cd bin
make
rm -rf bin*
cmake -S Reference-FMUs -D FMI_VERSION=2 -B bin2 && pushd bin2 && make && popd
cmake -S Reference-FMUs -D FMI_VERSION=3 -B bin3 && pushd bin3 && make && popd
1 change: 1 addition & 0 deletions Femyou.sln
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "misc", "misc", "{9D2D98F1-B
.gitignore = .gitignore
README.md = README.md
logo.svg = logo.svg
FMU\build-reference-FMUs.sh = FMU\build-reference-FMUs.sh
EndProjectSection
EndProject
Global
Expand Down
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ loading and running [fmi-standard](https://fmi-standard.org/) FMUs in .NET

## Features

This is a limited implementation of the fmi-standard.
This is a limited implementation of the fmi-standards.

Available features :
* Load FMU model
* Load FMU model encoded in either FMI 2.0 or 3.0 standard
* Get model variables
* Create co-simulation instance
* Read and write variable values from instance
Expand Down Expand Up @@ -42,8 +42,10 @@ while (h > 0 || Math.Abs(v) > 0)

## Demos

The [Bouncing Ball](https://github.com/modelica/Reference-FMUs/tree/master/BouncingBall) reference FMU visualized with GIF animation.
These GIFs were created with
- the included demo program
- the [Bouncing Ball](https://github.com/modelica/Reference-FMUs/tree/master/BouncingBall) reference FMU compiled in FMI 2.0 and 3.0 standards

This GIF was created with the included demo program.

![BouncingBall](BouncingBall.gif?raw=true)
| FMI 2.0 | FMI 3.0 |
|---------|---------|
| ![](BouncingBall2.gif?raw=true) | ![](BouncingBall3.gif?raw=true) |
2 changes: 1 addition & 1 deletion demos/BouncingBallGif/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ static void Main()
new Uri(System.Reflection.Assembly.GetExecutingAssembly().Location).AbsolutePath, nameof(Femyou)
),
"FMU",
"bin",
"bin3",
"dist"
);

Expand Down
4 changes: 2 additions & 2 deletions src/Femyou.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Description>Loading and running fmi-standard FMUs in dotnet core.</Description>
<Description>Loading and running fmi-standard FMUs in .NET</Description>
<AssemblyTitle>Femyou</AssemblyTitle>
<Authors>oaz</Authors>
<AssemblyName>Femyou</AssemblyName>
Expand All @@ -12,7 +12,7 @@
<Copyright>Copyright © Olivier Azeau</Copyright>

<TargetFramework>netstandard2.1</TargetFramework>
<Version>0.2.0</Version>
<Version>0.3.0</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
43 changes: 7 additions & 36 deletions src/Internal/Callbacks.cs
Original file line number Diff line number Diff line change
@@ -1,48 +1,19 @@
using System;
using System.Runtime.InteropServices;

namespace Femyou.Internal
{
class Callbacks : IDisposable
public abstract class Callbacks : IDisposable
{
public Callbacks(Instance instance, ICallbacks cb)
{
_instance = instance;
_cb = cb;
_handle = GCHandle.Alloc(this);
_functions = new FMI2.fmi2CallbackFunctions
{
logger = LoggerCallback,
allocateMemory = Marshalling.AllocateMemory,
freeMemory = Marshalling.FreeMemory,
stepFinished = StepFinishedCallback,
componentEnvironment = GCHandle.ToIntPtr(_handle)
};
Structure = Marshalling.AllocateMemory(1, (ulong)Marshal.SizeOf(_functions));
Marshal.StructureToPtr(_functions, Structure, false);
Instance = instance;
Cb = cb;
}

private readonly Instance _instance;
private readonly ICallbacks _cb;
public readonly IntPtr Structure;
private GCHandle _handle;
// ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable
private readonly FMI2.fmi2CallbackFunctions _functions;

public void Dispose()
{
Marshalling.FreeMemory(Structure);
_handle.Free();
}
public readonly Instance Instance;
public readonly ICallbacks Cb;
public abstract IntPtr Custom { get; }

private static void LoggerCallback(IntPtr componentEnvironment, string instanceName, int status, string category, string message)
{
var self = (Callbacks) GCHandle.FromIntPtr(componentEnvironment).Target;
self._cb?.Logger(self._instance, (Status)status, category, message);
}

private static void StepFinishedCallback(IntPtr componentEnvironment, int status)
{
}
public abstract void Dispose();
}
}
49 changes: 49 additions & 0 deletions src/Internal/Callbacks2.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using System.Runtime.InteropServices;
using Femyou.Interop;

namespace Femyou.Internal
{
class Callbacks2 : Callbacks
{
public Callbacks2(Instance instance, ICallbacks cb)
: base(instance, cb)
{
_handle = GCHandle.Alloc(this);
_functions = new FMI2.fmi2CallbackFunctions
{
logger = LoggerCallback,
allocateMemory = Marshalling.AllocateMemory,
freeMemory = Marshalling.FreeMemory,
stepFinished = StepFinishedCallback,
componentEnvironment = GCHandle.ToIntPtr(_handle)
};
_structure = Marshalling.AllocateMemory(1, (ulong)Marshal.SizeOf(_functions));
Marshal.StructureToPtr(_functions, _structure, false);
}

private readonly IntPtr _structure;
private GCHandle _handle;
// ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable
private readonly FMI2.fmi2CallbackFunctions _functions;

public override IntPtr Custom => _structure;

public override void Dispose()
{
Marshalling.FreeMemory(_structure);
_handle.Free();
}

private static void LoggerCallback(IntPtr componentEnvironment, string instanceName, int status, string category, string message)
{
var self = (Callbacks) GCHandle.FromIntPtr(componentEnvironment).Target;
self.Cb?.Logger(self.Instance, (Status)status, category, message);
}

private static void StepFinishedCallback(IntPtr componentEnvironment, int status)
{
}
}

}
36 changes: 36 additions & 0 deletions src/Internal/Callbacks3.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System;
using System.Runtime.InteropServices;
using Femyou.Interop;

namespace Femyou.Internal
{
class Callbacks3 : Callbacks
{
public Callbacks3(Instance instance, ICallbacks cb)
: base(instance, cb)
{
_handle = GCHandle.Alloc(this);
Custom = GCHandle.ToIntPtr(_handle);
LogMessageDelegate = LoggerCallback;
}

private GCHandle _handle;
public readonly FMI3.fmi3CallbackLogMessage LogMessageDelegate;


private static void LoggerCallback(
IntPtr componentEnvironment, string instanceName,
int status, string category, string message)
{
var self = (Callbacks) GCHandle.FromIntPtr(componentEnvironment).Target;
self.Cb?.Logger(self.Instance, (Status)status, category, message);
}

public override IntPtr Custom { get; }

public override void Dispose()
{
_handle.Free();
}
}
}
Loading

0 comments on commit 2f58710

Please sign in to comment.