AlohaMini Command Cheat Sheet#

← 教程资料库 · AlohaMini 硬件与操作

适用型号请结合本页硬件配置确认。


Common commands for setup, calibration, teleoperation, recording, replay, training, evaluation, and debugging.

Replace placeholders before running:

  • <Pi_IP>: Raspberry Pi / robot host IP.

  • <your_token>: Hugging Face token with read and write permissions.

  • $HF_USER: Hugging Face username.

  • alohamini1, alohamini2, alohamini2pro: must match the physical robot on the host side.

Environment#

Clone and install:

git clone https://github.com/liyiteng/lerobot_alohamini.git
cd lerobot_alohamini
conda create -y -n lerobot_alohamini python=3.12
conda activate lerobot_alohamini
pip install -e ".[all]"
pip install pyzmq feetech-servo-sdk
conda install -y ffmpeg=7.1.1 -c conda-forge

Alternative with uv:

uv sync --locked
uv sync --locked --extra test --extra dev
uv sync --locked --extra all

Serial permissions:

sudo usermod -a -G dialout $USER

Hugging Face login:

git config --global credential.helper store
hf auth login --token <your_token> --add-to-git-credential
HF_USER=$(hf auth whoami | sed 's/^user=//')
echo $HF_USER

Device Discovery#

Find motor serial ports:

lerobot-find-port
ls /dev/ttyACM*
ls /dev/serial/by-id/

Find cameras:

lerobot-find-cameras
v4l2-ctl --list-devices

Check camera formats and FPS:

v4l2-ctl -d /dev/video0 --list-formats-ext

Enable or disable robot cameras by editing the camera config:

sudo apt install micro
sudo micro src/lerobot/robots/alohamini/config_alohamini.py

In alohamini_cameras_config(), uncomment a camera block to enable it, or comment it out to disable it. After changing camera config, restart the AlohaMini host process.

Persistent Arm Ports#

Advanced and optional. Use udev rules to keep arm device names stable after reboot or USB reconnect. Run this on the machine where the arm controller boards are plugged in:

  • Follower arms: Raspberry Pi / robot host.

  • Leader arms: PC / DGX client.

Find the serial number of one arm controller board:

udevadm info --attribute-walk --name=/dev/ttyACM0 | awk -F'"' '/ATTRS{serial}/{print $2; exit}'

Repeat for each board by changing the device path:

udevadm info --attribute-walk --name=/dev/ttyACM1 | awk -F'"' '/ATTRS{serial}/{print $2; exit}'

Create or edit the udev rules file:

sudo nano /etc/udev/rules.d/90-mydevice.rules

Add follower-arm rules on the Pi / robot host, using the actual serial numbers from your boards:

SUBSYSTEM=="tty", ATTRS{serial}=="<follower_left_serial>", SYMLINK+="am_arm_follower_left"
SUBSYSTEM=="tty", ATTRS{serial}=="<follower_right_serial>", SYMLINK+="am_arm_follower_right"

Add leader-arm rules on the PC / DGX client, using the actual serial numbers from your boards:

SUBSYSTEM=="tty", ATTRS{serial}=="<leader_left_serial>", SYMLINK+="am_arm_leader_left"
SUBSYSTEM=="tty", ATTRS{serial}=="<leader_right_serial>", SYMLINK+="am_arm_leader_right"

Reload and trigger udev:

sudo udevadm control --reload-rules
sudo udevadm trigger

Verify the stable names:

ls /dev/am*

Use follower paths in src/lerobot/robots/alohamini/config_alohamini.py on the Pi / robot host:

left_port = "/dev/am_arm_follower_left"
right_port = "/dev/am_arm_follower_right"

Use leader paths in examples/alohamini/record_bi.py and examples/alohamini/teleoperate_bi.py on the PC / DGX client:

left_arm_config=SOLeaderConfig(port="/dev/am_arm_leader_left", ...)
right_arm_config=SOLeaderConfig(port="/dev/am_arm_leader_right", ...)

Host Side#

Run these on the Raspberry Pi / robot host.

