Getting NaN values from the model using FMPy

Question:

I’m running an FMU export from Simcenter that runs on 5e-7 step-size in FMPy. However, after a few steps the FMU starts returning NaN values. My expectation is that this is due to the way I am using FMPy, but I am unable to solve it until now.

  1. Which variables within FMPy should I use, considering the use-case (read below)?
  2. Anybody who has had NaN values, and knows how to solve this?

The FMU from Simcenter runs on a container within Azure, and receives input from and sends output to a local Simulink model. There’s basically a recurrent feedback loop between the two models. For my project, I need to run the FMU only for 1 step at a time, return result to Simulink and keep FMU active for future input that would simulate the FMU further. (for implementation of running FMU 1 step at a time with FMPy I’m using continue_simulation.py example from https://github.com/CATIA-Systems/FMPy/blob/main/fmpy/examples/continue_simulation.py.)

The local Simulink model and the Simcenter model run on different step-sizes. Therefore, we have included a rate-transition within the Simulink model. When we run the FMU directly within Simulink, this runs as expected. However, once I change the FMU into a Matlab function block, which is rerouted to the container on our platform, it starts returning NaN values.

Currently have the following variables configured within FMPY simulate_fmu():

filename
model_description
fmu_instance
input
initialize=False
start_time=0 (will be 5e-7 next run)
stop_time=5e-7 (will be 1e-6 next run)
step_size=5e-7
terminate=False
set_stop_time=False

The issue I’m facing now is when using 5e-7 step-size and 5e-7 stop-time, the FMU starts returning drastically different values comparing to same FMU running in Simulink from the 7th step and on the 10th step reaches NaN values as outputs.

Asked By: Taurius

||

Answers:

I found the solution. It was to stop using simulate_fmu() function that does quite some things under the hood and instead use the functions, that simulate_fmu() uses, myself to avoid using extra things that I did not need (also helped to better understand how FMPy works). This resulted in the model returning expected values and not NaN values anymore.

I used the example code from custom_input.py FMPy docs (https://github.com/CATIA-Systems/FMPy/blob/main/fmpy/examples/custom_input.py)

My custom function to run a step(s) of FMU now looks like this:

def set_input(self, inputs_array_values, step_size, interval):
    # Proceed with running the step(s)
    stop_time = self._current_simulation_time + interval
    while self._current_simulation_time < stop_time:
        # set the input
        print(f"value references: {self._vrs_inputs.values()}, input values: {inputs_array_values}")
        self._fmu.setReal(self._vrs_inputs.values(), inputs_array_values)
        # perform one step
        self._fmu.doStep(currentCommunicationPoint=self._current_simulation_time, communicationStepSize=step_size)
        # advance the time
        self._current_simulation_time += interval
        print(f"current simulation time: {self._current_simulation_time}")

    # return without delay. 1 step delay will be created in Simulink as Unit Delay is required to properly run the simulation by fixing algebraic loop
    outputs = []
    outputs = self._fmu.getReal(self._vrs_outputs.values())
    outputs.insert(0, float(self._current_simulation_time))
    row = tuple(outputs)
    self._results.append(str(row))

    return row
Answered By: Taurius
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.