wrist_2 and wrist_3 stop 5° short of each limit so those motors are never driven into the ends of travel; every other joint sweeps to its full limit. On a full-robot run it first prompts to clamp each gripper onto an item and holds it for the duration; when the soak finishes (or on Ctrl-C) the robot returns home with the item still gripped and the motors left enabled — run diag.rom-disable afterwards to release it and power down.
The arms are driven through the Rust realtime core — the same control path as teleop — so the soak exercises exactly the controller the robot ships with: the core owns the CAN buses, renders the streamed sweep at 240 Hz, and runs the host damping against fresh feedback.
Joint positions and torques are captured to a CSV under ~/.almond/diagnostics/captures at 5 Hz so the run can be charted in the diagnostics dashboard’s run history.
With --target mantis, the same soak machinery exercises only the two grippers at ID 8 on can_mantis_l / can_mantis_r; arm-joint and grasp-hold steps do not apply.
--joints selects which joints are swept; every other joint holds home. Before bring-up each bus is probed for which motors answer: every selected joint must be there (a missing one fails the run by name), while an unselected joint that does not answer is treated as absent and left out of bring-up — so a partially populated bench arm (say a wrist assembly on a single adapter) can run --joints wrist_2,wrist_3,gripper. Every motor that does answer is brought up and held, and the skipped joints are printed at startup; make sure they really are not attached, since an unpowered motor looks the same as an absent one. A full-robot run still requires every motor. A subset run skips the grasp step — if the gripper is among the selected joints it is cycled open↔close holding nothing.
A partial arm is off the robot, so it is driven as plain soft PD (the hand-guidable end of the stiffness slider) with the gravity, friction, inertia and host-damping feedforwards off — those are all modelled against the full arm in the robot’s mounting orientation, and the production gains vibrate on a wrist kit clamped to a bench. The run prints Partial arm — bench gains when this applies. Only missing arm joints count: a joint subset swept on a fully populated arm is still the robot and keeps the production gains, and so is a mounted arm whose gripper does not answer.
--left-channel / --right-channel override the SocketCAN interface used for each side. Defaults are the Axol pair for --target axol and the Mantis pair for --target mantis. With a single-channel adapter, combine a channel override with --no-left / --no-right.
By default each hands-on gripper step is an interactive input() prompt on the terminal. --web-prompts instead emits a [prompt] … marker and blocks on stdin, so the web dashboard can turn the step into a Continue button (it’s set automatically when launched from the dashboard).