com_breve_decoupling — decoupling the CoM inner loop from the Breve/Tikhonov solve
Concept
For a free-flying manipulator the system CoM obeys plain Newton,
m v̇_c = f_c— independent of the
arm’s internal configuration. So the CoM velocity should carry no arm-singularity (Tikhonov) damping. The
reconstruction solves the arm row alone (damped) and then recovers the base/CoM row in closed form, sov_c
stays exact to machine precision near a singularity while the arm alone absorbs the damping.
Status: ADOPTED on the trunk (merge to
main, 2026-06-25) — composed architectureThe decouple was built two ways: a flattened single-class experiment on
gnc-com-decoupleand the composed
form onspeed-derate. The merge kept the composed form after proving the two byte-identical
(max_abs_diff = 0.000e+00on a matched rollout — see Evidence). The CoM force law is its own
COMController(com_guidance,e14ee16); the hierarchical-Γ reconstruction lives in
BreveController.reconstruct_generalized_velocity(4ef96e4).
What this spans
GNC/breve_controller.py(breve_controller) —reconstruct_generalized_velocity(:504) + the damped
arm sub-solve_qdot(:537): the hierarchical inverse.utils/robot.py(robot) — the coupled transformΓand its closed-form inverseGam_inv(:303-309),
whose block structure the hierarchical solve reads directly.GNC/com_guidance.py(com_guidance) —COMController, the CoM force law (f_c), composed into the loop
by reference (has-a, not is-a).
Constituent pages
- breve_controller — the live workhorse; owns the hierarchical reconstruction.
- com_controller —
ControlLoop, the generic loop that composesCOMControllerasself.com; holds the
shared_augment_with_null_row(:188, the 7-DOF null-row). - com_guidance —
COMController(force law) besideCOMGuidance(the CoM reference). - breve_core_controller — the shared base-attitude/breve Template-Method base.
- robot —
Γ,Γ⁻¹, and theM̆/C̆reduction the reconstruction inverts. - tikhonov_regularization · com_vs_base · circumcentroidal_control.
Mechanism — the hierarchical inverse (where it lives in code)
Γ (utils/robot.py) maps [v_b, ω_b, q̇] → [v_c, ω_b, ν_e⊕] with block structure:
Γ = [ R_cb -R_cb[p_bc]× R_cb·J̄_v ] → v_c
[ 0 I 0 ] → ω_b
[ 0 G_ωb J⊕ ] → ν_e⊕
reconstruct_generalized_velocity (GNC/breve_controller.py:504) inverts it hierarchically for the 6-DOF case,
reading the blocks straight off dyn.Gamma:
- ω_b — identity row, exact.
- arm row, damped:
q̇ = (J⊕ᵀJ⊕ + λI)⁻¹ J⊕ᵀ (ν_e⊕ − G_ωb·ω_b)via_qdot(:537), withλon the
s_min_Gschedule — applied to the arm only. - base/CoM row, exact:
v_b = R_cb⁻¹·(v_c − (−R_cb[p_bc]×)·ω_b − (R_cb·J̄_v)·q̇).R_cbis a rotation
(orthogonal, condition number 1), sov_cpasses through with zero regularization.
The closed-form Gam_inv (utils/robot.py:303-309) already encodes this hierarchy (damping confined to the arm
sub-block); the old monolithic controller computed it and threw it away in favour of a contaminating
normal-equations solve. The 7-DOF redundant path (the v_n = 0 fibre via _augment_with_null_row,
GNC/com_controller.py:188) is kept under a guard.
Design B (minimal & attributable): keep the existing s_min_G damping schedule, just confine it to the arm.
Design A (the native s_min_J schedule of Gam_inv) is a documented follow-on — it also changes the arm
damping, risking the targeting-ON s_min_J collapse the tikhonov_regularization footgun warns of.
Evidence
- Exactness: the
v_cblock uses a rotation inverse (condition number 1), so itsΓ@vresidual is at
machine precision by construction — measured 3.3e-16 on a 120-step near-singular drive (min s_min_G ≈ 0.019); theω_bidentity row is0.0; the arm block carries the intended damping residual. - Composed ≡ flattened: B1 (composed) vs committed B2 (flattened) on a matched rollout —
max_abs_diff = 0.000e+00, identical key schema (_heredocs/test_parity_b1_b2.py; Jun25 CLAIMS “CoM parity
B1 vs B2”). The residual above is inherited byte-identically. - Full-mission benefit (decouple vs pre-decouple monolithic): the EE floor is preserved (
pe_p99flat),
ze_p99is sharper, arm effort drops,s_min_Gholds — full A/B in
generated_reports/GNC/com_decouple_pitchand the Jun25 CLAIMS. (The current gold, post orbit-sync, reports
operationally:pe_p990.1483,smin_median0.0245.)
Footguns
The cruise-median floor is NOT the contamination
Decoupling fixes the near-singular CoM-coupling side-effects (effort, pointing), not the feedforward residual
that sets the cruise-medianp_e. Don’t expect ~0.044 m (the idealized perfect-CoM-tracking limit); the
honest operational floor is ~0.10-0.15 m. Seeerror_floor.md/ current_sota.
brake_decelandvelocity_correction_alphaare goneTwo former footguns here are resolved on the trunk: the
velocity_correction_alphaCoM “band-aid” was purged
(522c085— it was an inert no-op), and the orbit-endbrake_decelwas removed (8d24ad9) once orbit-synced
termination eliminated the overrun that produced the end spike. Neither exists indesired_at_windownow.
Equations & references
- Coordinated control + the reduced working eq (Γ, M̆/C̆): current_sota > 4 ·
utils/robot.py:285-309. - Singularity / derate stack + the Tikhonov onset: current_sota > 6 · tikhonov_regularization.
Related
tikhonov_regularization · robot · breve_controller · com_controller · com_guidance ·
com_vs_base · circumcentroidal_control · terminology