# Unitree G1

<video
  src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/lerobot/unitree_g1_passing_can.mp4"
  autoplay
  loop
  muted
  playsinline
  style={{ width: "100%" }}
/>

Unitree G1 人形机器人已在 LeRobot 中获得支持。您可以进行遥操作、训练 locomanipulation 策略、在仿真环境中测试等。同时支持 29 自由度和 23 自由度两种版本。

## 具身选择

`UnitreeG1` 类通过 `UnitreeG1Config.embodiment` 来选择其关节定义。默认值为 `g1_29`；因此，现有配置将保留 G1-29 的行为。使用 `--robot.embodiment=g1_23` 或在 Python 中选择 23 自由度布局：

```python
from lerobot.robots.unitree_g1 import UnitreeG1Config

config = UnitreeG1Config(embodiment="g1_23", is_simulation=False)
```

| 功能                                          | G1-29                         | G1-23                                        |
| --------------------------------------------------- | ----------------------------- | -------------------------------------------- |
| 联合配置以及动作/观测特征 | 29 个身体关节，14 个手臂关节 | 23 个身体关节，10 个手臂关节                |
| DDS 命令/反馈布局                         | 29 个活动插槽               | 29 个关节缺失的槽位保持非活动状态    |
| MuJoCo 仿真                                   | 支持                     | 目前尚不支持；原生模型已在规划中      |
| 运动控制器                              | GR00T 和 Holosoma            | GR00T 和 Holosoma                           |
| SONIC 全身控制器                         | 支持                     | 不支持；该策略需要 29 个自由度    |
| 重力补偿                                | 支持，默认关闭     | 目前尚不支持；原生运动学功能已在规划中 |

两种变体均使用相同的 29 槽位 DDS 消息布局。G1-29 使用全部 29 个槽位，而 G1-23 使用 23 个槽位，并将六个不存在的关节槽位保持非活动状态。因此，`kp`、`kd` 和 `default_positions` 向量仍保持 29 个元素，并按 DDS 槽位进行索引。G1-23 的活动手臂槽位为 `15..19` 和 `22..26`。槽位 `13, 14, 20, 21, 27, 28` 没有活动关节；其配置值必须为零。它们从动作/观测特征中省略，而不是重新编号。在发布 G1-23 消息之前，会清除非活动和保留的命令条目。显式增益覆盖值必须是有限的、非负的，并使用相同的稀疏布局。默认增益按关节名称在两种变体间共享，因此相同的物理关节使用相同的增益，而 G1-23 中缺失的槽位保持为零。

目前尚不支持原生 G1-23 MuJoCo 仿真。在启用仿真的情况下选择 G1-23 构型，会在传输初始化之前失败。原生 G1-23 MuJoCo 模型计划在后续版本中提供。

---

## 第一部分：入门

### 安装 Unitree SDK

