Unitree G1 人形机器人现在已获 LeRobot 支持!你可以进行 teleoperation、训练移动操作(locomanipulation)policy、在 simulation 中测试等。29 和 23 自由度两种型号均受支持。
请遵循 unitree_sdk2_python 安装指南。已使用 unitree_sdk2py==1.0.1 和 cyclonedds==0.10.2 测试通过:
conda create -y -n lerobot python=3.12
conda activate lerobot
git clone https://github.com/unitreerobotics/unitree_sdk2_python.git
cd unitree_sdk2_python
pip install -e .
cd ..conda install ffmpeg -c conda-forge
conda install -c conda-forge "pinocchio>=3.0.0,<4.0.0"
git clone https://github.com/huggingface/lerobot.git
cd lerobot
pip install -e '.[unitree_g1]'目前,pinocchio 必须从 conda-forge(而非 pip)安装,以包含机械臂 IK 所需的 CasADi 绑定。
simulation environment 有自己的依赖。请查看 simulation environment 依赖:Unitree G1 Mujoco EnvHub。
pip install mujoco loguru msgpack msgpack-numpy
lerobot-teleoperate \
--robot.type=unitree_g1 \
--robot.is_simulation=true \
--teleop.type=unitree_g1 \
--teleop.id=wbc_unitree \
--robot.cameras='{"global_view": {"type": "zmq", "server_address": "localhost", "port": 5555, "camera_name": "head_camera", "width": 640, "height": 480, "fps": 30, "warmup_s": 5}}' \
--display_data=true \
--robot.controller=GrootLocomotionController这将为 G1 启动一个 MuJoCo simulation 实例。你可以在启动前将游戏手柄连接到机器,以便在 simulation 中控制机器人的移动。我们通过 --robot.controller 同时支持 HolosomaLocomotionController 和 GrootLocomotionController。
9 释放机器人7 / 8 增加 / 降低腰部高度G1 的以太网 IP 固定为 192.168.123.164。你的机器必须在同一子网上具有静态 IP:192.168.123.x,其中 x ≠ 164。
# Replace 'enp131s0' with your ethernet interface name (check with `ip a`)
sudo ip addr flush dev enp131s0
sudo ip addr add 192.168.123.200/24 dev enp131s0
sudo ip link set enp131s0 upssh unitree@192.168.123.164
# Password: 123G1 需要网络访问来克隆仓库和安装软件包。通过以太网共享你笔记本电脑的连接:
在笔记本电脑上:
sudo sysctl -w net.ipv4.ip_forward=1
# Replace wlp132s0f0 with your WiFi interface name
sudo iptables -t nat -A POSTROUTING -o wlp132s0f0 -s 192.168.123.0/24 -j MASQUERADE
sudo iptables -A FORWARD -i wlp132s0f0 -o enp131s0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i enp131s0 -o wlp132s0f0 -j ACCEPT在 G1 上:
sudo ip route del default 2>/dev/null || true
sudo ip route add default via 192.168.123.200 dev eth0
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
# Verify
ping -c 3 8.8.8.8conda create -y -n lerobot python=3.12
conda activate lerobot
git clone https://github.com/unitreerobotics/unitree_sdk2_python.git
cd unitree_sdk2_python
python -m pip install -e .
cd ..git clone https://github.com/huggingface/lerobot.git
cd lerobot
conda install -c conda-forge "pinocchio>=3.0.0,<4.0.0"
python -m pip install -e '.[unitree_g1]'目前,pinocchio 必须从 conda-forge(而非 pip)安装,以包含机械臂 IK 所需的 CasADi 绑定。
###(可选)在机器人上启用 WiFi
为了进行无线 SSH 访问,你可以在 G1 上启用 WiFi(默认是禁用的):
sudo rfkill unblock all
sudo ip link set wlan0 up
sudo nmcli radio wifi on
sudo nmcli device set wlan0 managed yes
sudo systemctl restart NetworkManager连接到 WiFi 网络:
nmcli device wifi list
sudo nmcli connection add type wifi ifname wlan0 con-name "YourNetwork" ssid "YourNetwork"
sudo nmcli connection modify "YourNetwork" wifi-sec.key-mgmt wpa-psk
sudo nmcli connection modify "YourNetwork" wifi-sec.psk "YourPassword"
sudo nmcli connection modify "YourNetwork" connection.autoconnect yes
sudo nmcli connection up "YourNetwork"
ip a show wlan0然后你就可以通过 WiFi(而非以太网)进行 SSH:
ssh unitree@<ROBOT_WIFI_IP>
# Password: 123在机器人上(从 ~/lerobot 目录):
cd ~/lerobot
python src/lerobot/robots/unitree_g1/run_g1_server.py --camera你可以从笔记本电脑通过以太网、通过 WiFi(实验性)运行 teleoperation 客户端,或直接在机器人本身上运行。请注意网络可能引入的延迟。
从你的笔记本电脑:
lerobot-teleoperate \
--robot.type=unitree_g1 \
--robot.is_simulation=false \
--robot.robot_ip=<ROBOT_IP> \
--teleop.type=unitree_g1 \
--teleop.id=wbc_unitree \
--robot.cameras='{"global_view": {"type": "zmq", "server_address": "<ROBOT_IP>", "port": 5555, "camera_name": "head_camera", "width": 640, "height": 480, "fps": 30}}' \
--display_data=true \
--robot.controller=HolosomaLocomotionController我们通过 --robot.controller 同时支持 GrootLocomotionController 和 HolosomaLocomotionController。
我们通过 Homunculus 外骨骼提供了一种移动操作解决方案——这是一款用于全身控制的开源 7 自由度外骨骼。点击这里了解详情。
lerobot-calibrate \ --teleop.type=unitree_g1 \ --teleop.left_arm_config.port=/dev/ttyACM1 \ --teleop.right_arm_config.port=/dev/ttyACM0 \ --teleop.id=exo
calibration 期间,将每个关节移动到其整个范围。装好后,将关节移动到中立位置并按下 n 继续。
lerobot-record \
--robot.type=unitree_g1 \
--robot.is_simulation=true \
--robot.cameras='{"global_view": {"type": "zmq", "server_address": "localhost", "port": 5555, "camera_name": "head_camera", "width": 640, "height": 480, "fps": 30}}' \
--teleop.type=unitree_g1 \
--teleop.left_arm_config.port=/dev/ttyACM1 \
--teleop.right_arm_config.port=/dev/ttyACM0 \
--teleop.id=exo \
--dataset.repo_id=your-username/dataset-name \
--dataset.single_task="Test" \
--dataset.num_episodes=2 \
--dataset.episode_time_s=5 \
--dataset.reset_time_s=5 \
--dataset.push_to_hub=true \
--dataset.streaming_encoding=true \
--dataset.encoder_threads=2注意: 如果你只使用操纵杆,请省略
--teleop.left_arm_config.port和--teleop.right_arm_config.port。
示例 dataset:nepyope/unitree_box_move_blue_full
python src/lerobot/scripts/lerobot_train.py \
--dataset.repo_id=your-username/dataset-name \
--policy.type=pi05 \
--output_dir=./outputs/pi05_training \
--job_name=pi05_training \
--policy.repo_id=your-username/your-repo-id \
--policy.pretrained_path=lerobot/pi05_base \
--policy.compile_model=true \
--policy.gradient_checkpointing=true \
--wandb.enable=true \
--policy.dtype=bfloat16 \
--policy.freeze_vision_encoder=false \
--policy.train_expert_only=false \
--steps=3000 \
--policy.device=cuda \
--batch_size=32训练完成后,我们建议使用 inference 时 RTC 部署 policy:
lerobot-rollout \
--strategy.type=base \
--policy.path=your-username/your-repo-id \
--policy.device=cuda \
--robot.type=unitree_g1 \
--robot.is_simulation=false \
--robot.controller=HolosomaLocomotionController \
--robot.cameras='{"global_view": {"type": "zmq", "server_address": "<ROBOT_IP>", "port": 5555, "camera_name": "head_camera", "width": 640, "height": 480, "fps": 30}}' \
--task="task_description" \
--duration=1000 \
--fps=30 \
--inference.type=rtcLeRobot 现在将 NVIDIA SONIC 全身部署技术栈的解码器部分移植为 SonicWholeBodyController。policy 不再直接命令关节,而是每个周期输出一个 64 维的潜空间运动 token(motion_token.{i}.pos);SONIC 解码器将该 token 与近期的本体感受历史映射为一个残差 action,该残差 action 经缩放后叠加到站立姿态上,为全部 29 个自由度生成 50 Hz 的关节位置目标。
控制器从 lerobot/sonic_decoder 加载其 ONNX 解码器和所有部署常量(PD 增益、default_angles、action_scale 以及中性 token)。该仓库还附带了蒸馏后的低延迟解码器,可通过控制器的 policy_type="low_latency" 参数选择(默认为 "default")。
任何在 SONIC 运动 token 上训练的 token 输出 policy(例如 nepyope/sonic_walk)都可以驱动它:
lerobot-rollout \
--strategy.type=base \
--policy.path=nepyope/sonic_walk \
--policy.device=cuda \
--robot.type=unitree_g1 \
--robot.is_simulation=true \
--robot.controller=SonicWholeBodyController \
--robot.cameras='{"ego_view": {"type": "zmq", "server_address": "localhost", "port": 5555, "camera_name": "head_camera", "width": 640, "height": 480, "fps": 30, "warmup_s": 15}}'在硬件上,请使用async inference而不是单一的 lerobot-rollout 循环来运行 policy。从笔记本电脑驱动的 rollout 会把网络置于控制回路中间:每一步都会阻塞在 inference 上,一次卡顿就会在机器人站立期间让 50 Hz 的平衡回路停摆。async inference 将两者分开——policy 在你的 GPU 机器上运行,而机器人客户端在 G1 的 Jetson 上运行,因此 SONIC 控制器线程和 rt/lowcmd 保持在机载端,只有 64 维的 token 块穿过网络。
三个进程,同时第二部分中的机器人服务器持续运行:
GPU machine G1 (Jetson)
policy_server ◄── gRPC ──► robot_client: UnitreeG1 + SONIC decoder @ 50 Hz
checkpoint │ ZMQ (lowcmd 6000, lowstate 6001, camera 5555)
▼
run_g1_server.py ◄──► rt/lowcmd, rt/lowstate (DDS)首先在 GPU 机器上启动 policy server:
python -m lerobot.async_inference.policy_server \ --host=0.0.0.0 \ --port=8080 \ --fps=30
在机器人上启动服务器(桥接 + 相机):
python src/lerobot/robots/unitree_g1/run_g1_server.py --camera
然后,在机器人的第二个终端中启动客户端。由于桥接在同一台机器上运行,机器人侧的一切都是回环:
python -m lerobot.async_inference.robot_client \
--server_address=<GPU_MACHINE_IP>:8080 \
--policy_type=pi05 \
--pretrained_name_or_path=nepyope/sonic_walk \
--policy_device=cuda \
--actions_per_chunk=50 \
--fps=30 \
--task="walk forward" \
--robot.type=unitree_g1 \
--robot.is_simulation=false \
--robot.robot_ip=127.0.0.1 \
--robot.controller=SonicWholeBodyController \
--robot.cameras='{"ego_view": {"type": "zmq", "server_address": "127.0.0.1", "port": 5555, "camera_name": "head_camera", "width": 640, "height": 480, "fps": 30, "warmup_s": 5}}'有几点需要注意:
--policy_device 是 服务器 加载 policy 的目标设备——客户端在握手期间发送它。--actions_per_chunk 不得超过 checkpoint 的 action chunk 大小(nepyope/sonic_walk 为 50)。SonicWholeBodyController 时,observation state 是 64 维的 token 回显,而不是 29 个关节位置,因此 checkpoint 必须针对相同的 state 进行训练。连接时,机器人在控制器接管之前会将每个关节缓慢移动到解码器的 default_angles,因此最初的 policy 命令不会从连接时的姿态突然跳动。
最后更新:2026 年 7 月
在 GitHub 上更新