Appearance
Limits
What it does not tune
- No integrator. ki is never searched, and
Goal.integratoris a placeholder nothing reads. Stop error from stiction is left to feed-forward. On geared joints that leaves holds parked inside the friction band, which is why K3 and K4 are open (evaluation). - No filters. There is no notch or low-pass design. A structural resonance can only be stayed under (ωn ≤ ⅓ of the mode the description states), not filtered out, and an unstated one is found only by the sweep ringing on it.
- No current loop. The drive's inner current loop is configuration. Its bandwidth is an input to the analytic start, never a knob the tuner turns.
- One control law. A PD position loop with feed-forward, in the shape a position-commanded drive runs it. Gain scheduling, LQR and other feedback laws are not built.
Assumptions
- Each box is one rigid axis. Identification fits
τ = J·q̈ + b·q̇ + τc·tanh(q̇/0.01) + gravitywhile every other joint holds home. The closed form assumesJ·q̈ + b·q̇ = τwith no compliance or backlash. The analytic start's bounds account for delay and loop lags; anything else is caught only by the sweep and the gates. - One gain set per joint, at one pose. On a serial arm, a proximal joint's inertia changes with the pose. Over random poses of the UR5e fixture, the shoulder pan joint's inertia (links plus rotor) spans 5.6×, and the shoulder lift's 3.3×. With fixed gains, ωn and ζ both scale as 1/√J, so ζ = 0.8 tuned at the light end falls to about 0.34 at the heavy end.
- No arm-level payload estimation. The robot model's feed-forward assumes the nominal payload. A heavier tool shows up only as what each joint's box can absorb, and as drift in
fine_tune. - Friction feed-forward is keyed to the reference velocity.
tanh(q̇*/band)is zero at every hold, which is exactly where stiction parks a joint. - Closed chains carry their own gravity. With passive joints or a loop closure, the robot model's feed-forward switches off, and each driven joint's box models gravity as a pendulum through home.
- The gain guard caps a session. The default allows at most 2× the as-found gains per session. A joint that is far from its best needs several write-and-retune rounds.
The analytic start
- Gain margin is its only robustness test. On the 22 gain-margin-bound starts in the evaluation, the start's own loop model gives a phase margin of 24–28° and a sensitivity peak of 2.7–2.9, both outside the usual ranges.
info["zeta"]reports the target ζ, not the damping the loop actually has. - The noise bound applies only where the description states sensor noise. None of the evaluation's descriptions do.
The evidence
- Mostly simulation. The KPIs come from 33 simulated joints on nine robot kinds, plus two simulated joints built from measured real-joint twins. Their factory gains are deliberately soft, and the gain guard is opened to 0.001–1000×, which a real joint would never get.
- Little real hardware. Three real test joints were tuned from factory gains inside the normal guard, before the analytic start existed: held-out stop p90 48.5 → 13.6, 38.1 → 4.6 and 15.5 → 6.3 mrad. No real arm has been tuned, and the tuner has written nothing to a real drive: its output is a proposal.
fine_tunehas only seen simulated wear. - The simulator is drive-like, not every drive.
ServoSimmodels one family of position-commanded drives: setpoint advanced at the commanded velocity between commands, a first-order current loop, a quantized and delayed encoder. K5 checks it against real joints of that family only. - Four of six KPIs are open. K2 (one joint ends worse than its start), K3 and K4 (stop error and hold convergence under stiction), K6 (12 of 35 joints within 15 % of the oracle).
- The cost mostly grades the feed-forward. Nominal held-out tracking does not separate what feedback buys from what feed-forward buys. There is no disturbance-rejection or model-error test in the cost.
- Held-out seeds were reused. The same held-out tapes were scored through many development iterations, so they are less "unseen" than a fresh set would be.
Practical
- The command line starts from factory gains. Seeding with the analytic start is a Python call (
tune(..., seed=...),tune_arm(..., seeds=...)). - A tune moves the joint for a while. For the quickstart joint,
tune.plan_secondsbounds the motion at about 20 minutes, most of it the search. Use it to budget a session before anything moves. - The chirp tops out at command rate / 50. At a 100 Hz host rate that is 2 Hz. A faster chirp breaks identification for drives that integrate the setpoint between commands.