unitree_ros2 SportClient详解:用请求响应机制让四足机器人站立、行走与后空翻

原创2026-10-24 18:14:211,674 阅读

unitree_ros2 SportClient详解:用请求响应机制让四足机器人站立、行走与后空翻

本文详解开源项目 unitree_ros2 中的 SportClient 类:它基于 DDS 的请求/响应机制,让你用几行代码就能让 Unitree 四足机器人(Go2、B2 等)站立、行走,甚至完成前空翻与后空翻动作。即使你是 ROS2 新手,也能跟着本文从零跑通第一个运动控制指令。

什么是 SportClient:Unitree 四足机器人运动模式控制的核心

unitree_ros2 是 Unitree 机器人官方的 ROS2 通信框架。它的核心思路是:Unitree 机器人底层本身使用 CycloneDDS 作为通信中间件,而 ROS2 同样以 DDS 为底层,因此两者可以直接互通——你无需再封装任何 SDK 接口,用标准的 ros2 命令和消息就能直接控制机器人 🤖。

项目支持 Go2、B2、B2-W、H1、H1-2、G1、H2 等型号,整体结构分为两部分:

目录 作用
cyclonedds_ws/ 存放机器人通信消息定义,如 unitree_go(Go2/B2 消息)和 unitree_api/(通用请求/响应消息)
example/ 各类官方示例源码,包括本文主角 SportClient 及其调用示例

控制 Unitree 机器人有两层抽象:

  • 运动模式(SportMode):机器人自带的高层行为,站立、行走、坐下、空翻等都已内置,开发者只需"发指令"。
  • 底层控制(LowCmd):直接控制每个关节电机,用于自定义步态等进阶场景。

SportClient 正是运动模式控制的核心封装类,源码位于 ros2_sport_client.cpp,头文件在 ros2_sport_client.h。它把几十个"机器人动作"封装成同名 C++ 方法:StandUp() 站立、Move() 行走、FrontFlip() 前空翻……调用哪个方法,机器人就做出哪个动作。

请求/响应机制:一条 DDS 消息如何驱动机器人

SportClient 的妙处在于它完全复用了 ROS2 的发布者/订阅者模型,没有引入任何私有协议。

工作机制只有 4 步:

  1. SportClient 构造时,向主题 /api/sport/request 创建一个发布者;
  2. 调用某个方法(如 Move)时,往 Request 消息里写入对应的 api_id 和 JSON 参数;
  3. 机器人收到请求后执行动作,并向 /api/sport/response 发布 Response 消息;
  4. 若需要返回值(如 AutoRecoveryGet),Call() 模板函数会订阅响应主题,按 api_id 匹配后把 JSON 结果解析返回。

请求消息 Request 的结构定义在 Request.msg,核心字段只有三个:

RequestHeader header      # 含 identity.api_id,标识要调用哪个接口
string parameter          # JSON 参数,例如 {"x":0.3,"y":0,"z":0}
uint8[] binary            # 二进制数据(一般用不到)

响应消息 Response 的结构见 Response.msg,其中 data 字段同样是一段 JSON 字符串。

以"以 0.3 m/s 前进"为例,Move 方法内部做的事情一目了然:

void SportClient::Move(unitree_api::msg::Request &req, float vx, float vy, float vyaw) {
  nlohmann::json js;
  js["x"] = vx;  js["y"] = vy;  js["z"] = vyaw;
  req.parameter = js.dump();
  req.header.identity.api_id = ROBOT_SPORT_API_ID_MOVE;  // 1008
  req_puber_->publish(req);
}

每个动作都对应一个唯一的 api_id 编号,这是理解整套机制的关键。常用接口一览:

动作 方法 api_id 动作 方法 api_id
阻尼(瘫软) Damp 1001 前空翻 FrontFlip 1030
平衡站立 BalanceStand 1002 前跳 FrontJump 1031
停止运动 StopMove 1003 后空翻 BackFlip 2043
站起 StandUp 1004 手倒立 HandStand 2044
坐下 StandDown 1005 自由行走 FreeWalk 2045
恢复站立 RecoveryStand 1006 经典步态行走 ClassicWalk 2049
调姿(欧拉角) Euler 1007 自动恢复设置 AutoRecoverySet 2054
速度控制 Move 1008 自由避障开关 FreeAvoid 2048
坐 / 起身 Sit / RiseSit 1009/1010 打招呼 / 比心 Hello / Heart 1016/1036
舞蹈 Dance1 / Dance2 1022/1023 速度档位 SpeedLevel 1015

完整编号表可以在 ros2_sport_client.h 开头的常量定义中查到。

RViz2 中可视化 Unitree 机器人雷达点云话题

