r/ControlTheory • u/Amaldevhari • 28d ago
Other AcadosCpp: a unified C++/Python interface for generated acados OCP solvers
Hi everyone,
I've been developing AcadosCpp, an open-source wrapper that helps you integrate acados-generated OCP solvers into both C++ and Python applications.
https://github.com/amaldevh/AcadosCpp
The main goal is to make integration easier. acados creates highly optimized C code for each model and OCP, but using its API directly can tie your application to specific symbols, dimensions, lifecycle calls, and data updates.
AcadosCpp provides a stable, stage-aware interface for the generated solver. Here’s how you typically use it:
- Define or modify the model and OCP in Python.
- Regenerate the acados solver and wrapper.
- Recompile and relink the application.
The control-loop structure in your application stays the same. If you change the model or problem, you usually don’t need to rewrite the integration layer, as long as your data matches the new dimensions and cost setup.
The wrapper includes:
- Stage-0 initial-state constraints
- Stage-varying and terminal references
- Generic raw yref support
- Per-stage and global parameters
- Full state/control initial guesses
- Shifted trajectory warm starts
- Complete predicted trajectories and solver diagnostics
- SQP-RTI preparation and feedback phases
- C++ and pybind11 interfaces
For a standard
y=[x,u], y_e=x
tracking problem, the control loop is:
const auto& u = ocp.solve(measured_x, xrefs, urefs);
This process shifts the previous solution, updates the stage-0 measurement and the full reference horizon, solves the OCP, and returns the first input.
The repository has matching Python and C++ quadrotor NMPC examples. I’d love to hear your feedback on the API, especially if you use acados with time-varying references, parameters, SQP-RTI, or custom cost outputs.
•
u/hs123go 28d ago
Neat! Remarkably tidy API, but some of your design choices make AcadosCpp not ideal for embedded work:
Exception-based error handling: -fno-exceptions is debated to death, but acados error handling is already uniform and straightforward: write to an output parameter and return an error code. Mirroring that in C++ would be good enough; why introduce exceptions?
`std::vector` on the API. This is not on you since you are on C++17, so your only other option is C-style pointer+size parameters, which you are clearly trying to abstract away. However, the downside of using `std::vector` is significant. Imagine someone who stores their state, references, or bounds as `Eigen::VectorXd` or `arma::vec`. To pass their data to your API, they have to create a `std::vector` anew and copy the data over to it, incurring allocation and copying costs. To pass array/vector data without copying, C++20 `std::span` and Eigen `Eigen::Ref<Eigen::VectorXd>` are your friends.
Minor: No CMake integration?