Terminal constraints in python

Hi there,

Thanks for the great tool that you’re developing.
I’m trying to slightly modify your pendulum example by transferring the terminal state from the cost function to the constraints.
I tried removing the cost on the final state and adding the following lines according to the pdf specifying the problem formulation.

# terminal constraints
ocp.constraints.Jbx_e  = np.eye(nx)
# ocp.constraints.Jsbx_e = 1e-2*np.eye(nx)
ocp.constraints.ubx_e  = np.array([0.0, np.pi, 0.0, 0.0])
ocp.constraints.lbx_e  = np.array([0.0, np.pi, 0.0, 0.0])

Unfortunately, it looks like the solver does not take this constraint into account since it converges to a “flat” solution (always 0 on the states and on the control).
Moreover, after these lines, if I ask for ocp.constraints.Jbx_e, I get the following error :
AttributeError: ‘AcadosOcpConstraints’ object has no attribute ‘_AcadosOcpConstraints__Jbx_e’
I guess this comes from the fact that in AcadosOcp.py, the declaration of self.__Jbx_e is commented…
I tried uncommenting it, resulting in no error, but the result of the solver is still the same !

Do you have any idea how to solve this ?



Hi @byfra,

welcome to the Forum and thanks for the post!

This is an error in the Python documentation.
The matrix Jbx_e and all similar matrices (Jbx, Jbu,…) are not actually part of the Python interface (yet).
Instead you have to specify a vector idxbx_e, which is a zero based index vector that defines which components should be bounded.
This means, instead of

ocp.constraints.Jbx_e = np.eye(nx)

you actually have to write

ocp.constraints.idxbx_e = np.array(range(nx))

I will try to implement the setters Jbx etc, which will then internally convert the matrix into the zero based vector mentioned above.

Thanks for pointing this out!


Actually the conversion seems to be partly there already, especially for Jbx_e, so I will try to have another look tomorrow…

Thanks for the quick reply, I confirm that the conversion works.
I missed the following setting :
ocp.dims.nbx_e = nx
Now, it works as expected !

Great that this worked.
Setting/checking the dimensions automatically in python is also on the TODO list :sweat_smile: