Fields¶
Each Field is a typed superposition of Disturbance objects, combined
per each disturbance's combining flag. See
Fields and disturbances for the concepts.
Base classes¶
manta.fields.Field ¶
Base for a typed physical field — a host that CARRIES disturbances.
A Field fixes value_shape (the CasADi-MX type its disturbances
produce) and registers compatible disturbances via add(). Two kinds
of field extend it:
SuperposedField— the disturbances SUM into onevalue_at_sym(point, t)(gravity, B-field, fluid, collision).OpticalField(an enumerated field) — the disturbances are kept SEPARATE and enumerated, never summed (a camera draws one box per ellipsoid). It has novalue_at_sym.
Field itself is the shared host (the registry + the value-shape
contract); it is not meant to be instantiated directly.
Source code in manta/fields/base.py
add ¶
Register a disturbance with this field. Returns self for chaining.
Source code in manta/fields/base.py
manta.fields.Disturbance ¶
Bases: DeclarationHost, ABC
Base for one contribution to a Field.
Subclass and implement contribute_at_sym(point, t). The returned
MX must have the Field's value shape (e.g. Vec3[WorldFrame] for
GravityField). Multiple disturbances on the same field combine
according to their combining flag (see Field.value_at_sym).
Disturbances may declare State / Noise channels at class scope.
The framework picks them up at compile time exactly like it does
for Parts:
* Each State slot becomes a graph input + output named
<disturbance.name>.<slot>; the disturbance's attribute is
rebound to the symbolic input inside contribute_at_sym.
* Each white Noise channel becomes a per-tick graph input.
* Each RW Noise channel (sigma > 0) synthesizes a bias state +
driver, evolving via bias_next = bias + sqrt(dt)·driver.
Args:
name — identifier used as the IR-slot prefix. Must be
unique across the world's disturbances. Defaults
to <ClassName>_<counter>.
combining — how this disturbance's contribution composes with
others on the same field. See Field.value_at_sym
for the per-stage rule. One of:
"additive" (default) — straight linear sum.
"averaged" — arithmetic-mean stage; the running
additive total + every averaged
contribution are averaged together.
"projected" — only the component of this
contribution that's orthogonal to
(or extends) the running sum is
kept. Order-dependent across
multiple projected entries; the
canonical order is insertion.
Source code in manta/fields/base.py
contribute_at_sym
abstractmethod
¶
Return this disturbance's contribution at the given world-frame
point at world-clock time t (Scalar MX). Output type matches
the host Field's value type. Static disturbances accept t and
ignore it.
Source code in manta/fields/base.py
Gravity¶
manta.fields.GravityField ¶
Bases: SuperposedField
Gravitational acceleration g(point) in the WorldFrame.
value_at_sym(point) returns Vec3[WorldFrame] giving the
acceleration a free-falling test mass would experience at point.
The add_uniform builder returns self for chaining:
GravityField().add_uniform((0,0,-9.81)). As a
convenience, the constructor accepts g=(gx,gy,gz) for the common
single-uniform case — equivalent to one add_uniform call.
Source code in manta/fields/gravity.py
add_uniform ¶
Attach a position-independent gravity vector. Returns self.
Other disturbances (point-mass, J2, …) attach via the generic
field.add(PointMassGravity(...)).
Source code in manta/fields/gravity.py
manta.fields.UniformGravity ¶
Bases: Disturbance
Position-independent gravity vector. The standard default for sims that don't care about altitude variation.
Args: g_vec — (x, y, z) gravity acceleration in WorldFrame, m/s². Conventionally (0, 0, -9.81) for Earth-near-surface with z pointing up.
Source code in manta/fields/gravity.py
manta.fields.PointMassGravity ¶
Bases: Disturbance
Newtonian gravity from a point mass at a fixed anchor position.
g(p) = -GM · (p - r_src) / |p - r_src|³
Args: position — (x, y, z) source position in WorldFrame, meters. GM — gravitational parameter (G·M), m³/s². For Earth GM ≈ 3.986e14; for the Moon ≈ 4.903e12. eps — softening length to avoid singularity at r→0 (m). Defaults to 1.0 — far below any realistic orbital scale, well above numerical noise.
Source code in manta/fields/gravity.py
manta.fields.J2Gravity ¶
Bases: Disturbance
J2 oblateness perturbation around a point mass.
For an oblate spheroid with equatorial bulge, the gravitational potential acquires a J2 term beyond the point-mass; the corresponding acceleration is
g_J2(r) = -(3/2) · J2 · GM · R_eq² / r⁵ · [
(1 - 5(ẑ·r̂)²) · r + 2(ẑ·r̂)·|r|·ẑ
]
where ẑ is the polar (spin) axis. This is the perturbation only —
add it alongside a PointMassGravity to model the full field.
Args: position — (x, y, z) planet center in WorldFrame, m. GM — gravitational parameter (G·M), m³/s². J2 — dimensionless J2 coefficient. Earth: 1.0826e-3. eq_radius — equatorial radius, m. Earth: 6.378e6. polar_axis — unit polar/spin axis in WorldFrame. Default (0, 0, 1). eps — softening length, m.
Source code in manta/fields/gravity.py
manta.fields.BodyPointMassGravity ¶
Bases: Disturbance
Inverse-square gravity from a point mass that RIDES a craft — the
field a GravitySource part emits to simulate a massive body (planet,
asteroid, station) moving through the sim. Same law as
PointMassGravity, but the source position tracks the carrying
craft's pose (read from the active trace), not a fixed world point.
Args: craft — the craft carrying the source. offset_body — the source position in the craft's body frame, m. GM — gravitational parameter (G·M), m³/s². eps — softening length, m. Default 1.0.
Source code in manta/fields/gravity.py
Fluid¶
manta.fields.FluidField ¶
Bases: SuperposedField
Fluid density + bulk velocity over the world frame.
The field value at a point is a FluidState. Concrete sources
(uniform background, localized currents, planet-registered ocean +
atmosphere) are added as Disturbance subclasses to one FluidField
instance.
The add_uniform builder returns self for chaining; other
disturbances attach via field.add(CurrentFlow(...)). The constructor
accepts density= for the common single-uniform case (no flow) —
equivalent to one add_uniform.
Source code in manta/fields/fluid.py
add_uniform ¶
Attach a uniform density (+ optional flow). Returns self.
manta.fields.FluidState
dataclass
¶
Local fluid properties at an world-frame point.
density — kg/m³. CasADi-MX scalar (so it composes with symbolic state in tracing). velocity — bulk fluid velocity at the point, Vec3[WorldFrame].
Disturbances and FluidField.value_at_sym return / consume this
type. Per-component addition is defined so the Field base class can
sum disturbances without special-casing this field.
manta.fields.UniformFluid ¶
Bases: Disturbance
Position-independent fluid: constant density + (optional) flow.
Args: density — kg/m³. Common values: ~1.225 (air), ~1025 (seawater), ~1000 (fresh water). velocity — bulk flow vector in WorldFrame, m/s. Default zero.
Source code in manta/fields/fluid.py
manta.fields.CurrentFlow ¶
Bases: Disturbance
Localized current — adds a velocity contribution without changing density.
v1 ships the simplest non-spatial model: a constant velocity
contribution everywhere. Future versions will accept a Gaussian
envelope around a centroid, or a tabulated current map. For now
CurrentFlow((0, 1, 0)) adds 1 m/s in +y to whatever density the
background UniformFluid provides.
Args: velocity — world-frame velocity contribution, m/s.
Source code in manta/fields/fluid.py
manta.fields.CraftWindBubble ¶
Bases: Disturbance
A localized wind contribution anchored to a craft.
Density contribution is zero (wind doesn't change density). The
velocity contribution equals the estimated wind vector inside the
bubble (where |point - craft.position| < radius) and zero
outside, gated by a hard ca.if_else.
The wind itself is a RandomWalkNoise channel — the framework
synthesizes a state slot named <bubble.name>.wind and an RW
driver, evolving the wind via wind_next = wind + sqrt(dt)·driver.
Args:
craft — owning Craft. The bubble follows the craft's
WorldFrame position symbolically (read inside
contribute_at_sym from the active trace's bindings).
radius — bubble radius in meters. Outside this, the
contribution is exactly zero.
sigma — RW drift density σ/√Hz for the wind. Larger ⇒ EKF
expects more drift in the wind estimate.
The default combining="averaged" matches the design intent:
overlapping bubbles compromise on the mean of their wind
estimates.
Source code in manta/fields/wind_bubble.py
Magnetic¶
manta.fields.MagField ¶
Bases: SuperposedField
Magnetic flux density field, Vec3[WorldFrame] in Tesla.
The add_uniform builder returns self for chaining; other
disturbances attach via field.add(DipoleMag(...)). The constructor
accepts B=(bx,by,bz) for the common single-uniform case — equivalent
to one add_uniform.
Source code in manta/fields/mag.py
add_uniform ¶
manta.fields.UniformMag ¶
Bases: Disturbance
Position-independent magnetic field.
For a quick first-order Earth-field model, common values (in Tesla): * Equator ≈ 30 µT — (3e-5, 0, 0) horizontal * Mid-lat ≈ 50 µT — (2e-5, 0, -4.5e-5) inclined * Pole ≈ 60 µT — (0, 0, -6e-5)
Source code in manta/fields/mag.py
manta.fields.DipoleMag ¶
Bases: Disturbance
Point magnetic dipole.
B(p) = μ₀/(4π) · [3(m·r̂)·r̂ − m] / r³
where r = p − r_src, r̂ = r/|r|.
Args: position — (x, y, z) dipole position in WorldFrame, m. moment — (mx, my, mz) magnetic dipole moment in WorldFrame, A·m². For Earth this is ~8e22 (purely fictitious point-dipole approximation). eps — softening length (m) to avoid singularity at the dipole position. Default 1e-3.
Source code in manta/fields/mag.py
manta.fields.BodyDipoleMag ¶
Bases: Disturbance
A magnetic dipole that RIDES a craft — the field a MagneticSource
part emits to model the magnetic signature of motors, magnets, or
magnetized structure on a moving vehicle. Same law as DipoleMag, but
BOTH the dipole position and its moment vector are body-fixed: the
position tracks the craft and the moment rotates with it (read from
the active trace), so a magnetometer on another craft sees the field
swing as the source turns.
Args: craft — the craft carrying the source. offset_body — dipole position in the craft body frame, m. moment_body — dipole moment in the craft body frame, A·m². eps — softening length, m. Default 1e-3.
Source code in manta/fields/mag.py
Collision¶
manta.fields.CollisionField ¶
Bases: SuperposedField
Outward-penetration vector field for contact detection.
Per the Field-base pattern, every registered Disturbance is an obstacle shape that contributes its own penetration vector when the query point is inside it. Multi-obstacle overlap composes additively.
Source code in manta/fields/base.py
manta.fields.HalfSpace ¶
Bases: Disturbance
Infinite half-space below a plane.
The plane is defined by an origin point on it and an outward
normal. Points where (p − origin) · normal < 0 are inside the
obstacle (below the plane); the outward direction is +normal.
Args: origin — point on the plane (world frame), m. normal — outward unit normal (world frame). For a ground plane at z=0 with air above and solid below: origin=(0,0,0), normal=(0,0,1).
Source code in manta/fields/collision.py
manta.fields.Sphere ¶
Bases: Disturbance
Solid sphere obstacle — e.g. a whole planet's surface.
Points with |p − center| < radius are inside; the outward
direction is the local radial, so a craft standing anywhere on the
sphere gets an up-is-outward contact normal — no per-site ground
plane needed.
Args: center — sphere centre (world frame), m. radius — sphere radius, m.
Source code in manta/fields/collision.py
Optical¶
manta.fields.OpticalField ¶
Bases: Field
A scene of semantic ellipsoids. Carries (does not sum) its
disturbances; the camera part enumerates ellipsoids and projects
each quadric to an image-frame bounding box.
Source code in manta/fields/base.py
add_ellipsoid ¶
Attach a fixed scenery ellipsoid. Returns self for chaining.
Source code in manta/fields/optical.py
manta.fields.SemanticEllipsoid ¶
Bases: _EllipsoidBase
A fixed semantic ellipsoid in the world (a landmark / scenery).
Args: center — (x, y, z) world position of the ellipsoid center, m. semi_axes — (a, b, c) half-extents along the ellipsoid's own axes, m. orientation— wxyz quaternion (world ← ellipsoid). Default upright. label — integer class id the camera reports with the box.
Source code in manta/fields/optical.py
manta.fields.BodySemanticEllipsoid ¶
Bases: _EllipsoidBase
A semantic ellipsoid that rides a craft (emitted by an
OpticalSource). Center and orientation track the carrying craft's
pose, read from the active trace; the semi-axes are the body extent.