Run minimal_example_mhe from C++

Hi!

I would like to use the Python auto generated code for a MHE solver directly from C++. As it was stated in MHE using algebraic variables, I was able to solve my problem using the Python interface thanks to the help provided here. However, I couldn’t use the auto generated solver from C++. So, I started from scratch with minimal_example_mhe.py to see if I could achieve that task.

After digging around with the code, I was able to create a CMake project where the mhe_pendulum_ode_test.cpp file uses the auto generated code to solve the same problem that was solved using Python. One detail that is bugging me is that the errors between the true and the estimated states are a little different from the Python version.

The code is in this repository mhe_acados_cpp. You can try it by doing the following

  1. Edit CMakeLists.txt to fit your acados installation.
  2. Go to solver/mhe folder and run python3 minimal_example_mhe.py to get the auto generated code.
  3. Go back to the project root, create a build directory and run cmake and make to get an executable
mkdir build
cd build
cmake ..
make
./mhe_acados_cpp
  1. After runing the executable you should have a text file called simXest.txt inside the build directory that contains the values of the MHE estimated states obtained using C++.
  2. Go into the src directory and run python3 plot_cpp_results.py to compare.

Could anyone point me if I’m missing something in the C++ code? It took me forever to realize how to set the parameters p (hint: it was the acados_update_params function).

Thanks in advance!

Hi,

I had a quick look.

Was this your main issue?
I reproduced the following:

Native Python:

difference |x0_est - x0_bar| 6.475980809298076e-12
difference |x_est - x_true| 1.5647168350951527e-09

Exported CPP:

difference |x0_est - x0_bar| 2.3906595541638575e-07
difference |x_est - x_true| 2.8829698023581986e-07

Exported CPP with more accuracy → 1 more iteration.

difference |x0_est - x0_bar| 1.1366692365338366e-15
difference |x_est - x_true| 7.431582678349519e-15

I guess some initialization of the solvers is different here, but in general this seems fine to me.

Best,
Jonathan

Hi Jonathan,

I think there is an issue related to the references not being updated properly for last entries of x in (x, u, x) of NONLINEAR_LS cost for line in cpp.

If I replace line with

ocp_mhe.model.cost_y_expr = vertcat(x, u)

and provide references only for (x,u) and run I get following result for both native python and cpp,

However if I run keeping line

ocp_mhe.model.cost_y_expr = vertcat(x, u, x)

and providing references for (x, u, x) then I get the result,

For native python:

For cpp:

Note that the result from cpp with

ocp_mhe.model.cost_y_expr = vertcat(x, u, x)

is exactly same as the one obtained with

ocp_mhe.model.cost_y_expr = vertcat(x, u)

I have been using NONLINEAR_LS cost in my formulation and face the same issue. In native python with NONLINEAR_LS cost my formulation works as expected but if I use generated code from native python in cpp then the solution is different in cpp from the native python.

Thanks,
Jay

Just for completeness.
This line wasn’t mimicked in C++