Skip to content

Commit

Permalink
Add setStringParameter and expose initial_guess parameter in proxqp (#15
Browse files Browse the repository at this point in the history
)
  • Loading branch information
traversaro authored Nov 12, 2024
1 parent 1a3c6e6 commit 8c1b68c
Show file tree
Hide file tree
Showing 12 changed files with 106 additions and 4 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.16...3.31)

project(QpSolversEigen VERSION 0.0.2)
project(QpSolversEigen VERSION 0.1.0)

include(GNUInstallDirs)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
Expand Down
5 changes: 5 additions & 0 deletions core/QpSolversEigen/NullSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@ bool NullSolver::setRealNumberParameter(const std::string& settingName, double v
return false;
}

bool NullSolver::setStringParameter(const std::string& parameterName, const std::string& value)
{
return false;
}

SolverInterface* NullSolver::allocateInstance() const
{
return new NullSolver();
Expand Down
1 change: 1 addition & 0 deletions core/QpSolversEigen/NullSolver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class NullSolver final: public SolverInterface
bool setBooleanParameter(const std::string& settingName, bool value) override;
bool setIntegerParameter(const std::string& settingName, int64_t value) override;
bool setRealNumberParameter(const std::string& settingName, double value) override;
bool setStringParameter(const std::string& parameterName, const std::string& value) override;
SolverInterface* allocateInstance() const override;
};

Expand Down
5 changes: 5 additions & 0 deletions core/QpSolversEigen/Solver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,11 @@ bool Solver::setRealNumberParameter(const std::string& parameterName, double val
return m_pimpl->solver->setRealNumberParameter(parameterName, value);
}

bool Solver::setStringParameter(const std::string& parameterName, const std::string& value)
{
return m_pimpl->solver->setStringParameter(parameterName, value);
}

