Exporting co-simulation FMUs

In this tutorial we are going to present how to use the fhFMUExport-executable to export Functional Mock-up Units (FMUs) for co-simulation from configuration files.

The Exporter

The exporter is an executable which can take different arguments as input for exporting a FMU. Running the FMU exporter with the argument --help prints the help message for the exporter:

fhFMUExport.exe --help
    Allowed options:
      --help                                produce help message
      --input-file arg                      FhSim input file
      --model-name arg (=fhsimexport)       model name in FMU
      --autocopy arg (=0)                   auto copy files and folders referenced
                                            in model attributes as paths into FMU
                                            and overwrite references in FMU fhsim
                                            model file to point to the bundled
                                            files and directories
      --add-dir-to-resources arg            paths to be added to FMU resource
                                            folder
      --debug arg (=0)                      build debug-fmu
      --author-name arg (=SINTEF)           author name in FMU
      --description arg (=Model exported from FhSim with fhFMUExport)
                                            model description
      --guess-input-interface arg (=0)      Guess to input interface from constant
                                            values in the interconnecitons (keeep
                                            initial values)
      --guess-output-interface arg          FhSim output file to guess additional
                                            FMI output from
      --include-license-file arg            Path to license file to include in FMU

Many of the options listed above are more or less self-explaining and will not be given much attention here. However, note that the exporter can be able to guess the I/O interface for the FMU based on the model xml configuration file and a result-file generated when simulating the model with FhSim. When this is initiated, remember that the tag FileOutput (under INTEGRATION ) should be set to "objects:ports" in the FhSim configuration xml file. If you have special resources that you wish to include you could either hope that the autocopy tags work, or you could specify them manually using --add-dir-to-resources.

In the following, a simple mass-spring system is used as an example for using the exporter.

3D mass-spring system

In this example we are going to export a mass and a spring as two separate FMUs. The mass itself is just a simple mass in 3D whithout any “internal” gravity forces (as was the case in the previous case). This means that all forces acting on the mass comes from outside and that only the kinematics and the inertia are modelled internally:

where and are the external forces acting on the mass, are the position coordinates, are the velocities and where is the mass. Note that it this mass is considered to be a point-mass where the rotations are neglected. The xml-file describing our mass is given as follows:

# mass.xml
<Contents>
    <OBJECTS>
        <Lib
            LibName="FhSimBaseLibrary"
            SimObject="Body/Mass"
            Name="M"
            Scale="1"
            Mass="1"
            Material="Simple/Red"
        />
    </OBJECTS>

    <VARIABLES>
        <Var Name="vel0" Value="0,0,-1" />
    </VARIABLES>

    <INTERCONNECTIONS>
        <Connection
            M.Force="0,0,0"
        />
    </INTERCONNECTIONS>

    <INITIALIZATION>
        <InitialCondition
            M.Pos="0,0,0"
            M.Vel="$vel0"
        />
    </INITIALIZATION>

    <INTEGRATION>
        <Engine
            IntegratorMethod="2"
            NumCores="1"
            TOutput="0, 1:1:10, 60"
            LogStates ="1"
            stepsize ="0.001"
            HMax="0.002"
            HMin="0.00000001"
            AbsTol="1e-3" RelTol="1e-3"
            UseRSSNormInsteadOfInfNorm="0"
            FileOutput="objects:ports"
        />

    </INTEGRATION>
</Contents>

When the exporter is set to guess the input interface (--guess-input-interface), we only need to specify the port in the INTERCONNECTION-connection xml block with konstant values (e.g. “0”). If we want to change any parameters, we also need to specify variables in the configuration file, such as vel0, the initial value for our mass, as shown in the mass xml configuration file. Before exporting our model, we test it with FhSim, also to generate a results-file to be used by the exporter. We call FhSim with the following command:

FhSim.exe --input-file path\to\mass.xml --output-file path\to\mass.csv

Afther FhSim has finished, we call the exporter with the following command

fhFMUExport.exe --input-file path\to\mass.xml --guess-input-interface 1 --guess-output-interface path\to\model.csv

Note that both these commands should be run from the bin-folder for FhSim (having the bin-folder as working directory), where the exporter is placed. Since we do not have any particular resource needs in this case, we do not add the –autocompy argument or the --add-dir-to-resource argument.

To make the spring, we use the following xml configuration

