blockfactory
blockfactory copied to clipboard
Notes about FMI support
These are some random notes related to get blockfactory
to generate FMUs according to the FMI standard ( https://fmi-standard.org/downloads/ ). It is meant to be more a place where to store relevant information, rather than an issue that should be closed in the short term.
@diegoferigo let me know if you are ok with this, or if you prefer that I move this notes/brainstorming somewhere else.
-
FMI version:
- Most existing blockfactory-blocks (i.e. the one from the https://github.com/robotology/wb-toolbox library) use exclusively vector-sized input and output ports. Minimal support for fixed-size vector-sized input and output is provided in FMI v2 through the use of variables called
a[1]
,a[2]
, etc etc, see https://fmi-standard.org/docs/2.0.1-develop/#_variable_naming_conventions_variablenamingconvention . However, full support will be included only in FMI v3, that is currently under development in themaster
branch of https://github.com/modelica/fmi-standard . For this reason, it make sense to just aim for FMI v3 only support, even if there is almost no tool support at the moment, given the draft status of the specification. For preliminary testing, it could make sense to explore the use of thefeature/fmi3
branch of FMPy: https://github.com/CATIA-Systems/FMPy/tree/feature/fmi3/fmpy . - TL;DR: Target FMI v3
- Most existing blockfactory-blocks (i.e. the one from the https://github.com/robotology/wb-toolbox library) use exclusively vector-sized input and output ports. Minimal support for fixed-size vector-sized input and output is provided in FMI v2 through the use of variables called
-
FMI direct feed-through:
- Most existing blockfactory-blocks (i.e. the one from the https://github.com/robotology/wb-toolbox library) are either systems in which the output is a function of an exogenous state (such as the YARPRead block), or in which the output y is a algebraic function of the input u
y = f(u)
, i.e."instantaneous" systems with just a direct feed-through. There are a few issues in the FMI issue tracker related to systems with direct feed-through, that we should checkout: https://github.com/modelica/fmi-standard/issues/117, https://github.com/modelica/fmi-standard/issues/126 - TL;DR: Checkout direct feed-through (instantaneous) system FMI's issues
- Most existing blockfactory-blocks (i.e. the one from the https://github.com/robotology/wb-toolbox library) are either systems in which the output is a function of an exogenous state (such as the YARPRead block), or in which the output y is a algebraic function of the input u
-
FMI for Model Exchange
- Even if at the moment the blockfactory block interface is targeting mostly instantaneous systems, it has stub support (even if not complete) for the updating the state derivative and discrete state, so it is clear that the closes match between Model Exchange and Co-simulation is Model Exchange, so we should aim to expose blockfactory-blocks as FMUs for Model Exchange. Eventually, we can look into automatically transforming those in FMUs for Co-simulation, for example using FMI4cpp support for wrapping Model Exchange FMUs as Co-simulation FMUs : https://github.com/SFI-Mechatronics/FMI4cpp/issues/5 .
- TL;DR: Wrap blockfactory's blocks as FMI-ME
Comparison of S-Functions and FMUs:
- https://en.wikipedia.org/wiki/Functional_Mock-up_Interface#Comparison_to_Simulink_S-Functions
- Chapter 4 (in particular section 4.3) of http://lup.lub.lu.se/student-papers/record/8847501/file/8859310.pdf
- Section 2.3.2 of https://www.computoolable.nl/P7a.pdf
- Section 3.4 of http://www.ep.liu.se/ecp/132/057/ecp17132507.pdf (limited to Clock/discrete time systems, a new feature that will be part of FMI 3)
- Code-based configuration vs file based configuration
-
In Simulink S-Functions and consequently in blockfactory, several configuration info such as the number of the ports, etc etc are specified by calling specific methods (in particular
setIOPortsData
in theconfigureSizeAndPorts
method). In FMI, this information are specified in the XML file. To handle this, possible solutions are (the last one is my favorite):- Duplicate this info in handwritten XML files for FMUs (yuk)
- Change how this info is specified (invasive)
- Generate the XML files after the build by running a program that invokes the
configureSizeAndPorts
method of the block to wrap as FMU (this will be problematic when cross-compiling, but it seems that easy solution for now)
-
TL;DR: Handle how to generate XML files for FMU block
-
Generate the XML files after the build by running a program that invokes the
configureSizeAndPorts
method of the block to wrap as FMU
Interestingly, part of this solution could be eventually re-used to automatize the existing manual process of writing the .slx
file of the block library (i.e. the one described in https://robotology.github.io/blockfactory/mkdocs/create_new_library/#create-an-new-simulink-library).
As you can check by manually inspecting an .slx
file, and by reading in https://stackoverflow.com/questions/23408186/information-about-simulink-mdl-and-slx-formats, the .slx
is just a .zip
file that contains a bunch of .xml
(and some other format) files. A complete parser for reading/writing .slx
does not seem to be available or feasible, but perhaps it could make sense to have a "template" .slx
that can be be configured based on the library blocks' and ports.
Having a templated slx imho does not simplify that much the creation / maintenance of a Simulink Library, it is usually a trivial step from the GUI. I am pretty sure that Matlab (even the cli version) has some functions to automatize it without dealing with the file formats.
The main problem are the masks, the have to be developed from the GUI. I'm afraid that operating only on the slx
or mdl
would never be enough :/
OT reply moved to https://github.com/robotology/blockfactory/issues/10#issuecomment-454439725
Having a templated slx imho does not simplify that much the creation / maintenance of a Simulink Library, it is usually a trivial step from the GUI.
It is trivial, if you have MATLAB/Simulink. It would be nice to be able to setup a blockfactory library without having MATLAB/Simulink on your PC (my current situation, for example : ) ).
The main problem are the masks, the have to be developed from the GUI. I'm afraid that operating only on the
slx
ormdl
would never be enough :/
Why this should be the case? Everything that you input through the GUI should be contained in the .slx
, right? As far as I can see, in particular the Mask information is contained in the <Mask>
tag of simulink/blockdiagram.xml
, for example for the SignalMath
block in the ExampleToolbox
:
<Block BlockType="S-Function" Name="Signal Math" SID="1">
<P Name="Ports">[2, 1]</P>
<P Name="Position">[335, 69, 470, 116]</P>
<P Name="ZOrder">1</P>
<P Name="FunctionName">BlockFactory</P>
<P Name="Parameters">'SignalMath','ExampleToolbox',operation</P>
<P Name="SFunctionDeploymentMode">off</P>
<P Name="EnableBusSupport">off</P>
<P Name="SFcnIsStateOwnerBlock">off</P>
<Mask>
<Display RunInitForIconRedraw="off">disp('Signal Math')
port_label('input',1,'Input 1')
port_label('input',2,'Input 2')
port_label('output',1,'Output')</Display>
<MaskParameter Name="operation" Type="popup" Evaluate="off">
<Prompt>Operation</Prompt>
<Value>Addition</Value>
<TypeOptions>
<Option>Addition</Option>
<Option>Subtraction</Option>
<Option>Multiplication</Option>
</TypeOptions>
</MaskParameter>
</Mask>
</Block>
Indeed automatically generating this may not be trivial, but I do not think it is impossible.
We can probably move this discussion in a separate issue, btw.
We can probably move this discussion in a separate issue, btw.
:+1:
OT reply
Indeed automatically generating this may not be trivial, but I do not think it is impossible.
Just to be clear, I never intended that this is impossible ^^ It is just complicating your own life. And, btw, if you don't plan to use Simulink (since you don't have it), why do you want to create a Simulink Library? If the aim is using / testing blockfactory, for simple models you could:
- Create a plugin library containing classes that inherit from
blockfactory::core::Block
- Implement a simple
blockfactory::core::BlockInformation
for your use case - Develop a system that connects the blocks by assigning a simulation order and sharing data between their input / outputs with buffers
Without having Simulink I don't see any benefit of passing through the slx
, but probably I didn't get entirely what you're trying to do.
Simulink related discussion moved to https://github.com/robotology/blockfactory/issues/10 .
PR adding some part of the array support to the FMI standard: https://github.com/modelica/fmi-standard/pull/543 .
Interesting paper on FMI interface with a real time communication protocol (in this case RabbitMQ): https://github.com/INTO-CPS-Association/rabbitmq-fmu-documentation/blob/e6e57da07394858bc1519ef7b746df8459123ed6/rabbitmq-fmu.pdf , similar to how BlockFactory is used with YARP.