Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[config] Allow external qpOASES dependency #22

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions .github/workflows/ci-conda.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ on:

jobs:
build-with-conda-and-test:
name: "[conda:${{ matrix.os }}:py${{ matrix.python_version }}]"
name: "[conda:${{ matrix.os }}:py${{ matrix.python_version }}:${{ matrix.qp_solver }}]"
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04, macos-13, macos-14, windows-2022]
python_version: ["3.13"]
build_type: ["Release"]
qp_solver: ["qpOases", "proxQP"]

steps:
- name: Install miniconda [Linux & macOS & Windows]
Expand Down Expand Up @@ -57,7 +58,28 @@ jobs:
- name: Install dependencies [Conda]
shell: bash -l {0}
run: |
conda install eigen libboost-headers pybind11 cxxopts
conda install eigen libboost-headers pybind11 cxxopts

- name: Install QP solver dependencies [Conda / proxQP]
if: contains(matrix.qp_solver, 'proxQP')
shell: bash -l {0}
run: |
conda install proxsuite
echo "CMAKE_OPTS_QPSOLVER=-DSOFTROBOTSINVERSE_ENABLE_PROXQP=ON -DSOFTROBOTSINVERSE_ENABLE_QPOASES=OFF" >> "$GITHUB_ENV"

- name: Install QP solver dependencies [Conda / qpOases & not osx-arm64]
if: contains(matrix.qp_solver, 'qpOases') && !contains(matrix.os, 'macos-14')
shell: bash -l {0}
run: |
conda install qpoases
echo "CMAKE_OPTS_QPSOLVER=-DSOFTROBOTSINVERSE_ENABLE_PROXQP=OFF -DSOFTROBOTSINVERSE_ENABLE_QPOASES=ON" >> "$GITHUB_ENV"

# Use embedded qpOases version as its conda package for python>3.10 under osx-arm64 platform is not supported anymore
- name: Install QP solver dependencies [Conda / qpOases & osx-arm64]
if: contains(matrix.qp_solver, 'qpOases') && contains(matrix.os, 'macos-14')
shell: bash -l {0}
run: |
echo "CMAKE_OPTS_QPSOLVER=-DSOFTROBOTSINVERSE_ENABLE_PROXQP=OFF -DSOFTROBOTSINVERSE_ENABLE_QPOASES=ON" >> "$GITHUB_ENV"

- name: Print environment [Conda]
shell: bash -l {0}
Expand All @@ -72,7 +94,7 @@ jobs:
run: |
mkdir build
cd build
cmake .. -GNinja \
cmake .. -GNinja $CMAKE_OPTS_QPSOLVER \
-DCMAKE_INSTALL_PREFIX=${CONDA_PREFIX} \
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \
-DPython_EXECUTABLE:PATH=${CONDA_PREFIX}/bin/python \
Expand All @@ -84,7 +106,7 @@ jobs:
run: |
mkdir build
cd build
cmake .. -G"Visual Studio 17 2022" -T "v143" \
cmake .. -G"Visual Studio 17 2022" -T "v143" $CMAKE_OPTS_QPSOLVER \
-DCMAKE_GENERATOR_PLATFORM=x64 \
-DCMAKE_INSTALL_PREFIX=${CONDA_PREFIX} \
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \
Expand Down
58 changes: 44 additions & 14 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ set(HEADER_FILES
${SRC_DIR}/component/solver/modules/NLCPSolver.h
${SRC_DIR}/component/solver/modules/QPInverseProblem.h
${SRC_DIR}/component/solver/modules/QPInverseProblemImpl.h
${SRC_DIR}/component/solver/modules/QPInverseProblemQPOases.h
${SRC_DIR}/component/solver/modules/QPMechanicalAccumulateConstraint.h
${SRC_DIR}/component/solver/modules/QPMechanicalSetConstraint.h
)
Expand Down Expand Up @@ -119,11 +118,9 @@ set(SOURCE_FILES
${SRC_DIR}/component/solver/QPInverseProblemSolver.cpp
${SRC_DIR}/component/solver/modules/ContactHandler.cpp
${SRC_DIR}/component/solver/modules/ConstraintHandler.cpp
${SRC_DIR}/component/solver/modules/LCPQPSolver.cpp
${SRC_DIR}/component/solver/modules/NLCPSolver.cpp
${SRC_DIR}/component/solver/modules/QPInverseProblem.cpp
${SRC_DIR}/component/solver/modules/QPInverseProblemImpl.cpp
${SRC_DIR}/component/solver/modules/QPInverseProblemQPOases.cpp
${SRC_DIR}/component/solver/modules/QPMechanicalAccumulateConstraint.cpp
${SRC_DIR}/component/solver/modules/QPMechanicalSetConstraint.cpp
)
Expand All @@ -141,24 +138,33 @@ endif()
set(DOC_FILES README.md)
file(GLOB_RECURSE EXAMPLE_FILES examples "*.pyscn" "*.py" "*.md" "*.psl" "*.pslx" "*.scn" "*.xml")

