coupled_dynamics — the coordinated map Γ and the reduced equations of motion
Concept
A free-FLYING manipulator’s base, CoM and arm are dynamically coupled: moving the arm moves the base,
moving the base moves the EE. The coordinated map Γ is the single change of coordinates that turns
the raw generalized velocity into the circumcentroidal (⊕) coordinates[v_c; ω_b; ν_e⊕]the
controllers actually command, and the reduced EoM (M̂/Ĉ → M̆/C̆) are the dynamics in those
coordinates. This earns its own page because the math lives in one file (utils/robot.py) but is
consumed across the control tower — and because the reverse direction (reconstructing the fullv)
happens in a different file again. The per-file page documents the method contract; this documents the
whole coupling story.
What this spans
utils/robot.py(robot) — owns the forward math: buildsΓ,Γ⁻¹,Γ̇, the reduced inertia/Coriolis
M̂/Ĉand their lower-right breve blocksM̆/C̆, plus the CoM-referenced EE JacobianJ⊕and its
3-tier damped inverse. All cached onself.dynin one FK pass per step.GNC/breve_controller.py(breve_controller) — owns the reverse map: given the controller-integrated
reduced state(v_c, ω_b, ν_e⊕), reconstruct the full generalized velocityvvia a (damped)Γsolve.- Thesis: the controllers never see the raw 6+n dynamics — they live entirely in the
⊕coordinates
produced byΓ, and the only bridge back to the plant’s generalized velocity is the regularized
inverse-Γ solve. Get the map (or its conditioning) wrong and every downstream wrench is wrong.
Constituent pages
Down-links to the per-file pages that hold each part’s contract:
- robot — the forward dynamics owner:
Γ,Γ⁻¹,Γ̇,M̂/Ĉ,M̆/C̆,J⊕, dampedJ⊕inverse,
s_min_G/s_min_Jwitnesses. “The equations live here, not in the controllers.” - breve_controller — the consumer + reverse map: reads
self.dyn.*for the control RHS, and runs the
reconstructionΓ-solve to recover fullvfor integration.
Mechanism (where it lives in code)
The end-to-end path, each step cited to path:line (verified to resolve at author time):
- One pass entry point —
all_dynamics_terms(q, v)runs FK → Γ → Γ⁻¹ → Ĉ → Ĵ → nullspace and caches
self.dyn—utils/robot.py:270. It first callsall_motion_termsfor frames/CoM/Gblocks —
utils/robot.py:128. - CoM-referenced EE Jacobian
J⊕—J_plus = J_nu_e − R_eb0 · Jv_bar(EE frame Jacobian minus the
rotated CoM Jacobian) —utils/robot.py:285; its smallest singular values_min_Jis logged here —
utils/robot.py:286. - Γ assembled — stacks the three row-blocks for
[v_c; ω_b; ν_e⊕]: the CoM/base coupling top row,
the identityω_bmid row, andbot = [0, G_ωb, J⊕]—utils/robot.py:294-297;s_min_G(the live
conditioning driver) is logged immediately after —utils/robot.py:298. - Γ⁻¹ assembled (closed form, not a numeric inverse — it reuses the damped
J_inv) —
utils/robot.py:304-309. - Damped
J⊕inverse — the 3-tierdamped_inverse(exact/Moore-Penrose abovesoft_floor, Tikhonov
between floors, hold-last at/belowhard_floor) —utils/robot.py:217; Tikhonov tier
regularized_svd—utils/robot.py:249. This inverse is what makesΓ⁻¹well-defined near the wall. - Reduced EoM —
P = M·Γ⁻¹;M̂ = Γ⁻¹ᵀ M Γ⁻¹;Ĉ = Γ⁻¹ᵀ(C − P·Γ̇)Γ⁻¹—utils/robot.py:345-348.
The controller-facing breve blocks are the lower-right submatrices:M̆ = M̂[3:,3:],
C̆ = Ĉ[3:,3:](and the cross-couplingC_c = Ĉ[3:,:3]) —utils/robot.py:370,utils/robot.py:374,
utils/robot.py:373. - Standalone reuse —
Gamma(q)/J_plus(q)evaluate the same FK pass at zero velocity for the σ_min
sampler —utils/robot.py:260/utils/robot.py:264. - Reverse map (state reconstruction) — the controller stacks
y = [v_c; ω_b; ν_e⊕]and solves the
(damped/Tikhonov)Γsystem for the full generalized velocityv:
reconstruct_generalized_velocity(st)—GNC/breve_controller.py:477; the concat is
GNC/breve_controller.py:479. The dampingλreusess_min_Gand the Γ-regularization floor —
GNC/breve_controller.py:488(see tikhonov_regularization).
Evidence
Purely structural topic — the establishing math is in the equations sheet (below) and the eq↔code mapping
in generated_reports/GNC/cross_check.md (§2 Γ + circumcentroidal velocities, §3 reduced EoM all
confirmed implemented faithfully). The why and the singular-regime caveats are harvested in
GNC/INSIGHTS.md (the [derate] / singularity entries) and utils/INSIGHTS.md (singularity / config /
math). Re-pin reproducibility (all 5 baselines max_abs_diff = 0.000e+00) is the standing guarantee that
edits to this map do not silently move the plant.
Footguns
The controller lives in ⊕ coordinates — the reconstruction Γ-solve is the ONLY bridge back
An agent reading
breve_controller.pyalone seesv_c, ω_b, ν_e⊕integrated and assumes those are
the state. They are not the plant’s generalized velocity —reconstruct_generalized_velocity
(GNC/breve_controller.py:477) invertsΓto get the realvfor integration and joint-limit
clipping. That solve is damped (λ = max(damping, floor² − s_min_G²),GNC/breve_controller.py:488):
a plainlstsqhere was the historical ghost injector (min-norm null-space leakage). Near a
singularity the Tikhonov floor is the only thing keeping the reconstructedvbounded. Tuning that floor
on a targeting-OFF proxy collapses conditioning with targeting ON (see breve_controller footguns).
M̆/C̆are the lower-right blocks ofM̂/Ĉ, not the whole reduced matricesThe control RHS uses
M̆/C̆(the[3:,3:]blocks,utils/robot.py:370/:374) plus the cross-coupling
C_c = Ĉ[3:,:3](utils/robot.py:373). ConfusingM̂(full reduced inertia) withM̆(the breve block
the controller solves against) silently changes the dimension and the dynamics. The breve blocks are
exactly the base-attitude + EE-wrench rows; thev_c(CoM-translation) rows are split off.
Γ⁻¹is a CLOSED FORM that reuses the dampedJ_inv— don'tnp.linalg.inv(Γ)
Γ⁻¹is assembled analytically (utils/robot.py:304-309) fromJ_inv = damped_inverse(J⊕), not by
numerically inverting the stackedΓ. So the conditioning of the whole map is governed by the J⊕
floors, ands_min_Gis a witness of (not an input to) the regularization. Re-derivingΓ⁻¹with a
raw inverse loses the 3-tier hold-last protection and blows up at the reach wall.
Equations & references
Key equations mirrored from current_sota — the math source of truth; see there for derivations.
Full coupled dynamics — §1, eq (1.4):
Reduced (circumcentroidal) block — §3, eq (3.4):
Passivity (skew-symmetry) of the coupled block — §3, eq (3.5):
References:
- The coordinated map
Γ+ circumcentroidal (⊕) velocities: current_sota > 2. - The reduced equations of motion
M̂/Ĉ(and the breve blocks): current_sota > 3. - Singularity handling — damped
J⊕(three-tier), Tikhonov Γ-regularization, the γ ramp:
current_sota > 6. - eq↔code cross-check:
generated_reports/GNC/cross_check.md(§2/§3 confirm Γ, Γ⁻¹,M̂/Ĉ
implemented as written). Never re-derive the math here.
Related
robot · breve_controller · circumcentroidal_control · com_vs_base · tikhonov_regularization · terminology