Appearance
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/ur5eTunes 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/leverTunes 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:
| file | contents |
|---|---|
proposal.json | the 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.npz | every 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.txt | the log printed above. |
Nothing is written to a drive. Applying a proposal is a separate step you run yourself.