python部分官方化对齐接口
This commit is contained in:
89
docs/OFFICIAL_API_COMPATIBILITY.md
Normal file
89
docs/OFFICIAL_API_COMPATIBILITY.md
Normal file
@@ -0,0 +1,89 @@
|
||||
# Unitree 官方 SDK 接口兼容说明
|
||||
|
||||
对比基准:Unitree [`unitree_legged_sdk`](https://github.com/unitreerobotics/unitree_legged_sdk)
|
||||
`go1` 分支,README 版本 `v3.8.6`,提交
|
||||
`4539a6c10dfbc9781cea6fcb7d51bc6ddc6f71e1`(2023-07-11)。
|
||||
|
||||
## 结论
|
||||
|
||||
本项目和官方 SDK 使用相近的低层对象模型,但此前不是调用兼容:本项目入口是
|
||||
`MCUClient.send()/recv_state()`,官方 Python wrapper 入口是
|
||||
`robot_interface.UDP.SetSend()/Send()/Recv()/GetRecv()`。
|
||||
|
||||
当前项目已提供 `robot_interface` 兼容模块。官方低层 Python 示例可保留原来的
|
||||
导入和主要调用流程,同时底层会使用 Go1 PRO 所需的 Blowfish 加密和 616 字节
|
||||
私有 `LowCmd` 协议。
|
||||
|
||||
## 接口矩阵
|
||||
|
||||
| 官方接口 | 本项目原接口 | 当前兼容状态 |
|
||||
|---|---|---|
|
||||
| `robot_interface.LowCmd/LowState` | 同名类型 | 已对齐命令和常用状态字段名 |
|
||||
| `MotorCmd/MotorState/IMU` | 同名类型 | 常用字段已对齐 |
|
||||
| `BmsState` | `BMS` | 名称已对齐;PRO 状态区较短,见下文 |
|
||||
| `BmsCmd`, `Cartesian`, `UDPState` | 原先缺失 | 已补齐 |
|
||||
| `UDP(LOWLEVEL, ...)` | `MCUClient(...)` | 已适配标准四参数构造 |
|
||||
| `InitCmdData` | 原先缺失 | 已实现官方 stop sentinel 初始化 |
|
||||
| `Recv/GetRecv/SetSend/Send` | `recv_latest/send` | 已适配 |
|
||||
| `Safety.PositionLimit` | `position_limit` | 已适配,跳过 `PosStopF` |
|
||||
| `Safety.PowerProtect` | `power_protect` | 调用兼容,算法不是官方闭源实现 |
|
||||
| `Safety.PositionProtect` | `position_protect` | 调用兼容,保护动作更保守 |
|
||||
| `HighCmd/HighState` | MQTT `Go1/Go1MQTT` | 类型已提供,UDP 传输不支持 |
|
||||
| `Loop/LoopFunc` | 无 | 官方 Python wrapper 本身也未导出 |
|
||||
| C++ headers/static library | 无 | 不兼容 C++ 源码或 ABI |
|
||||
|
||||
## 关键协议差异
|
||||
|
||||
官方 SDK 的公开结构不能直接描述本项目实测的 Go1 PRO 线协议。PRO 低层通道需要:
|
||||
|
||||
- 616 字节 `LowCmd`,CRC 位于 612;
|
||||
- Blowfish ECB 加密;
|
||||
- `bandWidth` 使用实测字节序和值;
|
||||
- 858 字节加密状态包中取 856 字节块解密,再解析 807 字节有效状态。
|
||||
|
||||
因此兼容层只对齐用户代码接口,不替换本项目现有 codec,也不承诺二进制包与官方
|
||||
EDU SDK 相同。
|
||||
|
||||
## 官方风格用法
|
||||
|
||||
```python
|
||||
import robot_interface as sdk
|
||||
|
||||
udp = sdk.UDP(sdk.LOWLEVEL, 8080, "192.168.123.10", 8007)
|
||||
safe = sdk.Safety(sdk.LeggedType.Go1)
|
||||
cmd = sdk.LowCmd()
|
||||
state = sdk.LowState()
|
||||
udp.InitCmdData(cmd)
|
||||
|
||||
udp.Recv()
|
||||
udp.GetRecv(state)
|
||||
|
||||
cmd.motorCmd[sdk.FR_1].q = 1.2
|
||||
cmd.motorCmd[sdk.FR_1].dq = 0.0
|
||||
cmd.motorCmd[sdk.FR_1].Kp = 5.0
|
||||
cmd.motorCmd[sdk.FR_1].Kd = 1.0
|
||||
safe.PositionLimit(cmd)
|
||||
safe.PowerProtect(cmd, state, 1)
|
||||
udp.SetSend(cmd)
|
||||
udp.Send()
|
||||
```
|
||||
|
||||
`UDP(HIGHLEVEL, ..., "192.168.123.161", 8082)` 不会被静默映射到 MQTT。两种通道
|
||||
状态模型和时序不同,兼容层会明确抛出 `NotImplementedError`。高层控制继续使用
|
||||
`Go1` 或 `Go1MQTT`。
|
||||
|
||||
## 尚未完全对齐的风险
|
||||
|
||||
- 官方 `PowerProtect` 实现在静态库中,头文件只公开签名。本项目当前保护逻辑按
|
||||
关节力矩限幅和实测过载执行,不等价于官方内部的累计功率算法。
|
||||
- 官方 `BmsState` 是 34 字节,本项目实测的 PRO 状态布局只给 BMS 分配 24 字节;
|
||||
`cell_vol` 后半部分不能视为完整的官方数据。
|
||||
- `LowState.tick` 当前没有从 PRO 包中解析,仍为默认值;`footForce` 和
|
||||
`footForceEst` 的偏移来自逆向推断,尚未达到官方字段的同等可信度。
|
||||
- `head/SN/version/reserve/crc` 在本地原生类型中部分使用 `bytes`,官方 wrapper
|
||||
使用定长整数数组或整数。命令 builder 接受两种常见赋值形态,但读取后的 Python
|
||||
类型不保证完全相同。
|
||||
- 本项目 `LowState` 是 PRO 抓包格式的解释,不应按官方 `#pragma pack(1)` 结构大小
|
||||
直接做内存映射。
|
||||
- 官方 C++ 用户需要单独的 C++ facade 和库链接方案;Python 兼容模块不能让现有
|
||||
C++ 程序直接重编译通过。
|
||||
Reference in New Issue
Block a user