Doctoral Research · Space Robotics Inspection with a Free-Flying Space Manipulator
A Doctoral Research Journal Aerospace Engineering

INSIGHTS summary + cross-check (Jun 19 2026)

A themed, oldest-context-first digest of GNC/INSIGHTS.md and validation/INSIGHTS.md (primary) and validation/LEGACY_INSIGHTS.md (distant third), with every load-bearing claim cross-checked against the live code, GNC/equations/current_sota.md, and the rule set. Method: 3 harvest agents (one per file) + 16 adversarial verifiers reading the actual sources. The cross-check section at the end is the payoff — what we have written down but not actually fixed, and where today’s Jun19 campaign intersects it.


1. Major Developments

Control architecture. - Flat control chain. CC_Controller (CoM force) is the root; BreveController (Giordano-2019 circumcentroidal: base attitude + EE wrench) is the live workhorse, flattened from the old BaseController→EEController inheritance. base_controller.py survives as a diagnostic (name: base). - Option-A single-knob derate. One γ ramp on s_min_G drives every derate mechanism (TASK_2). Per F4, Γ is singular iff J_νe⁺ is (Spearman ≥ 0.997), so the old s_min_J path collapsed onto it; s_min_J is kept only as a logged witness and for the 7-DOF kernel freeze. - CHAIN_5 mission headline adopted (64c3905): 5 derate knobs ON by default, duration 1100 s, all 5 baselines re-pinned. The joint-limit clip (outward wall-velocity zeroed, inward preserved) is what breaks the INITIAL elbow lock-in at θ₃≈−π. - CHAIN_12 retired the reactive flow (−181 lines, byte-identical replay). Only pose | anchor routings remain; POSE is the adopted default (camera scheduled deterministically; scorer INERT).

Singularity understanding (the spine of the project). - Determinant factorizes into 3 families: det J ∝ (reach bracket)·sin θ₃·sin θ₅. The elbow (θ₃) and wrist (θ₅) factors are length-independent (verified to 1e-16, CasADi↔︎Pinocchio↔︎MJCF). The arm sits at the elbow family. - Bare-arm law σ_min ≈ 0.107·|sin θ₃|; the Γ/CoM coupling is a bounded ~26% haircut, not a cancellation (the old “CoM cancels σ_min” lead was falsified Jun18). The structural escape is the 7-DOF null space (steer θ₃ off zero without moving the EE). - Deterministic q0 seed ADOPTED (Jun18): sets θ₃,θ₅ off zero so s_min_G ≥ 0.025 at init, RNG-free (seed-independent q0). Gold standard re-pinned to it. - Singularity floors derived closed-form: σ_crit1 = v/x_max = 0.90/2π ≈ 0.143 (derate onset), σ_crit2 = σ_crit1² ≈ 0.020 (= j_plus.soft_floor), σ_crit3 = √EPS = 1e-3 (provisional).

Feedforward. - Analytic desired-twist FF (analytic_feedforward.py, §3.4/§5.8–5.18) replaces finite-difference FF — pure function of the reference (never measured state). Roll-free ω_ed = u×u̇, ω̇_ed = u×ü. Gated by desired_twist.enable ∧ analytic_ff ∧ POSE; key defaults absent → byte-identical FD otherwise. - L1 velocity-FF form −C(v−v_des) makes (v=v_des, x̃=0) an exact equilibrium (the absolute −Cv left a pe ~ v·τ standing offset). - B3/B0 frame fix (flag omega_body_frame): correct base-attitude FD increment is the body-frame so3_log(R₋ᵀR₊); the spatial form was ~90° misdirected.

Determinism / infra / measurement. - pin_threads(1) (single-thread BLAS/OpenMP) — sub-bit reduction-order jitter changes macroscopic behavior in the near-singular loop; acceptance = divergence_series == 0 for two identical runs. - Gold-standard metric gate (test_gold_standard.py, full 1100 s) replaces the 5-baseline byte-identity gate (raw arrays diverge cross-machine on FP-order sensitivity). Pins: coverage 0.9952, pe_p99 0.1786, smin_median 0.0283, smin_min 0.0193. - signal_measurement facade is the single source of truth (parity to pipeline 1e-12). - Drop-proof dispatcher (analysis/dispatch.py + detached_run.py): sentinel-first status, weighted static partition, corroborated VANISHED, atomic two-rsync collection. - 7-DOF proof obligations verified symbolically (P3/P4 Lyapunov, passivity Lemma). - Chaos triage: NOT chaos — bounded near-singular ill-conditioning + washout (3 independent legs).


