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

GNC Code ↔︎ current_sota.md Cross-Check

Generated: 2026-06-18 (branch speed-derate) · read-only investigation (8-reader parallel sweep + reconciliation; high-impact claims spot-checked at source). Purpose: verify that GNC/ faithfully implements the equations in GNC/equations/current_sota.md §1–7. Note: structural orientation (code map, entry points, state machine, derate stack) lives in .claude/rules/GNC.md and is not duplicated here — this artifact is purely the equation↔︎code verification.

Bottom line: the GNC code is a faithful implementation of current_sota.md §1–7. Both Giordano-2019 published typo corrections (eq 31 sign, eq 34d block order) are present in code. The dynamics (Γ, Γ⁻¹, M̂/Ĉ, the three-tier damped J⊕ inverse) live in utils/robot.py, consumed by the controllers as self.dyn.*; the analytic desired-twist feedforward (§5.8–5.18) lives in GNC/guidance/analytic_feedforward.py. The remaining discrepancies are predominantly sheet text vs. code (the sheet was written without reading code).


Equation cross-check — current_sota.md → code

Legend for Status: yes = block-for-block match · partial = behaviorally equivalent, structurally/textually divergent · n/a = analysis-only, not expected in code.

Dynamics & control (SOTA §1–4)

SOTA Concept Code Status
eq 2.4 Γ Coordinate transform [v_b;ω_b;q̇]→[v_c;ω_b;ν_e⊕] robot.py:276–279 (self.dyn.Gamma) yes
eq 2.6 Γ⁻¹ Closed-form inverse robot.py:286–291 yes (J_inv is damped, see D-1)
eq 2.7 Γ̇ Project-corrected time-derivative robot.py:131–132, :314–324 yes (verified — F-S1 resolved)
eq 3.1/3.2 M̂,Ĉ Congruence Γ⁻ᵀMΓ⁻¹, Γ⁻ᵀ(C−MΓ⁻¹Γ̇)Γ⁻¹ robot.py:327–330 yes
eq 3.3/3.4 split 3×3 CoM + 9×9 attitude+EE block robot.py:356–360; breve_controller.py:466–498 yes
eq 4.1/4.2 J̃ₓ Error-rate Jacobians breve_controller.py:401–410, :206–209 yes (code adds J₁₂=cross(eₚ), see D-2)
eq 4.4 f_c CoM PD −K_c x̃_c − D_c v_c com_controller.py:141–176 yes (damper on velocity error, D-3)
eq 4.5 τ_b⊕ Base attitude PD breve_controller.py:353–361 yes (γ-derated at :359–360)
eq 4.6 w_e⊕ EE pose PD wrench breve_controller.py:363–397 yes
eq 4.7 compact Corrected negative-feedback sign (Giordano eq 31 typo fix) breve_controller.py:466–491 yes
eq 4.8 actuator F = Γᵀ G; f_b driven only by f_c com_controller.py:198–218 yes
eq 4.10 closed-loop CoM-coupling (C_c + D̆Ğ_vc)x̃̇_c breve_controller.py:466–498 yes
eq 4.11 q̇ recovery Corrected selector [−G_ωb, E] (eq 34d typo fix) com_controller.py:227–234; selector robot.py:161 yes
eq 4.12 working ctrl Damping-on-error + accel feedforward M̆v̆̇_d breve_controller.py:430–434, :466–498 yes (config-gated)
eq 4.13 integral fold K⁻¹I x_int pre-augmentation breve_controller.py:277–306, :389 yes
eq 4.14 cruise-lag x_ss Two-term floor analytic_feedforward.py:188–212 (opt-in log only) yes
eq 4.15/4.16 Lyapunov Stability certificate n/a (analysis-only)

Guidance, singularity, metrics (SOTA §5–7)

