20 #include <boost/test/unit_test.hpp> 21 #include <boost/utility/binary.hpp> 23 #include <tsid/solvers/solver-HQP-factory.hxx> 27 #ifdef TSID_WITH_PROXSUITE 33 #ifdef TSID_QPMAD_FOUND 44 #define CHECK_LESS_THAN(A, B) \ 45 BOOST_CHECK_MESSAGE(A < B, #A << ": " << A << ">" << B) 46 #define REQUIRE_FINITE(A) BOOST_REQUIRE_MESSAGE(isFinite(A), #A << ": " << A) 48 BOOST_AUTO_TEST_SUITE(BOOST_TEST_MODULE)
183 #define PROFILE_EIQUADPROG "Eiquadprog" 184 #define PROFILE_EIQUADPROG_RT "Eiquadprog Real Time" 185 #define PROFILE_EIQUADPROG_FAST "Eiquadprog Fast" 186 #define PROFILE_PROXQP "Proxqp" 187 #define PROFILE_OSQP "OSQP" 188 #define PROFILE_QPMAD "QPMAD" 191 std::cout <<
"test_eiquadprog_classic_vs_rt_vs_fast\n";
192 using namespace tsid;
193 using namespace math;
196 const double EPS = 1e-8;
198 const unsigned int nTest = 100;
199 const unsigned int nsmooth = 50;
201 const unsigned int nTest = 100;
202 const unsigned int nsmooth = 5;
204 const unsigned int n = 60;
205 const unsigned int neq = 36;
206 const unsigned int nin = 40;
220 std::cout <<
"Gonna perform " << nTest <<
" tests (smooth " << nsmooth
221 <<
" times) with " << n <<
" variables, " << neq <<
" equalities, " 222 << nin <<
" inequalities\n";
225 SolverHQPBase* solver_rt = SolverHQPFactory::createNewSolver<n, neq, nin>(
226 SOLVER_HQP_EIQUADPROG_RT,
"eiquadprog_rt");
227 solver_rt->resize(n, neq, nin);
229 SolverHQPBase* solver_fast = SolverHQPFactory::createNewSolver(
231 solver_fast->resize(n, neq, nin);
235 solver->resize(n, neq, nin);
237 #ifdef TSID_WITH_PROXSUITE 239 SolverHQPFactory::createNewSolver(SOLVER_HQP_PROXQP,
"proxqp");
242 #ifdef TSID_WITH_OSQP 244 SolverHQPFactory::createNewSolver(SOLVER_HQP_OSQP,
"osqp");
247 #ifdef TSID_QPMAD_FOUND 249 SolverHQPFactory::createNewSolver(SOLVER_HQP_QPMAD,
"qpmad");
250 solver_qpmad->resize(n, neq, nin);
258 auto cost = std::make_shared<ConstraintEquality>(
"c1",
A1,
b1);
259 HQPData[1].push_back(
269 for (
unsigned int i = 0;
i <
nin;
i++) {
270 if (constrVal[
i] > A_ub[
i]) {
273 A_ub[i] = constrVal[i] + MARGIN_PERC * fabs(constrVal[i]);
275 if (constrVal[i] < A_lb[i]) {
278 A_lb[i] = constrVal[i] - MARGIN_PERC * fabs(constrVal[i]);
282 std::make_shared<ConstraintInequality>(
"in1",
A_in,
A_lb,
A_ub);
283 HQPData[0].push_back(
285 1.0, in_constraint));
289 auto eq_constraint = std::make_shared<ConstraintEquality>(
"eq1",
A_eq,
b_eq);
290 HQPData[0].push_back(
292 1.0, eq_constraint));
297 for (
unsigned int i = 0;
i <
nTest;
i++) {
298 gradientPerturbations[
i] =
300 hessianPerturbations[
i] =
305 for (
unsigned int i = 0;
i <
nTest;
i++) {
306 if (
true ||
i == 0) {
307 cost->matrix() += hessianPerturbations[
i];
308 cost->vector() += gradientPerturbations[
i];
312 const HQPOutput& output_fast = solver_fast->solve(HQPData);
316 const HQPOutput& output_rt = solver_rt->solve(HQPData);
320 const HQPOutput& output = solver->solve(HQPData);
323 #ifdef TSID_WITH_PROXSUITE 325 const HQPOutput& output_proxqp = solver_proxqp->solve(HQPData);
329 #ifdef TSID_WITH_OSQP 331 const HQPOutput& output_osqp = solver_osqp->solve(HQPData);
335 #ifdef TSID_QPMAD_FOUND 337 const HQPOutput& output_qpmad = solver_qpmad->solve(HQPData);
341 for (
unsigned int j = 0; j < nsmooth; j++) {
343 (void)solver_fast->solve(HQPData);
347 (void)solver_rt->solve(HQPData);
351 (void)solver->solve(HQPData);
354 #ifdef TSID_WITH_PROXSUITE 356 (void)solver_proxqp->solve(HQPData);
360 #ifdef TSID_WITH_OSQP 362 (void)solver_osqp->solve(HQPData);
366 #ifdef TSID_QPMAD_FOUND 368 (void)solver_qpmad->solve(HQPData);
374 (
double)output_rt.activeSet.size());
377 BOOST_REQUIRE_MESSAGE(
378 output.status == output_rt.status,
379 "Status " + SolverHQPBase::HQP_status_string[output.status] +
380 " Status RT " + SolverHQPBase::HQP_status_string[output_rt.status]);
381 BOOST_REQUIRE_MESSAGE(
382 output.status == output_fast.status,
383 "Status " + SolverHQPBase::HQP_status_string[output.status] +
385 SolverHQPBase::HQP_status_string[output_fast.status]);
387 #ifdef TSID_WITH_PROXSUITE 388 BOOST_REQUIRE_MESSAGE(
389 output.status == output_proxqp.status,
390 "Status " + SolverHQPBase::HQP_status_string[output.status] +
392 SolverHQPBase::HQP_status_string[output_proxqp.status]);
394 #ifdef TSID_WITH_OSQP 395 BOOST_REQUIRE_MESSAGE(
396 output.status == output_osqp.status,
397 "Status " + SolverHQPBase::HQP_status_string[output.status] +
399 SolverHQPBase::HQP_status_string[output_osqp.status]);
406 ((A_in * output.x).array() <= A_ub.array() +
EPS).all(),
407 "Lower bounds violated: " +
408 toString((A_ub - A_in * output.x).transpose()));
411 ((A_in * output.x).array() >= A_lb.array() -
EPS).all(),
412 "Upper bounds violated: " +
413 toString((A_in * output.x - A_lb).transpose()));
416 output.x.isApprox(output_rt.x, EPS),
420 "\nDiff RT: " +
toString((output.x - output_rt.x).norm()));
423 output_rt.x.isApprox(output_fast.x, EPS),
427 "\nDiff FAST: " +
toString((output_rt.x - output_fast.x).norm()));
429 #ifdef TSID_WITH_PROXSUITE 431 output.x.isApprox(output_proxqp.x, 1e-4),
432 "\nDiff PROXQP: " +
toString((output.x - output_proxqp.x).norm()));
434 #ifdef TSID_WITH_OSQP 436 output.x.isApprox(output_osqp.x, 1e-4),
437 "\nDiff OSQP: " +
toString((output.x - output_osqp.x).norm()));
440 #ifdef TSID_QPMAD_FOUND 442 output.x.isApprox(output_qpmad.x, EPS),
443 "\nDiff QPMAD: " +
toString((output.x - output_qpmad.x).norm()));
448 std::cout <<
"\n### TEST FINISHED ###\n";
456 #ifdef TSID_WITH_PROXSUITE 460 #ifdef TSID_WITH_OSQP 465 BOOST_AUTO_TEST_SUITE_END()
#define PROFILE_EIQUADPROG_FAST
Stopwatch & getProfiler()
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > Matrix
std::string toString(const T &v)
void store(std::string name, const double &value)
class TSID_DLLAPI SolverHQPBase
int GRADIENT_PERTURBATION_VARIANCE
void stop(std::string perf_name)
Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > Vector
void svdSolveWithDamping(ConstRefMatrix A, ConstRefVector b, RefVector sol, double damping=0.0)
#define PROFILE_EIQUADPROG_RT
void report_all(int precision=2, std::ostream &output=std::cout)
int HESSIAN_PERTURBATION_VARIANCE
aligned_pair< T1, T2 > make_pair(const T1 &t1, const T2 &t2)
SOLVER_HQP_EIQUADPROG_FAST
list gradientPerturbations
#define CHECK_LESS_THAN(A, B)
BOOST_AUTO_TEST_CASE(test_eiquadprog_classic_vs_rt_vs_fast_vs_proxqp)
#define PROFILE_EIQUADPROG
void start(std::string perf_name)
Statistics & getStatistics()
list hessianPerturbations
void report_all(int precision=2, std::ostream &output=std::cout)