Can cost_type, "LINEAR_LS:" use "cost_expr_ext_cost"?

Hi all
I’m currently working on controlling a vehicle to follow a reference path using MPC, targeting the tracking of x, y, ψ, vx, and vy. While doing this, I did not specify a cost type, but provided the external cost and Hessian manually, and it worked very well. However, when I explicitly set cost_type = "EXTERNAL" and ran the same settings, it didn’t perform as expected. I’d appreciate it if you could explain why.
Also, another issue is that when using the default settings, changes in the QP weights don’t significantly affect performance, which is problematic.

Code
    # ocp.cost.cost_type   = "EXTERNAL"
    # ocp.cost.cost_type_e = "EXTERNAL"
    Q_n = diag([config.mpc.tqx_n, config.mpc.tqy_n, config.mpc.tqpsi_n, config.mpc.tqvx_n, config.mpc.tqvy_n, \
                config.mpc.tqomega_n,config.mpc.tqdelta_n, config.mpc.tqD_n])
    
    Q_tn = diag([config.mpc.tqx_n, config.mpc.tqy_n, config.mpc.tqpsi_n, config.mpc.tqvx_n, config.mpc.tqvy_n, \
                config.mpc.tqomega_n,config.mpc.tqdelta_n, config.mpc.tqD_n])
    R_n = diag([config.mpc.trdD_n,config.mpc.trddelta_n])

    ref_psi_e = ref_psi*config.mpc.tx_psi
    ec =  ca.sin(ref_psi_e)*(X - ref_x) - ca.cos(ref_psi_e)*(Y - ref_y)
    el = -ca.cos(ref_psi_e)*(X - ref_x) - ca.sin(ref_psi_e)*(Y - ref_y)
    epsi = psi - ref_psi

    E_state  = ca.vertcat(          
                X-ref_x,
                Y-ref_y,
                config.mpc.tx_psi*(psi - ref_psi),
                config.mpc.tx_vx*(vx  - ref_vx),
                config.mpc.tx_vy*(vy  - ref_vy),
                omega, delta, D
            )

    E_input  = ca.vertcat(          
                dD,
                ddelta
            )
    ocp.model.cost_expr_ext_cost = \
        ca.mtimes([E_state.T, Q_n, E_state]) + ca.mtimes([E_input.T, R_n, E_input])
    ocp.model.cost_expr_ext_cost_e = \
        ca.mtimes([E_state.T, Q_tn, E_state])

    # Custom Hessian (state and control)
    H_stage = 2 * ca.blockcat([[R_n,         ca.MX.zeros(nu, nx)],
                           [ca.MX.zeros(nx, nu),     Q_n      ]])
    H_term  = 2 * Q_tn

    ocp.model.cost_expr_ext_cost_custom_hess   = H_stage
    ocp.model.cost_expr_ext_cost_custom_hess_e = H_term

Thanks :pray:

Hi :waving_hand:

the default cost type is linear least squares. So I think if you do not set the cost type the external cost and custom Hessian that you provide are not used (which also explains why you do not observe a difference when changing the weights).

From the code you provided I would recommend to use the nonlinear least squares cost type and set the Hessian approximation option to Gauss Newton, cf. for instance the following example:

Best, Katrin