RotaOptimalds is a curvature-aware model predictive control framework for vessel route optimization. It combines waypoint tracking, obstacle-aware rerouting, and COLREG encounter classification in a scenario-driven workflow with both C++ and Python implementations.
- solves waypoint-following as a receding-horizon nonlinear MPC problem
- keeps curvature and steering smoothness inside the planning model instead of post-processing them afterward
- supports circular-obstacle detour waypoint generation
- includes preset COLREG encounter scenarios and scan logging
- provides both a C++ / CasADi implementation and a Python port with
casadiandacadosbackends
- use the Python version if you want the fastest path to a reproducible demo
- use the C++ version if you want the compiled solver workflow around the main implementation
Repository layout:
src/: C++ solver sourcescenarios/: C++ scenario filesdocs/: example plots and GIFsRotaOptimaldsPy/: Python portRotaOptimaldsPy/scenarios/: Python scenariosRotaOptimaldsPy/docs/: Python plots and benchmark figures
Contribution notes are in CONTRIBUTING.md. The project is released under the GNU GPL v3.0.
This is the easiest way to reproduce a result from the repository.
Requirements:
- Python 3.10+
pipcasadi,numpy,matplotlib- optional: a working
acadosinstallation if you want theacadosbackend
Setup:
cd RotaOptimaldsPy
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtRun the default scenario:
python3 main.pyRun a specific scenario:
python3 main.py --solver casadi --scenario scenarios/rotaoptimalds_obstacle_alt.iniPlot the result:
python3 plot_receding.py \
--log receding_log.csv \
--wp waypoints.csv \
--scenario scenarios/rotaoptimalds_default.iniPython backend details are documented in RotaOptimaldsPy/README.md.
Requirements:
- CMake 3.16+
- a C++17 compiler
- CasADi C++ headers and library installed locally
Build from the repository root:
cmake -S . -B build
cmake --build build -jIf CMake cannot find CasADi automatically, point it at your CasADi installation:
cmake -S . -B build -DCASADI_ROOT=/path/to/casadi
cmake --build build -jRun the default scenario:
./build/rota_optimal_ds --scenario scenarios/rotaoptimalds_default.iniRun the obstacle scenario:
./build/rota_optimal_ds --scenario scenarios/rotaoptimalds_obstacle.iniPlot the result:
python3 plot_receding.py \
--log receding_log.csv \
--wp waypoints.csv \
--scenario scenarios/rotaoptimalds_default.iniObstacle-aware route result:
- receding-horizon nonlinear MPC
- waypoint tracking with heading and curvature targets
- clothoid-like spatial propagation with sinc regularization
- curvature bounds and steering-rate limits
dsas an optimization variable- CSV logging for closed-loop analysis
- static and animated plotting scripts
- COLREG encounter classification with preset scenarios
The C++ side includes a COLREG encounter module for category-V style vessel encounters:
- head-on
- crossing starboard
- crossing port
- own-ship overtaking
- target-ship overtaking
The current implementation focuses on:
- encounter classification
- preset scenario generation
- constant-velocity scan logging
- static visualization and GIF generation
Each animation shows ship-shaped markers oriented to their heading, fading gradient trails, and live DCPA / TCPA metric panels. The background turns orange when COLREG risk is active.
Run the active COLREG preset:
./build/rota_optimal_ds --scenario scenarios/colreg_runner.iniRun a COLREG time scan:
./build/rota_optimal_ds \
--scenario scenarios/colreg_runner.ini \
--colreg-scan \
--scan-dt 0.5 \
--scan-steps 80 \
--out-colreg-log colreg_scan.csvGenerate a static plot:
python3 plot_colreg_scenario.py --scenario scenarios/colreg_runner.iniGenerate an animation:
python3 animate_colreg_scenario.py --scenario scenarios/colreg_runner.iniPreset selection is controlled in scenarios/colreg_runner.ini via:
colreg_scenario = head_onAvailable values:
head_oncrossing_starboardcrossing_portown_ship_overtakingtarget_ship_overtaking
The planner is built around a curvilinear motion description rather than treating geometry as a post-processing step.
- the predicted state uses
x,y,psi, and curvatureK - the optimizer chooses curvature command
Kcmdand spatial incrementds - turning-radius feasibility appears as curvature bounds
- steering smoothness appears as slew-rate limits and cost regularization
Conceptually, this follows the curvilinear relations dx/ds = cos(chi), dy/ds = sin(chi), and dchi/ds = kappa(s) and turns them into a repeated MPC solve that is practical for closed-loop route generation.
The Python port supports:
casadi: reference Python NLP implementationacados: faster backend for the same MPC structure
Typical comparison workflow:
cd RotaOptimaldsPy
python3 main.py --solver casadi --scenario scenarios/rotaoptimalds_obstacle_alt.ini
python3 main.py --solver acados --scenario scenarios/rotaoptimalds_obstacle_alt.ini
python3 compare_solver_speed.py \
--scenario scenarios/rotaoptimalds_obstacle_alt.ini \
--save docs/solver_speed_comparison.png \
--no-showExample benchmark figure:
This repository already demonstrates the main planning workflow well, but it is still best understood as a research and development codebase rather than a polished end-user application. The strongest audience fit is:
- MPC and optimal control developers
- marine robotics and autonomous navigation researchers
- people comparing
CasADiandacadosworkflows
If you want outside contributions, create a few GitHub issues labeled good first issue and help wanted. The repo now includes a contribution guide and issue templates so new contributors have a clear starting point.
mpc, model-predictive-control, casadi, acados, path-planning, collision-avoidance, marine-robotics, autonomous-systems, colreg, cpp, python











