guidance_classes — guidance data records & mode enums

Purpose

The vocabulary of the guidance tower: dataclass records (CameraPose, SurfaceTarget, Selection)
and the mode enums (GuidanceMode, OrbitPathMode, ScoringMode). No control logic — just the
typed payloads that flow through guidance, plus a plotting-style hook for shading mode bands.

Role in the system

Inputs / Outputs

  • In: raw vectors/quaternions and mesh indices from the finder + guidance; config strings for the
    enums (scoring.mode, the orbit-path mode).
  • Out: sanitized records — CameraPose (flat3 p_e, unit z_e), SurfaceTarget (flat3 x, unit
    normal n), Selection (target + pose + score). The enums validate config at construction and drive
    scoring/routing/plot-shading.

Key methods

  • mode_style_kwargs — matplotlib axvspan style for a mode band (later dicts override) — GNC/guidance/guidance_classes.py:13
  • GuidanceMode.colour — hex colour indexed by the mode’s ordinal — :55
  • GuidanceMode.style_kwargs — mode-coloured axvspan style dict (drawing now lives in analysis/plotter.py) — :70
  • CameraPose.__post_init__ — coerces p_e→flat3, z_e→unit; if R_e given, z_e = R_e[:,2]:89
  • SurfaceTarget.__post_init__ — coerces x→flat3, n→unit normal — :108

Footguns

The enums are StrEnum on purpose — fail-loud config validation

ScoringMode(cfg_string) validates YAML scoring.mode at construction; a bad mode raises instead of
silently falling through combined_score’s match (which left total_score undefined → NameError).
OrbitPathMode is likewise StrEnum with auto() (lower-cased member names) validating the YAML.
Do not demote these to plain strings. (GNC/INSIGHTS.md [footgun])

GUIDANCE_MODE_LINEWIDTH = 0.0 is load-bearing, not cosmetic

No edge on per-step mode bands: a nonzero edge smears adjacent bands into visible “stripes” in
mode-shaded plots. (GNC/INSIGHTS.md [config])

Mode semantics (what each band means)

INITIAL = startup hold; HOLD = the operational steady state (light blue); TARGETING = brief
reselect events (black); FALLBACK = degraded deterministic fallback when no scored candidate exists
(orange). The ordinal value, not insertion order, indexes the colour. (GNC/INSIGHTS.md [guidance])

Pseudocode (a record’s life)

EETargetFinder samples mesh        -> SurfaceTarget(x, n, tgt_idx, tri_idx, area)
score candidate via ScoringMode    -> total_score, score_terms
pack winner                        -> Selection(target, CameraPose, total_score, p_ce)
__post_init__ sanitizes            -> p_e/x flat3, z_e/n unit, z_e = R_e[:,2] if R_e given
EEGuidance state machine           -> GuidanceMode per step (INITIAL→HOLD/TARGETING/FALLBACK)
plotter                            -> ax.axvspan(*(t0,t1), **mode.style_kwargs())  # band-shade in analysis/plotter.py

Equations & references

  • Coverage / pointing-metric vocabulary the records carry (§7): current_sota > 7. The pointing
    metric (versine 1−cosθ) is computed in the measurement layer, not here.

ee_guidance · target_finder · base_guidance · com_guidance · analytic_feedforward · terminology · guidance_modes