set(OASES_LIBRARY_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/extlibs/qpOASES-3.2.0/")
add_subdirectory(${OASES_LIBRARY_DIRECTORY} extlibs/libqpOASES)
find_package(libqpOASES REQUIRED)
message("libqpOASES_INCLUDE_DIRS = ${libqpOASES_INCLUDE_DIRS}")
include_directories(${libqpOASES_INCLUDE_DIRS})
set(QPOASES_INCLUDE_DIR ${libqpOASES_INCLUDE_DIRS} CACHE INTERNAL "")
sofa_install_libraries(PATHS ${libqpOASES_LIBRARY})

option(SOFTROBOTSINVERSE_ENABLE_PROXQP "Build proxQP wrapper for inverse problems" OFF)
if(SOFTROBOTSINVERSE_ENABLE_PROXQP)
find_package(proxsuite REQUIRED)
message("Sofa.SoftRobots.Inverse: proxsuite FOUND. Will build with proxsuite support.")
option(SOFTROBOTSINVERSE_ENABLE_QPOASES "Build qpOASES wrapper for inverse problems" ON)

if(NOT SOFTROBOTSINVERSE_ENABLE_PROXQP AND NOT SOFTROBOTSINVERSE_ENABLE_QPOASES)
message(FATAL_ERROR "Both proxQP and qpOASES solvers are disabled. Please enable at least one solver.")
endif()

if(SOFTROBOTSINVERSE_ENABLE_PROXQP)
list(APPEND HEADER_FILES
${SRC_DIR}/component/solver/modules/QPInverseProblemProxQP.h
${SRC_DIR}/component/solver/modules/LCPQPSolverProxQP.h
)
list(APPEND SOURCE_FILES
${SRC_DIR}/component/solver/modules/QPInverseProblemProxQP.cpp
${SRC_DIR}/component/solver/modules/LCPQPSolverProxQP.cpp
)
endif()

if(SOFTROBOTSINVERSE_ENABLE_QPOASES)
list(APPEND HEADER_FILES
${SRC_DIR}/component/solver/modules/QPInverseProblemQPOases.h
${SRC_DIR}/component/solver/modules/LCPQPSolverQPOases.h
)
list(APPEND SOURCE_FILES
${SRC_DIR}/component/solver/modules/QPInverseProblemQPOases.cpp
${SRC_DIR}/component/solver/modules/LCPQPSolverQPOases.cpp
)
endif()

Expand All @@ -169,7 +175,11 @@ else()
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${DOC_FILES} ${EXAMPLE_FILES} "${SRC_DIR}/component/config.h.in")
endif()


if(SOFTROBOTSINVERSE_ENABLE_PROXQP)
find_package(proxsuite REQUIRED)
message("Sofa.SoftRobots.Inverse: proxsuite FOUND. Will build with proxsuite support.")

target_link_libraries(${PROJECT_NAME} PUBLIC proxsuite::proxsuite)
# XXX proxsuite vectorization support via SIMDE and activated by the compilation options '-march=native' or `-mavx2 -mavx512f`
# This will not be available if proxsuite has been fetched
Expand All @@ -178,11 +188,31 @@ if(SOFTROBOTSINVERSE_ENABLE_PROXQP)
target_compile_definitions(${PROJECT_NAME} PUBLIC SOFTROBOTSINVERSE_ENABLE_PROXQP)
endif()

if(SOFTROBOTSINVERSE_ENABLE_QPOASES)
find_package(qpOASES QUIET)