2. Tried and Failed (do not re-run)

Idea Why it failed
Speed-derate (scale ν_e by γ) Velocity bound ~644× worse than gain-derate; the throttle’s own pose-error growth collapses σ_min (0.0268→1e-5) harder than γ throttles v. Replaces impedance softening, not additive.
Link-lengthening to escape singularity sin θ₃=0 is length-independent; at fixed standoff a longer arm over-folds the elbow past 90°. A reach-margin/posture problem, not a CoM effect.
“CoM coupling cancels σ_min” Falsified Jun18 — it’s a bounded ~26% haircut; neutral config stays s_min_G < 1e-4.
L1-v1 Coriolis-referencing FF pe_med 0.075→0.200 — the referenced Coriolis re-energized the loop past the derate.
Monotone aim-clock knob (floor_rate/lead_max) Dwell increases; lead cap re-creates the dwell fixed point. Stays default-OFF.
L3 axis-slew retune (loosen axis.time_scale) Crawl-confounded; 200 s Pareto inverted on full helix (+19% time). rate_max is an implicit singularity guard. NO-ADOPT.
Wobble→p_e base-accel FF (CHAIN_2) Pearson r=−0.157 (wrong sign); the arm absorbs base wobble in world-frame tracking. STOPPED.
schedule-κ oracle Kinematics-only; calls most of the orbit near-singular, can’t localize standoff margin. PARKED.
min-norm lstsq (7-DOF reconstruction) Injects a ghost null-space (v_n≈0.157 non-decaying); fixed by Stage C fiber solve.
H1 FD-tangent / H2 curvature as κ drivers Killed; H3 (shoulder-frame reach) is the surviving κ-peak driver.

3. Lessons Learned (encoded in code today — verified)


4. Lessons NOT Learned — persistent footguns / lasting inconsistencies

