Library / SDK
loco-3d/crocoddyl avatar
loco-3d/crocoddyl

Crocoddyl: optimal control for robots that have to touch things

Crocoddyl is an optimal control library for robot control under contact sequence. Its solver is based on various efficient Differential Dynamic Programming (DDP)-like algorithms

1,322 stars216 forksC++BSD-3-Clause

At a glance

What is it?
Crocoddyl is a C++ optimal control library for robot motion under a contact sequence, built on differential dynamic programming solvers and on Pinocchio for the robot dynamics, with Python bindings and automatic code generation. It suits legged and humanoid control, and it expects you to supply the model, the costs and the contact sequence yourself.
Who is it for?
Adopt Crocoddyl if you are doing trajectory optimisation for a robot that makes or breaks contact, you already use Pinocchio, and you can accept writing the dynamics, the costs and the contact sequence yourself. Do not adopt it as a general motion planning library or as a replacement for a simpler controller, since the machinery is built around a structured optimal control problem rather than around planning.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Trajectories and feedback gains from a contact sequence

Crocoddyl is an optimal control library for robot control under a contact sequence, and the description of what it computes is precise: it computes optimal trajectories and feedback gains. Those two outputs are what distinguish an optimal control library from a motion planner. A trajectory is a sequence of states and controls, and a feedback gain is the local correction the controller applies when reality diverges from the plan, which is what a legged robot needs, because the ground it assumes is not the ground it gets. The other half of the design is the contact sequence, which is the structure that makes the problem tractable: if you know in advance which contacts are active over which interval, you can write the dynamics for each interval and let the solver work on the resulting structured problem. The solvers themselves are based on novel and efficient differential dynamic programming algorithms, that is DDP-like methods, which is a family that computes a trajectory by repeatedly linearising the dynamics and costs around the current guess and then taking a descent step, with a forward and a backward sweep. The library is the work of the robotics group at LAAS, and the README points at the underlying publications for the theory.

A menu of solvers, and why you would not always pick the same one

Crocoddyl is described as versatile, and the first item on the list of what makes it so is the range of optimal control solvers it ships: FDDP, OdynSQP, Intro and Ipopt. That list is short but each entry answers a different question. FDDP is the library's own DDP variant for problems with constraints, and the naming in the examples directory, with files comparing `boxfddp_vs_boxddp`, shows the FDDP and unconstrained DDP paths being exercised side by side. OdynSQP is an optimal control solver built on a sequential quadratic programming formulation, Ipopt is an interior point solver, and Intro is a solver with its own approach. The practical point is that the choice is part of your problem definition rather than an implementation detail, and the examples directory contains both `fwddyn` and `invdyn` variants of the same motions, which tells you the library supports both forward and inverse dynamics formulations of the same task. For an adopter, the sensible first step is to run the example closest to your own system rather than to read about the solvers, because the difference between them shows up in convergence behaviour on your problem, not in the documentation.

Derivatives, code generation and where the speed comes from

The performance story in the README is built on derivatives, and there are three routes offered. Analytical and sparse derivatives come via Pinocchio, which is also used for fast computation of the robot dynamics, and Pinocchio is additionally the source of the differential geometry support, which matters when your state is a Lie group element rather than a vector of angles. Automatic differentiation is available via CppAD, and numerical differentiation is supported as well, which is the pragmatic fallback when you have not written an analytic model. Then there is code generation in both C++ and Python via CppADCoGen, which is how you turn a symbolic derivative expression into compiled code and remove the autodiff overhead from your inner loop. The efficiency claims that follow are specific: cache friendly code, multi-threading support via OpenMP, Python bindings including abstractions via Boost Python, C++11, 14, 17 and 20 compliance, extensive testing, and the code generation paths. Put together, the intended workflow is that you prototype in Python with autodiff, then generate C++ or Python code for the part that runs at control rate, which is a workflow the library is clearly designed around rather than an accident of the implementation.

Six ways to install it, and the one you should probably use

The installation section offers a path for nearly every setup, and the breadth tells you something about the audience. For conda there is a single command, `conda install crocoddyl -c conda-forge`, and conda-forge is where the package is published and versioned. For pip there is `pip install --user crocoddyl`. For Arch there is the AUR, installed with your favourite AUR helper such as paru. For Nix, both `crocoddyl` and `python3Packages.crocoddyl` are in nixpkgs, and the repository is also a flake, so you can run a Python shell with the library straight from the source with `nix run github:loco-3d/crocoddyl`, or reference it from your own flake by setting the `crocoddyl.url` to that repository. The CI and developer build cache is the Geppetto cache on cachix. For ROS you clone the repository with `--recursive` into a catkin workspace and compile it. For Debian and Ubuntu there is the robotpkg route, which means adding the robotpkg repository and its key, installing the package and then exporting the environment variables for the binary, the pkg-config path, the library path and the Python path under `/opt/openrobots`. For a source build you need Pinocchio, Eigen, eigenpy and Boost in place first.

bash
conda install crocoddyl -c conda-forge
bash
pip install --user crocoddyl
bash
nix run github:loco-3d/crocoddyl

For most people the conda or the pip route is the one to start with, because the source route exists to work on the library itself rather than to use it.

The examples directory is the best documentation in the repository

