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

8.1 KiB
Raw Blame History

包结构与数据流

仓库分层

本仓库同时提供 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: 高层 (推荐)

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 aliasunitree_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