疑难杂症 · 6 7 月, 2025 1

宇树科技Go2 SDK开发指南中的坑以及解决方法

前言

不知有多少人看着 宇树科技Go2 SDK开发指南 尝试开发机器人应用的。站长跟着指南整活,被搞得心力交瘁。这里就把整活过程中遇到的坑以及解决过程记录于此。另外想问问写指南的那位,您真的跟着自己写的指南编译过代码吗??

1.“快速开始”中的坑

安装 unitree_sdk2
下载 unitree_sdk2 压缩包并解压至用户主目录。打开一个终端,并依次执行下列命令以安装 unitree_sdk2:

上来就是这个??

鄙人新安装的Ubuntu 24.04.2 LTS,光看开发指南是肯定make不了的。需要通过以下命令安装所需依赖:

sudo apt install cmake
sudo apt install gcc
sudo apt install build-essential
sudo apt install libeigen3-dev

这个倒是不难。后面的才是重量级。

2.“创建客户应用”中的坑

本文将指导用户如何使用 unitree_sdk2 创建一个属于自己的高层应用例程程序。
利用 unitree_sdk2 的 sport_client 类可以使得用户创建各式各样的高层应用,本小节会手把手教学用户使用 sport_client 创建一个 “让四腿朝天的Go2机器人翻身站立并在调整身体高度后往前行走一段距离” 的高层应用。

SDK版本是从官方GitHub下载的 unitree_sdk2-2.0.1 。但包括clone的最新版,如果根据官方指南做,你可能会遇到包括但不限于以下坑:

坑1:编译例程时出现“找不到TopicTraits.hpp”错误

不知有多少人遇到了编译例程时编译器报出找不到dds/topic/TopicTraits.cpp的错误。这是因为在SDK中,Fast-DDS的头文件没有被放在正确的位置所致。我们先看看SDK的文件结构(省略部分无关项目及更深层文件):

unitree_sdk2/
 |- cmake/
 |- example/
 |- include/
    |- unitree/
 |- lib/
 |- licenses/
 |- thirdparty/
    |- include/
       |- dds/
       |- ddsc/
       |- ddscxx/
          |- dds/
          |- org/
    |- lib/
◇ 原因分析

在“快速开始”中执行make install进行环境部署时,unitree_sdk2/includeunitree_sdk2/thirdparty/include/dds中的文件会被复制到系统的/usr/local/include中,编译例程时C++文件#include的根目录便是/usr/local/include。出现上述错误也就是说,编译器找不到/usr/local/include/dds/topic/TopicTraits.cpp这个文件

为什么会这样呢?因为在SDK目录中,文件TopicTraits.cpp并不在unitree_sdk2/thirdparty/include/dds里,而是被放在了unitree_sdk2/thirdparty/include/ddscxx/dds里! 自然地,在环境部署时,TopicTraits.cpp没有被复制到系统目录中。

顺带一提,看到SDK文件结构中的org/了吗?编译例程的时候也会用到它,可它现在在哪儿呢?

◇ 解决步骤

unitree_sdk2/thirdparty/include/ddscxx/dds中的文件全部复制到unitree_sdk2/thirdparty/include/dds里(即合并两文件夹),并将unitree_sdk2/thirdparty/include/ddscxx/org整个文件夹复制到unitree_sdk2/thirdparty/include里,确保SDK目录是以下结构:

...
 |- thirdparty/
    |- include/
       |- dds/(与ddscxx/dds合并)
       |- org/(从ddscxx中复制)
       |- ...

然后……再执行一遍“快速开始”中的make install。。

坑2:没有规则可制作目标(找不到)

解决了坑1,找不到hpp头文件的问题解决了。然而根据官方指南编译例程的时候又报出了新的错误:

make: *** 没有规则可制作目标“install”。 停止。

或者英文的

make: *** No rule to make target 'install'.  Stop.
◇ 原因分析

众所周知,一个C/C++项目如果有头文件,那也应该有对应的定义(.cpp 或 .cc 文件),亦或是静态(.a)/动态(.so)库文件。而指南中,编译例程似乎并没涉及这部分的内容。也就是说,它在指导你用几个空洞的头文件嗯编译,能成功就有鬼了。

◇ 解决步骤
  1. 重写CMakeLists.txt
    备份原先的unitree_sdk2/CMakeLists.txt,并新建CMakeLists.txt,写入以下内容:
cmake_minimum_required(VERSION 3.10)
project(unitree_example)

set(CMAKE_CXX_STANDARD 17)

# 设置 Unitree SDK 的路径
set(UNITREE_SDK_INCLUDE_DIR /usr/local/include)
set(UNITREE_SDK_LIB_DIR /usr/local/lib)

# 添加 include 路径
include_directories(${UNITREE_SDK_INCLUDE_DIR})

# 添加库路径
link_directories(${UNITREE_SDK_LIB_DIR})

# 添加你的源码
# 假设你按照官方指南把例程文件放到了example/user/
add_executable(app_height example/user/app_height.cpp)

# 链接 Unitree 的库(注意:去掉 lib 前缀和 .so 后缀)
target_link_libraries(app_height unitree_sdk2 ddsc ddscxx)
  1. 编译例程
    清空unitree_sdk2/build文件夹,并在该文件夹中执行指南中的命令:
cmake ..
make

然后你会发现依然make失败……哈?

坑3:SDK 2.0.1没有实现BodyHeight()功能!!

sport_client 是 unitree_sdk2 封装的高层接口类,通过调用该类的方法可以调用高层接口控制 Go2 机器人执行指定动作。该类位于 unitree_sdk2/include/unitree/robot/go2/sport/sport_client.hpp,见于下文

int32_t BodyHeight(float height)调整身体高度

然后编译报错:

app_height.cpp:(.text.unlikely+0x4a): undefined reference to unitree::robot::go2::SportClient::~SportClient()'
◇ 原因分析

于是我打开了sport_client.hpp,发现……

根本没有int32_t BodyHeight(float height)的定义!!

指南中提到的这个函数在哪儿呢?注意到官方GitHub Release中有一个“v2.0.0-Go2融合运控版本”,于是下载下来查看,找到了这个函数。也就是说,该函数在最新版的SDK中被删除了。。

更有意思的是,尝试用v2.0.0的sport_client.hpp替换v2.0.1的头文件,并用v2.0.0的库文件libunitree_sdk2.a替换v2.0.1的库文件,编译依然失败,报出了和坑2一样的错误。原来v2.0.0也没有实现这个函数,只有个头文件啊。。(掀桌子)

◇ 解决步骤

无了。你不能指望我替官方把这个函数给实现了。

折衷的方法就是,注释掉例程中sport_client.BodyHeight(-0.07);等使用了BodyHeight()函数的代码,替换为可能能够实现的函数(比如StandUp()之类的),然后再编译。

终于成功了。🍾🥳🎉

完整操作流程

请直接看VCR。