Solver* Solver::data()
{
return this;
Expand Down
10 changes: 10 additions & 0 deletions core/QpSolversEigen/Solver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,16 @@ class Solver
*/
bool setRealNumberParameter(const std::string& parameterName, double value);

/**
* Set a string parameter.
*
* @note Sometimes Enum parameters in a specific solvers are wrapped as a string parameter.
*
* @param parameterName the name of the parameter to bet set.
* @return true/false in case of success/failure.
*/
bool setStringParameter(const std::string& parameterName, const std::string& value);

/**
* Return a pointer to this class.
*
Expand Down
1 change: 1 addition & 0 deletions core/QpSolversEigen/SolverInterface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class SolverInterface
virtual bool setBooleanParameter(const std::string& settingName, bool value) = 0;
virtual bool setIntegerParameter(const std::string& settingName, int64_t value) = 0;
virtual bool setRealNumberParameter(const std::string& settingName, double value) = 0;
virtual bool setStringParameter(const std::string& settingName, const std::string& value) = 0;

/**
* Allocate a new instance of this class, and return a pointer to it.
Expand Down
10 changes: 9 additions & 1 deletion examples/mpc/MPCExample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,21 @@ int main()
}

// settings

// solver.setBooleanParameter("verbose", false);

// Set osqp-specific parameters
if (solver.getSolverName() == "osqp")
{
// solver.setBooleanParameter("verbose", false);
solver.setBooleanParameter("warm_starting", true);
}

// Set proxqp-specific parameters
if (solver.getSolverName() == "proxqp")
{
solver.setStringParameter("initial_guess", "WARM_START_WITH_PREVIOUS_RESULT");
}

// set the initial data of the QP solver
solver.setNumberOfVariables(12 * (mpcWindow + 1) + 4 * mpcWindow);
solver.setNumberOfConstraints(2 * 12 * (mpcWindow + 1) + 4 * mpcWindow);
Expand Down
8 changes: 8 additions & 0 deletions plugins/osqp/QpSolversEigenOsqp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class OsqpSolver final: public SolverInterface
bool setBooleanParameter(const std::string& settingName, bool value) override;
bool setIntegerParameter(const std::string& settingName, int64_t value) override;
bool setRealNumberParameter(const std::string& settingName, double value) override;
bool setStringParameter(const std::string& parameterName, const std::string& value) override;
SolverInterface* allocateInstance() const override;
};

Expand Down Expand Up @@ -417,6 +418,13 @@ bool OsqpSolver::setRealNumberParameter(const std::string& settingName, double v
return false;
}

bool OsqpSolver::setStringParameter(const std::string& parameterName, const std::string& value)
{
QpSolversEigen::debugStream() << "QpSolversEigen::OsqpSolver::setStringParameter: unknown setting name: " << parameterName << std::endl;
return false;
}


SolverInterface* OsqpSolver::allocateInstance() const
{
return new OsqpSolver();
Expand Down
50 changes: 50 additions & 0 deletions plugins/proxqp/QpSolversEigenProxqp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ class ProxqpSolver final: public SolverInterface
bool setBooleanParameter(const std::string& settingName, bool value) override;
bool setIntegerParameter(const std::string& settingName, int64_t value) override;
bool setRealNumberParameter(const std::string& settingName, double value) override;
bool setStringParameter(const std::string& parameterName, const std::string& value) override;
SolverInterface* allocateInstance() const override;
};

Expand Down Expand Up @@ -533,6 +534,55 @@ bool ProxqpSolver::setRealNumberParameter(const std::string& settingName, double
return false;
}

bool ProxqpSolver::setStringParameter(const std::string& parameterName, const std::string& value)
{
bool settingFound = false;
bool valueFound = false;

if (parameterName == "initial_guess")
{
settingFound = true;
if (value == "NO_INITIAL_GUESS")
{
proxqpSettings.initial_guess = proxsuite::proxqp::InitialGuessStatus::NO_INITIAL_GUESS;
valueFound = true;
} else if (value == "EQUALITY_CONSTRAINED_INITIAL_GUESS")
{
proxqpSettings.initial_guess = proxsuite::proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS;
valueFound = true;
} else if (value == "WARM_START_WITH_PREVIOUS_RESULT")
{
proxqpSettings.initial_guess = proxsuite::proxqp::InitialGuessStatus::WARM_START_WITH_PREVIOUS_RESULT;
valueFound = true;
} else if (value == "WARM_START")
{
proxqpSettings.initial_guess = proxsuite::proxqp::InitialGuessStatus::WARM_START;
valueFound = true;
} else if (value == "COLD_START_WITH_PREVIOUS_RESULT")
{
proxqpSettings.initial_guess = proxsuite::proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT;
valueFound = true;
}
}


if (settingFound && valueFound)
{
syncSettings();
return true;
}

if (!settingFound)
{
QpSolversEigen::debugStream() << "QpSolversEigen::ProxqpSolver::setStringParameter: unknown setting name: " << parameterName << std::endl;
} else if (!valueFound)
{
QpSolversEigen::debugStream() << "QpSolversEigen::ProxqpSolver::setStringParameter: unknown value << " << value << " for parameter with name: " << parameterName << std::endl;
}
return false;
}


SolverInterface* ProxqpSolver::allocateInstance() const
{
return new ProxqpSolver();
Expand Down
4 changes: 3 additions & 1 deletion plugins/proxqp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,6 @@ If you need support for more parameters, please open an issue.

### String parameters

TODO
| Name | Notes |
|:------------:|:-------------------------:|
| `initial_guess` | Possible values are `NO_INITIAL_GUESS`, `EQUALITY_CONSTRAINED_INITIAL_GUESS`, `WARM_START_WITH_PREVIOUS_RESULT`, `WARM_START` or `COLD_START_WITH_PREVIOUS_RESULT`. See https://simple-robotics.github.io/proxsuite/md_doc_22-ProxQP__api.html#OverviewInitialGuess for more details. |
6 changes: 5 additions & 1 deletion tests/MPCTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,11 +285,15 @@ TEST_CASE("MPCTest")
// settings
REQUIRE(solver.setBooleanParameter("verbose", false));

// Some parameters are only supported by osqp
// Set solver-specific parameters
if (solver.getSolverName() == "osqp")
{
REQUIRE(solver.setBooleanParameter("warm_start", true));
}
if (solver.getSolverName() == "proxqp")
{
REQUIRE(solver.setStringParameter("initial_guess", "WARM_START_WITH_PREVIOUS_RESULT"));
}

// set the initial data of the QP solver
solver.data()->setNumberOfVariables(12 * (mpcWindow + 1) + 4 * mpcWindow);
Expand Down
8 changes: 8 additions & 0 deletions tests/MPCUpdateMatricesTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,14 @@ TEST_CASE("MPCTest Update matrices")
REQUIRE(solver.setBooleanParameter("warm_start", true));
}

if (solver.getSolverName() == "proxqp")
{
REQUIRE(solver.setStringParameter("initial_guess", "WARM_START_WITH_PREVIOUS_RESULT"));
// Check that setStringParameter fail for unknown setting or unknown value
REQUIRE_FALSE(solver.setStringParameter("initial_guess", "THIS_IS_NOT_A_VALID_INITIAL_GUESS_VALUE"));
REQUIRE_FALSE(solver.setStringParameter("this_is_not_a_valid_proqp_parameter_name", "THIS_IS_NOT_A_VALID_INITIAL_GUESS_VALUE"));
}

// set the initial data of the QP solver
solver.data()->setNumberOfVariables(2 * (mpcWindow + 1) + 1 * mpcWindow);
solver.data()->setNumberOfConstraints(2 * (mpcWindow + 1));
Expand Down

0 comments on commit 8c1b68c

Please sign in to comment.