Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Structure specified does not correspond to what the interface can handle #19

Open
ImW1ll opened this issue Sep 10, 2024 · 3 comments
Open

Comments

@ImW1ll
Copy link

ImW1ll commented Sep 10, 2024

Hi!
I'm a student in Mechanical Engineer writing a sim for the Formula Student competition and we wanted to try out FatRop for our solver as ipopt as been a bit too slow for our liking lately. We think we have set up everything nicely according to some examples, although the ones using collocation are rare, however we have hit this wall today and have no clue what it means :
Error using casadi.Opti/solve (line 562) Error in Opti::solve [OptiNode] at .../casadi/core/optistack.cpp:165: .../casadi/core/function_internal.cpp:147: Error calling FatropInterface::init for 'solver': .../casadi/interfaces/fatrop/fatrop_interface.cpp:477: Assertion "errors.empty() && (A_ + total).nnz() == total.nnz()" failed: HPIPM: specified structure of A does not correspond to what the interface can handle. Structure is: N 2690, nx [10, 10, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 Error in OptiSetupCar (line 218) sol = opti.solve(); Error in CarOptimization (line 19) OptiSetupCar

The solver works perfectly fine with ipopt... I know this is maybe not the best place to note for such thing, but could it be possible to have an hint on where to find as we really want to evaluate FatRop's potential for our sim!

Thank you
William Chayer

@LouisThomasRoy
Copy link

I am working with William on this project. For all the constraints of our problem, CasADi throws this error: CasADi - 2024-09-11 11:56:38 WARNING("Structure detection error on row 10800. Constraint found depending on a state of the previous interval.") [.../casadi/interfaces/fatrop/fatrop_interface.cpp:86]

@wdecre
Copy link
Member

wdecre commented Sep 11, 2024

Can you verify that you did not include stagewise constraints depending on variables from different intervals?

Fatrop requires the problem to be written in a form with

  • an explicit integrator, i.e., $x_{k+1}=f_k(u_k, x_k)$,
  • stagewise constraints, i.e., $h_k(u_k, x_k)=0$ (and similar for inequality constraints).

You can find more information about the problem structure in the Fatrop paper.

Using an implicit integrator scheme with dynamics of this form $g_k(u_k,x_{k+1}, x_k)=0$, is not natively supported. In a future version we are looking to include efficient support for it.

However, it is possible to rewrite the implicit integrator in the format supported by Fatrop by introducing auxiliary controls $z_k$. Your controls then become $[u_k, z_k]$.

Concretely:

  • your dynamics ($f$ function) becomes: $x_{k+1}=z_k$ (which is in the form of an explicit integrator, cf. above),
  • your stagewise constraints ($h$ function) becomes: $g_k([u_k, z_k], x_k)=0$.

By introducing these extra controls your stagewise constraints only depend on variables of the corresponding stage, as required. Note that this is certainly not the most efficient way to implement implicit integrators, but in many examples we still see a significant speed-up w.r.t. Ipopt.

If you have not used it yet, there is a debugger functionality to inspect the structure. You can find more information about it in the instruction video.

@ImW1ll
Copy link
Author

ImW1ll commented Sep 30, 2024

@wdecre Thanks for the answer.
I'm only getting started with Optimization and collocation, solving this problem looks quite complex.
Do you have any example of direct collocation solving with FatRop I could maybe take a look at to better understand my issue?
We have looked at the debug output, it looks like so :
Screenshot 2024-09-30 at 10 22 16 AM

This is our current loop for collocation:

for k = 0:N-1
    %% Gap closing and collocation constraints
    % Collocation constraints
    Z = [Xk(:,k+1) Xkj(:,OPT_d*k+(1:OPT_d))]; % Concatenate states
    %-Dynamics
    %%-calculate derivatives of the approximating polynomial at the collocation points
    dPi = Z*C; 
    %%-calculate derivatives of the system at the collocation points
    [dXkj, Qk] = f_dyn(Xkj(:,OPT_d*k+(1:OPT_d)), Uk(:,k+1)+kron(duk(:,k+1),tau), Yk(:,k+1)+kron(dyk(:,k+1),tau), pv_col(:,OPT_d*k+(1:OPT_d)));
    %-State of approximating polynomial the end of the colocation interval
    Xk_end = Z*D;
    gck = [gck(:); dsk(k+1)*dXkj(:) - dPi(:); Xk_end-Xk(:,k+2)]; % Add collocation constraints

    opti.subject_to(dsk(k+1)*dXkj(:) == dPi(:));
    opti.subject_to(Xk_end == Xk(:,k+2));

    opti.subject_to(h_lb <= ghk(:,k+1) <= h_ub); % path constraints
    opti.subject_to(duk_lb <= gduk(:,k+1) <= duk_ub); % rate of inputs
 
    %% Path constraints
    if k == 0
        opti.subject_to(Xk(:,1) == max(x_min, Xi./x_s)); % Initial values
    end

    if k == N-1
        opti.subject_to(Xk(:,end) == max(x_min, Xf./x_s)); % Final values
    end


    opti.subject_to(x_min(:) <= Xk(:,k+1) <= x_max(:)) % states
    opti.subject_to(u_min(:) <= Uk(:,k+1) <= u_max(:)) % inputs
    opti.subject_to(y_min(:) <= Yk(:,k+1) <= y_max(:)) % aux variables
    opti.subject_to(x_min(:) <= Xkj(:,i) <= x_max(:)) % helper states
    i = i+1;
    opti.subject_to(x_min(:) <= Xkj(:,i) <= x_max(:)) % helper states
    i = i+1;
    opti.subject_to(x_min(:) <= Xkj(:,i) <= x_max(:)) % helper states
    i = i+1;
    %% Objective function
    % Integrate quadrature function
    J = J + Qk*B*dsk(k+1)/J_s + sumsqr(rdu.*duk(:,k+1)) + sumsqr(rdy.*dyk(:,k+1)) + sumsqr(rdu2.*duk2(:,k+1)) + sumsqr(rdy2.*dyk2(:,k+1)) + sumsqr(ru*Uk(2,k+1));
    % Collect contribution to time of each interval
    dt_opt{k+1} = Qk*B*dsk(k+1); 
end

Thank you again

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants