Closed stribor14 closed 2 years ago
Hi @stribor14 ,
Just a curiosity: do you have a Short, Self Contained and Compilable Example for your problem that you can share?
Sadly, I cannot share an example, but If I don't figure this out, I'll try to create a new one (which might also help me if I figure out how to produce this behavior)
Tomorrow I'll try running Matlab in gdb and see if there is an infinite loop occurring
Hi @traversaro ,
I think I found the problem, but I would like your thoughts on it. All matrices I give to update functions are class members variables (not pointers):
solver.updateHessianMatrix(P_);
solver.updateLinearConstraintsMatrix(A_);
solver.updateBounds(lo_bound_, up_bound_);
After debugging, I noticed that Matlab hangs when trying to clean up memory, so I removed P-value delete (intentionally introduced memory leak). Now everything works as intended.
My reasoning is that when I call updateSomeMatrix(Mat)
, osqp-eigen or osqp takes ownership of it and frees that memory before class destructor tries to free the same memory. (#16 )
P.S. This all sounds fishy because Valgrind gives 0 errors and memory leaks with c++ plant. I only have problem with Matlab. So far experience with osqp-eigen is great and straightforward (Kudos!)
Problem solved :)
In MPC class constructor, I had solver initialization (it should be noted that all of the matrices are initialized but still empty at this point):
solver.settings()->setVerbosity(false);
solver.settings()->setWarmStart(true);
solver.data()->setNumberOfVariables((N__ + 1) * n_x__ + N__ * n_u__);
solver.data()->setNumberOfConstraints(2 * (N__ + 1) * n_x__ + N__ * n_u__);
solver.data()->setHessianMatrix(P_);
solver.data()->setGradient(q_);
solver.data()->setLinearConstraintsMatrix(A_);
solver.data()->setUpperBound(up_bound_);
solver.data()->setLowerBound(lo_bound_);
solver.initSolver();
Then, in function call to get a new solution, I recalculate new matrices and update solver with them:
solver.updateHessianMatrix(P_);
solver.updateLinearConstraintsMatrix(A_);
solver.updateBounds(lo_bound_, up_bound_);
But, when this function is called first time, sparsity pattern changes and osqp-eigen has to create new solver. On all other subsequent calls, it only updates values in osqp (since later sparsity pattern doesn't change). This works without any problem with normal C++ application.
When writing Matlab S-function, this doesn't seem to work, so I tried to avoid creating new solver because of sparsity pattern change. I removed initialization from class constructor to function call after all of the matrices are calculated:
static bool first_pass = true;
if (first_pass)
{
first_pass = false;
solver.settings()->setVerbosity(false);
solver.settings()->setWarmStart(true);
solver.data()->setNumberOfVariables((N__ + 1) * n_x__ + N__ * n_u__);
solver.data()->setNumberOfConstraints(2 * (N__ + 1) * n_x__ + N__ * n_u__);
solver.data()->setHessianMatrix(P_);
solver.data()->setGradient(q_);
solver.data()->setLinearConstraintsMatrix(A_);
solver.data()->setUpperBound(up_bound_);
solver.data()->setLowerBound(lo_bound_);
solver.initSolver();
}
else {
solver.updateHessianMatrix(P_);
solver.updateLinearConstraintsMatrix(A_);
solver.updateBounds(lo_bound_, up_bound_);
}
I doubt that Matlab should crash because of that, maybe this is only a workaround for a bug, but it works.
Thanks @stribor14 ! Given that you found your solution, I think we can close the issue.
Hello.
I've hit a roadblock of sorts with this library. Usecase is following, I've implemented an MPC controller as a library and tested it with an ideal plant written in C++ (no noise, ideal delay, etc), and everything works fine. But for a more real use-case, we have a Simulink model so I've written s-function level 2 wrapper for the MPC controller. Every time I run the simulation, it works fine, but for some reason, Matlab hangs at the end of the simulation (or earlier if I hit stop). No error is given and the only way to recover is to kill the Matlab process and run everything from begging.
After a few hours of trying to find the source of the problem by commenting out everything and then block by block uncommenting and testing, I've narrowed it down to two lines:
If I comment out both of them, Matlab behaves normally (except, MPC is useless without them)
P.S. updating bounds does not result in freeze:
P.P.S. we have already implemented and tested similar things with osqp and Matlab, but now we wanted to use Eigen wrapper since a lot of our data is in Eigen classes