请按照 [unitree_sdk2_python 安装指南](https://github.com/unitreerobotics/unitree_sdk2_python#installation) 进行操作。已在 `unitree_sdk2py==1.0.1` 和 `cyclonedds==0.10.2` 上测试：

```bash
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 ..
```

### 安装 LeRobot

```bash
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]'
```

  目前，必须从 conda-forge（而非 pip）安装 pinocchio，以包含 arm IK 所需的 CasADi 绑定。

### 测试安装（模拟）

模拟环境有其自身的依赖项。请检查模拟环境依赖项：[Unitree G1 Mujoco EnvHub](https://huggingface.co/lerobot/unitree-g1-mujoco/tree/main)。

```bash
pip install mujoco loguru msgpack msgpack-numpy
```

```bash
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 sim instance](https://huggingface.co/lerobot/unitree-g1-mujoco/tree/main)。您可以在启动前将游戏手柄连接到您的机器，以便在仿真中控制机器人的运动。我们通过 `--robot.controller` 支持 [HolosomaLocomotionController](https://github.com/amazon-far/holosoma) 和 [GrootLocomotionController](https://github.com/NVlabs/GR00T-WholeBodyControl)。

- 按下 `9` 释放机器人
- 按 `7` / `8` 增加 / 减少腰部高度

#### 选择末端执行器

`--robot.end_effector` 指定机械臂末端携带的部件：`dex1` 表示平行夹爪（默认值），`dex3` 表示三指手，`dummy` 表示裸露的腕部。在仿真中，该参数用于选择 MuJoCo 模型，该模型决定了手指执行器以及场景中包含哪些相机——腕部相机安装在末端执行器上，因此 `dummy` 仅包含 `head_camera`。

```bash
lerobot-teleoperate \
  --robot.type=unitree_g1 \
  --robot.is_simulation=true \
  --robot.end_effector=dex3 \
  --teleop.id=wbc_unitree \
  --robot.controller=GrootLocomotionController
```

Sim 会通过 `--robot.sim_camera_port`（默认为 5555）上的 ZMQ 发布模型的相机数据，`--robot.cameras` 中的 `zmq` 相机即从此处读取。传入 `--robot.sim_publish_images=false` 可改为打开 MuJoCo 的交互式窗口：由于离屏上下文属于创建它们的线程而非查看器，Sim 只会渲染其相机或窗口，二者不可兼得。`--robot.sim_onscreen` 直接指定该选择，而非交由相机决定，同时请求两者会被拒绝；将其与 `--robot.sim_publish_images` 均设为 false 则两者都不渲染，这正是无显示设备的机器所能做的。

### 连接到物理机器人

G1 的以太网 IP 固定为 `192.168.123.164`。您的机器必须配置同一子网内的静态 IP：`192.168.123.x`，其中 `x ≠ 164`。

```bash
# 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 up
```

### 通过 SSH 连接到机器人

```bash
ssh unitree@192.168.123.164
# Password: 123
```

### 通过以太网共享互联网

G1 需要互联网访问权限以克隆代码仓库并安装软件包。请通过以太网共享笔记本电脑的网络连接：

**在您的笔记本电脑上：**

```bash
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 上：**

```bash
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.8
```

### 在 G1 上安装 Unitree SDK

请遵循 [unitree_sdk2_python 安装指南](https://github.com/unitreerobotics/unitree_sdk2_python#installation)：

```bash
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
python -m pip install -e .
cd ..
```

### 在 G1 上安装 LeRobot

```bash
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]'
```

  目前，必须从 conda-forge（而非 pip）安装 pinocchio，以包含 arm IK 所需的 CasADi 绑定。

### （可选）在机器人上启用 WiFi

如需通过无线方式访问 SSH，您可以在 G1 上启用 WiFi（默认情况下该功能被禁用）：

```bash
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 网络：**

```bash
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 连接：

```bash
ssh unitree@<ROBOT_WIFI_IP>
# Password: 123
```

---

## 第二部分：远程操作与运动

### 运行机器人服务器

在机器人上（从 `~/lerobot` 开始）：

```bash
cd ~/lerobot
python src/lerobot/robots/unitree_g1/run_g1_server.py --camera
```

### 运行 Locomotion Policy

您可以通过以太网、WiFi（实验性）在笔记本电脑上运行遥操作客户端，也可以直接在机器人本机上运行。请注意网络可能引入的延迟。

**从您的笔记本电脑：**

```bash
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](https://github.com/NVlabs/GR00T-WholeBodyControl) 和 [HolosomaLocomotionController](https://github.com/amazon-far/holosoma)。

---

## 第 3 部分：使用 Homunculus 外骨骼进行 Loco-Manipulation

我们通过 Homunculus 外骨骼提供了一套 loco-manipulation 解决方案——这是一款用于全身控制的开源 7 自由度外骨骼。点击[此处](https://github.com/nepyope/hmc_exo)查看。

### 校准

```bash
lerobot-calibrate \
  --teleop.type=unitree_g1 \
  --teleop.left_arm_config.port=/dev/ttyACM1 \
  --teleop.right_arm_config.port=/dev/ttyACM0 \
  --teleop.id=exo
```

在校准过程中，将每个关节移动至其整个活动范围。安装完成后，将关节置于中立位置，然后按 `n` 继续。

### 记录数据集

```bash
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`。

示例数据集：[nepyope/unitree_box_move_blue_full](https://huggingface.co/datasets/nepyope/unitree_box_move_blue_full)

---

## 第 4 部分：训练与推理

### 训练

```bash
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 \
  --trackio.enable=true \
  --policy.dtype=bfloat16 \
  --policy.freeze_vision_encoder=false \
  --policy.train_expert_only=false \
  --steps=3000 \
  --policy.device=cuda \
  --batch_size=32
```

### 使用 RTC 进行推理

兼容的已训练策略可以使用本地推理时 RTC：

```bash
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=rtc
```

G1 运动控制器未声明 rollout 可恢复等待所使用的保留目标契约。因此，在运动开始后，一旦其动作缓冲区耗尽，就会触发终止性故障，而不是进入宽限期等待。请求截止时间和观测数据年龄限制同样适用。在使用此配方之前，请验证策略可用的数据块是否足以覆盖推理延迟；请参阅 [本地 RTC 等待与预算](./inference#inference-backends)。SONIC 具有单独描述的保留令牌契约。

---

## 第 5 部分：SONIC 全身控制（潜在令牌策略）

LeRobot 现已将 NVIDIA [SONIC](https://nvlabs.github.io/GEAR-SONIC/) 全身部署栈中的 **decoder** 部分移植为 `SonicWholeBodyController`。策略不再直接指令关节，而是在每个 tick 输出一个 64 维的 **latent motion token**（`motion_token.{i}.pos`）；SONIC decoder 将该 token 与近期的本体感觉历史映射为一个残差动作，该动作经过缩放后叠加到站立姿态上，从而为全部 29 个自由度生成 50 Hz 的关节位置目标。

控制器从 [`lerobot/sonic_decoder`](https://huggingface.co/lerobot/sonic_decoder) 加载其 ONNX 解码器以及所有部署常量（PD 增益、`default_angles`、`action_scale` 和中性 token）。该仓库还附带了一个蒸馏后的低延迟解码器，可通过控制器的 `policy_type="low_latency"` 参数进行选择（默认为 `"default"`）。

### 在模拟环境中测试

任何在 SONIC 运动 token 上训练的 token 输出策略（例如 [`nepyope/sonic_walk`](https://huggingface.co/nepyope/sonic_walk)）都可以驱动它：

```bash
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}}'
```

### 在实体机器人上运行

在 GPU 机器上运行 [remote inference](./remote_inference) 策略服务器，并将机器人桥接、SONIC 解码器和 rollout 客户端保留在 G1 Jetson 上。只有 64 维的 token 块会通过网络传输；解码器和 50 Hz 的 `rt/lowcmd` 循环仍在本地运行。

在两台机器上安装远程附加组件。在 G1 上保留 Unitree 附加组件：

```bash
# GPU machine
python -m pip install -e '.[remote]'

# G1 Jetson
python -m pip install -e '.[unitree_g1,remote]'
```

在 GPU 机器上，从仓库根目录启动策略服务器。维护的配置与 `nepyope/sonic_walk` 相匹配；若要使用其他策略，请一并复制并更新其检查点和特征契约。

```bash
lerobot-policy-server \
  --config_path=examples/remote_inference/unitree_g1_sonic.yaml
```

在 G1 上，保持桥接和摄像头持续运行：

```bash
python src/lerobot/robots/unitree_g1/run_g1_server.py --camera
```

然后在第二个 G1 终端中启动 rollout 客户端，并将 `<GPU_MACHINE_IP>` 替换为：

```bash
lerobot-rollout \
  --strategy.type=base \
  --inference.type=remote \
  --inference.endpoint=tcp/<GPU_MACHINE_IP>:7447 \
  --inference.deployment=g1-sonic \
  --inference.semantics=unitree-g1-sonic-motion-token-v1 \
  --inference.encoding=jpeg \
  --inference.action_starvation_grace_s=1.0 \
  --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}}' \
  --task='walk forward' \
  --fps=30 \
  --return_to_initial_position=false \
  --interactive=true
