breve_controller — BreveController

Purpose

Giordano-2019 circumcentroidal coordinated control (base attitude + EE wrench) in one flat class.
The live workhorse: carries the derate stack, analytic/FD feedforward, and FOV coverage marking.

Role in the system

  • extends breve_core_controller (BreveCoreController, the shared base-attitude/breve template) →
    com_controller (CC_Controller, the per-step control loop root). Reparented 2026-06-22.
  • Sibling of base_controller (the base-attitude-only diagnostic mode); both subclass the shared base.
  • Reference trajectory comes from the guidance tower → ee_guidancebase_guidancecom_guidance.
  • Dynamics (Γ, , , s_min_G, damped J⊕) come from utils/robot.py as self.dyn.*.
  • Selected by controller.name == "arm".

Inputs / Outputs

  • In: State (q, v, dynamics cache), Desired (base + EE goals), config gains, s_min_G.
  • Out: base reduced torque τ_b⊕, EE reduced wrench ω_e⊕, step-integration derivatives, controller diagnostics.

Key methods

Defined here (the forked leaves + the active EE layer); the shared base-attitude/breve methods are now
inherited from breve_core_controller (see that page) — do not redefine them here.

  • build_desired_for_step — base + EE goals; gate analytic vs FD feedforward — GNC/breve_controller.py:67
  • RHS34b — working-control RHS (damping-on-error + K + coupling + posture + FF) — :377
  • v_breve_dot — reduced acceleration: (M̆+dt·D̆)⁻¹·RHS (implicit damping, default) or M̆⁻¹·RHS:454
  • calc_posture — joint-space posture regularization (CHAIN-5) — :419
  • reconstruct_generalized_velocity — full v from (v_c, omega_b, nu_e_oplus) via the (damped) Γ solve — :477
  • arm_gain_scale / base_gain_scale — the per-block γ gates — :262 / :268 (conditioning_scale is inherited)
  • compute_omega_e_oplus — EE wrench (P+D+I, axis-only) — :276
  • EE layer (active overrides of the base’s zero-leaves): x_e_tilde :163 · J_xe :315 · x_e_rhs :207 ·
    omega_b_damping_error :236 · nu_e_damping_error :240 · arm_breve_gains :329 · rhs_feedforward :345.
  • EE_COVERAGE_MARK_STRIDE = 5 — stride for FOV marking (module constant, :32).
  • Inherited from breve_core_controller: all_control_terms, compute_tau_b_oplus, conditioning_scale,
    x_b_tilde/x_b_tilde_dot/J_xb, x_tilde/J_x, _apply_step_state_update.

Footguns

Use gain-derate, not speed-derate

Speed-derate collapses the cruise-lag floor to ~1e-5. The endorsed mechanism is impedance (gain)
derate
: γ softens K/D and the base wrench; the slowdown is emergent. (GNC/INSIGHTS.md [derate])

Base velocity-damping is integrated IMPLICITLY — forward Euler is conditionally unstable

v_breve_dot solves (M̆ + dt·D̆)⁻¹·RHS when controller.base.implicit_damping (default ON), instead of
M̆⁻¹·RHS. Integrating the damping term v̆ ← (I − dt·M̆⁻¹D̆)v̆ by forward Euler is a period-2 limit cycle
when dt·μ > 2 (μ = eig(M̆⁻¹D̆); nominal dt·μ ≈ 3.84, critical dt* ≈ 0.0156 s) — counter-intuitively,
more damping is less stable. At full arm extension has a light mode, so μ_max is large.
The implicit (backward-Euler) multiplier 1/(1+dt·μ) ∈ (0,1) is unconditionally stable and cured the
omega_b base-rate ripple (every singular-direction lag-1 autocorr → +1.0; base wrench τ_b⊕ rms 0.33→0.02).
OFF is byte-identical to the old path. Adopted 2026-06-22; all 5 baselines + gold re-pinned. Cross-terms
cancel so applying (M̆+dt·D̆)⁻¹ to the whole RHS equals the damping-implicit update exactly.
(validation/INSIGHTS.md → omega_b_ripple_mechanism; derivation generated_reports/math/omega_b_forward_euler_instability.md)

Damping is on the error, not the state

-C̆(v̆ - v̆_des) makes (v̆ = v̆_des, x̃ = 0) an exact equilibrium; the absolute form -C̆ v̆ leaves
a velocity-proportional standing offset pe ≈ v·τ. (CHAIN_13 L1)

EE integral folds through JᵀK; off during hard derate

The integral enters as x̃ + K⁻¹ I x_int (one K⊕ slot for both P and I — no separate gain matrix).
Integration is skipped when conditioning_scale(s_min_G) < scale_gate to avoid windup.

The Tikhonov velocity-solve onset ( controller.base.gamma_regularization.floor) is tuned for targeting-ON — don't lower it on a targeting-OFF proxy

Lowering the onset 0.05→0.020 improves conditioning with targeting OFF (s_min_J frac_below 0.597→0.027)
but collapses it with targeting ON (s_min_J min 0.0279→1.4e-6, 99.6% sub-floor, reach over-extension):
the damping band is the only thing holding the camera-pose demand off the reach singular wall. The raw witnesses
s_min_J/s_min_G (utils/robot.py:286,298) are independent of the reg — it only shapes the commanded inverse
(GNC/breve_controller.py:510-516) — so their lockstep collapse proves the singularity is real, not a logging
artifact. Incumbent onset 0.05 stays (REJECT, 4-lens adversarial). (CLAIMS Jun 19 2026 / validation/INSIGHTS.md → compare_dk_vs_gold)

Pseudocode (one control step)

build_desired_for_step(t)            # base + EE goals; gate analytic vs FD feedforward
γ   = conditioning_scale(s_min_G)    # single ramp drives every derate mechanism
K,D = arm/base_breve_gains() * γ     # impedance derate
rhs = RHS34b                         # -C̆(v̆-v̆_des) - JᵀK(x̃ + K⁻¹I x_int) - D̆ v̆_err + coupling + posture + FF
v̆_dot = (M̆+dt·D̆)⁻¹ · rhs            # implicit-damping solve (default) → integrate (omega_b, nu_e_oplus)
mark FOV coverage every 5th step     # EE_COVERAGE_MARK_STRIDE; from the ACTUAL camera pose

Equations & references

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

Working control equation (RHS34b) — §4.3, eq (4.12):

EE integral fold (one JᵀK slot carries P+I) — §4.4, eq (4.13):

Cruise-lag (steady-state) floor §4.5, eq (4.14):

References:

  • Coordinated control + working eq (§4.4–4.12): current_sota > 4.
  • Singularity / derate stack (§6): current_sota > 6 · eq↔code in generated_reports/GNC/cross_check.md.

com_controller · base_controller · ee_guidance · analytic_feedforward · uncertainty_model · terminology · tikhonov_regularization · circumcentroidal_control · coupled_dynamics · speed_gain_derate · ee_feedforward · target_finding_coverage · ee_pose_error_antiwindup