Getting Started

This section concerns the getting started guide on how to install and use Overture FMU. The example used below can be downloaded here: Example Single Watertank Controller and imported via: File -> Open Projects from File System

Installing Overture FMU

To install the Overture FMU extension open Overture and follow these steps:

  1. Go to Help->Install new Software...
  2. Click Add...
  3. Enter
  4. Click Ok
  5. Check Overture FMI Integration
  6. Click Next / Finish, follow the usual stuff to accept and install.

Snapshot builds are available at https://overture.au.dk/into-cps/vdm-tool-wrapper/development/latest

Structure of VDM-RT Model

A VDM-RT model has to follow a certain structure in order to be exported as an FMU. The structure is illustrated via an example of a water tank controller. When the level (input) reaches 2 (parameter), then the valveState (output) is set to true (meaning that the valve should open). When the level reaches 1 (parameter), then the valveState is set to false (meaning that the valve should close).

The HardwareInterface can be auto-generated by importing a Model Description file via the menu Overture-FMU -> Import Model Description or it can be written manually. The HardwareInterface class that defines the FMU interface (note that the parameters (VDM-RT values) can be in another class):

The World class used to start the model. Example:

The system has one special instance variable hwi used to auto link the FMI interface to the VDM-RT model:

The LevelSensor class has a port that it operatres on:

The ValveActuator class has a port that it operates on:

Finally, the Controller class:

Importing a Model Description File

To import an Model Description file right-click on the project and:

=. Click Overture FMU -> Import Model Description. =. Select the model description file =. Check the console for errors

If the import is carried out on a clean project it creates the following files:

  • System.vdmrt
  • World.vdmrt
  • HardwareInterface.vdmrt

If these files already exists in the project, then it does the following:

  • Updates the HardwareInterface.vdmrt
  • Checks for an instance the hardware interface in the system and
  • Checks for the run operation in World.

Scalar Variable Naming

The VDM interpreter has to locate VDM values at run-time and therefore the scalar variable names used in the modelDescription.xml file must be fully qualified names of the VDM instance variables or a name mapping has to be provided.

An example with a fully qualified Scalar Variable is

<ScalarVariable
     name="System.hwi.level.value"
     valueReference="0"
     causality="input"
     variability="discrete">
     <Real start="0.0" />
 </ScalarVariable>

If a different name is desired within the :code:ScalarVariable` element, then one can provide one or more name mappings within the VendorAnnotations element:

<Tool name="Overture">
     <Overture>
         <link valueReference="0" name="System.hwi.level.value" />
         <!-- Possibly more link elements-->
     </Overture>
 </Tool>

And then the scalar variable can have a different name:

<ScalarVariable
     name="level"
     valueReference="0"
     causality="input"
     variability="discrete">
     <Real start="0.0" />
 </ScalarVariable>

Each link is mapped to a ScalarVariable via the valueReference attribute.

The VDM interpreter reads the Overture vendor annotation first and then ignores the scalar variable name attribute if the scalar variable is present in the vendor annotation.

Exporting a Tool-Wrapper FMU

To export a Tool-Wrapper FMU right-click on the project and click Overture FMU -> Export Tool Wrapper FMU.

This exports a .fmu file in the generated folder of the project on completion and list the export progress in the console, i.e. in context of the example above:

Followed by a printout of the modelDescription.xml file it generates.

Exporting a C-Code FMU

To export a C-Code FMU right-click on the project and click Overture FMU -> Export Source Code FMU.

Note that one has to compile the sources afterwards and place the resulting .so/.dylib/.dll file in the FMU at the location: binaries/<architecture>/fmuname.<library> where architecture typically is: win32/win64/darwin64/linux32/linux64 with library respectively being: .dll/.dll/.dylib/.sh/sh. A CMakeLists.txt file is provided to assist with the compilation.

Annotations

Annotations are the lines beginning with @.

Parameter Annotations

A parameter annotation can only be used with VDM values as shown here:

values
    -- @ interface: type = parameter, name="minlevel";
    public minlevel : RealPort = new RealPort(1.0);
    -- @ interface: type = parameter, name="maxlevel";
    public maxlevel : RealPort = new RealPort(2.0);

The annotation can be used on any value in any class.

Input and Output Annotations

An input or output annotation can only be used on instance variables in the HardwareInterface class as shown here:

class HardwareInterface

instance variables
    -- @ interface: type = input, name="level";
    public level : RealPort := new RealPort(0.0);

instance variables
    -- @ interface: type = output, name="valveState";
    public valveState : BoolPort := new BoolPort(false);

end HardwareInterface

FMI 2.0 Library for VDM

The FMI interface is modelled as a collection of VDM classes all deriving from the Port class:

/******************************************************************************************************************************
* FMI 2.0 interface for VDM
*
* The Port class is the base class for all ports. The following ports exists:
* - IntPort
* - BoolPort
* - RealPort
* - StringPort
* These concreate ports must be used in the HardwareInterface class. All of them must contain a private 'value' field
*  this field is accessed directly by the build-in FMI support in the simulator. The ports can be given as arguments to
*  other model elements. All access to the internal value must be done through set/getValue since this call insured that the
*  simulator knows that the value have been read or written to and requires a co-simulation step for synchronization.
*
* A port can be instantiated with a value or with no values to use the library default value.
*
******************************************************************************************************************************/

class Port

types
    public String = seq of char;
    public FmiPortType = bool | real | int | String;

operations

    public setValue : FmiPortType ==> ()
    setValue(v) == is subclass responsibility;

    public getValue : () ==> FmiPortType
    getValue() == is subclass responsibility;

    public static create: FmiPortType ==> IntPort | BoolPort | RealPort | StringPort
    create(v) ==
        if is_(v, String) then
            return new StringPort(v)
        elseif is_(v,bool) then
            return new BoolPort(v)
    elseif is_(v,int) then
            return new IntPort(v)
    else
            return new RealPort(v)

end Port

class IntPort is subclass of Port

instance variables
    value: int:=0;

operations
    public IntPort: int ==> IntPort
    IntPort(v)==setValue(v);

    public setValue : int ==> ()
    setValue(v) ==value :=v;

    public getValue : () ==> int
    getValue() == return value;

end IntPort

class BoolPort is subclass of Port

instance variables
    value: bool:=false;

operations
    public BoolPort: bool ==> BoolPort
    BoolPort(v)==setValue(v);

    public setValue : bool ==> ()
    setValue(v) ==value :=v;

    public getValue : () ==> bool
    getValue() == return value;

end BoolPort

class RealPort is subclass of Port

instance variables
    value: real:=0.0;

operations
    public RealPort: real ==> RealPort
    RealPort(v)==setValue(v);

    public setValue : real ==> ()
    setValue(v) ==value :=v;

    public getValue : () ==> real
    getValue() == return value;

end RealPort

class StringPort is subclass of Port

instance variables
    value: String:="";

operations
    public StringPort: String ==> StringPort
    StringPort(v)==setValue(v);

    public setValue : String ==> ()
    setValue(v) ==value :=v;

    public getValue : () ==> String
    getValue() == return value;

end StringPort