# 宇树 G1 / Go2 开发起步：unitree_sdk2、CycloneDDS 网卡配置、MuJoCo 仿真联调与常见报错速查

> 原文链接：https://robotics.hellobike.com/tutorials/unitree-g1-go2-ros2-mujoco-quickstart
> 频道：tutorials | 更新日期：2026-10-14 | 标签：G1, Go2, CycloneDDS, MuJoCo
> 核心摘要：用 sdk2 读状态，用 CycloneDDS 指定网卡，用 unitree_mujoco 先联调。不在文档里写机器人默认网段。

# 装什么

低层用 `unitree_sdk2`，Python 用 `unitree_sdk2_python`。ROS 2 不是读电机状态的前置条件。要和 Nav2 或其他 ROS 节点通信时再编 `unitree_ros2`，并让它和 sdk2 使用同一套 CycloneDDS。

Go2 目录卡的 SDK 列表包含 `unitree-sdk2-python`。G1、H1 走同一仓库，话题和关节数不同。G1 基础版卡片是 23 DoF、高 1.32 m；Go2 AIR 卡片是 12 DoF 的四足。不要用 Go2 的站立示例去初始化 G1。

## 网卡

开发机要用有线网卡直连机器人或直连厂商指定的交换机。Wi-Fi 和有线同时在线时，DDS 多播经常从错误的网卡出去。

CycloneDDS 用网卡名，不用把地址写进仓库：

```xml
<?xml version="1.0" encoding="UTF-8" ?>
<CycloneDDS>
  <Domain>
    <General>
      <Interfaces>
        <NetworkInterface name="enp3s0" priority="default" multicast="default" />
      </Interfaces>
    </General>
  </Domain>
</CycloneDDS>
```

`enp3s0` 换成 `ip link` 里那块连机器人的网卡。然后：

```bash
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
export CYCLONEDDS_URI=file://$HOME/cyclonedds.xml
```

ROS 2 还要设定和机器人一致的 `ROS_DOMAIN_ID`。只跑 sdk2 示例时，以 `DDS_service` 文档里的域配置为准。机器人使用的默认网段写在厂商文档里，和办公网叠在同一张路由表上时，多播会丢。两块网卡的网段必须错开。

## sdk2 最小回路

按仓库 README 编译 `unitree_sdk2`，先跑状态订阅示例，不要先跑高力矩示例。能稳定打印关节位置和 IMU，再考虑位置命令。

Python 绑定和 C++ 的版本要和机器人固件大版本一起看。绑定能 import、但是超时，优先查网卡名，而不是重装 Python。

真机第一次下发位置命令前：吊起来，或确认急停有效。Go2 和 G1 的默认姿态不一样。

## MuJoCo 联调

`unitree_mujoco` 用来在不上电的情况下走同一套 SDK 消息。仿真进程和示例进程都要看到同一份 `CYCLONEDDS_URI`。只启动仿真、示例仍指向真机网卡时，两边都在等对方。

联调顺序：

1. 只开仿真，确认模型能站立。G1 若用 menagerie 的 29 DoF 模型，不要和 23 DoF 基础版的关节索引混用。
2. 仿真 + 状态订阅。频率稳定再发命令。
3. 小幅度关节正弦，看方向。方向反了先改模型执行器，不要改策略符号。
4. 最后换真机网卡。仿真和真机不要同时在同一个域里。

`unitree_ros2` 的 `robot_state_publisher` 使用的 URDF 必须和 MuJoCo 模型是同一套关节名。名字差一个腰关节，TF 看起来是对的，末端已经偏了。

## 报错速查

| 现象 | 处理 |
| --- | --- |
| 示例超时，没有任何状态 | 网卡名错误，或多播从 Wi-Fi 出去。用 `tcpdump` 看那块网卡有没有 DDS 流量 |
| ROS 2 能列出话题，sdk2 超时 | 域 ID 或 RMW 不一致。只留 CycloneDDS |
| 有状态但全是 0 | 固件未进开发模式，或你订了错误机型的话题 |
| 一发命令就摔倒 | 命令是绝对位置，默认姿态和仿真零位差一截 |
| MuJoCo 里站立，真机一抖 | PD 增益按仿真写的，真机电机驱动器里还有一层环 |
| G1 手臂不动、腿在动 | 23 DoF 和 29 DoF 索引错位 |
| Go2 能走、换 G1 的程序不能 | 机型字符串和网络接口配置没有换 |
| 编译过、运行缺 .so | 没有 source 仓库提供的环境脚本 |

H1 的文档入口和 G1 分开，DDS 的配法相同，关节表不同。把本文的网卡步骤用在 H1 上可以，把 G1 的动作文件用在 H1 上不行。

## 原始参考来源 (Sources)

- [unitree_sdk2](https://github.com/unitreerobotics/unitree_sdk2)
- [unitree_sdk2_python](https://github.com/unitreerobotics/unitree_sdk2_python)
- [DDS 服务说明](https://support.unitree.com/home/en/developer/DDS_service)
- [unitree_mujoco](https://github.com/unitreerobotics/unitree_mujoco)
- [unitree_ros2](https://github.com/unitreerobotics/unitree_ros2)
- [G1 快速开始](https://support.unitree.com/home/en/G1_developer/quick_start)