if(qpOASES_FOUND)
message("Sofa.SoftRobots.Inverse: external qpOASES FOUND. Will build with qpOASES support.")
include_directories(${qpOASES_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} PUBLIC ${qpOASES_LIBRARIES})
set(QPOASES_INCLUDE_DIR ${qpOASES_INCLUDE_DIRS} CACHE INTERNAL "")
else()
message("External package qpOASES not found, using embedded version for qpOASES support")
set(OASES_LIBRARY_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/extlibs/qpOASES-3.2.0/")
add_subdirectory(${OASES_LIBRARY_DIRECTORY} extlibs/libqpOASES)
find_package(libqpOASES REQUIRED)
include_directories(${libqpOASES_INCLUDE_DIRS})
set(QPOASES_INCLUDE_DIR ${libqpOASES_INCLUDE_DIRS} CACHE INTERNAL "")
sofa_install_libraries(PATHS ${libqpOASES_LIBRARY})
target_link_libraries(${PROJECT_NAME} PUBLIC ${libqpOASES_LIBRARY})
endif()
target_compile_definitions(${PROJECT_NAME} PUBLIC SOFTROBOTSINVERSE_ENABLE_QPOASES)
endif()

target_link_libraries(${PROJECT_NAME} PUBLIC
SoftRobots
Sofa.Component.Constraint.Lagrangian.Solver
Sofa.Component.Collision.Response.Contact)
target_link_libraries(${PROJECT_NAME} PUBLIC ${libqpOASES_LIBRARY})

sofa_find_package(Sofa.Component.SolidMechanics.FEM.Elastic)
target_link_libraries(${PROJECT_NAME} PUBLIC Sofa.Component.SolidMechanics.FEM.Elastic)
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
23 changes: 23 additions & 0 deletions cmake/Modules/FindqpOASES.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Find the qpOASES includes and libraries.
# The following variables are set if qpOASES is found. If qpOASES is not
# found, qpOASES_FOUND is set to false.
# qpOASES_FOUND - True when the qpOASES include directory is found.
# qpOASES_INCLUDE_DIRS - the path to where the qpOASES include files are.
# qpOASES_LIBRARIES - The libraries to link against qpOASES

include(FindPackageHandleStandardArgs)

find_path(qpOASES_INCLUDE_DIR
NAMES qpOASES.hpp
PATH_SUFFIXES include
)

find_library(qpOASES_LIBRARY
NAMES qpOASES
PATH_SUFFIXES lib
)

set(qpOASES_INCLUDE_DIRS ${qpOASES_INCLUDE_DIR})
set(qpOASES_LIBRARIES ${qpOASES_LIBRARY})

find_package_handle_standard_args(qpOASES DEFAULT_MSG qpOASES_LIBRARIES qpOASES_INCLUDE_DIRS)
62 changes: 0 additions & 62 deletions cmake/modules/FindOASES.cmake

This file was deleted.

17 changes: 15 additions & 2 deletions src/SoftRobots.Inverse/component/solver/QPInverseProblemSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@
#include <SoftRobots.Inverse/component/solver/QPInverseProblemSolver.h>
#include <SoftRobots.Inverse/component/solver/modules/QPMechanicalSetConstraint.h>
#include <SoftRobots.Inverse/component/solver/modules/QPMechanicalAccumulateConstraint.h>

#ifdef SOFTROBOTSINVERSE_ENABLE_QPOASES
#include <SoftRobots.Inverse/component/solver/modules/QPInverseProblemQPOases.h>
#endif

#ifdef SOFTROBOTSINVERSE_ENABLE_PROXQP
#include <SoftRobots.Inverse/component/solver/modules/QPInverseProblemProxQP.h>
Expand Down Expand Up @@ -161,7 +164,12 @@ QPInverseProblemSolver::QPInverseProblemSolver()
, m_CP3(nullptr)
{
sofa::helper::OptionsGroup qpSolvers{"qpOASES" , "proxQP"};
#if defined SOFTROBOTSINVERSE_ENABLE_PROXQP && !defined SOFTROBOTSINVERSE_ENABLE_QPOASES
qpSolvers.setSelectedItem(QPSolverImpl::PROXQP);
#else
qpSolvers.setSelectedItem(QPSolverImpl::QPOASES);
#endif

d_qpSolver.setValue(qpSolvers);

d_graph.setWidget("graph");
Expand All @@ -181,19 +189,24 @@ void QPInverseProblemSolver::createProblems()
{
#ifdef SOFTROBOTSINVERSE_ENABLE_PROXQP
case QPSolverImpl::PROXQP :
// TODO conditionnal compilation w.r.t. optionnal proxQP dependency
msg_info() << "Using proxQP solver";
m_CP1 = new module::QPInverseProblemProxQP();
m_CP2 = new module::QPInverseProblemProxQP();
m_CP3 = new module::QPInverseProblemProxQP();
break;
#endif
default : // QPSolverImpl::QPOASES
#ifdef SOFTROBOTSINVERSE_ENABLE_QPOASES
case QPSolverImpl::QPOASES :
msg_info() << "Using qpOASES solver";
m_CP1 = new module::QPInverseProblemQPOases();
m_CP2 = new module::QPInverseProblemQPOases();
m_CP3 = new module::QPInverseProblemQPOases();
break;
#endif
default :
msg_error() << "Unkown specified solved: " << d_qpSolver.getValue();
sofa::core::objectmodel::BaseObject::d_componentState.setValue(sofa::core::objectmodel::ComponentState::Invalid);
break;
}


Expand Down
11 changes: 2 additions & 9 deletions src/SoftRobots.Inverse/component/solver/modules/LCPQPSolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,17 @@
******************************************************************************/
#pragma once

#include <sofa/type/vector.h>

// LCP solver using qpOASES QP solver
// QP formulation for solving a LCP with a symmetric matrix M.

namespace softrobotsinverse::solver::module {

using sofa::type::vector;

class LCPQPSolver
{

public:
virtual ~LCPQPSolver() = default;

LCPQPSolver(){}
~LCPQPSolver(){}

void solve(int dim, double*q, double**M, double*res);
virtual void solve(int dim, double*q, double**M, double*res) = 0;
};

} // namespace
Expand Down
Loading
Loading