I am a student from Slovak University of Technology and I would like to kindly ask you for your help.
My goal is to implement NMPC on a laboratory inverted pendulum system and I was recommended to use the acados package. I have already successfully implemented embedded linear MPC (using qpOASES) on a STM32F4 platform, featuring a swing-up algorithm. Now, I would like to use the full non-linear model and replace the existing control scheme with NMPC.
I was browsing the github examples, but it is still unclear to me where to start and what is the procedure to obtain the solver code, which I can include then into my main file. Could you please give me some guidance or provide a minimal working example of the procedure?
Thank you and have a nice day,
great that you want to start using acados.
You wrote that you are using a nonlinear model.
Our workflow to use nonlinear model with acados is to formulate it in CasADi, typically from Matlab or Python.
For details on how to formulate your model, see .
We have a Matlab and Python/Templating interface, see . Where the Matlab interface is rather for prototyping and the Python/Templating interface rather for going embedded, as it generates self-contained C code, which you can include into your main file.
I have chosen to go with the Python/Templating interface. So far I have managed to go through the installation process and I have been using the pendulum_example to generate c code. I have been trying to build and run the example, but I am still getting a few errors. I am using eclipse IDE, with a project setup for STM32F4 featuring ARM cortex M4.
Among the generated files “acados_solver_sfunction_pendulum_ode.c” is only used for MATLAB/Simulink and I do not need it for embedded implementation? Among the first errors when I included the generated files into the project was “simstruc.h: No such file or directory”, which I found out to be related to Simulink coder.
“libacados_solver_pendulum_ode.so: file not recognized: file format not recognized” error. When I tried to include the shared object library in the linker I was getting file not found. This was solved by adding prefix lib to the file name as the linker -lXXX is searching for libXXX.so file. Can the added “lib” prefix cause the file format to be not recognized?
This is a follow-up question from the last one. After trying to google the format error I found that there might be issues with the fact that I want to implement this on an ARM cortex M4. BLASFEO_TARGET support is for ARM cortex A and not the M. During the installation I have been using the “GENERIC” option. Honestly, I am not sure whether these influence the library format not recognized error I am getting. So the question is if it is possible to use the generated code on an ARM cortex M4 and if so, which settings to use?
1 - Yes you don’t need the s-function definition if you don’t want to use the solver through Simulink.
2 - Now library name has been fixed in master branch
3 - Yes GENERIC is the right BLASFEO_TARGET for that MCU, but is not only BLASFEO the problem, we never tried to run acados on a Cortex-M4 yet, because of its relatively limited hardware capabilities, the main problem is that it does not implement double precision floating-point unit, while
acados QP solver types relay on that capability.
Maybe @giaf can give you more details and outline some possible solutions.
An hardware work around to use
acados off-the-shelf could be to switch MCU to something which support DP FPU, like STM32F7 or ESP32, to be noted the first seems to be faster.
thank you for your response, I will consider changing the hardware.
Although I am also interested in hearing from @giaf whether there are any possible workarounds for SP FPU.
I’ll keep this thread updated if I get any new progress.
Just to be clear, in theory acados would already work on a Cortex M4. Since the hardware does not support DP FP, the compiler would generate calls to libraries instead (generally implemented using operations on integers). This means that from your side nothing special has to be done, but that the performance will be much slower (I guess something like an order of magnitude, maybe more) than the same operations performed in hardware in SP. Maybe this is fast enough for you.
The alternative to have more speed would be to use SP instead of DP. But for your particular application (unstable dynamics around the upright position of the pendulum together with long horizons) make this alternative most likely unfeasible in practice, at least using second order optimization methods.
Hope this helps to clarify the situation.
Thanks @giaf for the explanation.
I have tried creating a project for STM32F7, which features DP FPU. But when I try to compile it, I am still getting the same linker error - “libacados_solver_pendulum_ode.so: file not recognized: file format not recognized” and I don’t know what to do about it. Can you please point me out what might be the issue and how to solve it?
Also for testing purposes, I am still interested in trying to run it on the Cortex M4 to see how well/bad it behaves.
Hey @kulho. Maybe make is invoking successfully the compiler, but you still need to change the name of the library from
libacados_solver_pendulum_ode.<something> (dunno what is the supported format). You can do this by changing a few things in the generated Makefile. Also, apart from dealing with the generated C code, did you already cross-compile acados? If you manage to get it running we could think of making it part of some supported workflow.
I’ve been trying to work with the generated make file and here’s what I managed so far. First, I’ve added an option to generate the library with a different extension, I tried going with “.a”. In the link, you can see how I changed it https://pastebin.com/CsTzfm8W. I was getting some warnings that the defined paths did not exist. Changing the LIB_PATH solved the issue. Unfortunately, I still did not succeed in building the project. I tried quite a few different options but I still get either the previously mentioned error of library format not recognized, or I get a bunch of undefined references to functions https://pastebin.com/Nx5sd2B9. At this point, I’m stuck because I don’t know whether the library does not contain definitions to those functions or it just did not load properly. In the log, you can also see the linker invocation that I am using.
For the second part, I am not really sure what do you mean by cross-compiling acados. I have followed the steps to install acados and used the python interface to generate the c code. The generated unix executable of the pendulum example problem runs smoothly in the terminal.
I am not sure exactly what you modified.
But maybe you are still using
gcc to compile the interface and the external function generatad by
i.e. if you are still using
c_generated_code/Makefile as it is (looking at https://pastebin.com/CsTzfm8W).
If you use template interface (python), after generate the code you should change all the calls to
gcc with something like
arm-none-eabi-gcc and all the proper flags in the generated Makefile.
( cd pendulum_ode_model; gcc $(ACADOS_FLAGS) -c $(CASADI_MODEL_SOURCE))
Hey @tmmsartor, thanks for joining the discussion. I have also downloaded the newest version of acados lately. I have tried to change the gcc to arm-none-eabi-gcc, but I am still getting some errors, see the log https://pastebin.com/jFL9SQWR. Also, the gcc-only compiled pendulum example problem is now giving an error too https://pastebin.com/eAMAde3y. On an older version it ran properly. Although, I am more concerned about the first error with the libacados.a and how to make it work.
The errors you are seeing when you use the
arm-none-eabi-gcc compiler are because it is trying to use the acados library you compiled for your computer, which is not an ARM library. You need to compile acados with the
arm-none-eabi-gcc compiler as well, then point the LIB_PATH variable in the generated makefile to the compiled ARM libraries.
Thanks for the explanation @imcinerney, although I struggle with how to compile acados with
arm-none-eabi-gcc. I was following these instructions and then for the last part of compiling and installing acados I used the commands from python interface section. I tried to look through the make files, but I am not sure where to change the compiler to
arm-none-eabi-gcc. Could you please tell me, which files and where should I modify them to compile acados library with
@imcinerney I’d also appreciate a hint to solve this problem with how to compile acados with arm-none-eabi-gcc???
@kulho what software are you using to compile your code for the MCU? Cross-compiling can be somewhat tricky, since Acados relies on some standard library headers. If you let me know the toolchain you use, I can look into it.
I would much appreciate your help @imcinerney. I am using GNU MCU Eclipse which features GNU Arm Embedded Toolchain.
Dear @imcinerney please have you achieved some progress in testing the compilation of code (with the toolchain used by @kulho)?