Simple C++ abstraction layer for quadratic programming solvers using Eigen.
Please install the library following one (and just one) method listed below.
You can easily the library with conda in a new conda environment with
conda create -n newenvname -c conda-forge qpsolvers-eigen
conda will automatically install all the supported dependencies.
To add qpsolvers-eigen to a pixi project, just run:
pixi add qpsolvers-eigen
If you just want to modify qpsolvers-eigen and run the tests again your modification,
the easiest way to do that is to use pixi, in particular you just need to run:
git clone https://github.com/ami-iit/qpsolvers-eigen.git
cd qpsolvers-eigen
pixi run test
If you want to use a package manager that does not provide qpsolvers-eigen packages, youc can do that
as qpsolvers-eigen is a fairly standard CMake project. To do that, first of all install either via a package
manager or manually the following depencies:
Required dependencies:
Optional dependencies:
- sharedlibpp (if not found an internal copy is used and installed)
- osqp-eigen (if not found the
osqpplugin is not compiled) - proxsuite (if not found the
proxqpplugin is not compiled)
Test dependencies:
Then follow the instructions
- Clone the repository
git clone https://github.com/ami-iit/qpsolvers-eigen.git - Build it
cd osqp-eigen mkdir build cd build cmake -GNinja -DCMAKE_INSTALL_PREFIX:PATH=<custom-folder> ../ ninja ninja install - Add the following environmental variable to ensure that
find_package(QpSolversEigen REQUIRED)is successful:QpSolversEigen_DIR=/path/where/you/installed/
qpsolvers-eigen provides native CMake support which allows the library to be easily used in CMake projects.
qpsolvers-eigen exports a CMake target called QpSolversEigen::QpSolversEigen which can be imported using the find_package CMake command and used by calling target_link_libraries as in the following example:
cmake_minimum_required(VERSION 3.16)
project(myproject)
find_package(QpSolversEigen REQUIRED)
add_executable(example example.cpp)
target_link_libraries(example QpSolversEigen::QpSolversEigen)A minimal example.cpp is:
#include <cstdlib>
#include <iostream>
#include <QpSolversEigen/QpSolversEigen.hpp>
#include <Eigen/Dense>
#include <Eigen/Sparse>
int main()
{
Eigen::SparseMatrix<double> H_s(2, 2);
H_s.insert(0, 0) = 4;
H_s.insert(0, 1) = 1;
H_s.insert(1, 0) = 1;
H_s.insert(1, 1) = 2;
Eigen::SparseMatrix<double> A_s(3, 2);
A_s.insert(0, 0) = 1;
A_s.insert(0, 1) = 1;
A_s.insert(1, 0) = 1;
A_s.insert(2, 1) = 1;
Eigen::Matrix<double, 2, 1> gradient;
gradient << 1, 1;
Eigen::Matrix<double, 3, 1> lowerBound;
lowerBound << 1, 0, 0;
Eigen::Matrix<double, 3, 1> upperBound;
upperBound << 1, 0.7, 0.7;
QpSolversEigen::Solver solver;
// Here you select the solver, possible options are:
// * osqp
// * proxqp
bool ok = solver.instantiateSolver("osqp");
if (!ok)
{
std::cerr << "Error in instantiating the solver" << std::endl;
return EXIT_FAILURE;
}
// Set osqp-specific parameters
if (solver.getSolverName() == "osqp")
{
solver.setBooleanParameter("verbose", true);
solver.setRealNumberParameter("alpha", 1.0);
// See https://github.com/robotology/osqp-eigen/pull/172
solver.setBooleanParameter("polish", true);
}
solver.data()->setNumberOfVariables(2);
solver.data()->setNumberOfInequalityConstraints(3);
ok = ok && solver.data()->setHessianMatrix(H_s);
ok = ok && solver.data()->setGradient(gradient);
ok = ok && solver.data()->setInequalityConstraintsMatrix(A_s);
ok = ok && solver.data()->setLowerBound(lowerBound);
ok = ok && solver.data()->setUpperBound(upperBound);
ok = ok && solver.initSolver();
if (!ok)
{
std::cerr << "Error in solver initialization" << std::endl;
return EXIT_FAILURE;
}
ok = ok && (solver.solveProblem() == QpSolversEigen::ErrorExitFlag::NoError);
if (!ok)
{
std::cerr << "Error in solving the problem" << std::endl;
return EXIT_FAILURE;
}
std::cerr << "Solution: " << solver.getSolution() << std::endl;
}For more examples, check the content of the ./examples folder in this repo.
If you are already using osqp-eigen and you want to understand how to migrate your code to qpsolvers-eigen, check the ./docs/migrate_from_osqp_eigen.md document.
If you are interested to other projects that provide abstraction over QP solvers, you can check also this other projects:
- Python's
qpsolvers: Python abstraction layer over QPs, quite complete and definitely an inspiration forqpsolvers-eigen. isri-aist/QpSolverCollection: Another C++ QP standalone abstraction layer, that supports more solvers w.r.t. toqpsolvers-eigen, but does not permit to easily set parameters to the underlying solvers.RobotLocomotion/drake: Drake is a collection of tools for analyzing the dynamics of our robots and building control systems for them, with a heavy emphasis on optimization-based design/analysis. As part of its extensive capabilities, it also provide abstraction over QP solvers. However, it is quite an heavyweight dependency, and does not support Windows.casadiCasADi is an open-source tool for nonlinear optimization and algorithmic differentiation. As part of its extensive capabilities, it also provide abstraction over QP solvers.roboptimRobOptim is a C++ Library for Numerical Optimization applied to Robotics. Similarly tocasadiorqpsolvers-eigen, it permits to write solvers as dynamically loadable plugins that can be loaded without modifying the core library. Mantainance of the library seems to be stopped around 2019.
All types of issues are welcome.
Any ABI or API incompatible change will result in a minor release bump.
Materials in this repository are distributed under the following license:
All software is licensed under the BSD 3-Clause License. See LICENSE file for details.