pythonmodelicaopenmodelicafmipyfmi

Functional Mock-up Unit no valid when implemented in Python (created in OpenModelica)


I having trouble here when implementing a Modelica code as a FMU in Python. This is de model:

model integrator
  Modelica.Blocks.Continuous.Integrator y_to_x[6] annotation(
    Placement(visible = true, transformation(origin = {2, -12}, extent = {{20, 20}, {-20, -20}}, rotation = -180)));
  Modelica.Blocks.Interfaces.RealOutput x[6] annotation(
    Placement(visible = true, transformation(origin = {88, -12}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  Modelica.Blocks.Interfaces.RealInput y[6] annotation(
    Placement(visible = true, transformation(origin = {-82, -12}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-80, -40}, extent = {{-20, -20}, {20, 20}}, rotation = 0)));
equation
  connect(y_to_x.y, x) annotation(
    Line(points = {{24, -12}, {88, -12}}, color = {0, 0, 127}, thickness = 0.5));
  connect(y, y_to_x.u) annotation(
    Line(points = {{-82, -12}, {-22, -12}}, color = {0, 0, 127}, thickness = 0.5));

annotation(
    uses(Modelica(version = "4.0.0")));
end integrator;

Then I've created the FMU and wrote the same code as always in Python:

fmu_file = 'integrator.fmu'
model_description = fmpy.read_model_description(fmu_file)
dump(fmu_file)

t_start = 0; t_end = 200; t_step = 0.01

outputs = fmpy.simulate_fmu(
    fmu_file,
    start_time = t_start,
    stop_time = t_end,
    output_interval = t_step,
    input=np.array([0,2000,0,0,0,0], dtype=[("y[1]",np.float64), ("y[2]",np.float64), 
                                             ("y[3]",np.float64), ("y[4]",np.float64)
                                             ("y[5]",np.float64), ("y[6]",np.float64)]),
    output = ('x[1]','x[2]','x[3]','x[4]','x[5]','x[6]'))
  

                                          

The results are different in both interfaces (OpenModelica and Python). I have tried in serveral ways but it dosen't work. Anyone has a clue on what's going on?


Solution

  • This is a sum-up of my earlier comments and I just noted that you supplied and answer yourself.

    I am not sure I understand exactly what you want to do, but here is what I understand. See it as a partial answer. Perhaps someone else with more FMPy knowledge can add on.

    Your Modelica code works well in OpenModelica 1.21 and I exported an FMU of ME type for use in Linux Python environment.

    A bit tricky is that you in your Modelica model use RealInput as input. This input is normally used for a time series. If just want to give a constant value you should normally use the block Modelica.Blocks.Sources.Constant for that.

    From the interaction in OpenModelica after simulation I see that you can give the vector y[i] values for each component and remains constant. This value propagate to the input u of y_to_x[i] while the initial value of the integrator y_start is zero, of course.

    The block RealInput provide you a way to give constant values as input, without involving a source block. From the FMU you reach these as parameters, not as input signal as I understand it.

    In FMPy you provide start_values as a dictionary including both parameters and initial states. Thus you need to replace "input =" with start_values = { 'integrator.y[2]:2000.0} to get the result you seem to want.

    PS. The integration routine you do not need to change for this example. I just generally use CVODE since default in other contexts.