com_vs_base — COM vs base: two distinct points the GNC stack regulates
Concept
The whole-system center of mass (
p_c) and the actuated free-flyer base body are different
points: kinematically distinct, dynamically coupled throughΓ. Each has its own guidance layer and
its own control loop. This page exists because conflating them mis-attributes effects — e.g. blaming
“the base” for a CoM-loop behaviour, or reading base-attitude wobble as a CoM-position error. No single
file owns the distinction, so this documents the whole while the per-file pages document the parts.
What this spans
utils/robot.py(robot) — computes both points in one FK pass and theΓmap that couples them.GNC/com_controller.py(com_controller) — the CoM force loop (regulatesp_c/v_c), control-chain root.GNC/base_controller.py(base_controller) — base-attitude-only diagnostic controller (regulatesz_b/omega_b).GNC/com_guidance.py(com_guidance) — the CoM orbit reference (p_c,v_c,a_c), guidance-tower root.GNC/base_guidance.py(base_guidance) — the desired base attitude (R_b,z_b,omega_b) layered on top.- Thesis:
p_c(CoM position) and the base body are not interchangeable; every metric measures one
of them —p_c/v_care CoM,z_b/omega_bare base — and the only thing linking them isΓ.
Constituent pages
Down-links to the per-file pages that hold each part’s contract:
- robot — computes
p_cand assemblesΓ(the single coupling map); owns the dynamics, not the controllers. - com_controller — the CoM force loop (
f_c → Γᵀ → (f_b, τ_b, τ)); root of the control chain. - base_controller — base-attitude-only mode (every EE/arm slot zeroed); diagnostic, not the live controller.
- com_guidance — desired CoM state along the helix orbit; root of the guidance tower.
- base_guidance — desired base attitude (inward
z_b, roll-continuous frame) added on top of the CoM reference.
Mechanism (where it lives in code)
The two points are born in the same FK pass, then regulated by separate loops the Γ map ties together:
- CoM
p_c— whole-system center of mass, inertial frame; shifts as the arm moves (Pinocchiodata.com[0]) —utils/robot.py:137 - Base pose — the actuated 6-DOF body:
p_tb/R_tband the localomega_bfrom the same pass —utils/robot.py:135/utils/robot.py:143 - The coupling —
Γstacks[v_c; omega_b; ν_e⊕]; its top block maps[v_b; omega_b; q̇] → v_c, so base + arm velocities both feed the CoM —utils/robot.py:294 - Γ assembly +
s_min_G— the full 12×(6+n) stack and its smallest singular value (the one conditioning witness) —utils/robot.py:297/utils/robot.py:298 - CoM reference — desired
(p_c, v_c, a_c)along the orbit —GNC/com_guidance.py:170 - CoM control —
f_cpackage mapped throughΓᵀinto generalized forces —GNC/com_controller.py:201 - Base-attitude reference — desired
R_b/z_b/omega_blayered on the CoM desired —GNC/base_guidance.py:114 - Base-attitude control —
τ_b⊕PD on the base attitude error (EE/arm slots zeroed in the diagnostic mode) —GNC/base_controller.py:66
Evidence
Purely structural: the separation is enforced by where each quantity is computed and logged, not by a
single run. p_c and the base pose come from one FK pass (utils/robot.py:137 vs :135); v_c is the
Γ top block (utils/robot.py:294); the base-only controller proves the two loops are independent by
zeroing every EE/arm slot yet still flying the base (GNC/base_controller.py:66, byte-identical baseline
per base_controller). The wider history of not conflating them is recorded in GNC/INSIGHTS.md
([frame], [control]) and the operational-regime note (the tracked error is a CoM-velocity lag, not the
base-attitude oscillation — see com_controller “CoM integral is OFF by default”).
Footguns
Name the quantity —
p_c/v_care CoM,z_b/omega_bare baseA reader seeing only one file routinely mis-attributes a CoM effect to “the base” (or vice versa). State
explicitly which point each metric measures:p_c= CoM position,v_c= CoM velocity,
z_b= base attitude (a pointing axis),omega_b= base angular rate. The CoM shifts as the arm
moves (utils/robot.py:137), so a “position drift” can be pure arm motion with the base perfectly still.
Tikhonov / derate damping acts on
Γ(the CoM-coupling map), not on "the base"The conditioning ramp and the Tikhonov
Γregularization key offs_min_G(utils/robot.py:298) — the
singular value of the coordinated map that couples base+arm intov_c. Calling that “base damping” is
the exact conflation this page guards against; base angular damping is a separate term ridingτ_b⊕
(see base_controller “Base damping ridesτ_b⊕”). Sibling/dependency of tikhonov_regularization.
The base controller flies the base only — don't read its logs as CoM results
base_controller zeroes every EE/arm slot (
GNC/base_controller.py:66); it regulates base attitude
against base_guidance with no EE layer. Its diagnostics speak toz_b/omega_b, never to EE
pose or CoM tracking quality. (GNC/INSIGHTS.md[control])
Equations & references
Key equations mirrored from current_sota — the math source of truth; see there for derivations.
Block-diagonal split (the CoM decouples from the attitude+EE block) — §3, eqs (3.1–3.2):
Decoupled CoM Newton equation — §3, eq (3.3):
References:
- Coordinated map
Γ+ circumcentroidal velocities (thev_c/ω_b/ν_e⊕split, eqs 2.1–2.3): current_sota > 2 ·utils/robot.py:294. - Reduced EoM in
⊕coordinates (M̂/Ĉ, the dynamic coupling): current_sota > 3 ·utils/robot.py:297. - eq↔code cross-check:
generated_reports/GNC/cross_check.md.
Related
tikhonov_regularization · circumcentroidal_control · coupled_dynamics · robot · com_controller · base_controller · com_guidance · base_guidance · terminology