Opened 15 months ago

Last modified 7 months ago

#83 new user support

Hotstart bug when solving QPs in a looped function

Reported by: lrjcool Owned by: ferreau
Priority: VERY HIGH Milestone:
Component: C++ core Version: 3.2.1
Keywords: Cc:

Description

Hey guys. I am using qpOASES 3.2.1 and I have installed it properly. I have been trying to solve a series of QPs by calling the hotstart in a looped function (for some reason I have to solve the QPs in a looped function instead of the main function, imagine an embedded controller). This is what my code looks like (slightly modified from example1):

#include <qpOASES.hpp>

void solve_qp(int i);

USING_NAMESPACE_QPOASES

int main( )
{
	for (int i = 0; i < 2; i++)
		solve_qp(i);
	return 0;
}

void solve_qp(int i)
{ 
	static QProblem mysolver(2, 1);
	if (i == 0) //init soliver in the first loop
	{
		real_t H[2 * 2] = { 1.0, 0.0, 0.0, 0.5 };
		real_t A[1 * 2] = { 1.0, 1.0 };
		real_t g[2] = { 1.5, 1.0 };
		real_t lb[2] = { 0.5, -2.0 };
		real_t ub[2] = { 5.0, 2.0 };
		real_t lbA[1] = { -1.0 };
		real_t ubA[1] = { 2.0 };
		/* Solve first QP. */
		int_t nWSR = 10;
		mysolver.init(H, g, A, lb, ub, lbA, ubA, nWSR);
		real_t xOpt[2];
		mysolver.getPrimalSolution(xOpt);
	}
	else // use hotstart from the second loop
	{
		real_t g_new[2] = { 1.0, 1.5 };
		real_t lb_new[2] = { 0.0, -1.0 };
		real_t ub_new[2] = { 5.0, -0.5 };
		real_t lbA_new[1] = { -2.0 };
		real_t ubA_new[1] = { 1.0 };
		int_t nWSR = 10;
		mysolver.hotstart(g_new, lb_new, ub_new, lbA_new, ubA_new, nWSR);
		real_t xOpt[2];
		mysolver.getPrimalSolution(xOpt);
	}
}

The key part is that I created a static QProblem object in the loop function, trying to store its information after the first loop is over. But I get the error "Premature homotopy termination because QP is infeasible" for the hotstart in the second loop. Any idea to solve this issue? Is it possible to use hotstart in a looped function? Thanks very much!

Change History (3)

comment:1 Changed 15 months ago by potschka

Hi lrjcool,

I cannot reproduce your report with the current svn/trunk version of qpOASES:

potschka@alf:~/svn/qpOASES$ cat examples/bug_83.cpp 
 #include <qpOASES.hpp>

 void solve_qp(int i);

 USING_NAMESPACE_QPOASES

 int main( )
 {
         for (int i = 0; i < 2; i++)
                 solve_qp(i);
         return 0;
 }

 void solve_qp(int i)
 {
         static QProblem mysolver(2, 1);
         if (i == 0) //init soliver in the first loop
         {
                 real_t H[2 * 2] = { 1.0, 0.0, 0.0, 0.5 };
                 real_t A[1 * 2] = { 1.0, 1.0 };
                 real_t g[2] = { 1.5, 1.0 };
                 real_t lb[2] = { 0.5, -2.0 };
                 real_t ub[2] = { 5.0, 2.0 };
                 real_t lbA[1] = { -1.0 };
                 real_t ubA[1] = { 2.0 };
                 /* Solve first QP. */
                 int_t nWSR = 10;
                 mysolver.init(H, g, A, lb, ub, lbA, ubA, nWSR);
                 real_t xOpt[2];
                 mysolver.getPrimalSolution(xOpt);
         }
         else // use hotstart from the second loop
         {
                 real_t g_new[2] = { 1.0, 1.5 };
                 real_t lb_new[2] = { 0.0, -1.0 };
                 real_t ub_new[2] = { 5.0, -0.5 };
                 real_t lbA_new[1] = { -2.0 };
                 real_t ubA_new[1] = { 1.0 };
                 int_t nWSR = 10;
                 mysolver.hotstart(g_new, lb_new, ub_new, lbA_new, ubA_new, nWSR);
                 real_t xOpt[2];
                 mysolver.getPrimalSolution(xOpt);
         }
 }
potschka@alf:~/svn/qpOASES$ svn diff
Index: examples/Makefile
===================================================================
--- examples/Makefile   (revision 261)
+++ examples/Makefile   (working copy)
@@ -48,6 +48,7 @@
        ${BINDIR}/example4${EXE} \
        ${BINDIR}/example5${EXE} \
        ${BINDIR}/exampleLP${EXE} \
+       ${BINDIR}/bug_83${EXE} \
        ${BINDIR}/qrecipe${EXE} \
        ${BINDIR}/qrecipeSchur${EXE}
 
potschka@alf:~/svn/qpOASES$ bin/bug_83 


####################   qpOASES  --  QP NO.   1   #####################

    Iter   |    StepLength    |       Info       |   nFX   |   nAC    
 ----------+------------------+------------------+---------+--------- 
       0   |   5.833333e-01   |   ADD CON    0   |     1   |     1   
       1   |   1.000000e+00   |    QP SOLVED     |     1   |     1   


