I am using c code generated files to solve nonlinear MPC problem in C++. After the problem is solved I obtain control and decision variables that look reasonable when I plot them. I wanted to analyse cost value and residuals and I use the following commands to store their values at each iteration of MPC:
I got an error when I tried using ocp_nlp_eval_cost(nlp_solver, nlp_in, nlp_out) before getter. The reason being that ocp_nlp_eval_cost() is not defined in the c files generated by using the command ocp.generate_c_code in MATLAB. On the other hand ocp_nlp_get() is defined in the generated c files.
Am I missing some argument setting in MATLAB so that the generated c files will contain ocp_nlp_eval_cost() ?
You are right. The functions are defined in interfaces/acados_c/ocp_nlp_interface.h. I am able to calculate cost now, but strangely I get an error while making call to ocp_nlp_eval_residuals(). Unlike ocp_nlp_eval_cost(), ocp_nlp_eval_residuals() was not declared in interfaces/acados_c/ocp_nlp_interface.h, but even after manually declaring the function it does not work.
I declare ocp_nlp_eval_residuals in interfaces/acados_c/ocp_nlp_interface.h like void ocp_nlp_eval_residuals(ocp_nlp_solver *solver, ocp_nlp_in *nlp_in, ocp_nlp_out *nlp_out);.
When I call this function from my main cpp file I get the compilation error error: ‘ocp_nlp_eval_residuals’ was not declared in this scope. I am including ocp_nlp_inteface.h in my program as I am getting cost value without any problem. Can you suggest what could be the issue here?
Reinstalling acados solved the issue. Now I can print the relevant residuals. In my code the value of residuals are as follows:
As you can see that the residual for inequality constraint is quite high. To fix this issue changing the initial guess can be a solution. In my case I provide the solution of previous iteration from 2 to N (N is the horizon length of MPC) as initial guess for 1 to N-1 of next iteration (with N-th point given same initialization as of N-1). What else do you think can affect the Ineq residual.
Actually I observe a strange thing while printing residuals. The residuals printed are fixed and do not change over iterations of MPC. On tuning weights of cost function the solver sometimes find solution however the residuals again remain constant.
Can you please check it the residual function implementation is correct in the library?
Did you rule out that there is some infeasible QP, by printing the solver statistics?
In that case it could be that the solver doesnt actually perform iterations and thus the residuals stay constant.
So I am printing stats using ocp_model_acados_print_stats(acados_ocp_capsule); which is defined in acados_solver_ocp_model.c which is code generated from MATLAB. Just to analyse I remove all inequality constraints except constraints on input variable u. This is the output of above function:
The inequality residual from residual->inf_norm_res_ineq is close to 2.165610e+01 for most of the iterations. The bounds set on input variable are very loose and they are in fact respected when I check the solution of the solver.
Now I don’t understand why inequality residual is high even after this. Please help me understand
Actually the original problem I am solving has one major nonlinear inequality constraint. However in order to reason about the residual issue I was getting I removed this inequality constraint. The screenshot is for the SQP_RTI solver with only constraints set on input (lower and upper bounds on u). Since the print_stats works correctly with SQP, I checked using SQP that residuals are high when the bounds are very loose ~1e+7. Ofcourse if the max number of iterations are set less for SQP the solver returns with status max iterations reached with such loosebounds.
I want to confirm that since I have to include the nonlinear inequality constraint in my formulation, is it better to use SQP over SQP_RTI?
Sometimes it can be problematic to set bounds to high to mimic unboundedness.
To large values can lead to numerical issues.
I am not sure in what magnitude your u is. But if 1e5 is also very loose, it might be better to use that.
I typically use SQP and sometimes ignore status 2.
There is just very little performance to be gained switching to SQP_RTI.
Plus, in the latter, you can split preparation and feedback phase.