circumcentroidal_control — Breve coordinated control (base attitude + EE wrench)

Concept

The Breve coordinated control architecture (Giordano 2019 RA-L, circumcentroidal coordinated control):
one controller regulates CoM motion, base attitude, and the end-effector wrench together through the
coordinated map Γ, expressed in reduced circumcentroidal () coordinates. It spans four classes plus
the dynamics file, so each per-file page documents its part and this page documents the whole 9×9 system
start here, then descend. (Provenance: GNC/equations/current_sota.md §0 Provenance; NOT the 2020 RAS
reaction-wheel extension.)

What this spans

  • GNC/com_controller.py (com_controller) — the per-step control loop root: CoM force law, the Γᵀ force map, integral anti-windup, the uncertainty hook.
  • GNC/breve_core_controller.py (breve_core_controller) — the shared base-attitude/breve template (Template Method) that both leaf controllers inherit byte-identically.
  • GNC/breve_controller.py (breve_controller) — the live workhorse: full base + EE coordinated control, the working RHS, the derate stack.
  • GNC/base_controller.py (base_controller) — the base-attitude-only sibling (every EE/arm slot zeroed); a diagnostic, not the mission controller.
  • utils/robot.py (robot) — supplies Γ, , , s_min_G as self.dyn.*; the equations live there, the controllers consume them.
  • Thesis: the control is a single 9×9 reduced system — base attitude (3) + EE position (3) + EE orientation (3) — driven in circumcentroidal coordinates y = [v_c, ω_b, ν_e⊕]; the four classes are one inheritance chain that builds, derates, solves, and reconstructs that one system.

Constituent pages

Down-links to the per-file pages that hold each part’s contract:

  • com_controllerCC_Controller, the chain root: owns run_all/run_control_loop, the CoM force package, and Γᵀ. The task-space wrenches are placeholders here, filled by subclasses.
  • breve_core_controllerBreveCoreController, the shared template: the 13 base-attitude/breve methods both leaves share, with the EE/arm leaves left abstract (Template Method).
  • breve_controllerBreveController, the live workhorse: the full RHS34b, the implicit-damping solve, feedforward, FOV coverage marking, and the impedance-derate stack.
  • base_controllerBaseController, the base-only sibling: the same circumcentroidal machinery with every EE/arm leaf returning zero — the byte-identical diagnostic baseline.

Mechanism (where it lives in code)

The inheritance chain is CC_Controller → BreveCoreController → {BreveController, BaseController}:

  • chain root (CoM loop + Γᵀ map) — GNC/com_controller.py:23
  • shared base-attitude/breve template — GNC/breve_core_controller.py:24
  • live workhorse (full base + EE) — GNC/breve_controller.py:35
  • base-only sibling (EE slots zeroed) — GNC/base_controller.py:25

One coordinated control step, end to end (workhorse path):

  • build base + EE goals; gate analytic vs FD feedforward — GNC/breve_controller.py:67
  • single γ ramp on s_min_G drives every derate (Option A) — GNC/breve_core_controller.py:80
  • base attitude PD torque τ_b⊕, γ-scaled + saturated — GNC/breve_core_controller.py:84
  • stacked 9-vector task error x̃ = [x_b ; x_e] and the 9×9 Jacobian J_xGNC/breve_core_controller.py:68 / :72
  • working reduced RHS (-C̆(v̆-v̆_des) - JᵀK̆ x̃ - D̆ v̆_err + CoM coupling + posture + FF) — GNC/breve_controller.py:377
  • EE wrench ω_e⊕ (P+D+I, axis-only) — GNC/breve_controller.py:276
  • assemble [f_c ; τ_b⊕ ; ω_e⊕] and map through Γᵀ to (f_b, τ_b, τ)GNC/breve_core_controller.py:97
  • reduced acceleration v̆_dot = (M̆ + dt·D̆)⁻¹·RHS (implicit-damping solve, default) — GNC/breve_controller.py:454
  • reconstruct the full generalized velocity from (v_c, ω_b, ν_e⊕) via the damped Γ solve — GNC/breve_controller.py:477

The reduced dynamics consumed above are packed by the robot model as self.dyn.*:

  • M̆ = M_breve, C̆ = C_breve, Γ, s_min_Gutils/robot.py:370 / :374 / :375 / :381

Evidence

This is a structural topic; the load-bearing claim is the inheritance contract, established at the committed homes:

  • The reparenting + byte-identity proof (the 13 shared methods moved verbatim into BreveCoreController, all 5 baselines reproduce max_abs_diff = 0.000e+00): generated_reports/GNC/controller_twin_extraction.md.
  • Equation ↔ code cross-check for the coordinated map and the working control law: generated_reports/GNC/cross_check.md.
  • The why of the derate stack and the chain shape: GNC/INSIGHTS.md ([derate], [control], [history]).
  • Provenance pin (Giordano 2019 RA-L, the two published typos fixed): GNC/equations/current_sota.md §0.

Footguns

Editing the shared template changes BOTH leaves — there is no per-controller copy any more

Since 2026-06-22 the base-attitude/breve methods live once in breve_core_controller; breve_controller
and base_controller inherit them. Any logic edit there is a behaviour change to the whole control chain —
verify against all 5 baselines (max_abs_diff = 0.000e+00), and re-pin only via the sanctioned ceremony.
The forked leaves (RHS34b, v_breve_dot, calc_posture, reconstruct_generalized_velocity, and the EE
methods) stay per-subclass: zeroed in Base, full in Breve. (generated_reports/GNC/controller_twin_extraction.md)

"Coordinated" ≠ one class — read the chain before assuming a method exists where you're looking

Seeing only breve_controller.py hides compute_tau_b_oplus, all_control_terms, conditioning_scale, and
the stacked x_tilde/J_x — they are inherited from breve_core_controller, which itself inherits the
CoM loop + Γᵀ map from com_controller. The 9×9 system is assembled across three files. (GNC/INSIGHTS.md [history])

The 9×9 is base-attitude + EE-position + EE-orientation — NOT base position

The reduced state is y = [v_c, ω_b, ν_e⊕]: CoM linear velocity, base angular rate, and the EE
circumcentroidal twist. Base attitude is regulated; base position is folded into the CoM/Γ map, not a
separate 3-block. Treating it as base-position will mis-read every block of , J_x, and . (current_sota §2)

Equations & references

Key equations mirrored from current_sota — the math source of truth; see there for derivations.

The coordinated map current_sota §2.4, eq (2.4):

Reduced (circumcentroidal) equations of motion§3, eq (3.4):

Working control equation§4.3, eq (4.12):

References:

  • The coordinated map Γ and the circumcentroidal () velocities (§2): current_sota > 2 · utils/robot.py:375.
  • The control law: error coordinates, task laws, the working closed-loop equation (§4.1–4.9): current_sota > 4 · GNC/breve_controller.py:377.
  • Eq ↔ code (both Giordano-2019 typos fixed): generated_reports/GNC/cross_check.md.

coupled_dynamics · com_vs_base · speed_gain_derate · ee_pose_error_antiwindup · com_controller · breve_core_controller · breve_controller · base_controller · robot · current_sota · terminology