####################   qpOASES  --  QP NO.   2   #####################

    Iter   |    StepLength    |       Info       |   nFX   |   nAC    
 ----------+------------------+------------------+---------+--------- 
       0   |   1.666667e-01   |   ADD BND    1   |     2   |     0   
       1   |   1.000000e+00   |    QP SOLVED     |     2   |     0   

This was on Ubuntu 16.04. What's your machine setup?

comment:2 Changed 11 months ago by oscarjgv24

I can confirm that this is happening on my qpOASES version as well.

I have Ubuntu 18.04, and I simply compiled the example1a.cpp program with the "hotstart" lane in a loop like this.

/* Solve second QP. */

nWSR = 10;
for(int i=0;i<10;i++){
example.hotstart( H_new,g_new,A_new,lb_new,ub_new,lbA_new,ubA_new, nWSR,0 );
}

And it gives me the output,

################### qpOASES -- QP NO. 3 #####################

Iter | StepLength? | Info | nFX | nAC

----------+------------------+------------------+---------+---------

0 | 1.000000e+00 | QP SOLVED | 1 | 1

ERROR: Maximum number of working set recalculations performed
->ERROR: Unable to perform homotopy as previous QP is not solved

->ERROR: Unable to perform homotopy as previous QP is not solved

->ERROR: Unable to perform homotopy as previous QP is not solved

->ERROR: Unable to perform homotopy as previous QP is not solved

->ERROR: Unable to perform homotopy as previous QP is not solved

->ERROR: Unable to perform homotopy as previous QP is not solved

->ERROR: Unable to perform homotopy as previous QP is not solved

Anyone knows what is the problem with this?

Regards,
Oscar

comment:3 Changed 7 months ago by bowzheng

Hi guys,

I ran into the problem as well when putting QP hoststart in a loop. I can reproduce the errors @oscarjgv24 has mentioned. The code is as follows.

#include "qpOASES.hpp"

void solve_qp(int i);

USING_NAMESPACE_QPOASES

int main( )
{
  for (int i = 0; i < 2; i++)
    solve_qp(i);
  return 0;
}

void solve_qp(int i)
{ 
  static QProblem mysolver(2, 1);
  if (i == 0) //init soliver in the first loop
  {
    real_t H[2 * 2] = { 1.0, 0.0, 0.0, 0.5 };
    real_t A[1 * 2] = { 1.0, 1.0 };
    real_t g[2] = { 1.5, 1.0 };
    real_t lb[2] = { 0.5, -2.0 };
    real_t ub[2] = { 5.0, 2.0 };
    real_t lbA[1] = { -1.0 };
    real_t ubA[1] = { 2.0 };
    /* Solve first QP. */
    int_t nWSR = 10;
    mysolver.init(H, g, A, lb, ub, lbA, ubA, nWSR);
    real_t xOpt[2];
    mysolver.getPrimalSolution(xOpt);
  }
  else // use hotstart from the second loop
  {
    real_t g_new[2] = { 1.0, 1.5 };
    real_t lb_new[2] = { 0.0, -1.0 };
    real_t ub_new[2] = { 5.0, -0.5 };
    real_t lbA_new[1] = { -2.0 };
    real_t ubA_new[1] = { 1.0 };
    int_t nWSR = 10;
    for (int i = 0; i < 5; i++) { // we add loop here
      mysolver.hotstart(g_new, lb_new, ub_new, lbA_new, ubA_new, nWSR);
      real_t xOpt[2];
      mysolver.getPrimalSolution(xOpt);
    }
  }
}

Machine: Ubuntu 16.04
Code Version: 3.2.1
Complier: bazel 0.18.1

The output is as follows.

####################   qpOASES  --  QP NO.   1   #####################

    Iter   |    StepLength    |       Info       |   nFX   |   nAC
 ----------+------------------+------------------+---------+---------
       0   |   5.833333e-01   |   ADD CON    0   |     1   |     1
       1   |   1.000000e+00   |    QP SOLVED     |     1   |     1


####################   qpOASES  --  QP NO.   2   #####################

    Iter   |    StepLength    |       Info       |   nFX   |   nAC
 ----------+------------------+------------------+---------+---------
       0   |   1.250000e-01   |   ADD BND    1   |     2   |     0
       1   |   6.800000e-01   |   REM BND    0   |     1   |     0
       2   |   1.000000e+00   |    QP SOLVED     |     1   |     0


####################   qpOASES  --  QP NO.   3   #####################

    Iter   |    StepLength    |       Info       |   nFX   |   nAC
 ----------+------------------+------------------+---------+---------
       0   |   1.000000e+00   |    QP SOLVED     |     1   |     0
ERROR:  Maximum number of working set recalculations performed
->ERROR:  Unable to perform homotopy as previous QP is not solved
  ->ERROR:  Unable to perform homotopy as previous QP is not solved
    ->ERROR:  Unable to perform homotopy as previous QP is not solved
      ->ERROR:  Unable to perform homotopy as previous QP is not solved

It would be great if we can get helped with this issue.

Best,
Bryan

Note: See TracTickets for help on using tickets.