```

仅在 G1 确认可以移动后，才输入 `/start`。SONIC 声明支持等待，因为重新发送最后一个完整 token 可以保持机载解码器的平衡。在第一个策略结果之前，rollout 会发送解码器的中性 token。如果动作缓冲区耗尽，它会重复最后应用的 token，最长持续 `action_starvation_grace_s`（如上所述，为一秒）；如果没有新的预测到达，rollout 将发生故障，并遵循其配置的关闭/断开连接路径。由于无法以这种方式保留摇杆速度，因此不支持 G1 运动控制器。

该配方禁用了返回初始位置功能：通过 SONIC 的潜在令牌空间进行插值并非经过验证的物理归位轨迹。出于同样的原因，请避免使用 `/reset`，因为它会将令牌扫回其连接时的值。`/stop` 仍然会关闭远程会话，并通过正常的控制器关闭路径断开与机器人的连接。

使用 `SonicWholeBodyController` 时，观测状态是 64 维的 token echo，而非 29 个关节位置，因此兼容的检查点必须针对该状态进行训练。在连接时，机器人会先将关节平滑调整到解码器的 `default_angles`，然后控制器再接管。

---

## 其他资源

- [Unitree SDK 文档](https://github.com/unitreerobotics/unitree_sdk2_python)
- [GR00T-WholeBodyControl](https://github.com/NVlabs/GR00T-WholeBodyControl)
- [Holosoma](https://github.com/amazon-far/holosoma)
- [LeRobot 文档](https://github.com/huggingface/lerobot)
- [Unitree IL LeRobot](https://github.com/unitreerobotics/unitree_IL_lerobot)

---

_最后更新：2026 年 7 月_

