rigid-body sim · EKF · LQR

Declare the craft.
manta writes the math.

A Python-first, CasADi-backed framework for drones, rockets, underwater vehicles, and satellites. Simulation, state estimation, and control synthesis over a single declarative model — run it natively in Python, then lower the exact same model to embedded C++.

quickstart.py truth + estimator over one world
from manta import World, Craft, Sim, EKF, TargetNumpy
from manta.fields import GravityField
from manta.parts import IMU, Mass, Thruster

drone = Craft("drone")
drone.add(Mass("body", mass=1.5, moi=(.05, .05, .08)))
drone.add(Thruster("t", force=(0, 0, 1)))
drone.add(IMU("imu", gyro_noise_sigma=.005))

w = World().add_field(GravityField(g=(0, 0, -9.81)))
w.add_craft(drone, position=(0, 0, 5))

sim = TargetNumpy(Sim(w))     # truth model
ekf = TargetNumpy(EKF(w))     # estimator over the same world
why manta
model → transform → target

Three siblings, one model

Declare a World once. Sim, EKF, and LQR are siblings over it — each owns its math and emits a typed Module a backend lowers.

error-state · SO(3)

Manifold-aware EKF

Orientation stays on the quaternion sheet. Process and measurement noise are auto-assembled by autodiff from the noise channels you declared.

python → c++

Develop here, deploy embedded

Debug in native Python, then lower the identical model to a typed Eigen C++ class over flat-C kernels — the same loop, both backends.

system id · MAP

Fit to real flights

Promote physical parameters — masses, thruster gains, mounts — and recover them from logged controls and measurements.

World Sim / EKF / LQR Module IR TargetNumpy · TargetCpp · TargetJax