8.1 KiB
8.1 KiB
包结构与数据流
仓库分层
本仓库同时提供 Python SDK 和独立 C++ SDK,两者按构建系统和公共入口区分:
| 层 | Python | C++ |
|---|---|---|
| 公共 API | go1_pro_sdk/、robot_interface.py |
include/unitree_legged_sdk/ |
| 私有实现 | Python package 子模块 | src/ |
| 构建入口 | pyproject.toml |
CMakeLists.txt |
| 示例 | examples/*.py |
examples/cpp/*.cpp |
| 测试 | tests/*.py |
tests/cpp/ |
fast_lowcmd_cpp/ 属于 Python 侧:它生成 CPython extension,用来加速 Python 的命令
编解码和状态解析。它不提供 C++ 公共头文件,也不应被 C++ 应用直接链接。
Python 架构
模块依赖图
┌──────────────────────┐
│ MCUClient │ ← 用户主要 API
│ (connection/) │
└──────┬───────────────┘
│
┌──────────────┼──────────────┐
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ codec/ │ │ types/ │ │ safety/ │
│ Blowfish │ │ LowCmd │ │ apply_ │
│ build_* │ │ LowState │ │ safety │
│ parse_* │ │ MotorCmd │ │ │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
└────────────────┼────────────────┘
▼
┌─────────────┐
│ utils/ │
│ common.py │ ← CRC, float_hex
│ constants │ ← 关节限位, 默认地址
└─────────────┘
数据流: 收一帧 → 用户处理 → 发命令
UDP 858B 密文 UDP 616B 密文
▲ │
│ ▼
MCU :8007 MCU :8007
│ ▲
▼ │
┌─────────────────────────────────────────────────┐
│ MCUClient.recv_latest() │
│ socket.recvfrom() │
│ bf.decrypt_ecb(data[:856]) → 856B 明文 │
│ parse_low_state(...) → LowState 结构 │
└─────────────────────────────────────────────────┘
│
▼
┌──────────┐ 用户逻辑 ┌──────────┐
│ LowState │ ──────────► │ LowCmd │
└──────────┘ qDes, Kp, └──────────┘
Kd, tau... │
▼
┌─────────────────────────────────────────────────┐
│ apply_safety(cmd, state, power_factor=1) │
│ position_limit(cmd) │
│ power_protect(cmd, state, factor) │
│ position_protect(cmd, state, limit_rad) │
└─────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ MCUClient.send(cmd) │
│ build_low_cmd_plain(cmd) → 616B 明文 │
│ bf.encrypt_ecb(plain) → 616B 密文 │
│ sock.sendto(cipher, ...) │
└─────────────────────────────────────────────────┘
各包职责
utils/
最底层。纯函数, 无副作用, 无依赖其他模块。
common.py: CRC, float↔hex, tau↔2B, Kp↔2B, Kd↔2B, decode_sn/versionconstants.py: MCU 地址, 关节命名, 限位, TAU_MAX, DAMPING_POSE
types/
数据结构 (dataclass)。依赖 utils, 不依赖 codec/safety/connection。
motor.py: MotorCmd, MotorState, MotorModeimu.py: IMUbms.py: BMSremote.py: RemoteState, parse_remotelow_cmd.py: LowCmd (12 motorCmd + 元数据)low_state.py: LowState (12 motorState + IMU + BMS + remote 等)
codec/
加解密和序列化。依赖 types + utils。
blowfish.py: 标准 Blowfish ECB (LE 字节序), 接受预生成 statelowcmd_builder.py: LowCmd → 616B 明文 → 加密后 616Blowstate_parser.py: 解密后 807B → LowState 结构
safety/
控制保护层。依赖 types + utils。
safety.py: PositionLimit/PowerProtect/PositionProtect 三个保护 + 统一入口 apply_safety
connection/
UDP 高层抽象。依赖前面所有。
mcu_client.py: MCUClient (socket + Blowfish + 序列化 + safe_stop)
用户三种用法
Level 1: 高层 (推荐)
from go1_pro_sdk import MCUClient, LowCmd, MotorCmd, MotorMode
with MCUClient() as client:
client.wake_mcu()
state = client.recv_state()
cmd = LowCmd()
cmd.set_motor('FR_1', MotorCmd(mode=MotorMode.Servo, q=1.2, Kp=5, Kd=1))
client.send(cmd)
client.safe_stop()
Level 2: 中层 (自己管 socket, 用编解码)
from go1_pro_sdk import Blowfish, build_low_cmd_encrypted, parse_low_state, LowCmd
import socket
bf = Blowfish.from_state_file('go1_pro_sdk/_data/blowfish_state.bin')
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('', 0))
cmd = LowCmd()
sock.sendto(build_low_cmd_encrypted(cmd, bf), ('192.168.123.10', 8007))
data, _ = sock.recvfrom(2048)
state = parse_low_state(bf.decrypt_ecb(data[:856]))
Level 3: 底层 (诊断/逆向)
直接用 Blowfish.encrypt_block(b8) / Blowfish.decrypt_block(b8), 自己处理 8B 块。
适合协议研究或字节级 diff。
C++ 架构
应用源码
#include <unitree_legged_sdk/unitree_legged_sdk.h>
│
▼
include/unitree_legged_sdk/ 公共、官方兼容声明
comm.h / udp.h / safety.h / loop.h / quadruped.h
│
▼
src/
udp.cpp POSIX UDP、线程安全收发、官方方法适配
safety.cpp PositionLimit/PowerProtect/PositionProtect
loop.cpp Loop/LoopFunc 调度和 Linux CPU affinity
pro_codec.cpp 616B LowCmd、858B LowState、CRC、Blowfish
quadruped.cpp 版本、长度常量和 InitEnvironment
src/pro_codec.h 是库内部头文件,不安装给用户。C++ 应用只能包含
include/unitree_legged_sdk/ 下的头文件,这保证业务源码切换到官方 SDK 时不依赖 PRO
专有声明。PRO 的加密和私有线协议全部封装在 UDP 实现内部。
CMake 对外提供:
- 构建树目标:
unitree_legged_sdk; - namespaced alias:
unitree_legged_sdk::unitree_legged_sdk; - 安装后的
find_package(unitree_legged_sdk CONFIG REQUIRED); - 安装目录中的公共头文件、静态库、CMake config 和 Blowfish state。
共享边界
Python 与 C++ 没有运行时语言绑定关系,也不会互相调用。它们共享的是协议规格、实机 抓包回归基准和 Blowfish state。修改协议实现时必须同时运行:
conda run -n free_dog_sdk python -m pytest -q tests fast_lowcmd_cpp/test_fast_lowcmd.py
cmake -S . -B build-cpp -DCMAKE_BUILD_TYPE=Release
cmake --build build-cpp
ctest --test-dir build-cpp --output-on-failure