Attitude

class missiontools.AttitudeLaw(mode, *, q=None, frame=None, target=None, roll=0.0)[source]

Bases: object

Spacecraft/sensor pointing law with full quaternion internal storage.

Prefer the factory classmethods fixed(), track(), and nadir() for typical usage. The constructor is public and may be called directly by power users or subclasses.

Parameters:
  • mode (str) – Pointing mode: 'fixed' or 'track'.

  • q (ndarray of shape (4,), optional) – Unit quaternion [w, x, y, z] defining the body orientation in the reference frame. Required for mode='fixed'.

  • frame (str, optional) – Reference frame for the quaternion: 'lvlh', 'eci', or 'ecef'. Required for mode='fixed'.

  • target (Spacecraft, optional) – Target spacecraft to track. Required for mode='track'.

  • roll (float, optional) – Roll angle (rad) about the boresight axis. Default 0.

  • Boresight convention

  • ——————–

  • The sensor/spacecraft boresight is always **body-z. The pointing**

  • methods return this axis expressed in the requested frame.

  • Modes

  • —–

  • ``’fixed’`` – A constant body orientation in a given reference frame, stored as a unit quaternion [w, x, y, z].

  • ``’track’`` – Points from the host spacecraft toward a target Spacecraft. The 2-DOF pointing direction is fully defined; the roll DOF is reserved for a future release.

Parameters:
  • mode (str)

  • q (npt.NDArray | None)

  • frame (str | None)

  • roll (float)

Examples

Nadir pointing:

from missiontools import AttitudeLaw
law = AttitudeLaw.nadir()
p_eci = law.pointing_eci(r, v, t)

Track a target spacecraft:

from missiontools import Spacecraft, AttitudeLaw
target = Spacecraft(...)
law    = AttitudeLaw.track(target)

Fixed attitude in LVLH (e.g., body-z pointing along-track):

law = AttitudeLaw.fixed([0, 1, 0], 'lvlh')
classmethod fixed(vector, frame, roll=0.0)[source]

Fixed attitude law: constant body orientation in a given frame.

Parameters:
  • vector (array_like, shape (3,)) – Boresight direction (body-z) expressed in frame. Need not be a unit vector — it is normalised on input.

  • frame ({'lvlh', 'eci', 'ecef'}) – Reference frame in which vector is expressed.

  • roll (float, optional) – Roll angle (rad) about the boresight axis. Default 0 gives the minimum rotation from identity that aligns body-z with vector.

Raises:

ValueError – If frame is not recognised or vector is the zero vector.

Parameters:
Return type:

AttitudeLaw

classmethod track(target, roll=0.0)[source]

Target-tracking attitude law: boresight always points toward target.

Parameters:
  • target (Spacecraft) – The spacecraft to track.

  • 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. Note that roll=0 does not correspond to a physically meaningful reference orientation such as orbit-normal or sun-pointing; it is purely a deterministic convention that changes as the target moves.

Raises:

TypeError – If target is not a Spacecraft.

Parameters:

roll (float)

Return type:

AttitudeLaw

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.

Parameters:

roll (float, optional) – Roll angle (rad) about the boresight (nadir) axis. Default 0 gives body-x = along-track.

Parameters:

roll (float)

Return type:

AttitudeLaw

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.

Parameters:

solar_config (AbstractSolarConfig or None) – Solar config whose optimal_angle() defines the preferred sun-facing direction in the body frame. Pass None to deactivate yaw steering and revert to the static roll angle.

Raises:

TypeError – If solar_config is not an AbstractSolarConfig or None.

Return type:

None

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_like of datetime64, shape ``(N,)`` or scalar) – 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:

ndarray[tuple[Any, …], dtype[floating]]

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_like of datetime64, shape ``(N,)`` or scalar) – 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:

ndarray[tuple[Any, …], dtype[floating]]

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_like of datetime64, shape ``(N,)`` or scalar) – 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:

ndarray[tuple[Any, …], dtype[floating]]

rotate_from_body(v_body, r_eci, v_eci, t)[source]

Express a spacecraft body-frame vector in the ECI frame.

Supported for both 'fixed' and 'track' modes. For 'track' mode the roll angle stored on the law (default 0) pins the remaining degree of freedom using the minimum-rotation convention.

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_like of datetime64, shape ``(N,)`` or scalar) – 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:

ndarray[tuple[Any, …], dtype[floating]]