Getting status 4 from the iteration 0

Hi,

I am new to Acados and I am trying to generate the C code for my MPC for trajectory planning to a goal pose. My MPC with the Casadi works correct and my designed constraints are also satisfied while finding the path and reaching to the goal pose. I need to deploy my MPC to the hardware through S -function. I am unable to find the cause of the QP solver failure, I have followed the examples of Acados with the Matlab interface. I would appreciate any guidance.

typmodel = AcadosModel();
model.name = 'car_mpc';

% State (x)
x_pos   = SX.sym('x_pos'); y_pos = SX.sym('y_pos'); theta = SX.sym('theta');
z_x     = SX.sym('z_x');   z_y = SX.sym('z_y');   z_theta = SX.sym('z_theta');
x = [x_pos; y_pos; theta; z_x; z_y; z_theta];

% Control (u)
v = SX.sym('v'); delta = SX.sym('delta');
u = [v; delta];
nu = length(u);

% Parameters (p)
p = SX.sym('p', 3 + 1); % [xs_x, xs_y, xs_theta, delta_previous]

% -- Dynamics --
slip = atan((param.lr/param.L) * tan(delta));
f_expl = [ v * cos(theta + slip); ...
           v * sin(theta + slip); ...
           (v / param.lr) * sin(slip); ...
           x_pos - p(1); ...
           y_pos - p(2); ...
           theta - p(3) ];

model.f_expl_expr = f_expl;
xdot = SX.sym('xdot', nx, 1);
model.f_impl_expr = xdot - f_expl;
model.xdot = xdot; 
model.x = x;
model.u = u;
model.p = p;

% -- Cost Function --
state_orig   = x(1:3);               
state_int    = x(4:6);               
target_state = p(1:3);
prev_delta   = p(4);

% Stage cost 
error_stage = state_orig - target_state;
model.cost_expr_ext_cost = 0.5*error_stage' * param.Q * error_stage ...
                         + 0.5* u' * param.R * u ...
                         + 0.5* state_int' * param.Qi * state_int ...
                         + 0.5* steer_delta_weight * (delta - prev_delta)^2;

% Terminal cost 
error_terminal = state_orig - target_state;
model.cost_expr_ext_cost_e = 0.5* error_terminal' * param.P * error_terminal ...
                           + 0.5* state_int' * param.Qi * state_int;

model.cost_expr_ext_cost_0 = model.cost_expr_ext_cost;

% -- Constraints --
% Path constraints
slope = tan(param.cone_half_ang);
d = [x_pos; y_pos] - param.cone_apex;
Rm = [cos(-param.orientation), -sin(-param.orientation);
      sin(-param.orientation), cos(-param.orientation)];
dr = Rm * d;
Xr = dr(1); Yr = dr(2);

vel_term = param.eta * ( abs(v*cos(theta) - param.Vg(1)) ... 
                       + abs(v*sin(theta) - param.Vg(2)) ...
                       - param.slack ) - param.beta;

model.con_h_expr = [ Yr + slope*Xr; ...
                     -Yr + slope*Xr; ...
                     Xr - param.hyperplane; ...
                     vel_term - (abs(Xr) + abs(Yr)) ];

ocp_dims = AcadosOcp();
ocp_dims.model = model;
ocp_dims.dims.N = param.N;
ocp_dims.dims.nx = size(x, 1);
ocp_dims.dims.nu = size(u, 1);
ocp_dims.dims.np = size(p, 1);
ocp_dims.dims.nh = size(model.con_h_expr, 1);         % Number of path constraints
ocp_dims.dims.nh_e = size(model.con_h_expr_e, 1); % Number of terminal constraints

% -- Control bounds --
ocp_dims.constraints.lbu = [param.v_min; param.omega_min];
ocp_dims.constraints.ubu = [param.v_max; param.omega_max];
ocp_dims.constraints.idxbu = (0:ocp_dims.dims.nu-1)';
ocp_dims.constraints.idxbx_0 = (0:ocp_dims.dims.nx-1)';
ocp_dims.constraints.lbx_0 = zeros(ocp_dims.dims.nx, 1);
ocp_dims.constraints.ubx_0 = zeros(ocp_dims.dims.nx, 1);

ocp_dims.constraints.lh = [-inf; -inf; -inf; -inf];
ocp_dims.constraints.uh = [0; 0; 0; 0];

ocp_dims.solver_options.qp_solver      = 'FULL_CONDENSING_HPIPM';
ocp_dims.solver_options.hessian_approx = 'GAUSS_NEWTON';
ocp_dims.solver_options.integrator_type= 'IRK';
ocp_dims.solver_options.nlp_solver_type= 'SQP_RTI';

ocp_cost = AcadosOcpCost();
ocp_cost.cost_type_0 = 'EXTERNAL'; % For initial stage k=0
ocp_cost.cost_type   = 'EXTERNAL'; % For k=1...N-1
ocp_cost.cost_type_e = 'EXTERNAL'; % For terminal stage k=N
ocp_dims.cost = ocp_cost;
ocp_opts = acados_ocp_opts();

ocp_dims.solver_options.tf = param.T * param.N;
acados_solver = AcadosOcpSolver(ocp_dims, struct('print_level',2, 'qp_print_level', 2));

% MPC Loop
x_c = x0_real; % Current state of the "real" system
x0_ocp = [x_c; 0; 0; 0];             % Initial state for the OCP (physical + integral states)
X_init = repmat(x0_ocp, 1, param.N+1);
U_init = zeros(nu, param.N);
% Logging variables
time_log    = 0;
state_log   = x_c;
control_log = [];
u_prev_delta = 0; % Initialize previous steering angle
iter = 0;
tic;
while(norm(x_c - xs, 2) > 1e-3)
           x0_ocp = [x_c; 0; 0; 0]; % Reset integral states to 0 at each step
          acados_solver.set('constr_x0', x0_ocp);
          p_val = [xs; u_prev_delta];
          for k = 0:param.N
              acados_solver.set('p', p_val, k);
          end
          acados_solver.solve();
          status = acados_solver.get('status');
          if status ~= 0
              warning(['Acados solver returned status ' num2str(status) ' at iteration ' num2str(iter)]);
          end

          % Get the optimal control input
          u_ap = acados_solver.get('u', 0);
         % Apply control and simulate 
         x_c = shift_state(x_c, u_ap, param.T, param);
        % Log data and update for next iteration
         iter = iter + 1;
         control_log = [control_log, u_ap];
         state_log = [state_log, x_c];
        time_log = [time_log, time_log(end) + param.T];
        u_prev_delta = u_ap(2); % Update for the next iteration's cost function
       % Update initial guess for the next MPC step (shifting)
       X_opt = acados_solver.get('x');
       U_opt = acados_solver.get('u');
       X_init = [X_opt(:, 2:end), X_opt(:, end)];
       U_init = [U_opt(:, 2:end), U_opt(:, end)];
end

Hi :waving_hand:

Could you provide the output of solver.print('stat')?

Best, Katrin

Hello Katrin,

The print(‘stat’) is

iter	qp_status	qp_iter
0	0		0
1	3		9
Warning: Acados solver returned status 4 at iteration 0

And i think the initial guess is the problem maybe because when i give cold start for the my control inputs ‘U_init’ in the script then the solver runs infinite iteration but if I give warm start to the U_init it finds a solution and reach the goal pose even though the status says 4 and the solution is different from Casadi implementation and seems wrong. Moreover, in my Casadi implementation i am giving cold start to the U_init and it still finds the solution.