Attitude¶
- class missiontools.AbstractAttitudeLaw[source]¶
Bases:
ABCBase class for spacecraft/sensor pointing laws.
Stores full 3-DOF body orientation as unit quaternions
[w, x, y, z]. The boresight is always body-z.Subclasses must implement
pointing_eci(),rotate_from_body(), and__repr__(). The frame-conversion methodspointing_lvlh()andpointing_ecef()are provided by the base class.Optional yaw steering can be enabled via
yaw_steering()on subclasses that support it (FixedAttitudeLawandTrackAttitudeLaw).- abstractmethod pointing_eci(r_eci, v_eci, t)[source]¶
Boresight unit vector(s) in the ECI frame.
- Parameters:
r_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI position(s) (m).v_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI velocity(s) (m s⁻¹).t (
array_likeofdatetime64,shape ``(N,)``orscalar) – Observation epoch(s).
- Returns:
npt.NDArray[np.floating]– Unit pointing vector(s) in ECI, shape(N, 3)for array inputs or(3,)for scalar inputs.- Parameters:
r_eci (ArrayLike)
v_eci (ArrayLike)
t (ArrayLike)
- Return type:
- abstractmethod rotate_from_body(v_body, r_eci, v_eci, t)[source]¶
Express a spacecraft body-frame vector in the ECI frame.
- Parameters:
v_body (
array_like,shape (3,)) – Unit direction in the spacecraft body frame (need not be pre-normalised).r_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI position(s) (m).v_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI velocity(s) (m s⁻¹).t (
array_likeofdatetime64,shape ``(N,)``orscalar) – Observation epoch(s).
- Returns:
npt.NDArray[np.floating]– Unit vector(s) in ECI, shape(N, 3)or(3,).- Parameters:
v_body (ArrayLike)
r_eci (ArrayLike)
v_eci (ArrayLike)
t (ArrayLike)
- Return type:
- pointing_lvlh(r_eci, v_eci, t)[source]¶
Boresight unit vector(s) in the LVLH frame.
- Parameters:
r_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI position(s) (m).v_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI velocity(s) (m s⁻¹).t (
array_likeofdatetime64,shape ``(N,)``orscalar) – Observation epoch(s).
- Returns:
npt.NDArray[np.floating]– Unit pointing vector(s) in LVLH, shape(N, 3)for array inputs or(3,)for scalar inputs.- Parameters:
r_eci (ArrayLike)
v_eci (ArrayLike)
t (ArrayLike)
- Return type:
- pointing_ecef(r_eci, v_eci, t)[source]¶
Boresight unit vector(s) in the ECEF frame.
- Parameters:
r_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI position(s) (m).v_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI velocity(s) (m s⁻¹).t (
array_likeofdatetime64,shape ``(N,)``orscalar) – Observation epoch(s).
- Returns:
npt.NDArray[np.floating]– Unit pointing vector(s) in ECEF, shape(N, 3)for array inputs or(3,)for scalar inputs.- Parameters:
r_eci (ArrayLike)
v_eci (ArrayLike)
t (ArrayLike)
- Return type:
- yaw_steering(solar_config)[source]¶
Enable or disable solar yaw steering.
When active, the roll DOF is controlled dynamically at each timestep to maximise solar power generation. The boresight direction is unchanged; only the rotation about the boresight is affected.
Supported by
FixedAttitudeLawandTrackAttitudeLaw.- Parameters:
solar_config (
AbstractSolarConfigorNone) – Solar config whoseoptimal_angle()defines the preferred sun-facing direction in the body frame. PassNoneto deactivate yaw steering and revert to the static roll angle.- Raises:
NotImplementedError – If this attitude law type does not support yaw steering.
TypeError – If
solar_configis not anAbstractSolarConfigorNone.
- Return type:
None
- class missiontools.FixedAttitudeLaw(vector, frame, roll=0.0)[source]¶
Bases:
AbstractAttitudeLawFixed attitude law: constant body orientation in a reference frame.
- Parameters:
vector (
array_like,shape (3,)) – Boresight direction (body-z) expressed inframe. Need not be a unit vector — it is normalised on input.frame (
{'lvlh', 'eci', 'ecef'}) – Reference frame in whichvectoris expressed.roll (
float, optional) – Roll angle (rad) about the boresight axis. Default 0 gives the minimum rotation from identity that aligns body-z withvector.
- Raises:
ValueError – If
frameis not recognised orvectoris the zero vector.- Parameters:
Examples
Nadir pointing:
law = FixedAttitudeLaw.nadir()
Body-z along-track in LVLH:
law = FixedAttitudeLaw([0, 1, 0], 'lvlh')
- classmethod nadir(roll=0.0)[source]¶
Earth-nadir pointing law (body-z = −R̂ in LVLH).
Full 3-DOF convention at
roll=0: body-z = nadir (−R̂), body-x = along-track (Ŝ), body-y = −orbit-normal (−Ŵ). This is a right-handed body frame.
- pointing_eci(r_eci, v_eci, t)[source]¶
Boresight unit vector(s) in the ECI frame.
- Parameters:
r_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI position(s) (m).v_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI velocity(s) (m s⁻¹).t (
array_likeofdatetime64,shape ``(N,)``orscalar) – Observation epoch(s).
- Returns:
npt.NDArray[np.floating]– Unit pointing vector(s) in ECI, shape(N, 3)for array inputs or(3,)for scalar inputs.
- rotate_from_body(v_body, r_eci, v_eci, t)[source]¶
Express a spacecraft body-frame vector in the ECI frame.
- Parameters:
v_body (
array_like,shape (3,)) – Unit direction in the spacecraft body frame (need not be pre-normalised).r_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI position(s) (m).v_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI velocity(s) (m s⁻¹).t (
array_likeofdatetime64,shape ``(N,)``orscalar) – Observation epoch(s).
- Returns:
npt.NDArray[np.floating]– Unit vector(s) in ECI, shape(N, 3)or(3,).
- yaw_steering(solar_config)[source]¶
Enable or disable solar yaw steering.
When active, the roll DOF is controlled dynamically at each timestep to maximise solar power generation. The boresight direction is unchanged; only the rotation about the boresight is affected.
Supported by
FixedAttitudeLawandTrackAttitudeLaw.- Parameters:
solar_config (
AbstractSolarConfigorNone) – Solar config whoseoptimal_angle()defines the preferred sun-facing direction in the body frame. PassNoneto deactivate yaw steering and revert to the static roll angle.- Raises:
NotImplementedError – If this attitude law type does not support yaw steering.
TypeError – If
solar_configis not anAbstractSolarConfigorNone.
- Return type:
None
- class missiontools.TrackAttitudeLaw(target, roll=0.0)[source]¶
Bases:
AbstractAttitudeLawTarget-tracking attitude law: boresight always points toward a target.
- Parameters:
target (
Spacecraft | GroundStation) – The object to track. ASpacecrafttarget is propagated analytically; aGroundStationtarget is converted from its fixed geodetic position to ECI at each timestep.roll (
float, optional) – Roll angle (rad) about the boresight axis. Default 0 uses the minimum-rotation convention from_q_from_vec()to pin the remaining degree of freedom.
- Raises:
TypeError – If
targetis not aSpacecraftorGroundStation.- Parameters:
roll (float)
Examples
Track another spacecraft:
target = Spacecraft(...) law = TrackAttitudeLaw(target)
Track a ground station:
from missiontools import GroundStation gs = GroundStation(lat=51.5, lon=-0.1) law = TrackAttitudeLaw(gs)
- pointing_eci(r_eci, v_eci, t)[source]¶
Boresight unit vector(s) in the ECI frame.
- Parameters:
r_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI position(s) (m).v_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI velocity(s) (m s⁻¹).t (
array_likeofdatetime64,shape ``(N,)``orscalar) – Observation epoch(s).
- Returns:
npt.NDArray[np.floating]– Unit pointing vector(s) in ECI, shape(N, 3)for array inputs or(3,)for scalar inputs.
- rotate_from_body(v_body, r_eci, v_eci, t)[source]¶
Express a spacecraft body-frame vector in the ECI frame.
- Parameters:
v_body (
array_like,shape (3,)) – Unit direction in the spacecraft body frame (need not be pre-normalised).r_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI position(s) (m).v_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI velocity(s) (m s⁻¹).t (
array_likeofdatetime64,shape ``(N,)``orscalar) – Observation epoch(s).
- Returns:
npt.NDArray[np.floating]– Unit vector(s) in ECI, shape(N, 3)or(3,).
- yaw_steering(solar_config)[source]¶
Enable or disable solar yaw steering.
When active, the roll DOF is controlled dynamically at each timestep to maximise solar power generation. The boresight direction is unchanged; only the rotation about the boresight is affected.
Supported by
FixedAttitudeLawandTrackAttitudeLaw.- Parameters:
solar_config (
AbstractSolarConfigorNone) – Solar config whoseoptimal_angle()defines the preferred sun-facing direction in the body frame. PassNoneto deactivate yaw steering and revert to the static roll angle.- Raises:
NotImplementedError – If this attitude law type does not support yaw steering.
TypeError – If
solar_configis not anAbstractSolarConfigorNone.
- Return type:
None
- class missiontools.CustomAttitudeLaw(callback)[source]¶
Bases:
AbstractAttitudeLawCustom attitude law defined by a user-supplied callback.
The callback receives the spacecraft state at each timestep and returns full 3-DOF body attitude quaternions in ECI, giving complete control over pointing.
- Parameters:
callback (
callable) –A function with signature:
callback(t, r_eci, v_eci) -> quaternions
where:
t—(N,)array ofdatetime64[us]time instantsr_eci—(N, 3)ECI position array (m)v_eci—(N, 3)ECI velocity array (m s⁻¹)returns —
(N, 4)array of unit quaternions[w, x, y, z]defining body attitude in ECI
- Raises:
TypeError – If
callbackis not callable.
Examples
def my_attitude(t, r_eci, v_eci): N = len(t) q = np.zeros((N, 4)) q[:, 0] = 1.0 # identity: body frame aligned with ECI return q law = CustomAttitudeLaw(my_attitude)
- pointing_eci(r_eci, v_eci, t)[source]¶
Boresight unit vector(s) in the ECI frame.
- Parameters:
r_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI position(s) (m).v_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI velocity(s) (m s⁻¹).t (
array_likeofdatetime64,shape ``(N,)``orscalar) – Observation epoch(s).
- Returns:
npt.NDArray[np.floating]– Unit pointing vector(s) in ECI, shape(N, 3)for array inputs or(3,)for scalar inputs.
- rotate_from_body(v_body, r_eci, v_eci, t)[source]¶
Express a spacecraft body-frame vector in the ECI frame.
- Parameters:
v_body (
array_like,shape (3,)) – Unit direction in the spacecraft body frame (need not be pre-normalised).r_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI position(s) (m).v_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI velocity(s) (m s⁻¹).t (
array_likeofdatetime64,shape ``(N,)``orscalar) – Observation epoch(s).
- Returns:
npt.NDArray[np.floating]– Unit vector(s) in ECI, shape(N, 3)or(3,).
- class missiontools.LimbAttitudeLaw(body_vector, altitude_km, *, yaw_deg=0.0, roll_deg=0.0, body_semi_major_axis=6378137.0, body_flattening=0.0033528106647474805)[source]¶
Bases:
AbstractAttitudeLawLimb-pointing attitude law: body-frame vector grazes the central body.
The given body-frame vector is continuously aligned with the ray from the spacecraft that grazes an offset ellipsoid at altitude
altitude_kmabove the central body.- Parameters:
body_vector (
array_like,shape (3,)) – Body-frame axis to be aligned with the limb direction. Need not be pre-normalised.altitude_km (
float) – Grazing altitude above the central body (km, ≥ 0).yaw_deg (
float, optional) – Azimuth of the pointing direction in the LVLH horizontal plane, measured right-handed about zenith (+R̂) from the +Ŝ (along-track) axis. Default 0 (forward limb).roll_deg (
float, optional) – Right-hand rotation about the outward pointing vector. Default 0.body_semi_major_axis (
float, optional) – Equatorial radius of the central body (m). Defaults to Earth WGS84 (EARTH_SEMI_MAJOR_AXIS).body_flattening (
float, optional) – Flattening of the central body (dimensionless, in[0, 1);0gives a sphere). Defaults to Earth WGS84.
- Raises:
ValueError – If
body_vectoris the zero vector or not shape(3,),altitude_km < 0,body_semi_major_axis <= 0, orbody_flatteningis outside[0, 1).- Parameters:
Examples
Boresight (body-z) at the forward limb 20 km above the surface:
law = LimbAttitudeLaw([0, 0, 1], altitude_km=20)
Cross-track limb view with body-x aligned to the limb:
law = LimbAttitudeLaw([1, 0, 0], altitude_km=50, yaw_deg=90)
- pointing_eci(r_eci, v_eci, t)[source]¶
Boresight unit vector(s) in the ECI frame.
- Parameters:
r_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI position(s) (m).v_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI velocity(s) (m s⁻¹).t (
array_likeofdatetime64,shape ``(N,)``orscalar) – Observation epoch(s).
- Returns:
npt.NDArray[np.floating]– Unit pointing vector(s) in ECI, shape(N, 3)for array inputs or(3,)for scalar inputs.
- rotate_from_body(v_body, r_eci, v_eci, t)[source]¶
Express a spacecraft body-frame vector in the ECI frame.
- Parameters:
v_body (
array_like,shape (3,)) – Unit direction in the spacecraft body frame (need not be pre-normalised).r_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI position(s) (m).v_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI velocity(s) (m s⁻¹).t (
array_likeofdatetime64,shape ``(N,)``orscalar) – Observation epoch(s).
- Returns:
npt.NDArray[np.floating]– Unit vector(s) in ECI, shape(N, 3)or(3,).
- class missiontools.ConditionAttitudeLaw(default_attitude, condition_attitudes)[source]¶
Bases:
AbstractAttitudeLawConditional attitude law: route between attitude laws by condition.
Each timestep is dispatched to one of a chain of child attitude laws, selected by evaluating a list of
AbstractConditionpredicates in priority order. When no condition holds, the timestep falls through todefault_attitude.- Parameters:
default_attitude (
AbstractAttitudeLaw) – The fallback law used at any timestep where no condition holds.condition_attitudes (
listof(AbstractCondition,AbstractAttitudeLaw)) – Ordered chain of (condition, law) pairs. At each timestep, the first condition that evaluates toTrueselects its paired law; earlier pairs take precedence over later ones. An empty list is permitted and produces a degenerate wrapper arounddefault_attitude.
- Raises:
TypeError – If
default_attitudeis not anAbstractAttitudeLaw, or any element ofcondition_attitudesis not a 2-tuple of (AbstractCondition,AbstractAttitudeLaw).
Notes
Switching between child laws produces an instantaneous pointing discontinuity at the boundary; no slew dynamics are modelled.
Yaw steering, when enabled via
yaw_steering(), is propagated to every child law and to the default; if any child does not support yaw steering the call raisesNotImplementedError.Examples
Switch from nadir pointing to ground-station tracking when the spacecraft is in view of a downlink site:
from missiontools import (FixedAttitudeLaw, TrackAttitudeLaw, GroundStation, Spacecraft) from missiontools.attitude import ConditionAttitudeLaw from missiontools.condition import SpaceGroundAccessCondition sc = Spacecraft(...) gs = GroundStation(lat=51.5, lon=-0.1) link_law = TrackAttitudeLaw(...) nadir = FixedAttitudeLaw.nadir() cond = SpaceGroundAccessCondition(sc, gs, el_min_deg=5.0) law = ConditionAttitudeLaw( default_attitude = nadir, condition_attitudes = [(cond, link_law)], )
- pointing_eci(r_eci, v_eci, t)[source]¶
Boresight unit vector(s) in the ECI frame.
- Parameters:
r_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI position(s) (m).v_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI velocity(s) (m s⁻¹).t (
array_likeofdatetime64,shape ``(N,)``orscalar) – Observation epoch(s).
- Returns:
npt.NDArray[np.floating]– Unit pointing vector(s) in ECI, shape(N, 3)for array inputs or(3,)for scalar inputs.
- rotate_from_body(v_body, r_eci, v_eci, t)[source]¶
Express a spacecraft body-frame vector in the ECI frame.
- Parameters:
v_body (
array_like,shape (3,)) – Unit direction in the spacecraft body frame (need not be pre-normalised).r_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI position(s) (m).v_eci (
array_like,shape ``(N,3)``or(3,)) – Host spacecraft ECI velocity(s) (m s⁻¹).t (
array_likeofdatetime64,shape ``(N,)``orscalar) – Observation epoch(s).
- Returns:
npt.NDArray[np.floating]– Unit vector(s) in ECI, shape(N, 3)or(3,).
- yaw_steering(solar_config)[source]¶
Enable or disable solar yaw steering.
When active, the roll DOF is controlled dynamically at each timestep to maximise solar power generation. The boresight direction is unchanged; only the rotation about the boresight is affected.
Supported by
FixedAttitudeLawandTrackAttitudeLaw.- Parameters:
solar_config (
AbstractSolarConfigorNone) – Solar config whoseoptimal_angle()defines the preferred sun-facing direction in the body frame. PassNoneto deactivate yaw steering and revert to the static roll angle.- Raises:
NotImplementedError – If this attitude law type does not support yaw steering.
TypeError – If
solar_configis not anAbstractSolarConfigorNone.
- Return type:
None