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