Calibrate only, then exit:

python -m lerobot.robots.alohamini.alohamini_calibrate --robot_model alohamini2

The host commands below also check calibration and will prompt calibration automatically if it is missing.

AlohaMini 1:

python -m lerobot.robots.alohamini.alohamini_host --robot_model alohamini1

AlohaMini 2:

python -m lerobot.robots.alohamini.alohamini_host --robot_model alohamini2

AlohaMini 2 Pro:

python -m lerobot.robots.alohamini.alohamini_host --robot_model alohamini2pro

Base and lift only:

python -m lerobot.robots.alohamini.alohamini_host --robot_model alohamini2 --no_follower

ROS-compatible camera publishing is opt-in and does not change the default two-camera set. This branch runs Host control at 50 Hz:

python -m lerobot.robots.alohamini.alohamini_host \
  --robot_model alohamini2pro \
  --camera-stream

The Host uses TCP 5555 for commands, 5556 for observations and metadata, and 5557 for the optional camera-only stream. Plain 5556 requests retain the legacy state-plus-image response; request tokens ending in :state return state only. Native teleoperation defaults to 50 Hz control and 30 Hz camera requests. These can be set explicitly with --fps 50 --camera-fps 30. The existing record_bi.py keeps its original single-rate behavior, where control and dataset sampling both use --dataset.fps. Use record_bi_multirate.py when you want 50 Hz control while committing only fresh, timestamp-aligned images, state, and action at the dataset rate (normally 30 Hz). The multirate recorder collects the requested frame count, so a physical camera running at 29.5 Hz may extend wall-clock recording slightly. It stops explicitly if a camera stalls, multi-camera skew exceeds 50 ms, state alignment exceeds 100 ms, or the fresh frame rate falls below 90% of the requested rate.

Teleoperation#

Run these on the PC / DGX client after the host is running.

AlohaMini 1 with SO-ARM leader:

python examples/alohamini/teleoperate_bi.py \
  --robot.remote_ip <Pi_IP> \
  --robot.robot_model alohamini1 \
  --teleop.id so101_leader_bi \
  --teleop.arm_profile so-arm-5dof \
  --fps 50 \
  --camera-fps 30

AlohaMini 2 / 2 Pro with AM-ARM leader:

python examples/alohamini/teleoperate_bi.py \
  --robot.remote_ip <Pi_IP> \
  --robot.robot_model alohamini2 \
  --teleop.id am_leader_bi \
  --teleop.arm_profile am-leader-6dof \
  --fps 50 \
  --camera-fps 30

Lower FPS for network or CPU debugging:

python examples/alohamini/teleoperate_bi.py \
  --robot.remote_ip <Pi_IP> \
  --robot.robot_model alohamini2 \
  --teleop.id am_leader_bi \
  --teleop.arm_profile am-leader-6dof \
  --fps 10 \
  --camera-fps 10

Recording#

record_bi.py prints the local dataset path after setup and finalization, and uploads to Hugging Face Hub by default. Add --dataset.push_to_hub=false if you only want to keep the dataset locally. Add --dataset.root /path/to/dataset when you want to store or resume from a specific local directory.

For optional 50 Hz control with fresh camera frames at --dataset.fps, use the same arguments with the multirate entry point:

python examples/alohamini/record_bi_multirate.py \
  --dataset.repo_id $HF_USER/alohamini_multirate_test \
  --dataset.fps 30 \
  --robot.remote_ip <Pi_IP> \
  --robot.robot_model alohamini2pro \
  --teleop.id am_leader_bi \
  --teleop.arm_profile am-leader-6dof

Create a dataset for AlohaMini 1:

python examples/alohamini/record_bi.py \
  --dataset.repo_id $HF_USER/so100_bi_test \
  --dataset.num_episodes 1 \
  --dataset.fps 30 \
  --dataset.episode_time_s 45 \
  --dataset.reset_time_s 8 \
  --dataset.single_task "pickup1" \
  --robot.remote_ip <Pi_IP> \
  --robot.robot_model alohamini1 \
  --teleop.id so101_leader_bi \
  --teleop.arm_profile so-arm-5dof

