Files
go1_pro_sdk/README.md
2026-07-30 17:25:39 +08:00

330 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Go1 PRO SDK
Unitree Go1 **PRO** 机型的低层电机控制 Python/C++ SDK。完整逆向 PRO 版的私有协议Blowfish 加密 + 私有 LowCmd 格式不依赖官方二进制库Mac 直连可达 480Hz 控制频率。
> 这是为 PRO 准备的 SDK。如果你有 **EDU** 版机器狗,请用原版 [free-dog-sdk](https://github.com/Bin4ry/free-dog-sdk) — PRO 跟 EDU 协议有显著差异,互不兼容。
## 关键特性
- 完整 Blowfish ECB 加解密(用从机器狗内存提取的 state不依赖原始 key
- PRO 私有 LowCmd 格式616B / CRC@612 / bandWidth BE 字节序),跟 EDU 不同
- LowState 解析12 关节 + IMU + BMS + 足端力 + 遥控器)
- 实时遥控器按键/摇杆/L2 读取
- 三层安全保护PositionLimit / PowerProtect 1-10 / PositionProtect实测扭矩过载自动停机
- 实测频率: **Mac 直连 480Hz**(接近原版 EDU 500Hz
- 实测延迟: **每帧 1.74ms p50**Blowfish 加密 1ms + 解密 0.7ms + sendto 0.02ms
## 快速上手
### 语言与入口
| 使用方式 | 源码位置 | 构建入口 | 用户入口 |
|---|---|---|---|
| Python 原生 PRO API | `go1_pro_sdk/` | `pyproject.toml` | `import go1_pro_sdk` |
| Python 官方兼容 API | `robot_interface.py``go1_pro_sdk/compat/` | `pyproject.toml` | `import robot_interface as sdk` |
| Python 可选原生加速 | `fast_lowcmd_cpp/` | `fast_lowcmd_cpp/setup.py` | `FastLowCmdBuilder` |
| C++ 官方兼容 SDK | `include/``src/` | `CMakeLists.txt` | `#include <unitree_legged_sdk/unitree_legged_sdk.h>` |
`fast_lowcmd_cpp` 是供 Python 调用的 CPython 扩展,不是 C++ 用户的公共 SDK。C++ 用户
只依赖根目录 CMake 生成的 `unitree_legged_sdk` 库以及 `include/unitree_legged_sdk/`
中的公共头文件。两套实现共享同一份 PRO 协议和 Blowfish state但运行时不互相依赖。
Python 开发环境安装:
```bash
conda activate free_dog_sdk
python -m pip install -e .
```
### 官方 Python SDK 兼容接口
需要复用官方 `unitree_legged_sdk` Python 示例时,可以继续使用原来的模块名和
调用顺序:
```python
import robot_interface as sdk
LOWLEVEL = 0xff # 官方 wrapper 不导出这个常量,官方示例也是在应用中定义
udp = sdk.UDP(LOWLEVEL, 8080, "192.168.123.10", 8007)
safe = sdk.Safety(sdk.LeggedType.Go1)
cmd, state = sdk.LowCmd(), sdk.LowState()
udp.InitCmdData(cmd)
udp.Recv()
udp.GetRecv(state)
safe.PowerProtect(cmd, state, 1)
udp.SetSend(cmd)
udp.Send()
```
兼容范围和协议差异见 [`docs/OFFICIAL_API_COMPATIBILITY.md`](docs/OFFICIAL_API_COMPATIBILITY.md)。
官方 `HighCmd/HighState` UDP 通道和二进制 ABI 当前不在兼容范围内。
需要同一份代码同时运行在本项目和官方 SDK 上时,只使用官方实际导出的接口;参考
[`examples/example_official_compatible_position.py`](examples/example_official_compatible_position.py)。
### 官方 C++ SDK 兼容接口
同一份低层 C++ 源码可分别链接本项目或官方 `unitree_legged_sdk`
```cpp
#include "unitree_legged_sdk/unitree_legged_sdk.h"
using namespace UNITREE_LEGGED_SDK;
UDP udp(LOWLEVEL, 8090, "192.168.123.10", 8007);
Safety safe(LeggedType::Go1);
LowCmd cmd{};
udp.InitCmdData(cmd);
```
```bash
cmake -S . -B build-cpp -DCMAKE_BUILD_TYPE=Release
cmake --build build-cpp
ctest --test-dir build-cpp --output-on-failure
```
PRO 环境链接本项目生成的 `libunitree_legged_sdk`;官方机器人环境链接官方同名库。
参考 [`examples/cpp/example_official_compatible_position.cpp`](examples/cpp/example_official_compatible_position.cpp)。
Blowfish state 默认随库安装,也可用 `GO1_PRO_BLOWFISH_STATE` 指定。
### 高层控制 (走/跳/姿态, 通过 sportMode 系统)
```python
from go1_pro_sdk import Go1, Velocity, Pose, LED
with Go1() as dog:
dog.stand_up()
dog.set_walk_mode()
dog.walk(Velocity(vx=0.3)) # 前进
dog.dance_1()
dog.set_led(LED(0, 255, 0))
dog.stand_down()
```
通过 MQTT 控制树莓派上的 Legged_sport. 跟低层互不冲突, 但只能二选一同时用.
### 低层控制 (直接控 12 个电机)
```python
from go1_pro_sdk import MCUClient, LowCmd, MotorCmd, MotorMode
with MCUClient() as client:
client.wake_mcu() # 唤醒并切换为我们的客户端
state = client.recv_state() # 读一帧状态
print(f"FR_0 q = {state.motorState[0].q}")
print(f"电量: {state.bms.SOC}%")
print(f"遥控器按下: {state.remote.pressed}")
# 控制 FR 大腿 (注意先悬空 + 安全保护层)
cmd = LowCmd()
cmd.set_motor('FR_1', MotorCmd(
mode=MotorMode.Servo, q=1.2, Kp=5, Kd=1
))
client.send(cmd)
client.safe_stop() # 退出前发 damping
```
## 调试与验证
### 离线完整回归
以下测试使用 fake socket 和 `data/captures/` 中的实机历史抓包,不连接机器狗,也不会向
MCU 发送 UDP 数据。先在仓库根目录准备 Python 包和可选原生扩展:
```bash
conda run -n free_dog_sdk python -m pip install -e .
cd fast_lowcmd_cpp
PYTHONPATH=.. conda run -n free_dog_sdk python setup.py build_ext --inplace
cd ..
conda run -n free_dog_sdk python -m pytest -q tests fast_lowcmd_cpp/test_fast_lowcmd.py
```
C++ Release 回归会检查官方结构布局、PRO 明密文字节一致性、LowState 实机抓包、安全接口、
Loop以及安装后被独立 CMake 项目消费:
```bash
cmake -S . -B build-cpp -DCMAKE_BUILD_TYPE=Release \
-DGO1_PRO_CAPTURE_DIR="$PWD/data/captures"
cmake --build build-cpp --parallel
ctest --test-dir build-cpp --output-on-failure
```
配置阶段若显示 `Private data/captures fixtures not found`,说明只运行公共契约测试,未运行
实机抓包字节回归。`ctest` 不会运行 `examples/` 中会发送命令的示例程序。
### 定点调试
Python 可用 pytest 节点路径只运行单项并显示输出C++ 可直接运行兼容测试,或交给
LLDBmacOS/GDBLinux
```bash
conda run -n free_dog_sdk python -m pytest -vv -s \
tests/test_capture_fixtures.py
ctest --test-dir build-cpp -R cpp_official_compat -V
lldb -- build-cpp/test_cpp_compat
# Linux: gdb --args build-cpp/test_cpp_compat
```
需要验证另一份 Blowfish state 或外部抓包目录时:
```bash
GO1_PRO_BLOWFISH_STATE=/path/to/blowfish_state.bin ./build-cpp/test_cpp_compat
cmake -S . -B build-cpp -DGO1_PRO_CAPTURE_DIR=/path/to/captures
cmake --build build-cpp --target test_cpp_compat --parallel
```
### C++ 编译与运行时检查
先用严格警告检查可移植性ASan/UBSan 用于检查越界、生命周期和未定义行为TSan 单独
构建,不能与 ASan 混用:
```bash
cmake -S . -B build-cpp-warn -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_FLAGS="-Wall -Wextra -Wpedantic"
cmake --build build-cpp-warn --parallel
ctest --test-dir build-cpp-warn --output-on-failure
cmake -S . -B build-cpp-sanitize -DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_FLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer"
cmake --build build-cpp-sanitize --parallel
ctest --test-dir build-cpp-sanitize --output-on-failure
cmake -S . -B build-cpp-tsan -DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_FLAGS="-fsanitize=thread -fno-omit-frame-pointer"
cmake --build build-cpp-tsan --parallel
ctest --test-dir build-cpp-tsan --output-on-failure
```
### C++ 编解码基准
基准默认不参与构建。存在 `data/captures/mcu_response_new.bin` 时会同时测量
`EncodeLowCmd``DecodeLowState`;缺少抓包时只测编码:
```bash
cmake -S . -B build-cpp-benchmark -DCMAKE_BUILD_TYPE=Release \
-DGO1_PRO_BUILD_BENCHMARKS=ON
cmake --build build-cpp-benchmark --target benchmark_cpp_codec --parallel
./build-cpp-benchmark/benchmark_cpp_codec
```
### 实机烟雾验证
自动测试通过后再进入下一节的实机流程。`monitor_state.py``monitor_remote.py` 虽不发送
运动目标,但会执行 `wake_mcu()` 并持续发送 damping LowCmd 以维持回包,因此不是纯被动
抓包;运行前仍须悬空机器狗、停掉抢占源,结束后恢复 sportMode。C++ position 示例会发送
实际关节位置命令,只应按 [`docs/SAFETY.md`](docs/SAFETY.md) 的检查清单手动运行。
## 准备工作
### 1. 提取 Blowfish 密钥(仅需一次)
`go1_pro_sdk/_data/blowfish_state.bin` 已包含我们项目用的密钥。如果你的狗用的是不同的 key很少见除非固件升级需要重新提取
```bash
# SSH 到狗 (192.168.123.161)
scp tools/extract_blowfish_key.sh pi@192.168.123.161:/tmp/
ssh pi@192.168.123.161 "sudo bash /tmp/extract_blowfish_key.sh"
scp pi@192.168.123.161:/tmp/blowfish_dump.tar.gz ./data/
# Mac 端分析
python tools/analyze_blowfish_dump.py data/blowfish_dump.tar.gz
# → 输出 go1_pro_sdk/_data/blowfish_state.bin
```
### 2. 停掉狗上的抢占源
PRO 的 MCU 一次只接受一个客户端的命令。要让 SDK 工作,必须先停掉狗上的:
```bash
ssh pi@192.168.123.161 "sudo pkill -9 -f keep_sport_alive; \
sudo pkill -9 -f Legged_sport; \
sudo pkill -9 -f appTransit"
```
或用我们提供的:
```bash
bash tools/stop_sportmode.sh stop
```
### 3. 跑示例
```bash
# 状态监听(会发送 damping LowCmd不是纯被动监听
python examples/monitor_state.py --duration 30 --verbose
# 遥控器监听(会发送 damping LowCmd
python examples/monitor_remote.py
# 单腿 sin 摆动 (狗悬空, 振幅 0.3 rad)
python examples/example_sin_leg.py --amplitude 0.3 --freq 0.5
# 复刻原版 example_position(lowlevel).py
python examples/example_position.py
```
### 4. 测完恢复
```bash
bash tools/stop_sportmode.sh start
```
## ⚠️ 安全
直接控制 12 个电机是**危险操作**
- 第一次测试 **狗必须悬空** (脚架/吊带)
-`apply_safety(cmd, state, power_factor=1)` 限制力矩到 10%
- 准备 **拔电池** 作为终极停机 (Legged_sport 被杀后,遥控器 L2+B 不会工作)
-`docs/SAFETY.md`
## 包结构
```
go1_pro_sdk/ # Python 原生 PRO SDK
├── connection/ # MCUClient: UDP 客户端
├── codec/ # Python Blowfish、LowCmd、LowState
├── compat/ # 官方 robot_interface Python facade
├── highlevel/ # sportMode MQTT API
├── safety/ # Python Safety 实现
├── types/ # Python 数据结构
├── utils/ # CRC、常量和字段编解码
└── _data/ # Python wheel 内的 Blowfish state
robot_interface.py # 官方 Python SDK 同名顶层入口
pyproject.toml # Python 构建和安装入口
fast_lowcmd_cpp/ # Python 可选 CPython 加速扩展
include/unitree_legged_sdk/ # C++ 公共头文件,路径与官方一致
src/ # C++ 私有实现,不作为公共头文件安装
cmake/ # C++ find_package 配置模板
CMakeLists.txt # C++ 构建、测试和安装入口
examples/*.py # Python 示例
examples/cpp/ # C++ 同源码兼容示例
tests/*.py # Python、实机抓包和 facade 回归
tests/cpp/ # C++ 契约、安装消费测试与可选性能基准
data/captures/ # 本机实机抓包,存在时自动参与回归
```
Python 和 C++ 的公共 API 不交叉包含Python 安装由 `pyproject.toml` 管理,不会安装
C++ 头文件C++ 安装由 CMake 管理,不会安装 Python 包。两边唯一共享的运行数据是
`blowfish_state.bin`,安装时分别进入 Python package data 和 C++ data directory。
## 文档
- `docs/PROTOCOL.md` — PRO LowCmd/LowState 字节级格式规格
- `docs/SAFETY.md` — 安全测试清单
- `docs/REVERSE_ENGINEERING.md` — 逆向工程过程精华
- `docs/ARCHITECTURE.md` — 包结构与数据流
## 致谢
- 原版 [free-dog-sdk](https://github.com/Bin4ry/free-dog-sdk) by Bin4ry (Andreas Makris) — 提供了 EDU 版的基础数据结构和 CRC 实现
- Unitree 官方 [unitree_legged_sdk](https://github.com/unitreerobotics/unitree_legged_sdk) — 公开了 safety.h 的接口定义
## License
MIT (跟 free-dog-sdk 一致)