Library / SDK
leggedrobotics/ocs2 avatar
leggedrobotics/ocs2

OCS2: C++ Optimal Control and Robotics MPC Toolbox

Optimal Control for Switched Systems

1,528 stars328 forksC++BSD-3-Clause

At a glance

What is it?
OCS2 is a BSD-3-Clause C++ toolbox for nonlinear optimal control, with DDP, SQP, SLP, IPM, and MPC implementations tailored to robotic systems. It suits engineers who need more control over optimization structure than a higher-level controller interface provides, but its feature scope brings substantial integration work.
Who is it for?
Engineers building robotic MPC from a C++ codebase should consider OCS2 when they need access to its solver families, switched-system model, or robotics tooling. Projects that need a ready-made controller, a documented one-command setup, or a complete application example without substantial integration work should look elsewhere first.
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 24 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 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

OCS2's nonlinear optimal control scope

OCS2 addresses engineers who formulate and solve nonlinear optimal control problems for robotic systems, particularly when the optimizer must run as Model Predictive Control. Its name expands to Optimal Control for Switched Systems, and that phrase reflects a real capability rather than branding alone: the library supports mode schedules and jump maps, including problems with a single domain or multiple domains. A system whose motion changes behavior at defined transitions can therefore be represented within the same optimization structure.

The target audience is narrower than users of a general-purpose optimization library. OCS2 exposes costs, constraints, dynamics, reference management, rollout interfaces, and solver-specific building blocks. It is also aimed at robotics developers who need kinematics, dynamic models, end-effector tracking, self-collision avoidance, ROS deployment interfaces, and plotting tools around the controller. The README presents examples for systems including a double integrator, cartpole, ballbot, quadrotor, mobile manipulator, and legged robot. Those examples indicate intended use cases, but the README does not claim that every example is a turnkey template for an arbitrary robot.

The project separates the mathematical control layer from the robotics application layer. Based on the repository layout, a user can work directly with `ocs2_core` and `ocs2_oc`, select an implementation under `ocs2_ddp`, `ocs2_mpc`, `ocs2_sqp`, `ocs2_slp`, or `ocs2_ipm`, and add model or deployment support through the Pinocchio, ROS, and robotic example packages. This makes OCS2 more configurable than a controller packaged around one fixed solver, but it also means adoption includes deciding how the pieces fit together.

Solver choices inside OCS2's optimization loop

OCS2 provides several solver families rather than tying the user to one formulation. SLQ is described as a continuous-time constrained DDP implementation in the SLQ/DDP family. iLQR is the discrete-time constrained DDP option. SQP uses multiple shooting and solves its quadratic programming subproblems through HPIPM/BLASFEO. SLP uses sequential linear programming with PIPG, while IPM is a multiple-shooting nonlinear interior-point method.

This distinction matters because the choice is not merely an implementation detail. The README identifies time formulation and subproblem method for the alternatives, but it does not publish a decision table covering convergence, runtime, state dimensions, or constraint behavior. Consequently, an engineer cannot select a solver from the README alone based on measured results. The appropriate first step is to inspect the solver documentation and target example rather than assume that iLQR, SQP, or IPM are interchangeable.

DDP-family components occupy both `ocs2_ddp` and `ocs2_mpc`, while alternative optimization methods have separate packages. This organization lets an application isolate the numerical method from some shared optimal-control definitions. It does not mean that solver selection is independent of problem setup. Dynamics, costs, constraints, discretization, and reference management still have to be expressed through OCS2's interfaces.

The Python bindings are limited to selected components according to the README. OCS2 should therefore not be interpreted as a fully mirrored Python implementation of every C++ solver and robotics tool. The repository also includes `ocs2_mpcnet`, described as tooling for learned policy deployment and training. That extends the repository beyond conventional online optimization, although the README does not explain how MPC-Net integrates with a chosen classical OCS2 control stack.

Dynamics, constraints, and derivative generation

OCS2 models path constraints through Augmented Lagrangian or relaxed barrier methods. Constraints can be hard or soft, so applications can represent requirements differently depending on whether a violation must be resisted or admitted with a penalty. The documentation states that general path constraints are supported, but it does not promise that every constraint type or formulation is interchangeable across every solver.

Derivatives are central to these solvers, and OCS2 offers analytic derivative interfaces as well as automatic differentiation through CppAD. It also lists optional code generation through CppADCodeGen. This gives developers more than one route for supplying derivatives of dynamics, constraints, and costs. It also creates a design choice: the application team must decide whether to write analytic derivatives, use automatic differentiation, or evaluate generated derivatives in its build environment.

For robot models, the `ocs2_pinocchio` area provides URDF-to-model helpers, kinematics, centroidal models, self-collision constraints using HPP-FCL, and visualization support. The README specifically connects these tools with problems such as end-effector tracking and self-collision avoidance. That is useful because it reduces the amount of application-specific model plumbing, although the repository still expects developers to define the control objective and configure the relevant system.

Reference management and rollout interfaces are located in `ocs2_oc` and `ocs2_core`. Based on those package names and the documented building blocks, OCS2 separates problem construction, numerical rollout, and solver infrastructure. The repository does not provide enough information here to claim how these abstractions perform on a particular processor, state dimension, or constraint count.

Installing OCS2 and selecting a ROS branch

The README does not provide copy-and-paste installation commands. For ROS 1, it directs users to the Installation page in the online documentation. ROS 2 users are directed to `installation.md` on the `ros2` branch. Because exact dependency and build commands are absent from the available repository documentation, this article does not invent them.

The first important setup decision is the branch. The `main` branch corresponds to ROS 1, while the `ros2` branch contains the ROS 2 port. Users who follow installation instructions for the wrong branch could encounter a mismatch between the documented ROS interface and their target environment. Branch selection should therefore happen before attempting to build `ocs2_ros_interfaces`, `ocs2_msgs`, or the robotic example nodes.

