Targets and runtimes¶
A Target* lowers a Module to a backend. TargetNumpy returns the
matching native-Python runtime view; TargetCpp emits an Eigen C++
library; TargetJax emits a jitted rollout.
Targets¶
manta.TargetNumpy ¶
Lower a typed Module — or any transform exposing .module()
(Sim, EKF, LQR, a recurrence block) — to the matching
native-Python view (sim / filter / recurrence / regulator), or the
bare kernel engine when no view matches.
compile=True builds the kernel's CasADi functions with cc and
calls them as externals instead of interpreting the MX graph
(bit-identical, ~8x per call; cached on disk). Pair with NumpySim's
step_n to fold substeps for a further amortization.
Source code in manta/codegen/numpy/__init__.py
manta.TargetCpp ¶
C++ codegen target.
Args:
x — a Module, or a transform with .module().
out_dir — destination directory (created if missing).
class_name — C++ class name. Conventionally PascalCase.
basename — filename stem; defaults to class_name.lower().
namespace — C++ namespace enclosing the emitted class.
Returns:
EmitResult with paths to every emitted file plus a small funcs
summary (world_name / dims).
Source code in manta/codegen/cpp/__init__.py
manta.TargetJax ¶
Lower a Module (or any transform exposing .module()) to jitted
JAX kernels by name + a lax.scan rollout builder — the functional
artifacts a training loop wants (see manta.codegen.jax.JaxModule).
jax is imported only when this is called, so manta itself never
requires it.
Source code in manta/codegen/__init__.py
manta.NoiseDriver ¶
Draws the per-step samples that make an oracle Module's noise live.
Binds to the NOISE port's fields (name, dim, σ); each sample() is an
independent N(0, σ²) draw per active channel. Deliberately thin and
swappable — kept out of the pure kernels — and simply omitted on a
deploy target.
Source code in manta/codegen/numpy/_noise.py
Numpy runtime views¶
The view TargetNumpy(x) returns is determined by the Module's shape.
manta.codegen.NumpyRuntime ¶
The generic engine over a typed Module: state storage + the
typed-arg gather → kernel call → scatter. Views subclass it.
Source code in manta/codegen/numpy/_runtime.py
call ¶
Run one entry point. values/kwargs are keyed by port or state
name (use the dict for dotted names); TIME ports default to 0.
The Hosting contract: a THREADED module's state is the caller's —
supply state fields by name in values (unsupplied ones fall back
to the engine's last-written copy) and read the fresh writes from
the returned dict alongside the entry's returns. A HELD module's
state lives in the runtime and is read/written in place; only the
entry's returns come back.
Source code in manta/codegen/numpy/_runtime.py
build_u ¶
Resolve a {name: value} dict (full or suffix names) to the
flat control vector over the Module's declared defaults.
Source code in manta/codegen/numpy/_runtime.py
set_parameters ¶
Override promoted-parameter values (full or suffix names); every subsequent kernel call uses them. Values not overridden stay at the Module's declared defaults.
Source code in manta/codegen/numpy/_runtime.py
param_vector ¶
The flat promoted-parameter vector: declared defaults merged
with set_parameters overrides, in port-field order.
Source code in manta/codegen/numpy/_runtime.py
manta.codegen.NumpySim ¶
Bases: NumpyRuntime
The simulation oracle. The runtime holds the nested state dict
(sim.state); step(dt, u={...}) applies the commands and advances it,
realizing that step's sensor readings. The kernel is pure: rate gating is
the loop's job — build a rate_gate(...) / command_latch() from the
model's declared rates and apply them yourself (uniform across backends).
Read sensors with outputs() (raw nested) or reading(name) (one, by
name).
Source code in manta/codegen/numpy/_sim.py
state
property
writable
¶
The held nested state (lazy-seeded; mutate in place to set commands or override slots).
initial_state ¶
Fresh nested initial state: the manifold slots' defaults plus
input/noise placeholder entries (commands you may set; noise seeds
that stay at zero — a NoiseDriver draw never enters the dict).
Source code in manta/codegen/numpy/_sim.py
step ¶
Advance the held state by dt. u is {input: value} (full or
suffix names) applied this step over the held sim.state inputs.
Runs the oracle kernel (one noise draw) and returns the new state
dict. Rate-gated actuators: pass a command_latch()-held u.
Source code in manta/codegen/numpy/_sim.py
step_n ¶
Advance n substeps of dt in ONE folded call — u commands held
(ZOH) for the block, state chained through a mapaccum of the step
kernel. Output readings + state are bit-identical to n sequential
step(dt, u=u) calls; compiled (_enable_compile) it runs the whole
inner loop in C.
Falls back to sequential stepping when a NoiseDriver is attached (a
fresh stochastic draw per substep cannot be folded).
Source code in manta/codegen/numpy/_sim.py
outputs ¶
Sensor readings from the most recent step (nested, realized with that step's noise draw).
attach_driver ¶
Attach a stochastic NoiseDriver: every active (σ>0) channel of
the Module's NOISE port is sampled each step, so truth is noisy
with the very σ the EKF reads for R/Q. Without one the sim is a
noiseless oracle.
Source code in manta/codegen/numpy/_sim.py
reading ¶
The latest raw reading for a sensor (full or suffix name) from the
most recent step. Readings are realized every step; gate feeding
yourself with a rate_gate(name) if the sensor is rate-limited.
Source code in manta/codegen/numpy/_sim.py
rate_gate ¶
A RateGate at sensor name's declared rate (fires every step if
the sensor has none). Apply it in your loop:
if g.due(t): ekf.update(name, sim.reading(name), u=u).
Source code in manta/codegen/numpy/_sim.py
command_latch ¶
A CommandLatch over the actuators' declared intake rates (ZOH).
Apply it once per step and pass the held u to BOTH sim.step and
ekf.predict, so the filter predicts on the command truth acted on.
Source code in manta/codegen/numpy/_sim.py
manta.codegen.NumpyFilter ¶
Bases: NumpyRuntime
A predict/update filter over a held x/P, with baked per-sensor
update kernels — the same surface every backend emits.
You own the loop, identically in numpy and C++: fold each fresh measurement at the pre-predict state, then predict.
for nm in sensors:
if gate[nm].due(t):
ekf.update(nm, sim.reading(nm), u=u) # update-then-...
ekf.predict(dt, u=u) # ...-predict
The update-then-predict order is yours to keep: a reading sampled at the interval start belongs against the current (pre-predict) state.
Source code in manta/codegen/numpy/_filter.py
Q
property
writable
¶
Default process noise for predict (overridden per-call by
predict(dt, Q=...); None uses the model's baked L Σ Lᵀ).
state_dict ¶
reset ¶
Reset held state. state is a nested/flat dict merged over
the Module's declared initial values, or a flat ambient vector
taken verbatim; P resets the covariance.
Source code in manta/codegen/numpy/_filter.py
predict ¶
Advance the estimate by dt. Process noise: an explicit Q, else
self.Q, else the model's baked L Σ Lᵀ. u is {input: value}
(unset inputs fall to the Module's declared defaults); pass the same
held u truth ran on.
Source code in manta/codegen/numpy/_filter.py
update ¶
Fold one measurement at the current state.
update("gps.position", z)— by sensor name (full or suffix), through the baked Joseph-update kernel.update(h_sym, z, R=R)— a caller-suppliedh(x)callable + measurement covariance (custom measurements; numpy-only).
Source code in manta/codegen/numpy/_filter.py
manta.codegen.NumpyRegulator ¶
Bases: NumpyRuntime
A stateless control law: map a state estimate to commands via
control(estimate) -> {input: value}.
Holds the live reference point x_ref (seeded from the Module's
built operating point); retarget() moves it at runtime.
Source code in manta/codegen/numpy/_regulator.py
retarget ¶
Move the reference point the law regulates to (nested or flat dict, merged over the CURRENT reference). The gain K is NOT re-solved: exact wherever the dynamics are invariant along the moved direction (e.g. translating a hover setpoint); build a new LQR for a genuinely different operating point (new A/B or trim).
Source code in manta/codegen/numpy/_regulator.py
u ¶
Control vector for a flat ambient state (full-spec layout).
Source code in manta/codegen/numpy/_regulator.py
control ¶
Map a state estimate (nested or flat dict) → {input: value},
merged over the live reference point (unsupplied slots sit at
the reference, i.e. zero error).
Source code in manta/codegen/numpy/_regulator.py
manta.codegen.NumpyRecurrence ¶
Bases: NumpyRuntime
A stateful dataflow block (PID, Madgwick, …): step(dt, **inputs)
advances the held state and computes the readouts.
Source code in manta/codegen/numpy/_recurrence.py
Rate helpers¶
manta.RateGate ¶
Window gate: due(t) fires once per 1/rate window (and records
it); rate is None fires every call. Holds only the last fire time —
the one bit of state a sample-and-hold window needs.
Source code in manta/rates.py
manta.CommandLatch ¶
Zero-order-hold for rate-gated control inputs. latch(inputs, t)
returns inputs with every gated entry replaced by the value latched
at its last window boundary — mid-window writes are ignored until the
next boundary. Apply it once per step and pass the held dict to BOTH
sim.step and ekf.predict, so the filter predicts on the same held
command truth acted on. Ungated inputs pass through untouched (and an
empty gate set is a no-op that returns the dict unchanged).