Resume a dataset for AlohaMini 1:

python examples/alohamini/record_bi.py \
  --dataset.repo_id $HF_USER/so100_bi_test \
  --dataset.num_episodes 1 \
  --dataset.fps 30 \
  --dataset.episode_time_s 45 \
  --dataset.reset_time_s 8 \
  --dataset.single_task "pickup1" \
  --robot.remote_ip <Pi_IP> \
  --robot.robot_model alohamini1 \
  --teleop.id so101_leader_bi \
  --teleop.arm_profile so-arm-5dof \
  --resume

Create a dataset for AlohaMini 2 / 2 Pro:

python examples/alohamini/record_bi.py \
  --dataset.repo_id $HF_USER/am2_bi_test \
  --dataset.num_episodes 1 \
  --dataset.fps 30 \
  --dataset.episode_time_s 45 \
  --dataset.reset_time_s 8 \
  --dataset.single_task "pickup1" \
  --robot.remote_ip <Pi_IP> \
  --robot.robot_model alohamini2 \
  --teleop.id am_leader_bi \
  --teleop.arm_profile am-leader-6dof

Resume a dataset for AlohaMini 2 / 2 Pro:

python examples/alohamini/record_bi.py \
  --dataset.repo_id $HF_USER/am2_bi_test \
  --dataset.num_episodes 1 \
  --dataset.fps 30 \
  --dataset.episode_time_s 45 \
  --dataset.reset_time_s 8 \
  --dataset.single_task "pickup1" \
  --robot.remote_ip <Pi_IP> \
  --robot.robot_model alohamini2 \
  --teleop.id am_leader_bi \
  --teleop.arm_profile am-leader-6dof \
  --resume

Recording smoke test:

python examples/alohamini/record_bi.py \
  --dataset.repo_id $HF_USER/alohamini_smoke_test \
  --dataset.num_episodes 1 \
  --dataset.fps 10 \
  --dataset.episode_time_s 10 \
  --dataset.reset_time_s 3 \
  --dataset.single_task "smoke test" \
  --robot.remote_ip <Pi_IP> \
  --robot.robot_model alohamini2 \
  --teleop.id am_leader_bi \
  --teleop.arm_profile am-leader-6dof

Replay and Visualization#

Replay one episode:

python examples/alohamini/replay_bi.py \
  --dataset.repo_id $HF_USER/am2_bi_test \
  --dataset.episode 0 \
  --robot.remote_ip <Pi_IP> \
  --robot.robot_model alohamini2

If the dataset is not under $HF_LEROBOT_HOME/$HF_USER/am2_bi_test, add --dataset.root /path/to/am2_bi_test.

Visualize a dataset episode:

lerobot-dataset-viz \
  --repo-id $HF_USER/am2_bi_test \
  --episode-index 0 \
  --display-compressed-images

Training#

Train ACT:

lerobot-train \
  --dataset.repo_id=$HF_USER/am2_bi_test \
  --policy.type=act \
  --output_dir=outputs/train/act_am2_bi_test \
  --job_name=act_am2_bi_test \
  --policy.device=cuda \
  --wandb.enable=false \
  --policy.repo_id=$HF_USER/act_am2_bi_test \
  --dataset.video_backend=pyav

Train with uv:

uv run lerobot-train \
  --dataset.repo_id=$HF_USER/am2_bi_test \
  --policy.type=act \
  --output_dir=outputs/train/act_am2_bi_test \
  --job_name=act_am2_bi_test \
  --policy.device=cuda \
  --wandb.enable=false \
  --policy.repo_id=$HF_USER/act_am2_bi_test \
  --dataset.video_backend=pyav

Evaluation#

Evaluate a local checkpoint:

