janus::MultipleShooting provides a transcription method for optimal control problems that enforces continuity via high-accuracy numerical integration (using CasADi's integrator interface, e.g., CVODES or IDAS). It divides the time horizon into intervals with piecewise-constant controls and connects them with continuity constraints. This works in symbolic mode via the janus::Opti interface. The class lives in <janus/optimization/MultiShooting.hpp>.
Quick Start
auto [x, u, tau] = ms.setup(3, 1, 0.0, 2.0, opts);
return dxdt;
});
ms.add_continuity_constraints();
ms.set_final_state(0, 10.0);
ms.set_final_state(1, 5.0);
Multiple shooting transcription.
Definition MultiShooting.hpp:33
Main optimization environment class.
Definition Opti.hpp:167
void minimize(const SymbolicScalar &objective)
Set objective to minimize.
Definition Opti.hpp:555
OptiSol solve(const OptiOptions &options={})
Solve the optimization problem.
Definition Opti.hpp:603
Umbrella header that includes the entire Janus public API.
JanusVector< SymbolicScalar > SymbolicVector
Eigen vector of MX elements.
Definition JanusTypes.hpp:72
JanusVector< NumericScalar > NumericVector
Eigen::VectorXd equivalent.
Definition JanusTypes.hpp:67
T cos(const T &x)
Computes cosine of x.
Definition Trig.hpp:46
T sin(const T &x)
Computes sine of x.
Definition Trig.hpp:21
casadi::MX SymbolicScalar
CasADi MX symbolic scalar.
Definition JanusTypes.hpp:70
Options for MultipleShooting.
Definition MultiShooting.hpp:20
std::string integrator
Integrator plugin ("cvodes", "rk", "idas").
Definition MultiShooting.hpp:22
double tol
Integrator required tolerance.
Definition MultiShooting.hpp:23
int n_intervals
Number of shooting intervals.
Definition MultiShooting.hpp:21
Core API
| Method | Description |
| MultipleShooting(opti) | Construct with a janus::Opti instance |
| setup(n_states, n_controls, t0, tf, opts) | Create decision variables and time grid |
| set_dynamics(ode) | Set the ODE function: (x, u, t) -> dxdt |
| add_continuity_constraints() | Apply integrator-based continuity constraints |
| add_dynamics_constraints() | Unified alias for add_continuity_constraints() |
| set_initial_state(x0) | Set initial boundary condition |
| set_final_state(xf) | Set final boundary condition |
| n_intervals() | Number of shooting intervals |
| time_grid() | Normalized time grid [0, 1] |
MultiShootingOptions exposes:
- n_intervals: number of shooting intervals
- integrator: integrator type ("cvodes", "rk", "idas")
- tol: integrator tolerance
Advantages over Direct Collocation
- High Accuracy: Uses variable-step/variable-order integrators instead of fixed-order polynomials.
- Stiffness Handling: Better suited for stiff systems where low-order schemes fail.
- Sparse Structure: Retains the block-sparse structure of the NLP.
Disadvantages
- Cost: Evaluating integrator sensitivities can be computationally expensive compared to polynomial defects.
- Initialization: Can be harder to initialize if dynamics are unstable.
Usage Patterns
Basic Workflow
auto [x, u, tau] = ms.setup(n_states, n_controls, 0.0, T, opts);
return ;
});
ms.add_continuity_constraints();
ms.set_initial_state(x0);
ms.set_final_state(xf);
SymbolicScalar variable(double init_guess=0.0, std::optional< double > scale=std::nullopt, std::optional< double > lower_bound=std::nullopt, std::optional< double > upper_bound=std::nullopt)
Create a scalar decision variable.
Definition Opti.hpp:200
Unified Comparison Example
The file examples/optimization/transcription_comparison_demo.cpp runs and compares Direct Collocation, Multiple Shooting, Pseudospectral, and Birkhoff Pseudospectral on the same brachistochrone problem so you can compare solver behavior and NLP structure directly. It includes solve-time performance statistics and a convergence sweep across grid sizes.
When to Use
| Use Case | Why |
| High-fidelity simulation | Integrator accuracy |
| Stiff ODEs | Adaptive implicit methods |
| Matching simulation results | Same integration scheme |
| Fewer decision variables | Accuracy without more nodes |
See Also