robotology / osqp-eigen

Simple Eigen-C++ wrapper for OSQP library
https://robotology.github.io/osqp-eigen/
BSD 3-Clause "New" or "Revised" License
395 stars 118 forks source link

ERROR in LDL_factor: Error in KKT matrix LDL factorization when computing the nonzero elements. The problem seems to be non-convex #138

Closed mtncgj123 closed 1 year ago

mtncgj123 commented 1 year ago

Hi, I'm new to osqp-eigen, I'm trying to use osqp-eigen to solve a real-time trajectory optimization problem under ROS environment, I create and initiate the solver in the callback function, the solver solved the problem at first time, but at second time, there always comes the error "ERROR in LDL_factor: Error in KKT matrix LDL factorization when computing the nonzero elements. The problem seems to be non-convex". is there anyone can help me with this or provide a template code for using osqp-eigen in callback funciton?

traversaro commented 1 year ago

What is the difference between the first time you call the solver (when it is working) and the second time? In general It Is much easier for people to help you if you share more details of how you build you problem, or even better if you share your source code.

mtncgj123 commented 1 year ago

What is the difference between the first time you call the solver (when it is working) and the second time? In general It Is much easier for people to help you if you share more details of how you build you problem, or even better if you share your source code.

thanks for your quick reply, I share the related source code here. I define a OSQP solver as a global parameter, and define a ROS server node, which will receive the neccessary data from a client node and then call the OSQP solver to solve the problem, and it turns out my code works for the first call, and failed for the second. I guess the difference between the first and the latter call is the solver memory. After the first call, I used solver.clearSolver() to delete the memory, but dont know weather it works. (I also tried initiate the solver in the main function and use the solver.update~ to update the related matrix, but the outcome solution is strange at first place). I think the crux of my problem is how to repeat using a OSQP solver. Thank you~

` Eigen::VectorXd QPSolver(MatrixXd H, MatrixXd f, MatrixXd A, MatrixXd b, MatrixXd Aeq, MatrixXd beq) {

    int numOfVar = H.cols();
    int numOfCons = A.rows() + Aeq.rows();

    solver.settings()->setWarmStart(true);
    solver.settings()->setVerbosity(false);
    solver.data()->setNumberOfVariables(numOfVar);
    solver.data()->setNumberOfConstraints(numOfCons);

    Eigen::SparseMatrix<double> hessian;
    Eigen::VectorXd gradient;
    Eigen::SparseMatrix<double> linearMatrix;
    Eigen::VectorXd lowerBound;
    Eigen::VectorXd upperBound;

    hessian = H.sparseView();

    gradient = f;

    MatrixXd linearMatrix_modi=MatrixXd::Zero(Aeq.rows() + A.rows(), A.cols());
    linearMatrix_modi.block(0, 0, Aeq.rows(), Aeq.cols()) = Aeq;
    linearMatrix_modi.block(Aeq.rows(), 0, A.rows(), A.cols()) = A;
    linearMatrix = linearMatrix_modi.sparseView();

    MatrixXd upperBound_modi=MatrixXd::Zero(beq.rows() + b.rows(), 1);
    upperBound_modi.block(0, 0, beq.rows(), beq.cols()) = beq;
    upperBound_modi.block(beq.rows(), 0, b.rows(), b.cols()) = b;
    upperBound = upperBound_modi;

    MatrixXd lowerBound_modi = MatrixXd::Ones(beq.rows() + b.rows(), 1) * (-OsqpEigen::INFTY);
    lowerBound_modi.block(0, 0, beq.rows(), beq.cols()) = beq;
    lowerBound = lowerBound_modi;

    solver.data()->setHessianMatrix(hessian);
    solver.data()->setGradient(gradient);
    solver.data()->setLinearConstraintsMatrix(linearMatrix);
    solver.data()->setLowerBound(lowerBound);
    solver.data()->setUpperBound(upperBound);

    solver.initSolver();

    solver.solveProblem();

    Eigen::VectorXd QPSolution;
    QPSolution = solver.getSolution();

    solver.clearSolver();

    return QPSolution;
}

bool Callback(ros_learning::QP_Solver::Request &req,ros_learning::QP_Solver::Response &res) {

    int n_order=req.n_order;
    int n_seg=req.n_seg;
    int side_index=req.side_index;
    vector<double> waypoints=req.waypoints;
    vector<double> corridor=req.corridor;
    vector<double> ts=req.ts;
    double v_max=req.v_max;
    double a_max=req.a_max;
    double lambda_goal=req.lambda_goal;

    MatrixXd waypoints_eigen=Eigen::Map<MatrixXd>(waypoints.data(),2,2);
    MatrixXd corridor_eigen=Eigen::Map<MatrixXd>(corridor.data(),corridor.size()/2,2);

    vector<double> poly_coef=spatiotemporal_trajectory(waypoints_eigen, corridor_eigen, ts, n_seg, n_order,  v_max, a_max,  side_index, lambda_goal);

    res.poly_coef = poly_coef;

    return true;
}

int main(int argc, char **argv) {

ros::init(argc, argv, "Trajectory_generation");

ros::NodeHandle n;

ros::Rate loop_rate(10);

Spatiotemporal_trajectory Spa_traj;

ros::ServiceServer traj_service = n.advertiseService("/QP_Solver_test", &Spatiotemporal_trajectory::Callback,&Spa_traj);

ros::spin();

return 0;

}

`