python examples/alohamini/evaluate_bi.py \
  --eval.n_episodes 3 \
  --fps 20 \
  --eval.episode_time_s 45 \
  --dataset.single_task "Pick and place task" \
  --policy.path outputs/train/act_am2_bi_test/checkpoints/020000/pretrained_model \
  --dataset.repo_id $HF_USER/eval_act_am2_bi_test \
  --dataset.push_to_hub=true \
  --robot.remote_ip <Pi_IP> \
  --robot.id my_alohamini \
  --robot.robot_model alohamini2

Performance Debugging#

Check network latency:

ping <Pi_IP>

Check WiFi link:

iw dev
iw dev wlan0 link

Check bandwidth with iperf3:

# Host side
iperf3 -s

# Client side
iperf3 -c <Pi_IP>

Monitor CPU, memory, and GPU:

top
htop
nvidia-smi

Check video encoders available to FFmpeg:

ffmpeg -hide_banner -encoders | grep -E 'libsvtav1|h264|nvenc|vaapi|qsv'

Check Python package versions:

python -c "import av, cv2, torch; print('av', av.__version__); print('cv2', cv2.__version__); print('torch', torch.__version__)"

Run a lower-load recording test:

python examples/alohamini/record_bi.py \
  --dataset.repo_id $HF_USER/perf_debug_low_fps \
  --dataset.num_episodes 1 \
  --dataset.fps 10 \
  --dataset.episode_time_s 10 \
  --dataset.reset_time_s 3 \
  --dataset.single_task "perf debug" \
  --robot.remote_ip <Pi_IP> \
  --robot.robot_model alohamini2 \
  --teleop.id am_leader_bi \
  --teleop.arm_profile am-leader-6dof

Hardware Debug Scripts#

These commands come from examples/debug. Run them from the repository root.

View all motor states:

python examples/debug/motors.py get_motors_states \
  --port /dev/ttyACM0

Control the mobile base only:

python examples/debug/wheels.py \
  --port /dev/ttyACM0

Control the lift axis only:

python examples/debug/axis.py \
  --port /dev/ttyACM0

Rotate a specific motor by ID:

python examples/debug/motors.py move_motor_to_position \
  --id 1 \
  --position 2 \
  --port /dev/ttyACM0

Set a new motor ID:

python examples/debug/motors.py configure_motor_id \
  --id 1 \
  --set_id 8 \
  --port /dev/ttyACM0

Set the phase of a specified servo:

python examples/debug/motors.py configure_motor_phase \
  --id 1 \
  --set_phase 12 \
  --port /dev/ttyACM0

Set the phase for all servos:

python examples/debug/motors.py configure_motor_phase \
  --set_phase 12 \
  --port /dev/ttyACM0

Reset current position as the motor midpoint:

python examples/debug/motors.py reset_motors_to_midpoint \
  --port /dev/ttyACM1

Disable torque for all arm motors:

python examples/debug/motors.py reset_motors_torque \
  --port /dev/ttyACM0

Execute an action script on the robot arm:

python examples/debug/motors.py move_motors_by_script \
  --script_path examples/debug/action_scripts/test_dance.txt \
  --port /dev/ttyACM0

Move arm to rest position from script:

python examples/debug/motors.py move_motors_by_script \
  --script_path examples/debug/action_scripts/go_to_restposition.txt \
  --port /dev/ttyACM0

Move arm to midpoint from script:

python examples/debug/motors.py move_motors_by_script \
  --script_path examples/debug/action_scripts/go_to_midpoint.txt \
  --port /dev/ttyACM0

Run camera debug script:

python examples/debug/test_cv.py

Run CUDA debug script:

python examples/debug/test_cuda.py

Run network debug script:

python examples/debug/test_network.py

Run dataset debug script:

python examples/debug/test_dataset.py

Run keyboard/input debug script:

python examples/debug/test_input.py

Run microphone debug script:

python examples/debug/test_mic.py

Development#

Run tests:

uv run pytest tests -svv --maxfail=10

Run pre-commit checks:

pre-commit run --all-files

Run end-to-end tests:

DEVICE=cuda make test-end-to-end

Find AlohaMini references:

rg -n "alohamini|record_bi|teleoperate_bi|evaluate_bi" src examples docs