The simulation of cyber-physical systems plays an increasingly important role in the development process of such systems. It enables the engineers to get a better understanding of the system in the early phases of the development. These complex systems are composed of different subsystems, each subsystem model is designed with its own specialized tool sets. Because of this heterogeneity the coordination and integration of these subsystem models becomes a challenge.
The Functional Mockup Interface
(FMI) specification was developed by an industry consortium as a tool independent interface standard for integration and simulation of dynamic systems models. The models that conform to this standard are called Functional Mockup Units (FMU).
In this work we provide a method for automated FMU generation from UML models, making it possible to use model driven engineering techniques in the design and simulation of complex cyber-physical systems.
Functional Mockup Interface
The Functional Mockup Interface (FMI) specification is a standardized interface to be used in computer simulations for the creation of complex cyber-physical systems. The idea behind it being that if a real product is composed of many interconnected parts, it should be possible to create a virtual product which is itself assembled by combining a set of models. For example a car can be seen as a combination of many different subsystems, like engine, gearbox or thermal system. These subsystems can be modeled as Functional Mockup Units (FMU) which conform to the FMI standard.
The Functional Mockup Unit
(FMU) represents a (runnable) model of a (sub)system and can be seen as the implementation of an Functional Mockup Interface (FMI). It is distributed as one ZIP file archive, with a ".fmu" file extension, containing:
- FMI model description file in XML format. It contains static information about the FMU instance. Most importantly the FMU variables and their attributes such as name, unit, default initial value etc. are stored in this file. A simulation tool importing the FMU will parse the model description file and initialize its environment accordingly.
- FMI application programming interface provided as a set of standardized C functions. C is used because of its portability and because it can be utilized in all embedded control systems. The C API can be provided either in source code and/or in binary form for one or several target machines, for example Windows dynamic link libraries (".dll") or Linux shared libraries (".so").
- Additional FMU data (tables, maps) in FMU specific file formats
The inclusion of the FMI model description file and the FMI API is mandatory according to the FMI standard.
is a visual modeling and design tool supporting various industry standards including UML. It is extensible via plugins written in C# or Visual Basic. The UML models from which we generate our FMU are defined with Enterprise Architect.Embedded Engineer
is a plugin for Enterprise Architect that features automated C/C++ code generation from UML models.
We further used the FMU SDK
from QTronic for creating the FMI API. It also comes with a simple solver which we used to test our solution.
Our basic example to test our solution is called Inc
. It is a simple FMU with an internal counter
which is initialized at the beginning and it increments this counter by a specified step
value, each time it gets triggered, until a final to
value is reached or exceeded.
The state machine contains just an initial pseudo state which initializes the state machine and a state called Step
. The Step state has two transitions, one transition to itself, in case the counter is still lower then the to
value, if this is the case, the inc()
operation will be called and we are again in the Step
state. If the value is equal or greater to the to
value, it reaches the final state and no further process will be done.
The class diagram consists of two parts. The left part with the Inc class is project specific. It holds three attributes: counter
All attributes are of type int
. The initial value for the counter
, for the step
and for the to
value it's 50
. The FSM classes on the right are the mandatory classes for the Embedded Engineer to be able to generate the state machine code.
Some specific implementation code also exists in various places. In the state machine you can see, that we have some guards on the transitions. These guards are actually code that will be used to generate the code for the state machine:me->counter < me->to
andme->counter >= me->to
The property me
represents a pointer to an instance of the Inc class.
And finally the implementation of the inc()
operation is also provided:me->counter = me->counter + me->step;
Manual Code Generation
First we manually created our reference Inc FMU, the following steps where taken:
- UML models were defined in Enterprise Architect (class diagram and state machine diagram)
- C code was generated from the previously created models (with the Embedded Engineer plugin)
- The FMI model description xml file and the FMI API were created by hand
- The (compiled) FMI API was packaged together with the model description file into a FMU file. This was done with a batch script.
Automatic Code Generation
Now we want to automate the creation of the FMI model description file and the FMI API. For this purpose we wrote our own Enterprise Architect plugin. To be able to generate semantically correct FMI model description and FMI API artifacts, we attached additional information to the UML models. This was achived through the definition of various UML stereotypes for UML class attributes and methods. Since the FMI defines its own data types we also had to map the data types used in the UML models to the corresponding FMI data types. With these challenges addressed we were able to implement our FMU generation plugin.
Our work comprises a fundamental prototype that is only a start and could be improved in various ways. The following list describes some issues that could be tackled.
- One limitation of the current implementation is that we are not able to provide initial values for the FMU. Consequently, to test different configurations of our FMU, we always have to set the default values in the UML models and regenerate the FMU for the simulator again. Hence, future work includes creating new stereo types for initialization of FMU settings/variables and testing these bindings.
- We used the FMU SDK simulator for this project. Other (more powerful) simulators should be tested too. Furthermore, co-simulation with other FMUs needs to be tested.
- In our project we restricted ourselves to just look at discrete functions by using the event system of the FMU. To continue the journey we also have to consider continuous functions.
- More complex examples should be considered to test the capabilities of the automatically generated code. By creating more complex examples the practical limitations of modeling a FMU with a class diagram and a finite state machine need to be discovered. Questions like "What can be implemented?" and "What can not be implemented?" need to be answered.
- The automated code generation process could be reduced to a one-click functionality to directly generate the ".fmu" file without any additional compilation and packaging step necessary.
Screencast FMU with UML