Getting Started
Prerequisites
- OS: Linux (Ubuntu 20.04+)
- CUDA Toolkit: 11.0 or higher (11.8+ recommended)
- CMake: 3.18+
- C++ compiler: GCC 9+ / Clang 10+ (C++17)
- Pixi: recommended package manager — pixi.sh
Installation
Python bindings (recommended)
The fastest path to a working environment uses Pixi, which pins all native and Python dependencies (Eigen, nanobind, CMake, CUDA headers) through a conda-forge lock file.
git clone https://github.com/riccardo-enr/cuda-mppi.git
cd cuda-mppi
# Build and install the Python extension into the pixi environment
pixi run installpixi run install runs pip install --no-build-isolation -e . inside the managed environment. The extension is rebuilt from source via scikit-build-core and placed in the active Python prefix — no manual CMake invocation needed.
Verify the installation:
pixi run python -c "import cuda_mppi; print(cuda_mppi.MPPIConfig)"Standalone C++ build
Use this if you want to run the C++/CUDA tests or use the library as a CMake dependency without Python.
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j$(nproc)CMake options:
| Option | Default | Effect |
|---|---|---|
CUDA_MPPI_BUILD_TESTS |
ON |
Build GTest suites and standalone test binaries |
CUDA_MPPI_BUILD_EXAMPLES |
OFF |
Build simulation examples |
CMAKE_CUDA_ARCHITECTURES |
75;86;89 |
Target GPU architectures |
Running the tests
Python tests
pixi run test # pytest tests/ -v
pixi run tracking # quadrotor lemniscate tracking with plotpixi run tracking runs tests/test_tracking_comparison.py and prints the RMSE for each controller variant. Expected baselines:
| Controller | RMSE (m) | Compute (mean) |
|---|---|---|
| MPPI | ~0.60 | ~0.17 ms |
| K-MPPI | ~0.79 | ~0.03 ms |
| S-MPPI | skipped | — (see issue #30) |
C++ / CUDA tests
# GTest suites — must report [ PASSED ]
./build/tests/mppi_gtest
./build/tests/i_mppi_gtest
# Standalone verification scripts — print PASSED on success
./build/tests/pendulum_test
./build/tests/bspline_test
./build/tests/fsmi_unit_testQuick Python example
import numpy as np
import cuda_mppi
# --- dynamics & cost ---
dyn = cuda_mppi.QuadrotorDynamics()
dyn.mass = 2.0; dyn.gravity = 9.81; dyn.tau_omega = 0.05
cost = cuda_mppi.TrackingCost()
cost.set_Q_pos([5e3, 5e3, 5e3])
cost.set_Q_vel([4e1, 4e1, 4e1])
cost.set_R([2e-2, 2e-1, 2e-1, 2e-1])
# --- controller ---
cfg = cuda_mppi.MPPIConfig(
num_samples=900, horizon=40, nx=13, nu=4, lambda_=1000.0, dt=0.02
)
cfg.set_control_sigma([2.0, 0.5, 0.5, 0.3])
ctrl = cuda_mppi.QuadrotorMPPI(cfg, dyn, cost)
# --- one control step ---
state = np.zeros(13, dtype=np.float32)
state[6] = 1.0 # unit quaternion (hover)
ctrl.compute(state)
action = ctrl.get_action()
print("Action:", action) # [thrust, roll_rate, pitch_rate, yaw_rate]