A first practical use should follow the documentation's installation procedure, then select one robotic example whose system resembles the intended controller. The README lists examples and ROS wrappers but does not include the commands, configuration keys, URDF paths, launch files, or startup sequence needed to run one. Those details cannot be reconstructed safely from package names alone. The official Installation page and the selected example documentation are the authoritative next documents.

ROS integration includes messages, nodes, visualization, and plotting tools. For non-ROS C++ work, the core and solver packages remain the relevant area, while `ocs2_python_interface` exposes selected bindings. For ROS 2 work, the branch-specific installation file is the first documented installation reference.

Switched systems and robotic model boundaries

Switched-system support is OCS2's clearest differentiator within its documented scope. Mode schedules and jump maps let an optimal-control formulation represent transitions between operating modes. That is relevant to robotics when a controller must change dynamics or behavior during a trajectory, although the README does not name a specific commercial robot application using this feature.

The main practical limitation is integration depth. OCS2 is a toolbox, not a documented one-stop robot controller. Its value comes from reusable components, but the user still has to supply or connect dynamics, costs, constraints, references, and deployment interfaces. A team that cannot commit to that C++ and model-oriented workflow may receive more flexibility than it needs.

There is another boundary around documentation depth. The README names solver backends, branches, packages, and examples, but it does not record runtime requirements, minimum hardware, supported compiler versions, numerical tolerances, or upgrade instructions in the excerpt. It also does not explain how to migrate an existing OCS2 application across major versions. These omissions do not show that the documentation is absent from the online site, but they prevent the README from serving as a complete deployment guide.

The repository was not archived, and the last push was on 2026-09-29. The only listed recent release is version `v12.0`, dated 2023-07-14. This shows that repository activity and formal release history are not aligned, so engineers should not infer a current release cadence from repository updates alone. Upgrade cost appears higher than changing a small package because solver interfaces, dependency versions, ROS branches, and generated derivative workflows can all intersect. The exact migration burden is not documented in the README.

BSD-3-Clause licensing and operational use

OCS2 is licensed under BSD 3-Clause, with the license text stored in `LICENCE.txt`. For an engineering adoption review, this identifies the project's permissive license family and provides a concrete file to inspect for redistribution and compliance obligations. This is not legal advice, and organizations should review the actual license text against their distribution model.

The repository includes third-party material under `ocs2_thirdparty/`, while solver documentation names external components such as HPIPM, BLASFEO, PIPG, Pinocchio, HPP-FCL, Eigen, and CppAD-related facilities. The README does not enumerate all dependency licenses or explain how they are packaged. A production release therefore requires a dependency-level license review rather than relying on the top-level `LICENCE.txt` alone.

OCS2 may be a poor fit for a small robotics team seeking a narrowly packaged controller with a short documented setup path. The number of solver choices, model packages, derivative mechanisms, ROS interfaces, and examples creates a broad configuration surface. It is also not documented as a managed service with a compatibility promise. The repository's maintenance evidence is limited to its non-archived status and the last push on 2026-09-29, while the listed release remains `v12.0` from 2023-07-14. Those are concrete reasons to check compatibility before adopting it as an application foundation.

OCS2 versus a higher-level MPC controller framework

The clearest alternative is a higher-level MPC controller that exposes a fixed configuration interface for dynamics, costs, constraints, and controller execution. Such a framework may reduce the amount of C++ integration required because the user works through a narrower application model. OCS2 takes a different approach: it supplies solver and problem-construction packages inside a modular C++ toolbox, giving the application direct access to multiple numerical formulations and switched-system structures.

That difference affects selection criteria. A team that needs to combine CppAD derivatives, analytic derivative interfaces, a specific solver family, Pinocchio-based robot models, or ROS 1 and ROS 2 integration may prefer the access OCS2 provides. A team that mainly wants a ready-made control loop with limited integration work may find the same modularity burdensome.

The comparison should not be reduced to solver performance because the README supplies no benchmark data and this review has not run the project. Verify numerical behavior and resource use against the intended dynamics, horizon, constraints, and processor. Also verify whether your chosen Python, ROS, and Pinocchio dependencies are covered by the branch-specific setup instructions. OCS2's fit depends more on those architectural choices than on a general claim that one MPC approach is always superior.

Editorial conclusion

Engineers building robotic MPC from a C++ codebase should consider OCS2 when they need access to its solver families, switched-system model, or robotics tooling. Projects that need a ready-made controller, a documented one-command setup, or a complete application example without substantial integration work should look elsewhere first. The first checks should be the relevant installation page, the `main` versus `ros2` branch choice, solver compatibility with the intended dynamics and constraints, and whether the required robotic examples cover the target system. For the documented robotics workflow, adoption is closely tied to committing to OCS2's C++ interfaces and its ROS or Pinocchio integration model.

Frequently asked questions

Which ROS version does each OCS2 branch support?

The `main` branch supports ROS 1, while the `ros2` branch provides the ROS 2 port.

Which optimization solvers are available in OCS2?

OCS2 lists SLQ and iLQR for constrained DDP formulations, SQP through HPIPM/BLASFEO, SLP through PIPG, and a multiple-shooting nonlinear interior-point method.

Where are OCS2 installation instructions located?

ROS 1 users are directed to the online documentation's Installation page. ROS 2 users are directed to `installation.md` on the `ros2` branch.

Official sources

  1. leggedrobotics/ocs2 on GitHub
  2. License: BSD-3-Clause
  3. Project website
  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/leggedrobotics-ocs2.svg)](https://hysenlabs.com/projects/leggedrobotics-ocs2)

Was this useful?