The examples are numerous enough to be a curriculum rather than a sample, and their names are worth reading as a table of contents. There are biped gaits and biped pose problems, a biped walk with an upper bound, a double pendulum in both continuous and discrete variants, and aerial manipulator problems in forward and inverse dynamics form. Then there is the humanoid set, with a backflip, a frontflip, a bar routine, a monkey bar, a handstanding example, a manipulation example and a manipulation example with an upper bound, each again in forward or inverse dynamics form. The `boxfddp_vs_boxddp` example is a direct comparison of the constrained and unconstrained solvers on the same problem, which is exactly the kind of experiment a user should copy. Two conventions are visible and worth adopting. The `_fwddyn` and `_invdyn` suffixes distinguish the two formulations of the same motion, and the `_ubound` suffix marks problems with state constraints. For someone learning the library, the fastest route is to take the example that matches your robot's task, change the model, and read the cost and the contact sequence.

Bindings, ROS packaging and the shape of the project

The repository is a C++ library with a Python surface, and the packaging reflects that. There is an `include/` and `src/` tree, a `bindings/` directory, a `cmake/` directory with a `crocoddyl.cmake` module, a top level `CMakeLists.txt` and `package.xml` for ROS packaging, along with `dependencies.rosinstall` for catkin workspaces, a `flake.nix` and `flake.lock` for the Nix route, a `pyproject.toml` that configures ruff for the Python parts, and a `.pre-commit-config.yaml`. The Python side comes with `notebooks/` for exploration and a `unittest/` directory, and the build uses black as the code style, which the README badge states. Quality signals are visible too, with the CI running on a GitLab instance with a pipeline badge and a coverage badge, the documentation generated as Doxygen HTML, and a `PUBLICATIONS.md` file collecting the papers behind the methods, which the README recommends to anyone who wants to learn the solvers. The project also carries a CHANGELOG, a CONTRIBUTING guide and a `benchmark/` directory, so performance work is part of the repository rather than something done elsewhere.

What you have to build yourself

The boundary of the library is worth stating plainly, because a contact sequence based optimal control library can sound more general than it is. Crocoddyl supplies the solvers, the integrators, the derivative machinery and the code generation, and it expects you to supply the parts that are specific to your robot. The list of components it names as available includes various integrators, dynamics, costs and constraints, which is a menu rather than a model, so the model of your robot, the cost functions that express what you want, and the contact sequence itself are yours to write. That is a deliberate division, and it is why the library sits on top of Pinocchio instead of reimplementing robot dynamics, since the dynamics is the part that is well solved and heavily shared. The practical consequence for an adopter is that the value arrives in two stages. In the first, the examples and the Python bindings get you a working reference solution, and in the second, you replace the model and the costs with your own, which is where the code generation and the sparsity of the derivatives start to pay for the setup effort.

Editorial conclusion

Adopt Crocoddyl if you are doing trajectory optimisation for a robot that makes or breaks contact, you already use Pinocchio, and you can accept writing the dynamics, the costs and the contact sequence yourself. Do not adopt it as a general motion planning library or as a replacement for a simpler controller, since the machinery is built around a structured optimal control problem rather than around planning. Before you build, install it through conda or pip rather than from source, since the source route expects Pinocchio, Eigen, eigenpy and Boost to be present already, and decide which solver suits your problem, because the menu includes FDDP, OdynSQP, Intro and Ipopt and they differ in how they handle the contact structure. The licence is BSD-3-Clause, the current release is 3.2.1 from 2026-05-10, and the last push was on 2026-10-13 on the devel branch.

Frequently asked questions

What is Crocoddyl used for?

It is an optimal control library for robot control under a contact sequence. It computes optimal trajectories and feedback gains, using differential dynamic programming style solvers, and it relies on Pinocchio for fast computation of robot dynamics and analytical derivatives.

Which solvers does Crocoddyl include?

The README lists FDDP, OdynSQP, Intro and Ipopt among the available optimal control solvers, and the examples directory contains a file named `boxfddp_vs_boxddp` that exercises the constrained and unconstrained variants against the same problem.

How do I install Crocoddyl?

The shortest routes are `conda install crocoddyl -c conda-forge` and `pip install --user crocoddyl`. Arch users can use the AUR, Nix users can run `nix run github:loco-3d/crocoddyl` because the repository is a flake, ROS users clone with `--recursive` into a catkin workspace, and Debian and Ubuntu users can use the robotpkg repository.

Does Crocoddyl generate code and run in parallel?

Yes. The README lists code generation in both C++ and Python via CppADCoGen, multi-threading support via OpenMP, Python bindings including abstractions via Boost Python, and compliance with C++11, 14, 17 and 20. Derivatives can be analytical and sparse through Pinocchio, automatic through CppAD, or numerical.

What licence is Crocoddyl under?

BSD-3-Clause, as shown by the licence badge in the README and the LICENSE file in the repository. The current release is 3.2.1 from 2026-05-10, and the default branch is devel.

Official sources

  1. Issues
  2. License: BSD-3-Clause
  3. loco-3d/crocoddyl on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/loco-3d-crocoddyl.svg)](https://hysenlabs.com/projects/loco-3d-crocoddyl)

Was this useful?