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
osqp
plugin is not compiled) - proxsuite (if not found the
proxqp
plugin 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()->setNumberOfConstraints(3);
ok = ok && solver.data()->setHessianMatrix(H_s);
ok = ok && solver.data()->setGradient(gradient);
ok = ok && solver.data()->setLinearConstraintsMatrix(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.casadi
CasADi is an open-source tool for nonlinear optimization and algorithmic differentiation. As part of its extensive capabilities, it also provide abstraction over QP solvers.roboptim
RobOptim is a C++ Library for Numerical Optimization applied to Robotics. Similarly tocasadi
orqpsolvers-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.