These are written down somewhere but still bite or remain unfixed:

  1. XML box_limited joint ranges are task artifacts, not real UR3 (real = ±360°/joint). The nominal regime violates them constantly (wrist_1 75% OOR on the full helix); the CHAIN_5 envelope overrides the tails but the underlying model ranges stay unrealistic.
  2. Sim 0.025 floor does NOT transfer to real UR3. It only protects v ≤ 0.025·π/2 ≈ 0.039 m/s on a π-rad/s UR3 — far below the 0.90 m/s operating point. Documented (threshold_sizing.py) but the operating config still ships the sim-numerics floor.
  3. `current_sota.md §6.3 “speed derate” is a misnomer — the shipped γ is an impedance derate (the slowdown is emergent via larger lag, not a commanded twist reduction). The equation sheet still carries the misleading name.
  4. Pervasive hand-rolled metrics (~50 in the live census, 250+ in legacy) reinvent the facade despite documented replacements — never migrated (legacy was archived, not refactored).
  5. plotter.py overlay has a dead block after a return (title/labels/legend ~lines 270–282 never render); worked around with standalone scripts, the bug itself unfixed.
  6. Reach/shoulder geometric factor keeps derate elevated 0.64–0.80 (vs ref ~0.32) across CHAIN_5/8/13, even with the full mitigation stack — the persistent residual H3 confirmed as the primary κ-peak driver.
  7. Stateful traps carried in stubs: _aim_arclength floor is a no-op on the first call; default_selection.p_ce/default_R_be0 latch on first INITIAL and only reset_runtime_state clears them; cruise_lag_floor lstsq silently returns min-norm near singularity (derated steps must be manually filtered downstream — not enforced).
  8. Deferred debt: cKDTree swap in the finder; legacy flat-npz compat shim (Phase D); the column-v stub-shape bug flagged as recurring.

5. Promising directions to explore


6. Cross-check: mistakes we haven’t learned from yet

The 16 verifications came back 13 CONFIRMED, 3 PARTIAL/caveated, 0 incorrect — the code is faithful to the equations. The interesting findings are the caveats and the correct-but-unadopted fixes. Ranked by how much they matter, and tied to today’s Jun19 campaign:

6.1 — The base-frame fix is correct but DEFAULT-OFF (the #1 unlearned mistake)

omega_body_frame defaults false (parameters.yaml) — i.e. every gold-standard baseline runs the ~90°-misdirected spatial base-attitude frame. The body-frame branch is implemented and validated (base_omega_frame_fix.yaml: z_b rms 0.1459 → 0.0118, −92%) but “not adopted; adoption is a regime change (re-pin)” (b2904e8). Today’s campaign independently re-confirmed this: my rs040_uncorrected run had zb_rms 0.0152 vs 0.000536 corrected — 28×. So we now have two independent confirmations that the corrected frame is right, and it is still not the default. Decision needed: adopt + re-pin the 5 baselines, or document the 28×/92% base-pointing penalty as an accepted limitation. This is the single biggest “written down, not fixed.”

6.2 — Γ-reg eps=0.05 is over-damped vs the budget — and Jun19 lever D/K is exactly that fix

threshold_sizing.py flagged that gamma_regularization.floor=0.05 caps the velocity-solve gain at 1/eps=20 ≪ Q=50, and the budget-matching value is 1/Q = 0.02 — “the one misfit, left unchanged in parameters.yaml.” My Jun19 D/K lever lowered exactly this floor (0.05 → 0.020/0.025) and it was the campaign’s biggest conditioning win (near-singular fraction 0.597 → 0.027, pe_p99 −9%, verified not a crawl). So D/K is not a new idea — it is the known-but-unlearned fix, finally validated empirically. Strong recommendation: this is the highest-confidence adoption candidate (it matches the derived budget). Caveat to resolve first: the 0.8% coverage dip (goal 2 in the levers plan).

6.3 — “Speed derate” misnomer in the equation sheet (math source of truth)

current_sota.md §6.3 still names the shipped γ a “speed derate” when it is an impedance derate. A pencil-and-paper reviewer reading the sheet would mis-model the mechanism. Rename in the sheet.

6.4 — The 0.048 “operational singularity slope” is operating-point-dependent — don’t overclaim

The bare-arm σ_min ≈ 0.107·|sin θ₃| and the ~26% haircut are solid. But “operational ≈ 0.048·|sin θ₃|” was measured on a Jun17 log where θ₃ varied; on the adopted Jun18 gold the elbow is pinned at θ₃ ≈ −165.64°, so the single-factor model is not testable there (effective ratio 0.114 ≈ bare-arm, not the 0.048 haircut). Present 0.048 with this caveat, never as a universal law.

6.5 — σ_crit3 inconsistency (parked)

current_sota.md §6.4 defines σ_crit3 = λ_J analytically; the test implements √EPS = 1e-3. Documented in cross_check.md (D-7); λ_J / “the principled floor 3” is explicitly parked pending the user’s derivation.

6.6 — Reframing today’s nulls (a correction to my own campaign read)

The “engagement guard” lesson says a derate A/B is inconclusive if the band is never entered. My Jun19 incumbent does enter it (fbelow(0.025)=0.597, 60% of steps), so C/I (gain-derate OFF) ≡ incumbent is a genuine null, not a dormant-band artifact — the arm impedance derate, even when engaged, is dominated by the still-active velocity-retime (derate_desired_by_gamma) and the feedforward. Note the clean derate-vs-derate A/B onset is σ_crit1 = 0.143 (where the ramp fires hard), distinct from the adopted 0.025 — worth a deliberate run if we ever want to characterize the impedance derate in isolation.

6.7 — One PARTIAL worth a doc note

Speed-derate γ²-on-acceleration: the analytic FF path applies γ² explicitly; the FD path gets γ² implicitly (FD of a γ-scaled velocity). Same outcome, different mechanism — cross_check.md already notes it; a one-line clarification in the INSIGHTS stub would prevent confusion.


Bottom line for the levers plan