三步跑通 go2_sport_client 示例:环境配置与连接验证

项目自带了最完整的 SportClient 调用示例 go2_sport_client.cpp,内置 11 种测试模式(站立、行走、坐下、空翻……),只需一个命令行参数即可切换。

第一步:克隆并编译

git clone https://gitcode.com/gh_mirrors/uni/unitree_ros2
cd unitree_ros2/cyclonedds_ws
colcon build   # Humble 环境可跳过 cyclonedds 重编译
cd ~/unitree_ros2/example
colcon build

系统要求:Ubuntu 22.04 + ROS2 Humble(推荐)或 Ubuntu 20.04 + Foxy,详见 README.md。

第二步:配置网络与环境

用网线连接电脑与机器人(机器人网段 192.168.123.x),然后把电脑网卡设为 192.168.123.99。打开 setup.sh,把其中的网卡名改为你实际连接机器人的接口,然后:

source ~/unitree_ros2/setup.sh   # 加载 ROS2 + CycloneDDS 环境
ros2 topic list                   # 能看到 /sportmodestate 等主题即连接成功

没有真机想做仿真时,可以改用 setup_local.sh(走本地回环)或 setup_default.sh。

第三步:发送指令,看机器人动起来

./install/unitree_ros2_example/bin/go2_sport_client <模式号>
模式号 动作 模式号 动作
0 NORMAL_STAND 站立 5 DAMP 阻尼
1 BALANCE_STAND 平衡站立 6 RECOVERY_STAND 恢复站立
2 VELOCITY_MOVE 速度移动 7 SIT 坐下
3 STAND_DOWN 坐下(站姿) 8 RISE_SIT 起身
4 STAND_UP 站起 9 MOVE 直线行走
10 STOP_MOVE 停止

以"让机器人前向+侧向移动"为例,示例中对应的一行就是:

sport_client_.Move(req_, 0.3, 0, 0.3);  // vx=0.3, vy=0, vyaw=0.3

go2_sport_client 还会同时订阅 lf/sportmodestate 主题,把机器人的位置和 IMU 姿态实时打印到终端,方便你确认指令是否生效。

闭环控制:实时读取机器人运动状态

只发指令不读状态,就像"闭着眼开车"。unitree_ros2 把机器人状态也做成了标准 ROS2 话题,常用的是:

  • /sportmodestate(unitree_go::msg::SportModeState):位置、速度、IMU 姿态、步态类型(trot/run)、足端位置与速度、当前运动模式(idle/locomotion/lieDown/sit/frontFlip 等);
  • /lowstate:电机位置/速度/扭矩、电池、足端受力等底层状态;
  • /wirelesscontroller:遥控器摇杆与按键状态,适合做手动遥控。

完整的状态读取示例是 read_motion_state.cpp,运行后会持续输出:

Position -- x: 0.567083; y: 0.213920; z: 0.052338; body height: 0.320000
Velocity -- vx: -0.008966; vy: -0.001431; ...
Gait state -- gait type: 1; raise height: 0.090000

消息字段定义可以直接看 SportModeState。把"SportClient 发指令 + 订阅 sportmodestate 收状态"组合起来,就构成了完整的闭环控制框架——这正是大多数 Go2 应用(遥控、导航、动作编排)的标准玩法。

ros2 topic list 列出 Unitree 机器人话题

用 RViz2 可视化 Unitree 机器人数据

想"眼见为实"?项目文档演示了如何用 RViz2 可视化 Go2 的雷达数据:

  1. ros2 topic list 找到点云话题 /utlidar/cloud;
  2. ros2 topic echo --no-arr /utlidar/cloud 确认 frame_id 为 utlidar_lidar;
  3. 启动 ros2 run rviz2 rviz2,添加 PointCloud2 显示,把 Fixed Frame 改为 utlidar_lidar,即可看到机器人周围环境的实时点云。

RViz2 创建 PointCloud2 显示对话框

总结:新手上手路线

  • 认识机制:SportClient = 一组 api_id + 一条发布到 /api/sport/request 的 DDS 消息,请求/响应机制让它像调用函数一样简单;
  • 跑通示例:go2_sport_client 一个参数切换 11 种动作,是理解整套流程的最佳起点;
  • 建立闭环:订阅 sportmodestate 拿到实时位姿,再叠加 RViz2 可视化,调试效率倍增;
  • 进阶方向:想要自定义步态或全身控制,可以继续探索 low_level_ctrl.cpp 等底层控制示例。

所有示例的目标名与构建规则集中在 CMakeLists.txt,版本历史可参考 CHANGELOG.md。动手试试吧,让你的 Go2 也来一个帅气的后空翻 🎉

登录后查看全文
unitree_ros2