System identification¶
Fit a model's physical parameters (Fit) or its noise model (NoiseFit)
to recorded data. See Fit parameters from a log
for a worked recipe.
Parameter fit¶
manta.Fit ¶
MAP parameter fit over recorded windows (see module docstring).
Args:
world — the model. Finalized by the internal Sim; the
fit never mutates it (until result.apply()).
parameters — {param name/suffix: Prior | None}. Names resolve
against the model's promotable Parameters
(<craft>.<part>.<param>); None = flat prior
(only safe for parameters the data fully observes).
Source code in manta/fit/_map.py
solve ¶
Build the windowed prediction-error + prior NLP and solve it.
Args:
windows — the recorded data (≥ 1 Window).
weights — optional per-sensor scalar weights on the squared
residuals ({sensor name/suffix: w}); use
1/σ_meas² to whiten mixed-unit sensors. Default 1.
verbose — IPOPT iteration output.
ipopt_options — extra nlpsol options, merged last.
Source code in manta/fit/_map.py
manta.FitResult ¶
Fitted values + Gauss-Newton posterior diagnostics.
Attributes:
values — {full param name: fitted value} (float for
scalars, ndarray for vectors).
labels — one entry per fitted scalar component.
log_scale — per-component bool; True ⇒ the sigmas below
are RELATIVE (log-space).
prior_sigma — per-component prior σ (inf = no prior).
posterior_sigma — per-component Gauss-Newton posterior σ from
(JᵀJ + Σ₀⁻¹)⁻¹. ≈ prior σ ⇒ the data did
not inform this component.
JtJ — data-only Gauss-Newton information matrix in
decision space; its small eigenvalues are the
unidentifiable directions.
objective — final loss value.
stats — IPOPT return stats.
converged — IPOPT's success flag; False ⇒ the values below
are the failed solve's final iterate (a
RuntimeWarning was emitted), not an optimum.
Source code in manta/fit/_map.py
weak_directions ¶
The k least-informed directions of the DATA alone: list of
(eigenvalue, {label: component}) for the smallest eigenvalues
of JᵀJ. A near-zero eigenvalue is an unidentifiable parameter
combination (e.g. the thrust/mass scale).
Source code in manta/fit/_map.py
apply ¶
Write the fitted values back onto the world's Part instances.
A transform built afterwards (Sim(world), EKF(world), a C++
deploy) bakes them in as constants.
Source code in manta/fit/_map.py
summary ¶
Per-component table: fitted value, prior σ vs posterior σ.
post/prior ≈ 1 flags a component the data did not inform —
its fitted value is your prior talking, not the flight.
Source code in manta/fit/_map.py
Noise fit¶
manta.NoiseFit ¶
Innovation-NLL fit of noise σ values (see module docstring).
Args:
world — the model (dynamics/geometry at their — ideally
already fitted — declared values).
noise — {channel name/suffix: Prior | None}. Channel names
are the declaration names (drone.imu.gyro_noise,
drone.imu.gyro_bias); priors are relative
(log-space), None = flat.
sensors — measurement outputs the filter consumes (default: all
with traces required in every window).
Source code in manta/fit/_nll.py
solve ¶
Minimize the windows' total innovation NLL + prior over log-σ.
Args:
windows — recorded data; every chosen sensor needs a trace
in every window.
P0 — initial tangent covariance per window, P0 · I.
Keep small when x0 is trusted (synthetic truth);
grow it for estimator-seeded initial states.
Source code in manta/fit/_nll.py
manta.NoiseFitResult ¶
Fitted σ per channel + Laplace posterior diagnostics.
prior_sigma / posterior_sigma are RELATIVE (log-space) widths;
posterior ≈ prior means the data didn't inform that σ. converged
is IPOPT's success flag — False ⇒ the values are the failed solve's
final iterate (a RuntimeWarning was emitted), not an optimum.
Source code in manta/fit/_nll.py
apply ¶
Write the fitted σ back onto the owning parts
(<channel>_sigma attributes); transforms built afterwards
(an EKF(world)'s auto-Q/R, a NoiseDriverd truth sim) use
them.
Source code in manta/fit/_nll.py
Inputs¶
manta.Window
dataclass
¶
One fitting window: a short recorded rollout.
Args:
x0 — nested initial state dict (the sim.state shape:
{craft: {slot: value}}). Slots omitted fall back to the
world's initial state.
u — recorded controls: {input name/suffix: scalar | (K,)}.
A scalar is held for the whole window; inputs omitted hold
their model default.
z — recorded sensor readings: {sensor name/suffix:
(K, dim) | (K,)}. Row k is the reading produced by step k
(the step taken FROM state k). For Fit, only sensors
present here enter the loss; for NoiseFit, every chosen
sensor needs a trace.
dt — fixed step, seconds.
t0 — world-clock time of x0.
manta.Prior
dataclass
¶
Gaussian prior on one fitted parameter.
Args:
sigma — 1-σ width. Scalar (isotropic across the parameter's
components) or a per-component sequence. With log=True
it is RELATIVE (log-space): sigma=0.3 ≈ ±30%.
mean — prior mean. None (default) → the model's declared
value.
log — fit log(p) instead of p, elementwise. Strictly-
positive parameters only (mass, moi, a thrust magnitude
along one axis). Keeps every component positive with no
constraint and makes pure scale ambiguities linear.
NoiseFit ignores this flag — noise σ is ALWAYS fit in
log-space, and sigma there is always relative.