axol run-policy. Add any flag below to the command, or set it once in the control panel. See Command configuration for config files and syntax.
The shared settings file (~/.almond/settings.json) is read by default. It stores these flags in the sections below.
Policy
Action chunking
A custom policy’s endpoint sends the final plan, and the robot runs the rest of it unchanged. LeRobot policies use the chunk-blending settings below. The speed and acceleration limits apply to both.Recording
Optional. Set--repo_id to record the episodes to a dataset.
Contact safety
A contact stop trips when a joint pushes harder than the arm’s weight explains, which means the arm hit something. The arms then go limp instead of pushing through.Robot
CAN buses, cameras and what goes into observations.Cameras
One ZED camera per slot:overhead, left_arm, right_arm. Flags are shown for overhead; swap in the other slot names. Stereo ZED X cameras are detected from their serial. The control panel’s Cameras tab edits all of this visually.
Arm gains
Arm stiffness, gripper limits and per-joint gains.
Per-arm and per-joint flags are shown for
left / elbow. Swap in right, or any joint: shoulder_1, shoulder_2, shoulder_3, elbow, wrist_1, wrist_2, wrist_3.
A robot calibrated with
tune.pid --save, tune.friction --save, or tune.gravity --save uses its own measured values (from ~/.almond/calibration.json) instead of the defaults below. Flags you pass still override both.Controller and command rates
Controller and command rates
Position controller.
controller position sets every joint to its firmware position loop (a4 on the MyActuator joints, pv on the Damiao wrists) and uses the firmware.* gains. It is stiff: there is no compliance and no host feed-forward. Teleop takes --axol.controller position, and recorded-motion replays take --controller (tune.motion).At 400 Hz the bus can’t carry every motor every tick:- The MyActuator joints are commanded every tick.
- The two wrists are commanded on alternate ticks, 200 Hz each.
- One precise position read per tick rotates through the MyActuator joints and the gripper, about 67 Hz each.
impedance, a wire_mode you set on a joint is kept.With impedance_hz at 480.0, or any joint’s own impedance_hz at 480.0, the arm’s core runs at 480 Hz. The 480 Hz joints are commanded every tick, and the other impedance joints, including the Damiao wrists, on alternate ticks. tune.motion --impedance-hz 480 and tune.motion --fast-impedance right.shoulder_1 set these for one run.Firmware position loops (a4 and pv)
Firmware position loops (a4 and pv)
- A joint on
a4orpvhas no compliance and no host feed-forward. - An
a4joint’s torque reads NaN, so the contact stop can’t see that joint. Apvwrist keeps its torque reading. - The gripper, gravity compensation and the limp fallback always use
mit. On X6-P20 motors with the 2025-07 firmware, ana4joint that was hand-guided needs a re-enable before it tracks again. - On
pv, the core sets the Damiao control mode at bring-up and switches it back to MIT for limp and gravity compensation.
firmware.* fields are the motor’s own position and speed loops. They act only while a joint runs a firmware loop, so every joint leaves them null by default and bring-up keeps the motors’ stored values. When set, a gain is written to the motor’s ROM at enable. Find values with tune.a4.planner_accelat60000works best withcap_track. Values in between would re-plan every target so the joint barely moves, and are refused.cap_trackis sent to the realtime core, not written to the motor.tf_rated_current_aneeds firmware with command 0x73 (VersionDate 2026042402 or later) and direct tracking (planner_accel0). The X8-P20 shoulders have it, and the X6-P20 elbow doesn’t. Elsewhere the joint stays on plain 0xA4 and the core logs why.
Stiction, dither and Stribeck terms
Stiction, dither and Stribeck terms
These feed-forward terms target slow-motion stick-slip on geared joints. All are off by default.
- Stiction push. The peak push is
stiction_gain × fc + stiction_load_gain × abs(gravity). It fades on measured velocity and is gone above about 0.05 rad/s, so it never drives the slip. Keepstiction_gainbelow the breakaway-to-fcratio thattune.breakawaymeasures. - Dither. Start
dither_nmat 1 to 2 Nm on a shoulder. The dither is audible. - Stribeck cancellation. The term is
stribeck_gain × (stribeck_dfs + stribeck_load_gain × abs(gravity)) × exp(−(v/stribeck_vs)²) × tanh(v/0.02), so it is zero at rest. Raisestribeck_gainfrom 0.5 toward 0.9, and stop when the arm’s 3 Hz mode grows. - Stribeck pole.
20is smooth but lags a fast surge.40to80follows it more closely but adds encoder noise to the torque.
Per-joint defaults
Per-joint defaults
Both arms share these.
kp and kd are the values at stiffness 1 (the default), and the soft columns are what stiffness 0 blends toward. shoulder_1 sets kd_host_q to 3, and every other joint leaves kd_host_hz and kd_host_q at null. No joint runs the Stribeck cancellation by default.Slow-motion gains. A joint whose calibration includes its own slow-profile friction fit runs the stiffer set below.
tune.factory writes that fit by default, and so does tune.friction --profile slow --save. These gains oscillate on a joint that still uses the fallback friction, so an uncalibrated joint keeps the table above.Gains saved in the joint’s own calibration entry still override these, for example from
tune.pid --save or the friction fit’s stribeck_gain.Per-motor friction defaults
Per-motor friction defaults
Fallback values of
fc, k, fv, fo for each motor, measured on a reference robot with tune.friction. A joint’s slow-profile friction (fl and the Stribeck excess) comes only from its own calibration. There is no fallback for it, so calibrate each robot.