SOTA Concept Code Status
5.1 startup ramp v_d=[1−e^{−t/τ}]v_ref com_guidance.py:41–43, :96 yes
5.2 FF blend accel-blend window com_controller.py:150–157 partial — sheet note inverted, see D-4
5.3–5.5 helix analytic tangent + curvature orbit.py:44–99 yes
5.6 base SLERP geodesic interp base_guidance.py:183–200 yes (runtime re-derives inward z, D-5)
5.7 standoff pose p_ed, z_ed=r̂ analytic_feedforward.py:175; ee_guidance.py:672–684 yes (sign convention note D-6)
5.8–5.13 desired twist unit-vector rates → ω_ed analytic_feedforward.py:19–58 yes
5.14–5.18 ⊕ conversion world→local→circumcentroidal analytic_feedforward.py:62–185 yes (gated analytic_ff, default off → FD path live)
6.2 σ_crit cascade velocity-budget floors sampling.py:70–78; config parameters.yaml:87–92 partial — derived numerics only under cascade-study override, D-7
6.3 Tikhonov Γ-reg (ΓᵀΓ+λI)⁻¹Γᵀy breve_controller.py:581–593 partial — λ uses standalone floor=0.05, not σ_crit1², D-8
6.4 impedance derate γ scales gains (default) vs speed derate sampling.py:70–78; breve_controller.py:336–360 yes (impedance default-on; speed default-off)
6.5 damped J⊕ inverse three-tier (undamped/damped/hold-last) robot.py:198–235 yes
7.1 coverage per-triangle marking; area frac target_finder.py:196–289 yes
7.2 ANCHOR scoring Ω=∏σᵢ^{wᵢ}, novelty 1/(1+h) target_finder.py:401–485 yes (EXPONENTIAL mode = weighted; inert in POSE)
7.3 pointing versine 1−cosθ analysis/data_analyzer.py:556–560; facade signal_measurement.py yes (lives in measurement layer, not GNC)

Verdict: the §1–7 code cross-check is closed (the last open item, Γ̇ eq 2.7, was confirmed — see F-S1 below). The discrepancies below are predominantly sheet text vs. code, expected because the sheet was written without reading code (current_sota.md:10–11).

Discrepancies (sheet ↔︎ code) — for the sheet’s owner

ID Severity Summary Refs
D-1 low Sheet eq 2.6/4.11 print literal (J⊕)⁻¹; code uses the damped pseudoinverse (deliberate, the sheet’s own λ_J). robot.py:273
D-2 med Sheet eq 4.1 prints J̃ₓₑ strictly block-diagonal; code carries a non-zero J₁₂=cross(eₚ) (standard SE(3) pose-error coupling — code is right, sheet oversimplifies). breve_controller.py:404
D-3 low Dampers act on velocity error (tracking) throughout; eqs 4.4–4.6 print absolute velocities. Sheet’s own §2 conflict note endorses the tracking reading. com_controller.py:133–144
D-4 high §5.2 provenance is backwards. Sheet calls the rising blend “not yet matched in code” and prints the decaying form as primary; the live code implements exactly the rising blend and the decaying form appears nowhere. com_controller.py:150–157 vs current_sota.md:505–520
D-5 low §5.6 says SLERP “returns the stored frame at samples”; runtime re-derives inward z and borrows only the x-axis as a roll hint. base_guidance.py:210–232
D-6 low §5.7 writes p_ed=p_c − r_cam r̂; code uses + r_cam r̂ (self-consistent; camera between CoM and surface). analytic_feedforward.py:175
D-7 med σ_crit cascade numerics (0.143/0.0204/0.143) are not the default config ({low 0.005, high 0.025, floor 0.25}); they appear only under speed_derate_cascade_* study overrides. parameters.yaml:87–92
D-8 med Tikhonov λ uses standalone gamma_regularization.floor=0.05, not σ_crit1²−σ_G². breve_controller.py:581–591

F-S1 (Γ̇ eq 2.7) — RESOLVED: robot.py:132 R_cb_dot = R_cb @ cross(omega_b) = R_cb[ω_b]^ (corrected + sign); robot.py:131 p_bc_dot is the base-frame relative rate (transport stripped), so the (1,2) block (robot.py:318) has no double-count — exactly sheet eq 2.7.

Open for the sheet owner (not code defects): D-4 (§5.2 provenance, HIGH — swap the “not yet matched” note: the rising blend is the implementation), and D-7/D-8 (decide whether the documented σ_crit/Tikhonov numerics should be the sheet’s derived values or the live config defaults). Do not silently reconcile.


Equation-sheet defects (D-4, D-7, D-8) are forwarded to the sheet owner, not patched. Structural/orientation content lives in .claude/rules/GNC.md.