AlohaMini Command Cheat Sheet#
← Tutorial Library · AlohaMini Hardware and Operation
Please confirm the applicable models based on the hardware configuration on this page.
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