Skip to main content
Replays a reference motion through the same controller teleop uses, and scores tracking accuracy and smoothness for each joint. The gains, feed-forward and damping come from the same config as teleop and the SDK: your panel settings on top of the calibration. The motion is the same on every run, so you can change one gain with --gain, replay, and compare the numbers. The diagnostics dashboard shows the runs as charts, side by side. Every run is saved, with each joint’s full time series and scores, under ~/.almond/diagnostics/tuning/.

Safety

  • The arm moves to the motion’s start and back to rest on planned paths that avoid collisions.
  • A contact watchdog stops playback if a joint keeps pushing harder than the plan expects (--torque-threshold).
  • Before playback the tool checks that the arm reached the start pose. If a joint is more than about 3° off, the tool names it, skips playback and returns the arm to rest.
  • A tracking guard stops playback if a joint leaves its path, oscillates or vibrates. See Tracking guard.
If an --a4 joint fails the start check, its stored planner acceleration is probably neither 0 nor 60000. Read it with scripts/fw_gains.py --id <id>. Any value in between makes the joint barely move (see tune.a4).

Gain fields

--gain accepts these fields:
  • Impedance and damping: kp, kd, kd_host, kd_host_hz, kd_host_q, j_eff
  • Friction compensation: stiction_gain, stiction_load_gain, stiction_err_deg, dither_nm, dither_hz, stribeck_gain, stribeck_dfs, stribeck_load_gain, stribeck_vs, stribeck_pole, and the friction model as friction.fc, friction.k, friction.fv, friction.fo, friction.fl
  • Firmware position loop: firmware.position_kp, firmware.position_ki, firmware.position_kd, firmware.speed_kp, firmware.speed_ki, firmware.profile_acc
  • MyActuator 0xA4 planner: firmware.planner_accel (0 or 60000), firmware.cap_track (1 or more, for example 1.2) and firmware.planner_lead_ms
  • Torque feed-forward: firmware.tf_rated_current_a, in amps, for MyActuator a4 joints on V4.4 firmware
  • Gravity model: mass (kg) and com.x, com.y, com.z (m, in the link’s URDF frame), to try a gravity correction before you calibrate it
Firmware gains are written to the motor’s ROM when the joint enables, so they stay in the motor after the run. The next run without the override sets the planner back to 0.

Noise, filters and IK

With any of these, the run is still scored against the clean motion. The saved run also stores the stream that was sent, so the dashboard can overlay the clean, sent and measured positions for each joint. --ik solves the whole motion before playback starts, so slow solves don’t change the playback timing.

Controllers and rates

Learning and pre-compensation

With --learn, pass 1 runs uncorrected. After each pass, each joint gets a position offset that cancels its tracking error in --learn-band. A pass that comes out worse goes back to the best offset at half the gain. A learned offset belongs to the motion it was learned on. It shows how much each joint needed, which is the most a feed-forward model could achieve.

Tracking guard

By default the guard watches every driven joint’s tracking error and stops playback when a joint: When the guard trips, the run’s gain overrides go back to the base config, the arm holds still for 1.5 s, then returns to rest. The moves to and from the motion get twice the limits. If the return trips twice, the arm stays powered and holds its last command. Trips are saved with the run, and the command exits with status 3. For slow creep motions, tighten the limits, for example --guard-dev-deg 4 --guard-osc-deg 1. Pass --no-guard to turn the guard off.

Research flags

These flags are research tools and are not part of the production controller. Damping from the wrist camera’s IMU can add high-frequency oscillation, and its effect depends on how the camera is mounted on the wrist.

Reading the scorecard

Wrist IMU shake

Each pass also prints the shake the wrist camera’s IMU measures at the gripper. It is reported in mm, as the typical peak-to-peak motion over 2 s in the 1–15 Hz band. The score is given overall and along gravity, and the vertical part is split into low_mm (1–3 Hz, slow sway) and high_mm (3–15 Hz). The IMU sees motion the joint encoders can’t, such as gear backlash, link flex and the gripper itself. It is the number that matches a shake you can see at the tool. The saved run stores it as metrics.imu, with the raw samples. Joints that move less than 1° in the motion show - in the tracking columns. They keep their row and are still scored for buzz and torque chatter, which is where a vibration at a held pose shows up.