NTNU-IHB / FMI4cpp

FMI 2.0 implementation written in modern C++.
MIT License
95 stars 35 forks source link

Exception when trying to load an FMU generated from MATLAB Simulink #91

Closed JackHack96 closed 3 years ago

JackHack96 commented 4 years ago

I'm trying to write a little program that needs to load an example FMU generated from Simulink (a multiplier). It works using PyFMI but not in FMI4cpp, and specifically it's throwing an exception when trying to create a new instance.

  fmi4cpp::fmi2::fmu multiplier("multiplier.fmu");

  auto cs_fmu = multiplier.as_cs_fmu();
  auto cs_md = multiplier.get_model_description();
  auto step_size = cs_md->default_experiment->stepSize;
  auto stop_time = cs_md->default_experiment->stopTime;

  auto int1 = cs_md->get_variable_by_name("int1").as_real();
  auto int2 = cs_md->get_variable_by_name("int2").as_real();
  auto outv = cs_md->get_variable_by_name("out").as_real();

  auto slave = cs_fmu->new_instance(); // exception

The exception is:

Unable to load dynamic library '/tmp/fmi4cpp_multiplier_23920508/binaries/linux64/multiplier.so'! /tmp/fmi4cpp_multiplier_23920508/binaries/linux64/multiplier.so: cannot open shared object file: No such file or directory
terminate called after throwing an instance of 'std::runtime_error'
  what():  Unable to load dynamic library '/tmp/fmi4cpp_multiplier_23920508/binaries/linux64/multiplier.so'! /tmp/fmi4cpp_multiplier_23920508/binaries/linux64/multiplier.so: cannot open shared object file: No such file or directory

Am I missing something or it's a bug?

markaren commented 4 years ago

Are you able to share the FMU?

JackHack96 commented 4 years ago

Sure! Here is it!

multiplier.zip

markaren commented 4 years ago

I wonder if this is an FMU issue. It fails also with FMPy with the same error message. Unable to load dynamic library (windows). This error message is a bit misleading since it probably does find multiplier.dll, but fails to find dependent .dll libraries. FMPy also complains about Cannot locate installed MATLAB (Version 9.5). I do have MATLAB installed (2019b) on this machine, but probably another version (?) and don't think I have Simulink. I dunno why it works with PyFMI..

markaren commented 4 years ago

So I ran dependency walker on the dll. It depends on the following DLLs that cannot be found on Windows: LIBMATLABDATAARRAY.DLL, LIBMATLABENGINE.DLL, MWBOOST_SERIALIZATION-VC140-MT-1_65_1.DLL, MWBOOST_SYSTEM-VC140-MT-1_65_1.DLL

At least the boost dlls should be embedded in the FMU. Dunno about the matlab dlls. If they are FMU specific they should also be included in the FMU.

JackHack96 commented 4 years ago

So I ran dependency walker on the dll. It depends on the following DLLs that cannot be found on Windows: LIBMATLABDATAARRAY.DLL, LIBMATLABENGINE.DLL, MWBOOST_SERIALIZATION-VC140-MT-1_65_1.DLL, MWBOOST_SYSTEM-VC140-MT-1_65_1.DLL

At least the boost dlls should be embedded in the FMU. Dunno about the matlab dlls. If they are FMU specific they should also be included in the FMU.

That's why I have to use LD_LIBRARY_PATH environment variable (I'm on Linux), as documented here: https://it.mathworks.com/help/simulink/ug/export-model-as-tool-coupling-fmu.html

markaren commented 4 years ago

Can you test the FMU with FMPy under linux. I don't have easy access to Linux right now. pip install fmpy[complete] python -m fmpy.gui

JackHack96 commented 4 years ago

Ok, I'll proceed after lunch. For now, here is the screenshot with PyFMI: image See I have to export an environment variable. I'll test with FMPy later

markaren commented 4 years ago

So how do you export the environment variable so that it's picked up when you run using FMI4cpp?

JackHack96 commented 4 years ago

I've tested with FMPy, and it just works :smile: Screenshot from 2020-03-23 13-11-01

With FMI4cpp, I'm using CLion, and for exporting the environment variable I'm using the appropriate textbox on the launch configurations: Screenshot from 2020-03-23 13-13-11

markaren commented 4 years ago

Hmm.. Then I'm guessing the system does not pick up the environment variable even though you define it though CLion. I don't think FMI4cpp handles library loading any differently than FMIL, which is used by PyFMI.

markaren commented 4 years ago

I would try setting the environment variable permanently.

JackHack96 commented 4 years ago

I tried that but without luck. I even tried to print the value of LD_LIBRARY_PATH before running the code, and it's correct. image

The problem is the same with other FMUs generated from MATLAB, while other FMUs (like the example one on the official repository) seems to work.

markaren commented 4 years ago

If you can, it would be great if you could figure out if FMI Library handles loading dynamic libraries differently than I do with FMI4cpp and then perhaps make a PR if thats the case. I personally won't be able to do so.

JackHack96 commented 4 years ago

Wow, that would be a difficult task as I'm learning C++ with this project (that's part of my thesis). Anyway, if I manage to get it working, I'll try to do a PR :D

markaren commented 4 years ago

I think comparing

https://github.com/modelon-community/fmi-library/blob/0bf8a2e1aea1cc76010b7fb5f2a5fb4fb2da0e9e/src/Util/src/JM/jm_portability.c and https://github.com/NTNU-IHB/FMI4cpp/blob/fb299a1e77dfb0a3ebc0b16b6187d29e00603701/src/fmi4cpp/fmi2/library_helper.hpp

would go a long way.