Skip to content

Command line ​

The command line runs the tuner on built-in simulations. It is the quickest way to see a full run and its output files.

Real hardware is driven through your own Plant, from Python. There is no built-in hardware runner.

arm-sim ​

bash
pidtuna arm-sim --out runs/ur5e

Tunes every joint of a simulated UR5e-class arm (needs the [arm] extra for MuJoCo). The arm carries a payload its model does not know about, --payload kg (default 2.0). Each joint is tuned tip to base while the others hold home, with the robot model's gravity, link inertia and coupling riding along as feed-forward. Then all six joints play held-out pick-and-place motion together, and any joint the arm check flags backs off.

arm-sim starts from the factory gains with the default 0.25–2× gain guard, so it shows a careful first session, not the best the tuner can do. Seeding from the analytic start is a library call (tune_arm(..., seeds=...)).

A run takes about 75 s on a 24-core desktop. The log, trimmed:

text
== ur5e: joint wrist_3_joint (others hold home under their current controllers)
wrist_3_joint: identify (48 s of excitation at the as-found gains)
  J 0.0808 kg.m2  b 0.294  tau_c 0.801 N.m  gravity 0.00454 N.m  [identified, cond 4, 2418 rows]
  as found: wn 14.9 rad/s, zeta 0.62
wrist_3_joint: bandwidth sweep at zeta 0.8
  sweep wn   14.93 rad/s  kp       18  kd    1.636  ringing  0.000 mrad  overshoot   0.0 %  crossings 0  chatter 1.8e-14 mN.m  zeta 0.80
  sweep wn   17.91 rad/s  kp    25.92  kd    2.022  ringing  0.000 mrad  overshoot   0.0 %  crossings 0  chatter 2.38e-14 mN.m  zeta 0.80
  sweep wn   21.11 rad/s  kp       36  kd      2.4  ringing  0.000 mrad  overshoot   0.0 %  crossings 0  chatter 3.11e-14 mN.m  zeta 0.79
  reached the gain guard without ringing; deploy wn <= 21.1 rad/s
wrist_3_joint: pass 1, feed-forward at the as-found gains
  ...
  feedforward  as-found gains, FF (Coulomb x1, viscous) + FB stop p90    5.49  tracking    3.59  cost  0.21
  ...
wrist_3_joint: verify on held-out tapes (seed 1)
  before: stop p90 44.3 mrad, tracking 42.1 mrad
  after:  stop p90 4.23 mrad, tracking 3.4 mrad
...
== ur5e: all joints together on held-out pick-and-place tapes
  elbow_joint            before stop p90    45.9 tracking    35.4  ->  after    19.8 /    16.1 mrad
  shoulder_lift_joint    before stop p90    23.8 tracking      21  ->  after    11.5 /    10.4 mrad
  shoulder_pan_joint     before stop p90     6.3 tracking    8.34  ->  after    3.28 /    3.42 mrad  BACK OFF
  ...
  note: shoulder_pan_joint: coordinated motion rang; backed off to wn 14.3 rad/s (round 1).
  note: shoulder_pan_joint: coordinated motion rang; backed off to wn 11.4 rad/s (round 2).

The shoulder pan joint was quiet when tuned alone but rang with the whole arm moving, so it backed off twice, 0.8× per round. Final stop p90 with all joints moving: elbow 45.9 → 19.8, shoulder lift 23.8 → 11.5, shoulder pan 6.3 → 4.7, wrist 1 117 → 51, wrist 2 69 → 15, wrist 3 43.9 → 5.3 mrad.

sim ​

bash
pidtuna sim lever --out runs/lever

Tunes one built-in simulated demo joint: lever (a geared servo driving a loaded lever against gravity) or conveyor (a belt conveyor carrying parcels its model does not know about). --guard low,high sets the gain guard as multiples of the as-found gains.

Output files ​

Every run writes three files into --out:

filecontents
proposal.jsonthe proposal: gains to set, host feed-forward, identified model, before/after on held-out tapes, every sweep rung and candidate. arm-sim writes the arm form, one proposal per joint plus the whole-arm before/after.
traces.npzevery trace as arrays, keyed <group>/<index>/<field> with fields t, q, qd, tau_nm, q_target, qd_target, tau_ff_nm, plus a meta JSON string (tape, motion class, controller label, end reason).
log.txtthe log printed above.

Nothing is written to a drive. Applying a proposal is a separate step you run yourself.

Source: coming soon.