Files
go1_pro_sdk/docs/ARCHITECTURE.md
2026-07-30 15:29:30 +08:00

202 lines
8.1 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.
# 包结构与数据流
## 仓库分层
本仓库同时提供 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/version
- `constants.py`: MCU 地址, 关节命名, 限位, TAU_MAX, DAMPING_POSE
#### types/
数据结构 (dataclass)。依赖 utils, 不依赖 codec/safety/connection。
- `motor.py`: MotorCmd, MotorState, MotorMode
- `imu.py`: IMU
- `bms.py`: BMS
- `remote.py`: RemoteState, parse_remote
- `low_cmd.py`: LowCmd (12 motorCmd + 元数据)
- `low_state.py`: LowState (12 motorState + IMU + BMS + remote 等)
#### codec/
加解密和序列化。依赖 types + utils。
- `blowfish.py`: 标准 Blowfish ECB (LE 字节序), 接受预生成 state
- `lowcmd_builder.py`: LowCmd → 616B 明文 → 加密后 616B
- `lowstate_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: 高层 (推荐)
```python
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, 用编解码)
```python
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++ 架构
```text
应用源码
#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。修改协议实现时必须同时运行
```bash
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
```