Commit af8f8262 authored by Guilhem Saurel's avatar Guilhem Saurel
Browse files

Merge remote-tracking branch 'main/devel' into release/1.0.0

parents 2a187468 85328671
Pipeline #7731 passed with stage
in 120 minutes and 8 seconds
......@@ -6,16 +6,17 @@ SET(PROJECT_NAME crocoddyl)
SET(PROJECT_DESCRIPTION "Contact RObot COntrol by Differential DYnamic programming Library (Crocoddyl)")
SET(PROJECT_URL https://github.com/${PROJECT_NAMESPACE}/${PROJECT_NAME})
# Check if the submodule cmake have been initialized
IF(NOT EXISTS "${CMAKE_SOURCE_DIR}/cmake/base.cmake")
MESSAGE(FATAL_ERROR "\nPlease run the following command first:\ngit submodule update --init\n")
ENDIF()
# Include important cmake modules
INCLUDE(cmake/base.cmake RESULT_VARIABLE SUBMODULE_FOUND)
INCLUDE(cmake/base.cmake)
INCLUDE(cmake/test.cmake)
INCLUDE(cmake/boost.cmake)
INCLUDE(cmake/python.cmake)
# Check if the cmake (git submodule) have been initialized
IF(SUBMODULE_FOUND STREQUAL "NOTFOUND")
MESSAGE(FATAL_ERROR "\nPlease run the following command first:\ngit submodule update --init\n")
ENDIF(SUBMODULE_FOUND STREQUAL "NOTFOUND")
INCLUDE(cmake/apple.cmake)
# Print initial message
MESSAGE("${PROJECT_DESCRIPTION}, version ${PROJECT_VERSION}")
......@@ -49,6 +50,9 @@ ENDIF()
COMPUTE_PROJECT_ARGS(PROJECT_ARGS LANGUAGES CXX)
PROJECT(${PROJECT_NAME} ${PROJECT_ARGS})
# If needed, fix CMake policy for APPLE systems
APPLY_DEFAULT_APPLE_CONFIGURATION()
# Add the different required and optional dependencies
ADD_REQUIRED_DEPENDENCY("eigen3 >= 3.0.5")
ADD_REQUIRED_DEPENDENCY("eigenpy")
......@@ -88,8 +92,7 @@ SET(BOOST_OPTIONAL_COMPONENTS "")
IF(BUILD_PYTHON_INTERFACE)
SET(BOOST_OPTIONAL_COMPONENTS ${BOOST_OPTIONAL_COMPONENTS} python)
FINDPYTHON()
FIND_NUMPY()
INCLUDE_DIRECTORIES(SYSTEM ${PYTHON_INCLUDE_DIRS} ${NUMPY_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(SYSTEM ${PYTHON_INCLUDE_DIRS})
ENDIF(BUILD_PYTHON_INTERFACE)
SET(BOOST_COMPONENTS ${BOOST_REQUIERED_COMPONENTS} ${BOOST_OPTIONAL_COMPONENTS} ${BOOST_BUILD_COMPONENTS})
......
[Carlos Mastalli](https://cmastalli.github.io/) (University of Edinburgh): main developer and manager of the project
## I. About
Crocoddyl has been written in C++ for efficiency and uses the Eigen library for linear algebra routines. It comes with Python bindings for easy prototyping. Crocoddyl is currently supported for most Linux distributions, with plans to release on Mac OS X and Windows. The project is fully open-source under the permissive BSD-3-Clause license and is hosted on GitHub.
[Nicolas Mansard](http://projects.laas.fr/gepetto/index.php/Members/NicolasMansard) (LAAS-CNRS): project instructor
## II. Design pattern
Crocoddyl is designed using virtualization pattern for easy prototyping and yet efficient implementation. In early benchmark, we have shown that virtualization is as efficient as static polymorphism (i.e. CRTP design) for system dynamics higher than 16. The real benefits of static polymorphism are in very small system (with dimension less than 6), however, virtualization is still competitive.
[Rohan Budhiraja](https://scholar.google.com/citations?user=NW9Io9AAAAAJ) (LAAS-CNRS): features extension
One of the main design concepts of Crocoddyl is the strict separation between _model_ and _data_. A model describes a system or procedure, e.g. action, cost, and activation models. Any model has been abstracted to easily derive new systems in both C++ and Python. By data, we refer to a container that stores computed and intermediate values used during the calculation routine performed by a model. Each model creates its own data, and with this, we avoid any temporary memory allocation produced by algebraic expressions in Eigen. To improve efficiency, especially in systems with dimension slower than 16, the Eigen members inside a data object can be defined with fixed dimensions. It allows for efficient use of modern CPU features by using vectorization and Same Instruction Multiple Data (SIMD) operations.
[Justin Carpentier](https://jcarpent.github.io/) (INRIA): efficient analytical rigid-body dynamics derivatives
## III. Code Format
[Maximilien Naveau](https://scholar.google.fr/citations?user=y_-cGlUAAAAJ&hl=fr) (MPI): unit-test support
Crocoddyl CI also checks code format (for both c++ and Python code) as effort to maximize readability and maintainability. Depending on the language, c++ or Python, we use different format policies which are tested with [Gepetto/linters](https://github.com/gepetto/linters) repository. For c++ code, Crocoddyl uses Google format convention, instead for Python code it follows [flake8 rules](http://flake8.pycqa.org/en/latest/) with a maximum length of 119 characters.
[Guilhem Saurel](http://projects.laas.fr/gepetto/index.php/Members/GuilhemSaurel) (LAAS-CNRS): continuous integration and deployment
Despite that Crocoddyl follows the strict code format, you don't need to learn each specific details of these formatting rules. For that, you have two options:
1. configuration your IDE to lint your code automatically (or check it), and
2. let our linter to adjust your code.
[Wolfgang Merkt](http://www.wolfgangmerkt.com/research/) (University of Edinburgh): feature extension and debugging
Here we explain how to do the later. For this, you can either use the provided docker image (subsection 1), or manually setup your environment by yourself (subsection 2).
[Josep Martí Saumell](https://www.iri.upc.edu/staff/jmarti) (UPC): feature extension
### 1. Direct use of the provided docker image
[Bilal Hammoud](https://scholar.google.com/citations?hl=en&user=h_4NKpsAAAAJ) (MPI): features extension
```bash
docker run --rm -v $PWD:/app -w /app -it gepetto/linters
```
## Acknowledgments
This will not work if the root user doesn't have the right to go into your current working directory.
And if your current working directory is accessed through symlinks, you might need to replace `$PWD` by `$(pwd -P)`.
The development of **Pinocchio** is supported by the [EU MEMMO project](http://www.memmo-project.eu/), the [Gepetto team](http://projects.laas.fr/gepetto/) [@LAAS-CNRS](http://www.laas.fr), and the [Statistical Machine Learning and Motor Control Group](http://wcms.inf.ed.ac.uk/ipab/slmc) [@University of Edinburgh](https://www.edinburgh-robotics.org/).
### 2. Manual use of each tool
Before starting with it, you need to clone **Gepetto/linter** repository, i.e.
```bash
git clone git@github.com:Gepetto/linters.git
sudo apt install clang-format-6.0
pip install --user flake8 isort yapf
```
**Please note yapf is in a beta version, we tested our system with v0.27.0.**
*Please note that with the following instructions your current code will be updated*
#### 2.1. Formatting your c++ code
For c++ testing through clang-format. We used the configuration file defined in the Gepetto linter. Then, you need to install the configuration files in the current working directory (beware of git if doing so) or in a parent directory. Your home might be a good choice:
```bash
cd ${YOUR_CROCCODDYL_SOURCE_PATH}
ln -s ${YOUR_GEPETTO_LINTER_PATH}/.clang-format .clang-format
```
And for formatting your c++ code, you just need to run the follows:
```bash
cd ${YOUR_CROCCODDYL_SOURCE_PATH}
clang-format-6.0 -i $(find . -path ./cmake -prune -o -iregex '.*\.\(h\|c\|hh\|cc\|hpp\|cpp\|hxx\|cxx\)$' -print)
```
#### 2.2. Formatting your Python code
```bash
cd ${YOUR_CROCCODDYL_SOURCE_PATH}
flake8 .
yapf -ri .
```
\ No newline at end of file
......@@ -6,8 +6,9 @@ SET(${PROJECT_NAME}_PYTHON_BINDINGS_FILES
__init__.py
)
ADD_LIBRARY(${PROJECT_NAME}_pywrap SHARED ${${PROJECT_NAME}_PYTHON_BINDINGS_SOURCES})
SET_TARGET_PROPERTIES(${PROJECT_NAME}_pywrap PROPERTIES SUFFIX ${PYTHON_EXT_SUFFIX})
PKG_CONFIG_USE_DEPENDENCY(${PROJECT_NAME}_pywrap eigen3)
PKG_CONFIG_USE_DEPENDENCY(${PROJECT_NAME}_pywrap eigenpy)
PKG_CONFIG_USE_DEPENDENCY(${PROJECT_NAME}_pywrap pinocchio)
......@@ -20,7 +21,6 @@ TARGET_COMPILE_OPTIONS(${PROJECT_NAME}_pywrap PRIVATE "-Wno-conversion")
INSTALL(TARGETS ${PROJECT_NAME}_pywrap DESTINATION ${PYTHON_SITELIB}/${PROJECT_NAME})
FOREACH(python ${${PROJECT_NAME}_PYTHON_BINDINGS_FILES})
PYTHON_BUILD(. ${python})
INSTALL(FILES
......
......@@ -9,11 +9,13 @@
#ifndef BINDINGS_PYTHON_CROCODDYL_CORE_HPP_
#define BINDINGS_PYTHON_CROCODDYL_CORE_HPP_
#include "python/crocoddyl/core/data-collector-base.hpp"
#include "python/crocoddyl/core/state-base.hpp"
#include "python/crocoddyl/core/actuation-base.hpp"
#include "python/crocoddyl/core/action-base.hpp"
#include "python/crocoddyl/core/diff-action-base.hpp"
#include "python/crocoddyl/core/activation-base.hpp"
#include "python/crocoddyl/core/data/actuation.hpp"
#include "python/crocoddyl/core/integrator/euler.hpp"
#include "python/crocoddyl/core/numdiff/action.hpp"
#include "python/crocoddyl/core/numdiff/diff-action.hpp"
......@@ -37,11 +39,13 @@ namespace crocoddyl {
namespace python {
void exposeCore() {
exposeDataCollector();
exposeStateAbstract();
exposeActuationAbstract();
exposeActionAbstract();
exposeDifferentialActionAbstract();
exposeActivationAbstract();
exposeDataCollectorActuation();
exposeIntegratedActionEuler();
exposeActionNumDiff();
exposeDifferentialActionNumDiff();
......
......@@ -9,6 +9,7 @@
#ifndef BINDINGS_PYTHON_CROCODDYL_CORE_ACTION_BASE_HPP_
#define BINDINGS_PYTHON_CROCODDYL_CORE_ACTION_BASE_HPP_
#include "crocoddyl/core/utils/exception.hpp"
#include "crocoddyl/core/action-base.hpp"
namespace crocoddyl {
......@@ -24,10 +25,12 @@ class ActionModelAbstract_wrap : public ActionModelAbstract, public bp::wrapper<
void calc(const boost::shared_ptr<ActionDataAbstract>& data, const Eigen::Ref<const Eigen::VectorXd>& x,
const Eigen::Ref<const Eigen::VectorXd>& u) {
if (static_cast<std::size_t>(x.size()) != state_->get_nx()) {
throw std::invalid_argument("x has wrong dimension (it should be " + std::to_string(state_->get_nx()) + ")");
throw_pretty("Invalid argument: "
<< "x has wrong dimension (it should be " + std::to_string(state_->get_nx()) + ")");
}
if (static_cast<std::size_t>(u.size()) != nu_) {
throw std::invalid_argument("u has wrong dimension (it should be " + std::to_string(nu_) + ")");
throw_pretty("Invalid argument: "
<< "u has wrong dimension (it should be " + std::to_string(nu_) + ")");
}
return bp::call<void>(this->get_override("calc").ptr(), data, (Eigen::VectorXd)x, (Eigen::VectorXd)u);
}
......@@ -35,10 +38,12 @@ class ActionModelAbstract_wrap : public ActionModelAbstract, public bp::wrapper<
void calcDiff(const boost::shared_ptr<ActionDataAbstract>& data, const Eigen::Ref<const Eigen::VectorXd>& x,
const Eigen::Ref<const Eigen::VectorXd>& u, const bool& recalc = true) {
if (static_cast<std::size_t>(x.size()) != state_->get_nx()) {
throw std::invalid_argument("x has wrong dimension (it should be " + std::to_string(state_->get_nx()) + ")");
throw_pretty("Invalid argument: "
<< "x has wrong dimension (it should be " + std::to_string(state_->get_nx()) + ")");
}
if (static_cast<std::size_t>(u.size()) != nu_) {
throw std::invalid_argument("u has wrong dimension (it should be " + std::to_string(nu_) + ")");
throw_pretty("Invalid argument: "
<< "u has wrong dimension (it should be " + std::to_string(nu_) + ")");
}
return bp::call<void>(this->get_override("calcDiff").ptr(), data, (Eigen::VectorXd)x, (Eigen::VectorXd)u, recalc);
}
......@@ -59,13 +64,13 @@ void exposeActionAbstract() {
"derivatives. These computations are mainly carry on inside calc() and calcDiff(),\n"
"respectively.",
bp::init<boost::shared_ptr<StateAbstract>, int, bp::optional<int> >(
bp::args(" self", " state", " nu", " nr=1"),
bp::args("self", "state", "nu", "nr"),
"Initialize the action model.\n\n"
"You can also describe autonomous systems by setting nu = 0.\n"
":param state: state description,\n"
":param nu: dimension of control vector,\n"
":param nr: dimension of the cost-residual vector"))
.def("calc", pure_virtual(&ActionModelAbstract_wrap::calc), bp::args(" self", " data", " x", " u"),
":param nr: dimension of the cost-residual vector (default 1)"))
.def("calc", pure_virtual(&ActionModelAbstract_wrap::calc), bp::args("self", "data", "x", "u"),
"Compute the next state and cost value.\n\n"
"It describes the time-discrete evolution of our dynamical system\n"
"in which we obtain the next state. Additionally it computes the\n"
......@@ -73,8 +78,7 @@ void exposeActionAbstract() {
":param data: action data\n"
":param x: time-discrete state vector\n"
":param u: time-discrete control input")
.def("calcDiff", pure_virtual(&ActionModelAbstract_wrap::calcDiff),
bp::args(" self", " data", " x", " u", " recalc=True"),
.def("calcDiff", pure_virtual(&ActionModelAbstract_wrap::calcDiff), bp::args("self", "data", "x", "u", "recalc"),
"Compute the derivatives of the dynamics and cost functions.\n\n"
"It computes the partial derivatives of the dynamical system and the\n"
"cost function. If recalc == True, it first updates the state evolution\n"
......@@ -83,22 +87,22 @@ void exposeActionAbstract() {
":param data: action data\n"
":param x: time-discrete state vector\n"
":param u: time-discrete control input\n"
":param recalc: If true, it updates the state evolution and the cost value.")
.def("createData", &ActionModelAbstract_wrap::createData, bp::args(" self"),
":param recalc: If true, it updates the state evolution and the cost value (default True).")
.def("createData", &ActionModelAbstract_wrap::createData, bp::args("self"),
"Create the action data.\n\n"
"Each action model (AM) has its own data that needs to be allocated.\n"
"This function returns the allocated data for a predefined AM.\n"
":return AM data.")
.def("quasiStatic", &ActionModelAbstract_wrap::quasiStatic_wrap,
ActionModel_quasiStatic_wraps(
bp::args(" self", " data", " x", " maxiter=100", " tol=1e-9"),
bp::args("self", "data", "x", "maxiter", "tol"),
"Compute the quasic-static control given a state.\n\n"
"It runs an iterative Newton step in order to compute the quasic-static regime\n"
"given a state configuration.\n"
":param data: action data\n"
":param x: discrete-time state vector\n"
":param maxiter: maximum allowed number of iterations\n"
":param tol: stopping tolerance criteria\n"
":param tol: stopping tolerance criteria (default 1e-9)\n"
":return u: quasic-static control"))
.add_property(
"nu", bp::make_function(&ActionModelAbstract_wrap::get_nu, bp::return_value_policy<bp::return_by_value>()),
......@@ -132,7 +136,7 @@ void exposeActionAbstract() {
"user-defined action model. The action data typically is allocated onces by running\n"
"model.createData() and contains the first- and second- order derivatives of the dynamics\n"
"and cost function, respectively.",
bp::init<ActionModelAbstract*>(bp::args(" self", " model"),
bp::init<ActionModelAbstract*>(bp::args("self", "model"),
"Create common data shared between AMs.\n\n"
"The action data uses the model in order to first process it.\n"
":param model: action model"))
......
......@@ -29,13 +29,13 @@ void exposeDifferentialActionLQR() {
"where Fq, Fv, Fu and f0 are randomly chosen constant terms. On the other\n"
"hand the cost function is given by\n"
" l(x,u) = 1/2 [x,u].T [Lxx Lxu; Lxu.T Luu] [x,u] + [lx,lu].T [x,u].",
bp::init<int, int, bp::optional<bool> >(bp::args(" self", " nq", " nu", " driftFree=True"),
bp::init<int, int, bp::optional<bool> >(bp::args("self", "nq", "nu", "driftFree"),
"Initialize the differential LQR action model.\n\n"
":param nx: dimension of the state vector\n"
":param nu: dimension of the control vector\n"
":param driftFree: enable/disable the bias term of the linear dynamics"))
":param driftFree: enable/disable the bias term of the linear dynamics (default True)"))
.def("calc", &DifferentialActionModelLQR::calc_wrap,
DiffActionModel_calc_wraps(bp::args(" self", " data", " x", " u=None"),
DiffActionModel_calc_wraps(bp::args("self", "data", "x", "u"),
"Compute the next state and cost value.\n\n"
"It describes the time-continuous evolution of the LQR system. Additionally it\n"
"computes the cost value associated to this discrete state and control pair.\n"
......@@ -44,8 +44,7 @@ void exposeDifferentialActionLQR() {
":param u: time-continuous control input"))
.def<void (DifferentialActionModelLQR::*)(const boost::shared_ptr<DifferentialActionDataAbstract>&,
const Eigen::VectorXd&, const Eigen::VectorXd&, const bool&)>(
"calcDiff", &DifferentialActionModelLQR::calcDiff_wrap,
bp::args(" self", " data", " x", " u=None", " recalc=True"),
"calcDiff", &DifferentialActionModelLQR::calcDiff_wrap, bp::args("self", "data", "x", "u", "recalc"),
"Compute the derivatives of the differential LQR dynamics and cost functions.\n\n"
"It computes the partial derivatives of the differential LQR system and the\n"
"cost function. If recalc == True, it first updates the state evolution\n"
......@@ -54,17 +53,17 @@ void exposeDifferentialActionLQR() {
":param data: action data\n"
":param x: time-continuous state vector\n"
":param u: time-continuous control input\n"
":param recalc: If true, it updates the state evolution and the cost value.")
":param recalc: If true, it updates the state evolution and the cost value (default True).")
.def<void (DifferentialActionModelLQR::*)(const boost::shared_ptr<DifferentialActionDataAbstract>&,
const Eigen::VectorXd&, const Eigen::VectorXd&)>(
"calcDiff", &DifferentialActionModelLQR::calcDiff_wrap, bp::args(" self", " data", " x", " u"))
"calcDiff", &DifferentialActionModelLQR::calcDiff_wrap, bp::args("self", "data", "x", "u"))
.def<void (DifferentialActionModelLQR::*)(const boost::shared_ptr<DifferentialActionDataAbstract>&,
const Eigen::VectorXd&)>(
"calcDiff", &DifferentialActionModelLQR::calcDiff_wrap, bp::args(" self", " data", " x"))
"calcDiff", &DifferentialActionModelLQR::calcDiff_wrap, bp::args("self", "data", "x"))
.def<void (DifferentialActionModelLQR::*)(const boost::shared_ptr<DifferentialActionDataAbstract>&,
const Eigen::VectorXd&, const bool&)>(
"calcDiff", &DifferentialActionModelLQR::calcDiff_wrap, bp::args(" self", " data", " x", " recalc"))
.def("createData", &DifferentialActionModelLQR::createData, bp::args(" self"),
"calcDiff", &DifferentialActionModelLQR::calcDiff_wrap, bp::args("self", "data", "x", "recalc"))
.def("createData", &DifferentialActionModelLQR::createData, bp::args("self"),
"Create the differential LQR action data.")
.add_property(
"Fq", bp::make_function(&DifferentialActionModelLQR::get_Fq, bp::return_value_policy<bp::return_by_value>()),
......@@ -101,7 +100,7 @@ void exposeDifferentialActionLQR() {
bp::class_<DifferentialActionDataLQR, bp::bases<DifferentialActionDataAbstract> >(
"DifferentialActionDataLQR", "Action data for the differential LQR system.",
bp::init<DifferentialActionModelLQR*>(bp::args(" self", " model"),
bp::init<DifferentialActionModelLQR*>(bp::args("self", "model"),
"Create differential LQR data.\n\n"
":param model: differential LQR action model"));
}
......
......@@ -23,13 +23,13 @@ void exposeActionLQR() {
"A Linear-Quadratic Regulator problem has a transition model of the form\n"
"xnext(x,u) = Fx*x + Fu*u + f0. Its cost function is quadratic of the\n"
"form: 1/2 [x,u].T [Lxx Lxu; Lxu.T Luu] [x,u] + [lx,lu].T [x,u].",
bp::init<int, int, bp::optional<bool> >(bp::args(" self", " nx", " nu", " driftFree=True"),
bp::init<int, int, bp::optional<bool> >(bp::args("self", "nx", "nu", "driftFree"),
"Initialize the LQR action model.\n\n"
":param nx: dimension of the state vector\n"
":param nu: dimension of the control vector\n"
":param driftFree: enable/disable the bias term of the linear dynamics"))
":param driftFree: enable/disable the bias term of the linear dynamics (default True)"))
.def("calc", &ActionModelLQR::calc_wrap,
ActionModel_calc_wraps(bp::args(" self", " data", " x", " u=None"),
ActionModel_calc_wraps(bp::args("self", "data", "x", "u"),
"Compute the next state and cost value.\n\n"
"It describes the time-discrete evolution of the LQR system. Additionally it\n"
"computes the cost value associated to this discrete\n"
......@@ -39,7 +39,7 @@ void exposeActionLQR() {
":param u: time-discrete control input"))
.def<void (ActionModelLQR::*)(const boost::shared_ptr<ActionDataAbstract>&, const Eigen::VectorXd&,
const Eigen::VectorXd&, const bool&)>(
"calcDiff", &ActionModelLQR::calcDiff_wrap, bp::args(" self", " data", " x", " u=None", " recalc=True"),
"calcDiff", &ActionModelLQR::calcDiff_wrap, bp::args("self", "data", "x", "u", "recalc"),
"Compute the derivatives of the LQR dynamics and cost functions.\n\n"
"It computes the partial derivatives of the LQR system and the\n"
"cost function. If recalc == True, it first updates the state evolution\n"
......@@ -48,16 +48,16 @@ void exposeActionLQR() {
":param data: action data\n"
":param x: time-discrete state vector\n"
":param u: time-discrete control input\n"
":param recalc: If true, it updates the state evolution and the cost value.")
":param recalc: If true, it updates the state evolution and the cost value (default True).")
.def<void (ActionModelLQR::*)(const boost::shared_ptr<ActionDataAbstract>&, const Eigen::VectorXd&,
const Eigen::VectorXd&)>("calcDiff", &ActionModelLQR::calcDiff_wrap,
bp::args(" self", " data", " x", " u"))
bp::args("self", "data", "x", "u"))
.def<void (ActionModelLQR::*)(const boost::shared_ptr<ActionDataAbstract>&, const Eigen::VectorXd&)>(
"calcDiff", &ActionModelLQR::calcDiff_wrap, bp::args(" self", " data", " x"))
"calcDiff", &ActionModelLQR::calcDiff_wrap, bp::args("self", "data", "x"))
.def<void (ActionModelLQR::*)(const boost::shared_ptr<ActionDataAbstract>&, const Eigen::VectorXd&,
const bool&)>("calcDiff", &ActionModelLQR::calcDiff_wrap,
bp::args(" self", " data", " x", " recalc"))
.def("createData", &ActionModelLQR::createData, bp::args(" self"), "Create the LQR action data.")
bp::args("self", "data", "x", "recalc"))
.def("createData", &ActionModelLQR::createData, bp::args("self"), "Create the LQR action data.")
.add_property("Fx", bp::make_function(&ActionModelLQR::get_Fx, bp::return_value_policy<bp::return_by_value>()),
&ActionModelLQR::set_Fx, "Jacobian of the dynamics")
.add_property("Fu", bp::make_function(&ActionModelLQR::get_Fu, bp::return_value_policy<bp::return_by_value>()),
......@@ -79,7 +79,7 @@ void exposeActionLQR() {
bp::class_<ActionDataLQR, bp::bases<ActionDataAbstract> >(
"ActionDataLQR", "Action data for the LQR system.",
bp::init<ActionModelLQR*>(bp::args(" self", " model"),
bp::init<ActionModelLQR*>(bp::args("self", "model"),
"Create LQR data.\n\n"
":param model: LQR action model"));
}
......
......@@ -26,9 +26,9 @@ void exposeActionUnicycle() {
"by (v,w). Note that the state is defined only with the position. On the\n"
"other hand, we define the quadratic cost functions for the state and\n"
"control.",
bp::init<>(bp::args(" self"), "Initialize the unicycle action model."))
bp::init<>(bp::args("self"), "Initialize the unicycle action model."))
.def("calc", &ActionModelUnicycle::calc_wrap,
ActionModel_calc_wraps(bp::args(" self", " data", " x", " u=None"),
ActionModel_calc_wraps(bp::args("self", "data", "x", "u"),
"Compute the next state and cost value.\n\n"
"It describes the time-discrete evolution of the unicycle system.\n"
"Additionally it computes the cost value associated to this discrete\n"
......@@ -38,7 +38,7 @@ void exposeActionUnicycle() {
":param u: time-discrete control input"))
.def<void (ActionModelUnicycle::*)(const boost::shared_ptr<ActionDataAbstract>&, const Eigen::VectorXd&,
const Eigen::VectorXd&, const bool&)>(
"calcDiff", &ActionModelUnicycle::calcDiff_wrap, bp::args(" self", " data", " x", " u=None", " recalc=True"),
"calcDiff", &ActionModelUnicycle::calcDiff_wrap, bp::args("self", "data", "x", "u", "recalc"),
"Compute the derivatives of the unicycle dynamics and cost functions.\n\n"
"It computes the partial derivatives of the unicycle system and the\n"
"cost function. If recalc == True, it first updates the state evolution\n"
......@@ -47,16 +47,16 @@ void exposeActionUnicycle() {
":param data: action data\n"
":param x: time-discrete state vector\n"
":param u: time-discrete control input\n"
":param recalc: If true, it updates the state evolution and the cost value.")
":param recalc: If true, it updates the state evolution and the cost value (default True).")
.def<void (ActionModelUnicycle::*)(const boost::shared_ptr<ActionDataAbstract>&, const Eigen::VectorXd&,
const Eigen::VectorXd&)>("calcDiff", &ActionModelUnicycle::calcDiff_wrap,
bp::args(" self", " data", " x", " u"))
bp::args("self", "data", "x", "u"))
.def<void (ActionModelUnicycle::*)(const boost::shared_ptr<ActionDataAbstract>&, const Eigen::VectorXd&)>(
"calcDiff", &ActionModelUnicycle::calcDiff_wrap, bp::args(" self", " data", " x"))
"calcDiff", &ActionModelUnicycle::calcDiff_wrap, bp::args("self", "data", "x"))
.def<void (ActionModelUnicycle::*)(const boost::shared_ptr<ActionDataAbstract>&, const Eigen::VectorXd&,
const bool&)>("calcDiff", &ActionModelUnicycle::calcDiff_wrap,
bp::args(" self", " data", " x", " recalc"))
.def("createData", &ActionModelUnicycle::createData, bp::args(" self"), "Create the unicycle action data.")
bp::args("self", "data", "x", "recalc"))
.def("createData", &ActionModelUnicycle::createData, bp::args("self"), "Create the unicycle action data.")
.add_property(
"costWeights",
bp::make_function(&ActionModelUnicycle::get_cost_weights, bp::return_value_policy<bp::return_by_value>()),
......@@ -69,7 +69,7 @@ void exposeActionUnicycle() {
"Action data for the Unicycle system.\n\n"
"The unicycle data, apart of common one, contains the cost residuals used\n"
"for the computation of calc and calcDiff.",
bp::init<ActionModelUnicycle*>(bp::args(" self", " model"),
bp::init<ActionModelUnicycle*>(bp::args("self", "model"),
"Create unicycle data.\n\n"
":param model: unicycle action model"));
}
......
......@@ -9,6 +9,7 @@
#ifndef BINDINGS_PYTHON_CROCODDYL_CORE_ACTIVATION_BASE_HPP_
#define BINDINGS_PYTHON_CROCODDYL_CORE_ACTIVATION_BASE_HPP_
#include "crocoddyl/core/utils/exception.hpp"
#include "crocoddyl/core/activation-base.hpp"
namespace crocoddyl {
......@@ -23,7 +24,8 @@ class ActivationModelAbstract_wrap : public ActivationModelAbstract, public bp::
void calc(const boost::shared_ptr<ActivationDataAbstract>& data, const Eigen::Ref<const Eigen::VectorXd>& r) {
if (static_cast<std::size_t>(r.size()) != nr_) {
throw std::invalid_argument("r has wrong dimension (it should be " + std::to_string(nr_) + ")");
throw_pretty("Invalid argument: "
<< "r has wrong dimension (it should be " + std::to_string(nr_) + ")");
}
return bp::call<void>(this->get_override("calc").ptr(), data, (Eigen::VectorXd)r);
}
......@@ -31,7 +33,8 @@ class ActivationModelAbstract_wrap : public ActivationModelAbstract, public bp::
void calcDiff(const boost::shared_ptr<ActivationDataAbstract>& data, const Eigen::Ref<const Eigen::VectorXd>& r,
const bool& recalc = true) {
if (static_cast<std::size_t>(r.size()) != nr_) {
throw std::invalid_argument("r has wrong dimension (it should be " + std::to_string(nr_) + ")");
throw_pretty("Invalid argument: "
<< "r has wrong dimension (it should be " + std::to_string(nr_) + ")");
}
return bp::call<void>(this->get_override("calcDiff").ptr(), data, (Eigen::VectorXd)r, recalc);
}
......@@ -46,21 +49,20 @@ void exposeActivationAbstract() {
"In crocoddyl, an activation model takes the residual vector and computes the activation\n"
"value and its derivatives from it. Activation value and its derivatives are computed by\n"
"calc() and calcDiff(), respectively.",
bp::init<int>(bp::args(" self", " nr"),
bp::init<int>(bp::args("self", "nr"),
"Initialize the activation model.\n\n"
":param nr: dimension of the cost-residual vector"))
.def("calc", pure_virtual(&ActivationModelAbstract_wrap::calc), bp::args(" self", " data", " r"),
.def("calc", pure_virtual(&ActivationModelAbstract_wrap::calc), bp::args("self", "data", "r"),
"Compute the activation value.\n\n"
":param data: activation data\n"
":param r: residual vector")
.def("calcDiff", pure_virtual(&ActivationModelAbstract_wrap::calcDiff),
bp::args(" self", " data", " r", " recalc=True"),
.def("calcDiff", pure_virtual(&ActivationModelAbstract_wrap::calcDiff), bp::args("self", "data", "r", "recalc"),
"Compute the derivatives of the residual.\n\n"
"It computes the partial derivatives of the residual vector function\n"
":param data: activation data\n"
":param r: residual vector \n"
":param recalc: If true, it updates the residual value.")
.def("createData", &ActivationModelAbstract_wrap::createData, bp::args(" self"),
.def("createData", &ActivationModelAbstract_wrap::createData, bp::args("self"),
"Create the activation data.\n\n")
.add_property(
"nr",
......@@ -71,7 +73,7 @@ void exposeActivationAbstract() {
bp::class_<ActivationDataAbstract, boost::noncopyable>(
"ActivationDataAbstract", "Abstract class for activation data.\n\n",
bp::init<ActivationModelAbstract*>(bp::args(" self", " model"),
bp::init<ActivationModelAbstract*>(bp::args("self", "model"),
"Create common data shared between AMs.\n\n"
"The action data uses the model in order to first process it.\n"
":param model: action model"))
......
......@@ -17,16 +17,16 @@ namespace python {
namespace bp = boost::python;
void exposeActivationQuadraticBarrier() {
bp::class_<ActivationBounds>(
"ActivationBounds",
"Activation bounds.\n\n"
"The activation bounds describes the lower and upper vector plus it activation range\n"
"(between 0 and 1), its default value is 1.",
bp::init<Eigen::VectorXd, Eigen::VectorXd, double>(bp::args(" self", " lb", " ub", " beta=1."),
"Initialize the activation model.\n\n"
":param lb: lower bounds\n"
":param ub: upper bounds\n"
":param beta: range of activation (between 0 to 1)"))
bp::class_<ActivationBounds>("ActivationBounds",
"Activation bounds.\n\n"
"The activation bounds describes the lower and upper vector plus it activation range\n"
"(between 0 and 1), its default value is 1.",
bp::init<Eigen::VectorXd, Eigen::VectorXd, double>(
bp::args("self", "lb", "ub", "beta"),
"Initialize the activation model.\n\n"
":param lb: lower bounds\n"
":param ub: upper bounds\n"
":param beta: range of activation (between 0 to 1, default 1)"))
.add_property("lb", bp::make_getter(&ActivationBounds::lb, bp::return_value_policy<bp::return_by_value>()),
"lower bounds")
.add_property("ub", bp::make_getter(&ActivationBounds::ub, bp::return_value_policy<bp::return_by_value>()),
......@@ -41,19 +41,18 @@ void exposeActivationQuadraticBarrier() {
"activation equations:\n"
"a(r) = 0.5 * ||r||^2 for lb < r < ub\n"
"a(r) = 0. for lb >= r >= ub.",
bp::init<ActivationBounds>(bp::args(" self", " bounds"),
bp::init<ActivationBounds>(bp::args("self", "bounds"),
"Initialize the activation model.\n\n"
":param bounds: activation bounds\n"
":param ub: upper bounds\n"
":param beta: range of activation (between 0 to 1)"))
.def("calc", &ActivationModelQuadraticBarrier::calc_wrap, bp::args(" self", " data", " r"),
.def("calc", &ActivationModelQuadraticBarrier::calc_wrap, bp::args("self", "data", "r"),
"Compute the inequality activation.\n\n"
":param data: activation data\n"
":param r: residual vector")
.def<void (ActivationModelQuadraticBarrier::*)(const boost::shared_ptr<ActivationDataAbstract>&,
const Eigen::VectorXd&, const bool&)>(
"calcDiff", &ActivationModelQuadraticBarrier::calcDiff_wrap,
bp::args(" self", " data", " r", " recalc=True"),
"calcDiff", &ActivationModelQuadraticBarrier::calcDiff_wrap, bp::args("self", "data", "r", "recalc"),
"Compute the derivatives of inequality activation.\n\n"
":param data: activation data\n"
"Note that the Hessian is constant, so we don't write again this value.\n"
......@@ -61,8 +60,8 @@ void exposeActivationQuadraticBarrier() {
":param recalc: If true, it updates the residual value.")
.def<void (ActivationModelQuadraticBarrier::*)(const boost::shared_ptr<ActivationDataAbstract>&,
const Eigen::VectorXd&)>(
"calcDiff", &ActivationModelQuadraticBarrier::calcDiff_wrap, bp::args(" self", " data", " r"))
.def("createData", &ActivationModelQuadraticBarrier::createData, bp::args(" self"),
"calcDiff", &ActivationModelQuadraticBarrier::calcDiff_wrap, bp::args("self", "data", "r"))
.def("createData", &ActivationModelQuadraticBarrier::createData, bp::args("self"),
"Create the weighted quadratic action data.")
.add_property("bounds",
bp::make_function(&ActivationModelQuadraticBarrier::get_bounds,
......
......@@ -22,24 +22,24 @@ void exposeActivationQuad() {
"Quadratic activation model.\n\n"
"A quadratic action describes a quadratic function that depends on the residual, i.e.\n"
"0.5 *||r||^2.",
bp::init<int>(bp::args(" self", " nr"),
bp::init<int>(bp::args("self", "nr"),
"Initialize the activation model.\n\n"
":param nr: dimension of the cost-residual vector"))
.def("calc", &ActivationModelQuad::calc_wrap, bp::args(" self", " data", " r"),
.def("calc", &ActivationModelQuad::calc_wrap, bp::args("self", "data", "r"),
"Compute the 0.5 * ||r||^2.\n\n"
":param data: activation data\n"
":param r: residual vector")
.def<void (ActivationModelQuad::*)(const boost::shared_ptr<ActivationDataAbstract>&, const Eigen::VectorXd&,
const bool&)>(