Solver behaviour depends on initial cost function after reinitialization

Hello,

I am using the Python interface to implement a Nonlinear MPC. As a solver, I use PARTIAL_CONDENSING_HPIPM and SQP_RTI. For parameter tuning, my goal is to run a simulation of the system multiple times without re-compiling acados each time. The initial conditions stay the same, however I need to change the cost function weights and the slack term weights.

To do so, I initialize the solver with an arbitrary parametrization (e.g. unit matrices). For running a simulation, I reset all solver parameters to their initial state by restoring the initial iterate with load_iterate(). From what I can see, the solver state should be identical at each start of the simulation.

I then set the relevant parameters using the cost_set() method:

# assign cost function weights
    Q   = np.diag([parametrization['q_xy'],
                parametrization['q_xy'],
                parametrization['q_yaw'],
                parametrization['q_vel']])
    R   = np.diag([parametrization['r_jerk'],
                parametrization['r_steering_rate']])
    Qe  = Q
    # assign slack term penalties
    L1 = parametrization['L1']
    L2 = parametrization['L2']

    W = scipy.linalg.block_diag(Q, R)
    We = Qe

    # update cost function weights
    for i in range(N):
        solver.cost_set(i, 'W', W)
    solver.cost_set(N, 'W', We)

    # update slack terms
    z = np.ones((2,)) * L1
    Z = np.ones((2,)) * L2
    solver.cost_set(0, 'zl', z)
    solver.cost_set(0, 'zu', z)
    solver.cost_set(0, 'Zl', Z)
    solver.cost_set(0, 'Zu', Z)
    solver.cost_set(N, 'zl', z)
    solver.cost_set(N, 'zu', z)
    solver.cost_set(N, 'Zl', Z)
    solver.cost_set(N, 'Zu', Z)
    z = np.ones((3,)) * L1
    Z = np.ones((3,)) * L2
    for i in range(1, N):
        solver.cost_set(i, 'zl', z)
        solver.cost_set(i, 'zu', z)
        solver.cost_set(i, 'Zl', Z)
        solver.cost_set(i, 'Zu', Z)

However, the solver depends strongly on the chosen initial parametrization - for parametrizations that are similar to the initial one, a solution is found. However, if the initial values differ strongly, the solver fails to find a solution even for previously sucessful parameters.

Additionally, it appears that after having crashed once, the solver is not able to find a solution anymore. Let’s say parametrization A is feasible and B is not. When using A, B and then A again, only the first trial of A can be solved.

I suppose that I do not fully reset the solver, leading to some information being conserved and interfering with the next trial. However I have been unable to encounter the error. Does anybody have experience with this behaviour? I would be thankful for any help.

Thanks in advance!

Hi,

in general, in acados all values from the previous solver call stay in the memory, if you don’t set them explicitly.
load_iterate() sets all solver variables though.
There was a bug fix recently, when updating W in the nonlinear least squares module: NLS cost module: Change W_changed flag if cost matrix was changed by lukasfro · Pull Request #939 · acados/acados · GitHub
Please make sure you are in a newer version.

Moreover, if you have a QP solver failure, which results in NaNs.
Issues might persist with the values in the memory of the QP solver.
For HPIPM with partial condensing you can reset the QP solver memory using this function:
https://docs.acados.org/python_interface/index.html?highlight=reset#acados_template.acados_ocp_solver.AcadosOcpSolver.reset

Best,
Jonathan