ADCS.estimators.measurement_stack module

Canonical measurement assembly for attitude estimators.

MeasurementStack is the one estimator-facing owner of measurement order, availability, residual coordinates, covariance, and Jacobians. Raw telemetry remains in the satellite’s historical order: attitude sensors followed by reaction-wheel momentum measurements. The residual vector may have a different dimension: a quaternion attitude measurement is reduced from four stored coefficients to three local attitude coordinates.

class ADCS.estimators.measurement_stack.MeasurementSource(source, name, raw_slice, residual_slice, sensor_index=None, wheel_index=None)[source]

Bases: object

One identifiable source in the canonical measurement vector.

name is stable within a stack and intended for configuration and diagnostics. raw_slice addresses received/predicted telemetry, while residual_slice describes this source’s unmasked innovation width.

Parameters:
  • source (Any)

  • name (str)

  • raw_slice (slice)

  • residual_slice (slice)

  • sensor_index (int | None)

  • wheel_index (int | None)

property is_quaternion_attitude: bool
property kind: str

Return sensor or reaction_wheel.

name: str
property raw_size: int
raw_slice: slice
property residual_size: int
residual_slice: slice
sensor_index: int | None
source: Any
wheel_index: int | None
class ADCS.estimators.measurement_stack.MeasurementStack(satellite)[source]

Bases: object

Assemble estimator measurements from an EstimatedSatellite.

The stack has one entry for each attitude sensor and one entry for each reaction-wheel momentum measurement. An entry is active only when all of its raw values are finite, it is explicitly enabled, and, when time_s is supplied, its sample_time schedule is due. This deliberately makes a partially missing vector measurement unavailable as a whole: retaining a subset would silently change that sensor’s physical measurement model.

active_mask is entry-wise, while active_measurements and residual return compact vectors in the selected entry order. Every operation that accepts an entry mask also accepts the selectors understood by mask(); selectors are resolved once to a NumPy boolean mask before numerical work begins.

Quaternion residuals, Jacobians, and covariances consistently use right attitude errors. This is intentionally fixed rather than exposed as a partially supported convention knob.

Parameters:

satellite (Any)

active_mask(measurements, *, time_s=None, enabled=None, epoch_s=0.0, predicted=None)[source]

Return the active entry mask for a raw measurement vector.

An entry is also inactive when predicted is supplied and any of its predicted values are non-finite. time_s is elapsed seconds on the sensor sampling timeline; it is intentionally not an orbital J2000 value. When omitted, a received finite measurement is treated as live, which is the useful default for asynchronous telemetry streams. A sensor with sample_time <= 0 is treated as continuously sampled. Reaction-wheel measurements are continuously sampled until the hardware model gains a sampling period. enabled may be a boolean mask or any semantic selector accepted by mask().

Parameters:
  • measurements (Any)

  • time_s (float | None)

  • enabled (Any | None)

  • epoch_s (float)

  • predicted (Any | None)

Return type:

ndarray

active_measurements(measurements, active_mask)[source]

Return the compact raw measurement vector selected by active_mask.

Parameters:
  • measurements (Any)

  • active_mask (Any)

Return type:

ndarray

covariance(state, active_mask, *, form='full', quaternion_mode='quaternion_vector', predicted=None)[source]

Return active residual covariance R using right-error coordinates.

When predicted (the raw prediction from predict()) is given, an active entry with a non-finite prediction raises, the same contract residual() enforces, so a stale first-pass mask cannot produce a covariance whose dimension disagrees with the residual.

Parameters:
  • state (EstimatorState)

  • active_mask (Any)

  • form (str)

  • quaternion_mode (str)

  • predicted (Any | None)

Return type:

Covariance

entry(selector)[source]

Return the single source identified by selector.

Exact names, entry indices, source objects, and MeasurementSource objects are accepted. Broader selectors such as "gyro" or Gyro must match exactly one source here; use mask() when selecting groups.

Parameters:

selector (Any)

Return type:

MeasurementSource

jacobian(state, orbital_state, active_mask, *, quaternion_mode='quaternion_vector', coordinates='tangent', predicted=None)[source]

Return the active right-error measurement Jacobian H.

An active entry whose sensor Jacobian is non-finite at the estimate (the measurement is unavailable there) raises with the entry name; passing predicted additionally applies the finite-prediction contract of residual().

coordinates="tangent" returns the minimal attitude-error Jacobian used by a MEKF. coordinates="full" returns the Jacobian with respect to normalized additive quaternion coordinates for a conventional quaternion EKF. Measurement residuals remain minimal in both cases.

Parameters:
  • state (EstimatorState)

  • orbital_state (Any)

  • active_mask (Any)

  • quaternion_mode (str)

  • coordinates (str)

  • predicted (Any | None)

Return type:

ndarray

mask(*include, exclude=())[source]

Build an entry-wise boolean mask from semantic selectors.

With no include selectors, all sources are selected. Selectors may be names ("gyro[0]"), source families ("gyro"), groups ("sensors" or "reaction_wheels"), entry indices, hardware objects, source classes, MeasurementSource objects, nested sequences, or an existing boolean mask.

Examples:

stack.mask("gyro", "star_tracker_quaternion")
stack.mask("sensors", exclude="gyro[1]")
stack.mask(exclude="reaction_wheels")
Parameters:
  • include (Any)

  • exclude (Any)

Return type:

ndarray

predict(state, orbital_state, active_mask=None)[source]

Evaluate raw predicted measurements h(x) in canonical order.

When active_mask is supplied, inactive sensor models are not evaluated and their raw slots are filled with NaNs. Pass the result back to active_mask() as predicted to remove entries that are unavailable at the estimated state.

Parameters:
Return type:

ndarray

raw_mask(mask)[source]

Expand an entry mask to the raw telemetry-vector dimension.

Parameters:

mask (Any)

Return type:

ndarray

readings(state, orbital_state, *, dmode=None)[source]

Return raw readings in the stack’s canonical order.

This is the estimator-neutral telemetry path. Estimators should pass its result to active_mask() before performing an update.

Parameters:
  • state (State)

  • orbital_state (Any)

  • dmode (Any)

Return type:

ndarray

residual(measurements, predicted, active_mask, *, quaternion_mode='quaternion_vector')[source]

Return compact innovations in their proper local coordinates.

Additive sources use z - h(x). A quaternion star tracker uses the right relative quaternion q_pred^{-1} * q_measured and converts it to the three attitude coordinates selected by quaternion_mode.

Parameters:
  • measurements (Any)

  • predicted (Any)

  • active_mask (Any)

  • quaternion_mode (str)

Return type:

ndarray

residual_mask(mask)[source]

Expand an entry mask to the unmasked residual-vector dimension.

Parameters:

mask (Any)

Return type:

ndarray

selected(mask)[source]

Return source descriptions selected by a mask or semantic selector.

Parameters:

mask (Any)

Return type:

tuple[MeasurementSource, …]

property entries: tuple[MeasurementSource, ...]

Ordered, immutable measurement-source descriptions.

property names: tuple[str, ...]

Stable semantic source names in stack order.

property source_order: tuple[str, ...]

Compatibility alias for names.