Ring Edge Fit (RingEdgeNav)
Overview
RingEdgeNav recovers a single translation
from one or more ring-edge polylines by aligning each polyline against the image’s
edge-distance-transform. The technique consumes every offered
RING_EDGE feature, weights its vertices by
the prior precision derived from the per-edge sigma, and runs the same coarse-NCC plus
Tukey-reweighted Levenberg-Marquardt refinement that
DT Fitting (Shared Polyline-vs-Image Fitter) describes.
When every consumed ring edge is flagged straight-line the combined Jacobian is rank- deficient — all parallel ring edges share a single ring-plane normal so the along-edge axis is unobservable. The returned covariance is honestly rank-1 in that case; the orchestrator’s ensemble combine fuses it with any orthogonal-axis result (a star, body limb, body blob) before declaring a final answer.
Feasibility passes when at least one offered RING_EDGE has a non-empty polyline. A single
non-empty edge is sufficient — even an all-flat scene produces a useful rank-1 constraint.
Feasibility fails when every offered RING_EDGE is empty (a ring system entirely outside the
extended FOV or below the per-pixel resolution threshold).
Theory
The technique fits a per-image translation by minimising the weighted squared distance from the model ring-edge polylines to the image edges, exactly as the limb fit does — see DT Fitting (Shared Polyline-vs-Image Fitter) for the cost function, the LM mechanics, the polarity filter, and the Tukey biweight.
Rank-deficient covariance
Ring edges differ from limbs in that each ring edge is only locally observable along its
radial direction (orthogonal to the edge tangent). Motion along the tangent of a single
ring edge produces no DT cost change. When a single ring edge dominates the consumed set,
the joint Jacobian’s null space is the along-edge tangent and the M-estimator information
matrix is rank-1. The Moore-Penrose pseudoinverse used by
information_matrix_to_covariance() handles this
gracefully — the returned 2x2 covariance has an effectively-infinite eigenvalue along the
tangent direction.
Multi-edge inputs at different orbital radii share the same ring-plane normal but sample
different points around the projected ring; the joint information matrix becomes full-rank
when at least two non-parallel edges contribute. The technique reports an
is_rank_1 flag that the curator
surfaces; downstream consumers (the ensemble combine, the operator’s per-image log) can
distinguish a rank-1 ring-edge result from a full-rank one.
Restrictions and assumptions
The orchestrator must populate
image_edge_dt_extandimage_gradient_vu_ext; in their absence the technique cannot evaluate the cost.Per-vertex normals supplied by the upstream rings model are oriented so that the image gradient should point from outside the ring system inward at a bright ring edge against a dark background. Polarity-rejected vertices contribute a near-infinite synthetic residual so the Tukey biweight zeroes their weight on the first reweighting.
Ring edges that have collapsed to a sub-pixel radial extent are emitted by the upstream model as
RING_ANNULUStemplates instead, so the technique never sees them. See Ring Annulus Correlate (RingAnnulusNav).The fit assumes the per-image SPICE pose is good enough that the integer NCC seed lands in the basin of attraction of the correct ring edge. When the SPICE pointing error exceeds the per-instrument search-window margin the seed lands on a wrong edge and the LM converges to a wrong local minimum.
Sources of uncertainty
The reported covariance is the Moore-Penrose pseudoinverse of the M-estimator information
matrix at convergence; the rank-1 case carries an unbounded eigenvalue along the tangent
direction. When the converged offset sits within the at-edge tolerance of any axis bound,
or when the rotation parameter is at the configured fraction of its cap, the result is
flagged at_edge.
Configuration
All numeric tunables for this technique live in techniques.RingEdgeNav.tuning in
src/nav/config_files/config_510_techniques.yaml.
at_edge_tolerance_px— float, default1.0px. A converged offset whose absolute distance from any search-window axis bound falls within this tolerance is flaggedat_edge. Matches the bilinear-DT half-cell width.spurious_dt_rms_factor— float, default5.0(dimensionless). Final DT residual exceeding this many radial-sigmas marks the result spurious.spurious_dt_floor_px— float, default3.0px. Floor of the spurious-detection threshold; the threshold is the larger of the floor and the per-feature sigma multiple.spurious_min_inliers— int, default6(count). Below this Tukey-inlier count the M-estimator covariance is uninformative; the result is flagged spurious.rotation_at_edge_fraction— float, default0.95(dimensionless). Whenfit_camera_rotationis true, the converged rotation magnitude tripsat_edgeonce it crosses this fraction of the per-imagemax_rotation_degcap.
Per-instrument overrides
The five keys above are global; per-instrument YAML files in
src/nav/config_files/config_4N0_inst_*.yaml do not override any of them.
Confidence formula
The technique reports a calibrated confidence in \([0, 1]\) produced by the shared
sigmoid combination; see Confidence Calibration (Shared Sigmoid-of-Linear Combination). The formula spec is
techniques.RingEdgeNav and consumes attributes off
RingEdgeDiagnostics plus
at_edge.
total_edge_length_px— alpha = 1.0, offset = 0.0, divisor = 200.0, cap at 1.0. Cumulative pixel length of all surviving ring-edge polylines. More polyline earns confidence up to a 200-pixel saturation point.per_edge_dt_rms_summed— alpha = -2.0, offset = 0.0, divisor = 1.0, no cap. Sum of per-edge final DT RMS values. Larger residuals pull confidence down.
Hard-zero gate: at_edge
firing forces confidence to zero. The constant baseline is \(\alpha_{0} = -1.0\). No
post-sigmoid hard_cap is applied.
Implementation
Source files:
src/nav/nav_technique/nav_technique_ring_edge.py—RingEdgeNav.src/nav/nav_technique/dt_fitting.py— shared coarse-NCC and LM-refinement helpers; documented at DT Fitting (Shared Polyline-vs-Image Fitter).src/nav/nav_orchestrator/image_derivatives.py— image-side derivatives; documented at Image Derivatives (Shared Gradient and Edge DT).src/nav/nav_technique/confidence.py— sigmoid-combination evaluator; documented at Confidence Calibration (Shared Sigmoid-of-Linear Combination).src/nav/nav_technique/diagnostics.py—RingEdgeDiagnostics; documented at Per-Technique Diagnostics (Shared Dataclass Family).
Public class RingEdgeNav, base
NavTechnique. Self-registers via
__init_subclass__.
Class attributes:
name—'RingEdgeNav'.accepts_feature_types—frozenset({RING_EDGE}).requires_prior—False.confidence_attributes—{'at_edge', 'total_edge_length_px', 'per_edge_dt_rms_summed', 'edge_count', 'is_rank_1'}.
Public methods (autodocumented at nav.nav_technique):
is_feasible() and
navigate().
Diagnostics
total_edge_length_px— cumulative pixel length of all surviving ring-edge polylines. Consumed by the confidence formula.per_edge_dt_rms_summed— sum of per-edge final DT RMS values. Consumed by the confidence formula.edge_count— number ofRING_EDGEfeatures fused.is_rank_1— True when every consumed ring-edge feature was straight-line and the combined covariance is rank-1.
Call path
Call path traced through
navigate():
Open a logged section. Fail fast (
RuntimeError) if eitherimage_edge_dt_extorimage_gradient_vu_extis missing.Filter the offered features to
RING_EDGEentries with non-empty polylines and concatenate the per-feature vertex / normal / sigma arrays.Build the binary polyline mask and pull the search-window margin off the observation via
search_window_for_obs(). Runcoarse_ncc_search()for the integer seed.Read
fit_camera_rotationand set the rotation pivot to the centroid of the concatenated vertices when rotation is fit.Call
lm_subpixel_refine()and capture the convergedLMRefineResult.Detect the rank-1 condition: every consumed
RING_EDGEflaggedis_straight_linecollapses the joint Jacobian to rank-1. The flag is recorded inis_rank_1so downstream consumers can branch on it.Result-shape branches on
fit_camera_rotation:No rotation fit.
covariance_px2is the (2, 2) translation block returned bylm_subpixel_refine()(rank-1 when every edge is straight; full-rank otherwise).Rotation fit.
covariance_px2is the (3, 3) translation + rotation information matrix.
Apply the at-edge tests and the spurious tests on RMS / inlier-count.
Build a
RingEdgeDiagnostics, evaluate the confidence spec, log the breakdown, and assemble theNavTechniqueResult.
Examples
ring_only_curved(Cassini ISS NAC, imageN1447064164_1)A curved Saturn-ring scene with no body in FOV. The rings model emits multiple
RING_EDGEpolylines (the F ring, the A-ring outer edge, etc.) at different orbital radii; the curvature gives the joint Jacobian non-degenerate column rank.RingEdgeNavconverges to a 2-D translation against the operator-verified offset \((\Delta v, \Delta u) = (5.85, 3.55)\) px. Theis_rank_1flag is False on this scene (the curvature lifts the rank-deficiency) and the orchestrator’s ensemble combine fuses the result without needing an orthogonal-axis cross-check.ring_only_curved(Cassini ISS NAC, imageN1492091163_1)A high-curvature single-edge scene with no other ring features in the FOV. The rings model emits one
RING_EDGEpolyline whose curvature lifts the rank-1 degeneracy.RingEdgeNavconverges to \((\Delta v, \Delta u) \approx (5.00, -25.00)\) px against an operator-verified ground truth of(4.92, -24.32)px — sub-pixel agreement on a single curved edge. The technique reports a sub-pixel final DT residual; theis_rank_1flag is False because the per-edge curvature exceedsFLAT_CURVATURE_THRESHOLD_PX.ring_only_flat(Saturn ansa scene class, no body in FOV)An edge-on or extreme-grazing ring view in which every surviving polyline is flagged
is_straight_line. The joint-Jacobian column rank collapses to 1 along the shared radial direction; the technique returns the rank-1 pseudo-inverse covariance described in the Theory section, setsis_rank_1True, and reports a calibrated confidence drawn down by the missing along-edge constraint. The orchestrator’s ensemble combine treats the result as a one-axis observation and relies on a cross-feature (a body limb arc, a star prediction) to constrain the orthogonal axis. When no cross-feature is available the orchestrator surfaces the rank-1 result withconfidencecapped by the rank-1 confidence formula.