Planets¶
A Planet is a world-level entity: a planet-fixed frame, standing
disturbances on the shared fields, and initial-state factories.
manta.Planet ¶
Body-fixed rotating planet frame + field-disturbance source.
Args:
name — identifier (used in repr + lookups).
position — planet center in WorldFrame (m). Default origin.
rotation_axis — unit rotation axis in WorldFrame. Default (0,0,1).
omega — angular rate, rad/s. Positive ⇒ right-hand-rule
rotation about rotation_axis. Earth sidereal
is ~7.272e-5 rad/s; default 0 (non-rotating).
Source code in manta/planets/base.py
R_world_from_planet ¶
3×3 rotation matrix from PlanetFrame to WorldFrame at time t.
Source code in manta/planets/base.py
omega_vec_world ¶
planet_to_world ¶
Position + velocity of a point that, in PlanetFrame at time
t, has coords (p_planet, v_planet). Returns (p_world, v_world).
Velocity transform: v_world = R · v_planet + ω × (p_world − planet.position)
Source code in manta/planets/base.py
position_world_sym ¶
omega_world_sym ¶
R_world_from_planet_sym ¶
3×3 MX rotation from PlanetFrame to WorldFrame at symbolic t.
Rodrigues' formula with angle = omega·t. Branch-free.
Source code in manta/planets/base.py
position ¶
Return a PlanetState wrapping a PlanetFrame position. Pass
directly to World.add_craft(..., position=...) to seed the
craft's initial WorldFrame position from PlanetFrame coords.
Source code in manta/planets/base.py
velocity ¶
Return a PlanetState wrapping a PlanetFrame velocity.
at_rest ¶
Shorthand for planet.velocity(0, 0, 0) — sets the WorldFrame
velocity such that the craft sits at rest in PlanetFrame
(i.e., co-rotates with the planet).
local_tangent_basis ¶
Local East/North/Up unit vectors (WorldFrame) at a WorldFrame point — a purely Cartesian local-tangent frame, no lat/lon.
Up is the local radial (from the planet centre out through the
point). North is the planet's spin axis projected into the
tangent plane and normalised — the same true-north direction a
gyrocompass finds from the spin vector. East = North × Up.
Where North is undefined — the planet isn't rotating, or the
point sits on the spin axis — it falls back to a stable
tangential reference (world +x, else +y), so the basis is always
well-formed (only its azimuth is then arbitrary). Returns
(east, north, up).
Source code in manta/planets/base.py
local_tangent_orientation ¶
World-from-craft quaternion (w, x, y, z) placing the craft in
the local-tangent frame at WorldFrame point position: body
forward (+x) along North, up (+z) along the local radial, yawed by
heading (radians, right-handed about Up — 0 faces North).
Cartesian and general: 'North' is the spin-axis tangential
projection (see local_tangent_basis).
Source code in manta/planets/base.py
scene_at ¶
A local Scene anchored at PlanetFrame point position — a
ground patch with a human-friendly East/North/Up frame, used to
place craft and to translate poses/state for reporting + rendering.
position is in the planet-fixed frame (origin at the planet
centre), so a point on the surface is a planet-radius vector — with
the planet left at the world origin you place a craft anywhere on
it: north pole (0, 0, R_EQ), equator (R_EQ, 0, 0). The scene's
axes are the local tangent frame there (+z up, +x north), optionally
yawed by heading (radians) about up. See Scene for the full API
(at_rest, relative, world_pose).
Source code in manta/planets/base.py
register_disturbances ¶
Called by Sim(world) to attach this planet's standing
contributions to the world's shared fields. Subclasses (Earth,
Moon, ...) override to install gravity / ocean / atmosphere /
magnetic-dipole disturbances. Base default: no-op.
Subclasses should use world.get_or_create_field(FieldClass) to
get the shared instance, then .add(disturbance).
Source code in manta/planets/base.py
manta.planets.Earth ¶
Earth(name='earth', *, position=(0.0, 0.0, 0.0), rotation_rate=None, rotation_axis=(0.0, 0.0, 1.0), sea_level=0.0, water_density=1025.0, air_density=1.225, sea_level_temperature=T0_ISA, lapse_rate=LAPSE_ISA, gravity_mu=MU, include_j2=False, dipole_moment=0.0, waves=None, surface_collision=True, surface_smoothing=0.0)
Bases: Planet
Standard Earth preset.
Args:
name — identifier. Default "earth".
position — planet center in WorldFrame (m).
rotation_rate — angular rate, rad/s. Default: Earth's true
sidereal rate (Earth.SIDEREAL). Pass 0.0 for a
non-rotating Earth. Most users never set this —
place craft with earth.scene_at(...) instead.
sea_level — elevation of the ocean's top above the
planet's equatorial radius, m. Default 0
(sea-level surface coincides with R_EQ).
water_density — ocean density, kg/m³. Default 1025 (seawater).
air_density — atmosphere density at sea level, kg/m³. Default
1.225 (ISA). Sets the sea-level pressure via the
ideal-gas law P0 = ρ0·R·T0; aloft the air
follows the ISA troposphere (lapse + ideal gas),
so density is no longer a pure exponential.
sea_level_temperature — ISA sea-level temperature T0, K. Default
288.15. Drops with altitude at lapse_rate.
lapse_rate — ISA troposphere temperature lapse, K/m. Default
6.5e-3.
gravity_mu — gravitational parameter μ (m³/s²). 0 disables
gravity. Default Earth.MU.
include_j2 — register a J2 oblateness perturbation
alongside the point-mass term. Default False.
dipole_moment — magnetic dipole strength, A·m². 0 disables
magnetic. Default 0.
waves — optional SeaWaves: a sinusoidal moving sea
surface (boundary elevation + underwater
orbital velocity). Default None (flat sea).
surface_collision — register the sea-level sphere as a solid
CollisionField obstacle (a rough model of
the surface), so Collider-footed craft can
stand anywhere on the planet without a
per-site ground plane. Default True.
surface_smoothing — m. Blend the water/air switch over this
length (a C¹ Hermite step in altitude) instead
of a hard if_else. Physically: a finite-size
volume element crosses the surface over its
own diameter; numerically it turns point-
sampled buoyancy from bang-bang into a smooth
ramp (a floating hull finds a stable draft, a
surface-piercing foil gets a smooth lift-vs-
height slope). Default 0 (hard boundary).
Source code in manta/planets/earth.py
planet_radius
property
¶
Radius from planet center to sea-level surface. Equal to R_EQ + sea_level.
manta.planets.Scene ¶
A local East/North/Up frame fixed in a planet's body frame.
Construct via planet.scene_at(position, heading=...) rather than
directly. position is the anchor point in PlanetFrame (typically a
point on the surface); the scene's axes are the local tangent frame
there — +z up (radial), +x north (the planet spin axis projected into
the tangent plane), +y = up×north — optionally yawed by heading
(radians) about up.
Source code in manta/planets/scene.py
R_world_from_scene ¶
3×3 rotation from the scene frame to WorldFrame at time t.
origin_world ¶
world_pose ¶
(origin_world, quat_world_from_scene) at time t — the scene's
own pose, to publish as a parent/anchor entity for rendering.
Source code in manta/planets/scene.py
at_rest ¶
Initial state for a craft at rest in the scene (co-rotating
with the planet) at scene-frame coordinate position, yawed
heading (radians) about local up from the scene's north.
Returns a kwargs dict (position, velocity, orientation,
angular_velocity, all WorldFrame) to splat into
World.add_craft::
w.add_craft(sub, **scene.at_rest((0, 0, -0.2))) # 0.2 m down
w.add_craft(buoy, **scene.at_rest(heading=np.radians(35)))
The orbital velocity ω × r and body spin rate R_craftᵀ·ω are
filled in so the craft is genuinely fixed to the planet (a gyro
reads the planet's spin; it does not drift through the co-rotating
sea/air).
Source code in manta/planets/scene.py
relative ¶
Re-express a craft's WorldFrame state in the scene frame.
state is a per-craft state dict (as from sim.state[name] or
ekf.state_dict()[name]): position/velocity (WorldFrame),
orientation (world-from-craft quaternion), angular_velocity
(body rates). Returns a dict of the same shape with:
position— in scene coordinates,orientation— scene-from-craft quaternion,velocity— velocity relative to the co-rotating scene (i.e. relative to the ground), in scene coords,angular_velocity— body rate relative to the scene's spin (zero for a craft sitting still on the ground).
Any other keys (part states like joint angles) pass through
unchanged. t is the sim time the state was sampled at (needed for
a spinning planet; default 0).
Source code in manta/planets/scene.py
manta.planets.PlanetState ¶
Initial-state value carrying its PlanetFrame origin.
Resolved by World.add_craft at compile time via
planet.planet_to_world(...).
Source code in manta/planets/state.py
manta.planets.SeaWaves
dataclass
¶
Planar deep-water sinusoid riding a planet's sea surface.
The surface elevation (above the sea-level sphere) is
η(p, t) = amplitude · cos(k·ξ − ω·t), ξ = p_planet · direction
with k = 2π/wavelength and ω = k·c. The phase speed c defaults to
the deep-water dispersion relation c = √(g·λ / 2π). Underwater, the
fluid carries the matching first-order orbital velocity — particles
circle with radius amplitude at the surface, decaying as e^{k·z}
with depth — so drag surfaces and foils feel the moving water, not
just the moving boundary.
direction is a planet-frame vector (normalized; its radial
component at the point of interest should be ~0). The wave is a
PLANAR field in planet coordinates — valid for a local patch of
ocean, not a globe-wrapping solution.
Args: amplitude — m (crest height above mean sea level). wavelength — m (crest-to-crest). direction — planet-frame propagation direction. Default +x. speed — phase speed override, m/s. None → deep-water dispersion using the planet's surface gravity.