Why I'm obtaining NaN in the output of a simple FMU exported from Simulink and tested in Python 3?

589 views Asked by At

I'm new to the FMI standard and FMUs. I'm trying to export a FMU of a simple Simulink model, the Ohm's law in my case, to test the funcionality of the FMI standard in Python. I'm obtaining NaN in the output of this simple FMU exported from Simulink and tested in Python 3.

In the next model I'm defining 2 inputs (Voltage and Resistance), a division and 1 output (Current). Then, I export the FMU by clicking on Save As > Export Model To > Standalone FMU. Note I'm configuring fixed-step size in the model settings. I've also tested exporting the FMU from the Command Window with the following line: Simulink model

exportToFMU2CS('OhmLaw')

The FMU is exported correctly, but when I go to test it in Python 3 with a Jupyter notebook, I'm not obtaining the expected output. As shown below, for the input values V=10 and R=2, the simulation returns I=NaN. I'm also pasting the minimal code: Jupyter notebook

from pyfmi import load_fmu
model = load_fmu('OhmLaw.fmu')
model.set('Voltage', 10)
model.set('Resistance', 2)
res = model.simulate(final_time=1, input=(), options={'ncp': 1})
model.get('Current')

I've tested with different data types in all blocks (auto, int32 and double), but I'm still not able to achieve the correct result.

Does anyone know what's happening here? I'm using MATLAB R2022a in Windows 10.

UPDATE. Finally, I've been able to simulate the FMU with the FMPy library in Python. Note that "pip install fmpy" is giving problems, so I've installed it with "conda install -c conda-forge fmpy" and used a Jupyter Notebook.

2

There are 2 answers

1
Christian Bertsch On

I assume that the model get's evaluated in initialization mode before the inputs are set. Does the Simulink FMU export allow for setting start values for the inputs? Then set them to a nonzero value.

1
Robotics010 On

You just need to set start values before dividing by 0 happens. It can be done in fmpy (do not confuse with pyfmi) in the following way:

import fmpy

fmu_filename = 'Ohm.fmu'

def simulate_with_start_values():

    # calculate the parameters for this run
    start_values = {'Voltage': 10.0, 'Resistance': 2.0, }

    # simulate the FMU
    result = fmpy.simulate_fmu(fmu_filename,
                               start_values=start_values,
                               start_time=0.0,
                               stop_time=1.0)

    # plot Current output
    fmpy.util.plot_result(result)

if __name__ == "__main__":
    simulate_with_start_values()

Then you get your Current output right:

results_chart