Python API Reference

Module: cuda_mppi

Install via:

pixi run install    # recommended
# or: pip install --no-build-isolation -e .

Configuration

MPPIConfig

Shared configuration struct passed to every controller.

cfg = cuda_mppi.MPPIConfig(
    num_samples=900,     # K: parallel rollouts
    horizon=40,          # T: timesteps per rollout
    nx=13,               # state dimension
    nu=4,                # control dimension
    lambda_=1000.0,      # temperature (inverse sensitivity)
    dt=0.02,             # integration timestep (s)
    u_scale=1.0,         # legacy uniform control scale (prefer set_control_sigma)
    w_action_seq_cost=0.0,  # S-MPPI smoothness cost weight
    num_support_pts=0,   # K-MPPI: number of RBF support points (0 = disabled)
    lambda_info=0.0,     # I-MPPI: information gain weight
    alpha=0.0,           # I-MPPI: baseline mixing coefficient
)
cfg.set_control_sigma([2.0, 0.5, 0.5, 0.3])  # per-channel noise std (overrides u_scale)

Dynamics

QuadrotorDynamics

13-DOF quadrotor in NED/FRD frame. State: [x, y, z, vx, vy, vz, qw, qx, qy, qz, ωx, ωy, ωz]. Control: [thrust, roll_rate, pitch_rate, yaw_rate].

dyn = cuda_mppi.QuadrotorDynamics()
dyn.mass      = 2.0    # kg
dyn.gravity   = 9.81   # m/s²
dyn.tau_omega = 0.05   # body-rate time constant (s)

x_next = dyn.step(state, action, dt)  # host-side RK4 step

DoubleIntegrator / DoubleIntegrator3D

di = cuda_mppi.DoubleIntegrator()    # 4-DOF: [x, y, vx, vy], control: [ax, ay]
di3 = cuda_mppi.DoubleIntegrator3D() # 6-DOF: [x, y, z, vx, vy, vz], control: [ax, ay, az]

Costs

TrackingCost

Quadratic reference-tracking cost for the quadrotor.

cost = cuda_mppi.TrackingCost()
cost.set_Q_pos([5e3, 5e3, 5e3])              # position weights
cost.set_Q_vel([4e1, 4e1, 4e1])              # velocity weights
cost.Q_quat = 2e1                             # quaternion attitude weight
cost.set_Q_omega([2e1, 2e1, 2e1])            # angular rate weights
cost.set_R([2e-2, 2e-1, 2e-1, 2e-1])        # control effort weights
cost.set_R_delta([1e-3, 1e-2, 1e-2, 1e-2])  # control rate weights
cost.terminal_weight = 10.0
cost.set_hover_pos([0.0, 0.0, -2.5])         # hover fallback position (NED)

InformativeCost

Multi-objective cost combining tracking, information gain (FSMI), and collision avoidance.

cost = cuda_mppi.InformativeCost()
cost.lambda_info       = 1.0
cost.lambda_local      = 1.0
cost.collision_penalty = 100.0
cost.target_weight     = 10.0
cost.use_grid_3d       = False
cost.bound_x_min = -10.0; cost.bound_x_max = 10.0
cost.bound_y_min = -10.0; cost.bound_y_max = 10.0

Occupancy Grids

OccupancyGrid2D

grid = cuda_mppi.OccupancyGrid2D(
    width=200, height=200, resolution=0.1,
    origin_x=-10.0, origin_y=-10.0
)
grid.upload(np_array)                              # float32 (height, width)
grid.update_fov(x, y, yaw, fov_range, fov_angle)  # ray-cast sensor update
arr = grid.download()

OccupancyGrid3D

grid = cuda_mppi.OccupancyGrid3D(
    width=100, height=100, depth=50, resolution=0.2,
    origin_x=-10.0, origin_y=-10.0, origin_z=0.0
)
grid.upload(np_array)   # float32 (depth, height, width)
arr = grid.download()

InfoField

GPU-accelerated FSMI information field.

field = cuda_mppi.InfoField(
    Nx=200, Ny=200, resolution=0.1, origin_x=-10.0, origin_y=-10.0
)
field.compute(grid, uav_x, uav_y, sensor_range, sensor_fov)
info_map = field.download()   # float32 (Ny, Nx)

Controllers

All controllers share a common interface:

Method Description
compute(state) Run \(K\) GPU rollouts and compute optimal action (synchronous — blocks until done)
get_action() Return first action of the optimal sequence
shift() Shift nominal sequence forward by one step
set_nominal_control(u) Broadcast a control vector across the full horizon
set_applied_control(u) Set the control actually applied at the last step
set_cost(cost) Swap the cost object
set_state_reference(ref, horizon) Upload flattened reference trajectory (T × nx,)

QuadrotorMPPI

Standard MPPI for the 13-DOF quadrotor.

ctrl = cuda_mppi.QuadrotorMPPI(config, dynamics, cost)

QuadrotorKMPPI

Kernel MPPI — RBF-parameterised noise in support-point space, ~6× faster per step than standard MPPI.

config.num_support_pts = 10   # M ≪ T RBF knots
ctrl = cuda_mppi.QuadrotorKMPPI(config, dynamics, cost)

QuadrotorSMPPI

Smooth MPPI — velocity-space noise integration.

ctrl = cuda_mppi.QuadrotorSMPPI(config, dynamics, cost)

Known issue: Effective exploration collapses to near-zero for small \(\Delta t\) because integrate_actions_kernel scales noise by \(\Delta t\). Tracking diverges until issue #30 is fixed.

QuadrotorIMPPI

Informative MPPI — biased sampling toward reference + information gain. Extends the standard MPPI interface with:

ctrl = cuda_mppi.QuadrotorIMPPI(config, dynamics, cost)
ctrl.set_reference_trajectory(ref_flat, horizon)
ctrl.update_cost_grid(grid_2d)
ctrl.update_cost_grid_3d(grid_3d)
ctrl.update_cost_info_field(info_field)

DI3IMPPI

I-MPPI for the 3D double integrator (DoubleIntegrator3D + InformativeCost3D).

ctrl = cuda_mppi.DI3IMPPI(config, dynamics_3d, cost_3d)

JITMPPIController

Generic controller with runtime-compiled dynamics and cost (NVRTC). Write your dynamics and cost in C++/CUDA strings; the library compiles a .cubin at startup.

ctrl = cuda_mppi.JITMPPIController(
    config,
    dynamics_code="__device__ void step(...) { ... }",
    cost_code="__device__ float compute(...) { ... }",
    include_paths=["/path/to/cuda-mppi/include"],
)
ctrl.compute(state)
action    = ctrl.get_action()
nom_traj  = ctrl.get_nominal_trajectory()  # (T × nu) numpy array

Planning

TrajectoryGenerator

Layer-2 informative path planner that generates waypoint sequences maximising information gain subject to dynamic feasibility.

tg_cfg = cuda_mppi.TrajectoryGeneratorConfig()
tg_cfg.horizon = 20
tg_cfg.num_samples = 500

tg = cuda_mppi.TrajectoryGenerator(tg_cfg, mppi_ctrl)
result = tg.plan(state, info_field)
waypoints = result.trajectory   # (T × 3) numpy array