Model — World, Craft, Coupling¶
The declarative layer: build a World, populate it with Crafts and
Couplings, then hand it to a transform.
World¶
manta.World ¶
Top-level simulation container.
Source code in manta/world.py
finalize ¶
Resolve the compile-time registrations and lock the model.
Runs once (idempotent): planets contribute their standing
disturbances to the shared fields, field-source parts emit their
craft-anchored disturbances, cameras are pointed at the optical
ellipsoids they can see, and PlanetState initial-state wrappers
resolve to WorldFrame. Afterwards add_craft / add_field /
add_planet / add_coupling raise — every transform built over
this world sees the same finalized model.
Called automatically by the first transform (Sim, EKF,
LQR, …); call it directly only to lock a world early.
Source code in manta/world.py
add_field ¶
Register a Field with this world. One instance per Field
subclass is allowed — call field.add(disturbance) on the
registered instance to attach more sources.
Returns self for chaining.
Source code in manta/world.py
get_field ¶
get_or_create_field ¶
Return the registered field of type cls, creating + adding
a fresh empty instance if none is registered. Used by
Planet.register_disturbances so a planet's contributions land
on the same field instance whether or not the user pre-added
one.
Source code in manta/world.py
add_planet ¶
Register a planet with this world. The planet's
register_disturbances(world) is called at Sim(world)
time, attaching its standing contributions to the world's
shared fields. Multi-planet worlds superpose contributions
from every registered planet.
Source code in manta/world.py
add_craft ¶
add_craft(craft, *, position=(0.0, 0.0, 0.0), orientation=(1.0, 0.0, 0.0, 0.0), velocity=(0.0, 0.0, 0.0), angular_velocity=(0.0, 0.0, 0.0), **extra_state)
Add a craft to the world.
Args:
craft — the Craft instance.
position — craft-origin position, WorldFrame (m).
orientation — wxyz quaternion, world-from-craft.
velocity — craft-origin velocity, WorldFrame (m/s).
angular_velocity — body rates in CraftFrame (rad/s) — the
same convention as the integrated state
(what a strapped-down gyro reads). For a
non-identity orientation, world-frame
rates must be rotated into the body first.
**extra_state — per-part state overrides
(e.g., **{"wheel.angle": 0.5}).
Source code in manta/world.py
add_coupling ¶
Add an inter-craft coupling. Both endpoint crafts must already
be registered via add_craft. The coupling forces them into the
same connected component at compile time → one shared compiled
tick over both.
Source code in manta/world.py
Craft¶
manta.Craft ¶
A collection of parts with shared rigid-body dynamics.
Internally a craft is a tree of parts rooted at Craft.root (a
RootPart). craft.add(part) is sugar for craft.root.add(part);
craft.parts returns a flat tuple of all parts in the tree (DFS
order). Nested composition (e.g. a joint hosting another joint
for a pan-tilt gimbal) is supported via the standard composite
add() chain on individual parts.
State (13 DOF):
position : Vec3[WorldFrame]
orientation : Quat[WorldFrame, CraftFrame]
velocity : Vec3[WorldFrame]
angular_velocity : Vec3[CraftFrame]
plus one Scalar per R1 State slot declared on any of the parts.
Source code in manta/craft.py
parts
property
¶
Flat tuple of every part in the tree, root first (DFS order). Excludes the root itself.
total_mass
property
¶
Sum of the declared mass of every genuinely inertial part
(contributes_inertia trait) — gain-like mass parameters
(e.g. TrajectoryEndpoint's feedforward) don't count.
add ¶
aggregate_inertials ¶
Public-facing accessor: see _aggregate_inertials. Useful for
external inspection and tests.
sample_noise ¶
Draw one tick of white-Gaussian samples for every declared
Noise slot on every part. Returns a dict of
"<part>.<noise>" → np.ndarray ready to merge into the state
dict before calling the compiled tick.
Slots whose sigma is 0 return zero vectors without consuming RNG state (so a deterministic-seed sim stays reproducible regardless of which noise channels are active).
Source code in manta/craft.py
initial_state ¶
Build the initial state dict for the compiled tick.
Returns a dict with the rigid-body slots (position, orientation,
velocity, angular_velocity) AND a "<part_name>.<state_name>"
entry for every part that declares state. Defaults come from each
State declaration's init; keyword overrides replace them by name.
Source code in manta/craft.py
Coupling¶
manta.Coupling ¶
Bases: ABC
Abstract base for inter-craft constraints.
A concrete subclass (e.g. Tether) declares two craft endpoints
(craft_a / craft_b) and produces the extra wrench terms they
exchange (compute_wrenches_sym) in the tick graph for the connected
component. The presence of a Coupling forces both crafts into the same
compile unit.
compute_wrenches_sym
abstractmethod
¶
The wrench pair (wrench_on_a, wrench_on_b) this coupling
applies, given each craft's TickContext. Frames: each wrench is
in its own craft's CraftFrame, at that craft's origin.
Source code in manta/couplings/base.py
manta.couplings.Tether ¶
Bases: Coupling
Linear spring-damper tether between two TetherEndpoint Parts.
Args: craft_a, craft_b — the two coupled crafts (Craft instances). endpoint_a, endpoint_b — names of the TetherEndpoint Parts on craft_a / craft_b (strings). stiffness — spring constant k, N/m. damping — damper constant c, N·s/m. rest_length — natural length L_rest, m. The spring exerts zero force at exactly this separation.
Convention: tension positive — when L > rest_length the tether pulls A toward B (and B toward A). Compression (L < rest_length) pushes them apart, mimicking a rigid rod. For a string that goes slack, set stiffness=0 below rest_length using a custom subclass — the v1 Tether models a rigid spring (no slack).
Source code in manta/couplings/tether.py
compute_wrenches_sym ¶
Return (wrench_on_a_at_craft_origin, wrench_on_b_at_craft_origin).
Both wrenches are in their respective CraftFrame, lifted to the body origin (force-at-offset + lever-arm torque). The compile layer adds these directly to each craft's aggregate net wrench.
Source code in manta/couplings/tether.py
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | |