target_finding_coverage — where the camera looks, and how area coverage accrues
Concept
Two intertwined-but-separable jobs that no single file owns: target finding (the EE camera
deciding where to look) and coverage (accumulating which surface triangles the camera has
actually swept). They share one ground-truth (EETargetFinder’s per-triangle counts), so they read
like one mechanism — but in the adopted POSE default they are decoupled: the look-axis is
scheduled, and coverage accrues from the achieved trajectory, not from any selection decision.
What this spans
GNC/guidance/target_finder.py(target_finder) — owns the mesh, the ANCHOR-mode scorer, and the
FOV coverage marker / area-coverage summary (the source ofinspection.area_coverage_frac).GNC/guidance/ee_guidance.py(ee_guidance) — runs target selection (theGuidanceModebranch)
and the deterministic POSE aim path; the top of the guidance tower.GNC/breve_controller.py(breve_controller) — marks FOV coverage everyEE_COVERAGE_MARK_STRIDEth
step from the actual camera pose, not the desired one.- Thesis: coverage is trajectory-driven, not selection-driven. In POSE mode the scorer is inert,
yetarea_coverage_frac → 1.0over the full helix — so the lever for coverage is the orbit path, never
the scoring weights or the reselect cadence.
Constituent pages
Down-links to the per-file pages that hold each part’s contract:
- target_finder — mesh sampling, candidate scoring (ANCHOR-only), and the FOV raycast marker + area summary.
- ee_guidance — the per-step pose decision: INITIAL → POSE / HOLD / TARGETING / FALLBACK.
- breve_controller — the strided marking call from the achieved camera pose.
Mechanism (where it lives in code)
The end-to-end path — select a pose, then mark what the achieved pose actually saw:
Selection (one raw EE pose per step)
- Step counter set, then branch into the pose decision —
GNC/guidance/ee_guidance.py:216 - Branch owner across all
GuidanceModes —GNC/guidance/ee_guidance.py:699 - POSE default: deterministic schedule, scorer never runs —
GNC/guidance/ee_guidance.py:722 - ANCHOR scorer entry (candidate poses around the anchor → best
Selection) —GNC/guidance/target_finder.py:546 - candidate hemisphere poses ranked by visible-target count —
GNC/guidance/target_finder.py:126 - position-only visibility gate (depth + incidence + line-of-sight) —
GNC/guidance/target_finder.py:159 - per-(target, pose) score across all terms —
GNC/guidance/target_finder.py:360
Marking (accumulate coverage from the ACHIEVED pose)
- stride constant —
GNC/breve_controller.py:32 - strided + mode-gated marking guard —
GNC/breve_controller.py:132 - mark from the actual camera pose (
motion_cache.p_e,motion.R_te) —GNC/breve_controller.py:145 - the raycast that increments per-triangle counts —
GNC/breve_controller.py:146 - pinhole-frustum raycast marker (the live coverage marker) —
GNC/guidance/target_finder.py:201 - area-weighted coverage summary (the reported metric) —
GNC/guidance/target_finder.py:266
Reporting
area_coverage_fraclogged into the inspection Package —analysis/logger.py:313- gate direction registered as higher-is-better —
analysis/pre_run_loader.py:423
Evidence
- Mission headline: coverage 0.9990 at the adopted operating point (path + sync + aim + clip + INITIAL
posture) —generated_reports/GNC/Jun10_26/mission_1_success.md(the >= 0.99 mission gate is met). - Coverage = orbit-traversal clock, not selection: full pole-to-pole helix → 1.0, short runs only sweep
the southern cap (~0.47); the appendage-offset correlate was a red herring (detours cancel) —
GNC/INSIGHTS.md[guidance]/[coverage]. - Scorer is inert in POSE yet coverage still accrues —
GNC/INSIGHTS.md[guidance](lifted into
target_finder > Footguns).
Footguns
Coverage is trajectory-driven — do NOT tune scoring to move it
In POSE (the adopted default) the pose is scheduled by
orbit_path_poseand the
EETargetFinderscorer never runs (GNC/guidance/ee_guidance.py:722), yetarea_coverage_frac
still climbs becausecompute_triangle_camera_visibilitymarks the FOV in every mode
(GNC/breve_controller.py:146). The lever for coverage is the orbit trajectory (full helix,
traversal completion), not thescoring.weightskeys or the reselect cadence. (GNC/INSIGHTS.md[guidance])
Marking reads the ACHIEVED pose, not the desired one
The controller marks from
motion_cache.p_e/motion.R_te(GNC/breve_controller.py:145), so a
tracking lag or derate shows up as missed triangles — coverage measures what the camera physically
swept, decoupled from what guidance asked for. It is strided (EE_COVERAGE_MARK_STRIDE = 5,
GNC/breve_controller.py:32) and gated to skip pure-INITIAL steps unlessmark_during_initial
(CHAIN_4 aim-during-INITIAL); a guidance-only rollout that bypasses the controller marks nothing.
Two FOV definitions: don't invent a third
Both novelty scoring and area coverage read the same per-triangle counts (
triangle_stats/
seen_triangles), so they share one ground truth. The pointing-error metric is the catalog versine
1 − cos θand lives in the measurement layer, not here — never recompute coverage or pointing in an
ad-hoc script. (GNC/INSIGHTS.md; MEASUREMENT contract)
Equations & references
Key equations mirrored from current_sota — the math source of truth; see there for derivations.
Area coverage (surface-area fraction seen ≥ once) — §7, eq (7.1):
ANCHOR weighted-product score (inert in POSE; novelty ) — §7, eq (7.2):
References:
- Per-triangle coverage marking + the area-coverage measure (eq 7.1): current_sota > 7 — implemented at
GNC/guidance/target_finder.py:201onward;analysis/logger.py:313logs the reported fraction. - POSE-mode standoff pose (the scheduled aim point coverage rides on): current_sota > 5 (§5.4) —
realized byorbit_path_pose(GNC/guidance/ee_guidance.py:684). - ANCHOR scoring law (inert in POSE): current_sota > 7 (weighted-product) · eq↔code in
generated_reports/GNC/cross_check.md.
Related
guidance_modes · orbit_com_path · target_finder · ee_guidance · breve_controller · terminology