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
extendsbreve_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_guidance → base_guidance → com_guidance.
- Dynamics (
Γ,M̆,C̆,s_min_G, dampedJ⊕) come fromutils/robot.pyasself.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:67RHS34b— working-control RHS (damping-on-error + K + coupling + posture + FF) —:377v_breve_dot— reduced acceleration:(M̆+dt·D̆)⁻¹·RHS(implicit damping, default) orM̆⁻¹·RHS—:454calc_posture— joint-space posture regularization (CHAIN-5) —:419reconstruct_generalized_velocity— fullvfrom(v_c, omega_b, nu_e_oplus)via the (damped) Γ solve —:477arm_gain_scale/base_gain_scale— the per-block γ gates —:262/:268(conditioning_scaleis 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_dotsolves(M̆ + dt·D̆)⁻¹·RHSwhencontroller.base.implicit_damping(default ON), instead of
M̆⁻¹·RHS. Integrating the damping termv̆ ← (I − dt·M̆⁻¹D̆)v̆by forward Euler is a period-2 limit cycle
whendt·μ > 2(μ = eig(M̆⁻¹D̆); nominaldt·μ ≈ 3.84, criticaldt* ≈ 0.0156 s) — counter-intuitively,
more dampingD̆is less stable. At full arm extensionM̆has a light mode, soμ_maxis large.
The implicit (backward-Euler) multiplier1/(1+dt·μ) ∈ (0,1)is unconditionally stable and cured the
omega_bbase-rate ripple (every singular-direction lag-1 autocorr → +1.0; base wrenchτ_b⊕rms 0.33→0.02).
OFFis 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; derivationgenerated_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 offsetpe ≈ v·τ. (CHAIN_13 L1)
EE integral folds through
JᵀK; off during hard derateThe integral enters as
x̃ + K⁻¹ I x_int(oneK⊕slot for both P and I — no separate gain matrix).
Integration is skipped whenconditioning_scale(s_min_G) < scale_gateto 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 proxyLowering the onset 0.05→0.020 improves conditioning with targeting OFF (
s_min_Jfrac_below 0.597→0.027)
but collapses it with targeting ON (s_min_Jmin 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.
Related
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