Time varying constraints, reference etc with acados in matlab

Hi :wave:

I am new to acados and would like to set up MPC problems in Matlab with constraints, reference, weights, expressions etc that change over time (time dependent, time varying, dynamic).

To explore the possibilities, I first tried to add some changes to the minimal_example_ocp with the pendulum_on_cart_model that was given at github as an example to acados.

I already saw that after setting up the solver, it should be possible to change all those things for specific time steps (“stages”) with:

ocp.set('constr_lbx', lbx_i, i)

So this would change the lower bound for x to the values in lb_x_i for stage i.
And similar one could do this for other bounds, references, expressions.

In the minimal_example_ocp code, there was already this line:

ocp.set('constr_lbx', x0, 0)

This line works fine. In general, if the stage is i=0, setting the lower or upper bound for x for only this stage works (at least it is runnable like this, I did not check if it in this case has an effect).
If using another stage, e.g.

ubx_6=[0.5; inf; inf; inf];
ocp.set('constr_ubx', ubx_6, 6);

this error message appears:

Error using ocp_set
ocp_set: error setting constr_ubx, wrong dimension, got 4, need 0

Error in acados_ocp/set (line 260)
                ocp_set(obj.cost_ext_fun_type, obj.cost_ext_fun_type_e, obj.C_ocp, obj.C_ocp_ext_fun, field, value, stage);

Error in minimal_example_ocp (line 129)
ocp.set('constr_ubx', x_bound_step_6, 6);

I do not understand why this happens. Just to try, I also ran:

ocp.set('constr_ubx', [], ubx_6, 6);

to achieve the 0-dimension. Then the code is actually runnable, but I do not see the expected change in the result. To me it seems like nothing has changed by adding this constraint to stage 6.

Another thing I already tried was to change the reference y_ref:

ocp.set('cost_y_ref', [0;1;0;0], 10);

There, I got the error message:

Error using ocp_set
ocp_set: error setting cost_y_ref, wrong dimension, got 4, need 5

Error in acados_ocp/set (line 260)
                ocp_set(obj.cost_ext_fun_type, obj.cost_ext_fun_type_e, obj.C_ocp, obj.C_ocp_ext_fun, field, value, stage);

Error in minimal_example_ocp (line 142)
ocp.set('cost_y_ref', [0;1;0;0], 10);

So also here, I just tried to satisfy the dimensions demanded by changing it to:

ocp.set('cost_y_ref', [0;1;0;0;0], 10);

In this case, it again was runnable and even gave the expected result. So this seems to work, I would just like to know why changing the dimensions was necessary and what the additional number exactly means.

The lines written above are the only thing I changed in the public available example.
I added them right after the line

ocp.set('constr_lbx', x0, 0)  .

So my questions are:

  • First, for this might already solve everything: Is there maybe a documentation I overlooked, which lists the things that can be adjusted for specific stages and how to do this for each of them?
  • How do I achieve to change the lower and upper bound of x for a specific ctage i?
  • Why does the error message with the dimensions appear?
  • For the y_ref case, why is the additional value required and what does it mean?
  • Or maybe is there other possibilities to achieve different constraints etc for different stages?

I hope my problem is understandable.

Thank you very much for your help! :blush:

Hi Sofie,

first of all, welcome to the forum!

I’ll try to briefly answer your questions.

Generally: After creating an acados OCP solver, you can change numerical values but not the problem dimensions.
Did you check this PDF? acados/problem_formulation_ocp_mex.pdf at master · acados/acados · GitHub
Essentially the dimensions are separate for the inital and terminal shooting nodes and the same for all intermediate nodes.

This explains most of your questions:

Setting new values of ubx which are empty before and after chaning them doesnt change the problem, as here:
ocp.set('constr_ubx', [], ubx_6, 6);

This gives a dimension error because the nbx dimension of node 6 is 0.

ubx_6=[0.5; inf; inf; inf];
ocp.set('constr_ubx', ubx_6, 6);

For this:

For the y_ref case, why is the additional value required and what does it mean?

Please check the y_expr in the model, it matches what you can set.
It is y = [x,u] in that example.



Hi FreyJo,

thank you for you welcoming words and for your answer, this was very helpful! :blush:

I checked that PDF, yes. Before I did not read out anything that helped me with these questions, but you are right, in chapter 7 it is mentioned in a way.
That the dimension of the ocp can not be changed later anymore but only the values makes sense, I could have thought about that.

So essentially, one needs to “initialize” all bounds etc he wants to use already in ocp_model, e.g. like this:

ocp_model.set('constr_lbx', [-inf; -inf; -inf; -inf]); 
ocp_model.set('constr_ubx', [ inf;  inf;  inf;  inf]);
ocp_model.set('constr_Jbx', eye(nx));                      %nx: dim(x)

for the pendulum on card example, if one wants to later set bounds on the states x for specific stages later?

Then, actually another problem occurs for me - when I add any lbx and ubx bounds, the resulting trajectory happens to be just filled with zeros for some reason. I observed this any time I used lbx and ubx so far.
Maybe you have an idea, what could cause this? Could I do anything wrong there?
Maybe I shoud start another topic for this issue, if there is no simple obvious solution?

For the y_ref:

With y_expr you mean cost_expr_y in the pendulum_on_cart_model file, right?
Ok, I see how the dimensionality of y happens to be dim(x)+dim(u) then.

Sorry if this might be actually obvious, but I do not really understand this point:
The cost_expr_y specified in the model file was never handed to the ocp as far as I can see.
So, do I oversee something? Or is y=[x,u] and the respective y_ref the default? Or what else?

Thank you very much for your help and your good explanations! :blush:


I think the default cost type in Matlab is auto where we try to detect the cost type automatically. I think there should be some output info in the example about this.

Yes, just that you cannot use inf but that has been discussed in other threads in the forum.

1 Like

Hi FreyJo,

ah, using inf was actually what caused my other problem then.
Good to know, thank you very much for your help!
I appreciate it.

So what would you recommend if one wants to add a constraint only for some states or for some stages? Just use a large number instead of inf (I guess inf is actually just a as large as possible number too), is there an upper limit from which it does not work anymore?
Or is there another better way?