# spring.xml
<Contents>

  <VARIABLES>
	<Var Name="l0" Value="10" />
	<Var Name="k" Value="100" />
  </VARIABLES>

  <OBJECTS>
	<Lib
		LibName="FhSimBaseLibrary"
        SimObject="Cable/LinearSpring"
        Name="S"
        Stiffness="$k"
        RelaxedLength="$l0"
	/>

  </OBJECTS>
  <INTERCONNECTIONS>
  <Connection
    S.PosA="0,0,0"
    S.PosB="0,0,-10"
  />
  </INTERCONNECTIONS>

  <INITIALIZATION>
	<InitialCondition
	/>
  </INITIALIZATION>

  <INTEGRATION>
    <Engine
    IntegratorMethod="2"
    NumCores="1"
    TOutput="0, 1:1:10, 60"
    LogStates ="1"
    stepsize ="0.001"
    HMax="0.002"
    HMin="0.00000001"
    AbsTol="1e-3" RelTol="1e-3"
    UseRSSNormInsteadOfInfNorm="0"
    FileOutput="objects:ports"
	/>

  </INTEGRATION>
</Contents>

Note that in this case we have made variables for both the unstreatched spring length l0 and the spring stiffness k. To export the spring FMU we follow the same procedure as the mass model. NB! Note that the environmental variable SFH_LICENSE_FILE must be set and point to the FhSim license file in order for the FMU to run.

To run the co-simulation, we need a co-simulation master algorithm, e.g. Coral which will be used here. It is out of scope here to give a through introduction to how to use Coral, and the use is referred to the ViProMa webpage for a thorough introduction. In short, Coral requires two different configuration files, one for how to configure and connect the models, and one for how to execute the co-simulation. For our special case, these are given as follows:

name "Mass-spring co-simulation using FhSim models"

slaves {

    Spring {
        type "Spring"
        init {
            visualization[0] 0
            l0[0] 10.0
            k[0] 100.0
        }
    }

    Mass {
        type "Mass"
        init {
            visualization[0] 0
            vel0[0] 0.0
            vel0[1] 0.0
            vel0[2] -1.0
        }
    }
}

connections {

    Spring.fmiInput.S-PosB[0]   Mass.fmiOutput.M-Pos[0]
    Spring.fmiInput.S-PosB[1]   Mass.fmiOutput.M-Pos[1]
    Spring.fmiInput.S-PosB[2]   Mass.fmiOutput.M-Pos[2]

    Mass.fmiInput.M-Force[0]    Spring.fmiOutput.S-ForceB[0]
    Mass.fmiInput.M-Force[1]    Spring.fmiOutput.S-ForceB[1]
    Mass.fmiInput.M-Force[2]    Spring.fmiOutput.S-ForceB[2]
}
start 0.0
stop 50.0
step_size 0.01

Note that in this case we have turned off the 3D visualization (visualization[0]=0). If we ran this simulation and plotted the z-position of the mass and the z-component of the spring force in the mass-connection we get the results shown in the figure below.


Co-simulation results from mass-spring system

As can be seen by the results, the simulation get unstable with the given co-simulation configuration. As a matter of fact, this system will never be stable in a co-simulation setup. This is because there is no dissipation of energy in the systems, while the co-simulation wrongfully introduces energy between the systems according to basic co-simulation theory. It is out of scope here to elaborate this further, and the readers are referred to co-simulation stability theory. for more information. The reason for presenting such a case is also to warn and encourage the reader to fully understand what co-simulation really is all about.

For reference, the script used to plot the results is given as follows:

import numpy as np
import matplotlib.pyplot as plt

mass = np.genfromtxt("mass.csv", delimiter=',', names=True)
#print(mass.dtype.names)

spring = np.genfromtxt("spring.csv", delimiter=',', names=True)
#print(spring.dtype.names)

plt.figure()
plt.subplot(2,1,1)
plt.title("Co-simulated mass-spring system")
plt.plot(mass['Time'], mass["fmiOutputMPos2"], label=r"z-position")
plt.ylabel("[m]")
plt.grid(True)
plt.subplot(2,1,2)
plt.plot(spring['Time'], spring["fmiOutputSForceB2"], label=r"z-springforce")
plt.xlabel("Time [s]")
plt.ylabel("[N]")
plt.grid(True)
plt.show()

This concludes this short introduction to exporting FhSim models as FMUs.