- s10_robot.py: protocol framing, mTLS client, heartbeat, status and control APIs - demo_stand_rotate_lie.py: stand, rotate in place, lie down with safe recovery - status_probe.py: read-only status subscription - tests: protocol unit tests and local fake robot - docs: remote control command reference
468 lines
20 KiB
Markdown
468 lines
20 KiB
Markdown
# 山猫 S10 遥控指令整理
|
||
|
||
> **资料依据**
|
||
> - 《山猫S10 软件开发指南》V1.0.2(2026-10-13)第 1 章「本体监控协议」
|
||
> - 《DeepRoboticsLab 2.5.4 备份与密钥分析》(2026-10-29)连接与加密实测部分
|
||
>
|
||
> **整理日期:**2026-10-29
|
||
>
|
||
> 本文只整理「遥控(手动/半自主)控制」所需的内容:连接方式、帧格式、控制类指令、必要的状态回读。
|
||
> 导航任务下发、CPU/电池等设备监控、ROS2 话题不在本文范围内。
|
||
|
||
---
|
||
|
||
## 0. 一分钟速查
|
||
|
||
| 功能 | Type | Command | 关键 Items | 响应 |
|
||
|---|---|---|---|---|
|
||
| 心跳(保活 + 开启状态上报) | `0x00100064` | `0x00000005` | 无 | 有 |
|
||
| 使用模式切换 | `0x00100002` | `0x00500002` | `Mode` | 有 |
|
||
| 运动状态转换(站/趴/阻尼) | `0x00100001` | `0x00200002` | `MotionParam` | 有 |
|
||
| 运动步态切换 | `0x00100001` | `0x00300002` | `GaitParam` | 有 |
|
||
| 运动控制(轴指令) | `0x00100001` | `0x00100002` | `X/Y/Z/Roll/Pitch/Yaw` | **无响应帧** |
|
||
| 运动控制(速度指令) | `0x00100001` | `0x00110002` | `X/Y/Z/Roll/Pitch/Yaw` | **无响应帧** |
|
||
| 自定义灯语 | `0x00100005` | `0x00200002` | `CustomMode`、`Led[]` | 有 |
|
||
| 自主充电 | `0x00100004` | `0x00100002` | `Charge` | 有 |
|
||
| 运动 SDK 模式 | `0x00100005` | `0x00300002` | `SDKEnable`、`Frequency` | 有 |
|
||
| 休眠模式设置 | `0x00100002` | `0x00400002` | `Sleep`、`Auto`、`Time` | 有 |
|
||
|
||
十进制换算(JSON 里必须写数字,不能写带空格的十六进制):
|
||
|
||
| 十六进制 | 十进制 | 十六进制 | 十进制 |
|
||
|---|---|---|---|
|
||
| `0x00100001` | 1048577 | `0x00000005` | 5 |
|
||
| `0x00100002` | 1048578 | `0x00100002` | 1048578 |
|
||
| `0x00100004` | 1048580 | `0x00110002` | 1114114 |
|
||
| `0x00100005` | 1048581 | `0x00200002` | 2097154 |
|
||
| `0x00100064` | 1048676 | `0x00300002` | 3145730 |
|
||
| `0x0010007f` | 1048703 | `0x00400002` | 4194306 |
|
||
| `0x00f00000` | 15728640 | `0x00500002` | 5242882 |
|
||
|
||
---
|
||
|
||
## 1. 连接与帧格式
|
||
|
||
### 1.1 连接参数
|
||
|
||
| 项目 | 值 |
|
||
|---|---|
|
||
| 机器人地址(实测) | `10.21.33.103` |
|
||
| TLS(TCP + 加密) | 端口 **30003** |
|
||
| DTLS(UDP + 加密) | 端口 **30004** |
|
||
| 角色 | 机器人为服务端,上位机/外部板卡为客户端 |
|
||
| 加密 | 默认开启;关闭需修改 `robotserver` 配置文件(联系技术支持),系统更新不会覆盖该配置 |
|
||
|
||
**安全机制是 mTLS 双向认证**(实测结论,不是可选的):
|
||
|
||
- 客户端必须提供 `client_chain.crt` + `client.key`,服务端用同一 CA 链验证;
|
||
- 不带客户端证书,服务端直接返回 `TLSV13_ALERT_CERTIFICATE_REQUIRED`;
|
||
- 明文 TCP 会被服务端用 TLS alert 拒绝(`15 03 03 00 02 02 16`);
|
||
- 实测协商结果:TLSv1.3 / `TLS_AES_256_GCM_SHA384`,服务端证书 `CN=server.local`,可用导出的 `root_ca.crt` 校验通过。
|
||
|
||
证书材料来自 App 的 `assets/certs/`,运行时复制到 `filesDir/certs/`:
|
||
|
||
| 文件 | 说明 |
|
||
|---|---|
|
||
| `client.key` | 客户端私钥,RSA 2048 / PKCS#8 / PEM,无口令 |
|
||
| `client_chain.crt` | 客户端证书链(client.local ← TLS CA ← Project CA ← Root CA) |
|
||
| `root_ca.crt` | 根 CA,有效期 2026-04-03 ~ 2036-03-31 |
|
||
|
||
> 客户端叶子证书有效期 2026-04-03 ~ 2027-04-03,过期后需重新获取。
|
||
> TCP 与 DTLS 复用同一套证书和同一个 TLS 上下文,不存在单独的对称密钥或 PSK。
|
||
|
||
### 1.2 协议帧(16 字节头 + ASDU)
|
||
|
||
| 偏移 | 长度 | 字段 | 说明 |
|
||
|---|---|---|---|
|
||
| 0 | 4 | 同步字符 | 固定 `EB 91 EB 90` |
|
||
| 4 | 2 | 长度 | ASDU 字节数,**小端**;单帧 ASDU ≤ 1000 字节,分包总长 ≤ 65535 |
|
||
| 6 | 2 | 报文 ID | 小端,请求/响应同值,0 → 65535 循环;分包须一致 |
|
||
| 8 | 1 | ASDU 格式 | `0x00` = XML,`0x01` = JSON |
|
||
| 9 | 1 | 当前包编号 | 从 0 递增,≤ 255 |
|
||
| 10 | 1 | 协议版本 | 固定 `0x01` |
|
||
| 11 | 5 | 预留 | 全 0 |
|
||
|
||
### 1.3 ASDU 结构
|
||
|
||
根节点固定为 `PatrolDevice`,四个字段:
|
||
|
||
| 字段 | 含义 |
|
||
|---|---|
|
||
| `Type` | 消息类型 |
|
||
| `Command` | 消息命令码 |
|
||
| `Time` | 本地时区发送时间,`YYYY-MM-DD HH:MM:SS`(实测响应带毫秒,如 `2026-10-29 19:50:18.403`,两种均可) |
|
||
| `Items` | 参数项 |
|
||
|
||
推荐 JSON(官方说明:JSON 处理更快、支持的消息类型更全)。
|
||
|
||
### 1.4 数值写法(容易踩坑)
|
||
|
||
官方文档示例里写的是 `"Type": 0x0010 0064` 这种**带空格的十六进制,这不是合法 JSON**。实际发送必须用整数:
|
||
|
||
```json
|
||
{"PatrolDevice":{"Type":1048676,"Command":5,"Time":"2026-01-01 00:00:00","Items":{}}}
|
||
```
|
||
|
||
---
|
||
|
||
## 2. 手动遥控操作时序
|
||
|
||
```
|
||
① 建立 mTLS 连接 (30003/TCP 或 30004/UDP)
|
||
│
|
||
② 心跳 0x00100064 / 0x00000005,频率 ≥ 1Hz(持续保活)
|
||
│ └─ 机器人开始向该 IP:端口 上报状态(2Hz/10Hz/1Hz)
|
||
│
|
||
③ 使用模式 0x00100002 / 0x00500002 Mode=0 常规(手动)
|
||
│
|
||
④ 运动状态 0x00100001 / 0x00200002 MotionParam=1 站立
|
||
│ └─ ASDU 下发站立完成后会自动进入 RL 控制状态
|
||
│
|
||
⑤ 步态 0x00100001 / 0x00300002 GaitParam=0x1001 基础
|
||
│ (必须在机器人完全停止后下发)
|
||
│
|
||
⑥ 轴指令 0x00100001 / 0x00100002 持续下发 X/Y/Yaw(建议 ≥10Hz)
|
||
│ (无响应帧,靠状态上报确认)
|
||
│
|
||
⑦ 结束:轴指令全 0 → 趴下 MotionParam=4,或直接断开
|
||
```
|
||
|
||
**导航(半自主)路线**与上面的差异:
|
||
|
||
```
|
||
③ Mode=1 导航模式
|
||
⑤ GaitParam=0x3002(平地导航)/ 0x3003(楼梯导航,须在进楼梯前切换)
|
||
⑥ 改用速度指令 0x00100001 / 0x00110002(单位 m/s、rad/s,仅导航模式生效,建议 10Hz)
|
||
```
|
||
|
||
**关键约束**
|
||
|
||
- 心跳必须持续发:连续 **2 秒** 未收到就关闭主动上报,需重新建立连接。
|
||
- 轴指令/速度指令要求 **2 秒内来自同一客户端**,否则返回 `0xE006`。
|
||
- 步态切换必须在机器人**完全停止**后下发,否则指令被缓存、停机后才执行。
|
||
- 站立后:走 **ASDU** 会自动进 RL 控制,可直接发速度/步态;走 **ROS2 话题**不会自动进,需要再补一条 RL 控制指令。
|
||
- 轴指令和速度指令**不返回响应帧**,只能靠状态上报判断是否生效。
|
||
|
||
---
|
||
|
||
## 3. 控制类指令详解
|
||
|
||
### 3.1 心跳指令
|
||
|
||
| Type | Command | 说明 |
|
||
|---|---|---|
|
||
| `0x00100064` | `0x00000005` | 心跳,Items 为空 |
|
||
|
||
```json
|
||
{"PatrolDevice":{"Type":1048676,"Command":5,"Time":"2026-01-01 00:00:00","Items":{}}}
|
||
```
|
||
|
||
- 建议 ≥ 1Hz。
|
||
- 机器人会向**持续发送心跳的 IP 和端口**主动上报实时状态与异常状态。
|
||
- 超时 2 秒关闭主动上报,超时后需要重新建立链接。
|
||
|
||
### 3.2 使用模式切换
|
||
|
||
| Type | Command | 说明 |
|
||
|---|---|---|
|
||
| `0x00100002` | `0x00500002` | 切换机器人使用模式 |
|
||
|
||
| 参数 | 类型 | 取值 |
|
||
|---|---|---|
|
||
| `Mode` | int | `0` 常规模式 / `1` 导航模式 / `2` 辅助模式 |
|
||
|
||
```json
|
||
{"PatrolDevice":{"Type":1048578,"Command":5242882,"Time":"2026-01-01 00:00:00","Items":{"Mode":0}}}
|
||
```
|
||
|
||
- 常规模式下支持轴指令;导航模式下支持导航任务。
|
||
- 切换结果需通过状态上报 `ControlUsageMode` 确认。
|
||
|
||
### 3.3 运动状态转换
|
||
|
||
| Type | Command | 说明 |
|
||
|---|---|---|
|
||
| `0x00100001` | `0x00200002` | 转换机器人运动状态 |
|
||
|
||
| 参数 | 类型 | 取值 |
|
||
|---|---|---|
|
||
| `MotionParam` | int | `-2` 软急停 / `0` 默认(初始、趴卧)/ `1` 站立 / `2` 关节阻尼 / `4` 趴下 / `5` 标零 / `17` RL 控制 / `0x1001` 阻尼趴下 |
|
||
|
||
```json
|
||
{"PatrolDevice":{"Type":1048577,"Command":2097154,"Time":"2026-01-01 00:00:00","Items":{"MotionParam":1}}}
|
||
```
|
||
|
||
> 「空闲」与「软急停」只能查询,**不能通过该指令下发转换**。
|
||
> 用途:`MotionParam=1` 站立、`4` 趴下是最常用的两条;`2` 关节阻尼可作为软急停后的安全态。
|
||
|
||
### 3.4 运动步态切换
|
||
|
||
| Type | Command | 说明 |
|
||
|---|---|---|
|
||
| `0x00100001` | `0x00300002` | 切换运动步态 |
|
||
|
||
| 参数 | 类型 | 取值 |
|
||
|---|---|---|
|
||
| `GaitParam` | int | `0x1001` 基础(常规)/ `0x1003` 楼梯(常规)/ `0x3002` 平地(导航)/ `0x3003` 楼梯(导航) |
|
||
|
||
```json
|
||
{"PatrolDevice":{"Type":1048577,"Command":3145730,"Time":"2026-01-01 00:00:00","Items":{"GaitParam":4097}}}
|
||
```
|
||
|
||
- 步态切换会自动切到对应运动模式,运动模式切换也会自动切到默认步态。
|
||
- 二次开发做自主导航时**必须**用导航专用步态:平地 `0x3002`,楼梯 `0x3003`,且楼梯步态要在**进楼梯前**切换,严禁进楼梯后再切。
|
||
- 必须停机后下发。
|
||
|
||
### 3.5 运动控制(轴指令)
|
||
|
||
| Type | Command | 说明 |
|
||
|---|---|---|
|
||
| `0x00100001` | `0x00100002` | 六自由度速度比例控制,**无响应帧** |
|
||
|
||
```json
|
||
{"PatrolDevice":{"Type":1048577,"Command":1048578,"Time":"2026-01-01 00:00:00","Items":{"X":0.0,"Y":0.0,"Z":0.0,"Roll":0.0,"Pitch":0.0,"Yaw":0.0}}}
|
||
```
|
||
|
||
| 参数 | 含义 | 单位 | 范围 |
|
||
|---|---|---|---|
|
||
| `X` | 前后速度 | %(相对最大速度比例) | [-1, 1] |
|
||
| `Y` | 左右速度 | % | [-1, 1] |
|
||
| `Z` | 高度方向速度 | % | [-1, 1] |
|
||
| `Roll` | 翻滚角速度 | % | [-1, 1] |
|
||
| `Pitch` | 俯仰角速度 | % | [-1, 1] |
|
||
| `Yaw` | 偏航角速度 | % | [-1, 1] |
|
||
|
||
- 仅常规模式和辅助模式可用(导航模式请用速度指令)。
|
||
- **基础步态只响应 X、Y、Yaw**;Z、Roll、Pitch、Yaw 的额外自由度仅在特殊步态下有效。
|
||
- 正方向按右手坐标系;X 正为前进、Y 正为左移、Yaw 正为逆时针。
|
||
- 需要连续下发维持运动;停止时发全 0。
|
||
|
||
### 3.6 运动控制(速度指令)
|
||
|
||
| Type | Command | 说明 |
|
||
|---|---|---|
|
||
| `0x00100001` | `0x00110002` | 真实物理量速度控制,**无响应帧** |
|
||
|
||
```json
|
||
{"PatrolDevice":{"Type":1048577,"Command":1114114,"Time":"2026-01-01 00:00:00","Items":{"X":0.0,"Y":0.0,"Z":0.0,"Roll":0.0,"Pitch":0.0,"Yaw":0.0}}}
|
||
```
|
||
|
||
| 参数 | 含义 | 单位 | 范围 |
|
||
|---|---|---|---|
|
||
| `X` | 前后速度 | m/s | ±1.67 |
|
||
| `Y` | 左右速度 | m/s | ±0.4 |
|
||
| `Z` | 高度方向速度 | m/s | — |
|
||
| `Roll` | 翻滚角速度 | rad/s | — |
|
||
| `Pitch` | 俯仰角速度 | rad/s | — |
|
||
| `Yaw` | 偏航角速度 | rad/s | ±1.0 |
|
||
|
||
- 字段与轴指令完全相同,差别是**不做速度换算、原样下发执行端**,单位为物理量。
|
||
- **仅导航模式生效**,建议 10Hz 下发。
|
||
|
||
### 3.7 自定义灯语
|
||
|
||
| Type | Command | 说明 |
|
||
|---|---|---|
|
||
| `0x00100005` | `0x00200002` | 分别设置头灯、尾灯的灯光模式/颜色/占空比 |
|
||
|
||
| 参数 | 类型 | 取值 |
|
||
|---|---|---|
|
||
| `CustomMode` | bool | `true` 开启自定义 / `false` 关闭 |
|
||
| `Led[0]` | object | 头灯 |
|
||
| `Led[1]` | object | 尾灯 |
|
||
| `Led[].Type` | int | `0` 常亮 / `1` 填充式流水 / `2` 移动式流水 / `3` 渐变式流水 / `4` 呼吸 / `5` 单色闪烁 |
|
||
| `Led[].Color` | array\<int\> | `0` 黑 / `1` 白 / `2` 绿 / `3` 蓝 |
|
||
| `Led[].Cycle` | int | 占空比,单位 s;仅呼吸、闪烁模式使用 |
|
||
|
||
```json
|
||
{"PatrolDevice":{"Type":1048581,"Command":2097154,"Time":"2026-01-01 00:00:00","Items":{"CustomMode":true,"Led":[{"Type":0,"Color":[1],"Cycle":1},{"Type":0,"Color":[2],"Cycle":1}]}}}
|
||
```
|
||
|
||
> 官方原文的 JSON 示例缺逗号、`"Led"` 后直接跟数组,不是合法 JSON;上面是修正后的可直接发送版本。
|
||
|
||
### 3.8 自主充电
|
||
|
||
| Type | Command | 说明 |
|
||
|---|---|---|
|
||
| `0x00100004` | `0x00100002` | 控制自主充电 |
|
||
|
||
| 参数 | 类型 | 取值 |
|
||
|---|---|---|
|
||
| `Charge` | int | `0` 结束充电 / `1` 开始充电 / `2` 清除充电状态、恢复空闲 |
|
||
|
||
```json
|
||
{"PatrolDevice":{"Type":1048580,"Command":1048578,"Time":"2026-01-01 00:00:00","Items":{"Charge":1}}}
|
||
```
|
||
|
||
> `Charge=2` 会强制切断充电电流、状态归零并清除相关错误记录,**有风险,慎用**。
|
||
|
||
### 3.9 运动 SDK 模式
|
||
|
||
| Type | Command | 说明 |
|
||
|---|---|---|
|
||
| `0x00100005` | `0x00300002` | 进入/退出 SDK 运动控制模式 |
|
||
|
||
| 参数 | 类型 | 取值 |
|
||
|---|---|---|
|
||
| `SDKEnable` | bool | `true` 开启 / `false` 关闭 |
|
||
| `Frequency` | int | 关节话题数据发布频率,[1, 200] 且能整除 1000 |
|
||
|
||
```json
|
||
{"PatrolDevice":{"Type":1048581,"Command":3145730,"Time":"2026-01-01 00:00:00.000","Items":{"SDKEnable":true,"Frequency":100}}}
|
||
```
|
||
|
||
### 3.10 休眠模式设置
|
||
|
||
| Type | Command | 说明 |
|
||
|---|---|---|
|
||
| `0x00100002` | `0x00400002` | 设置休眠/自动休眠 |
|
||
|
||
| 参数 | 类型 | 取值 |
|
||
|---|---|---|
|
||
| `Sleep` | bool | `true` 进入休眠 / `false` 唤醒 |
|
||
| `Auto` | bool | 到时间是否自动休眠 |
|
||
| `Time` | uint(min) | 心跳断联后等待多久休眠 |
|
||
|
||
```json
|
||
{"PatrolDevice":{"Type":1048578,"Command":4194306,"Time":"2026-01-01 00:00:00.000","Items":{"Sleep":false,"Auto":true,"Time":5}}}
|
||
```
|
||
|
||
---
|
||
|
||
## 4. 遥控必须回读的状态
|
||
|
||
心跳建立后机器人主动上报。上报地址 = 最近发心跳的 IP:端口。
|
||
|
||
| 上报 | Type | Command | 频率 | 遥控关注点 |
|
||
|---|---|---|---|---|
|
||
| 基础状态 | `0x00100064` | `0x00f00000` | 2Hz | `MotionState`、`Gait`、`ControlUsageMode`、`HES`、`Charge` |
|
||
| 运控状态 | `0x00100001` | `0x00f00000` | 10Hz | 实际速度、姿态、关节角,用于闭环 |
|
||
| 设备状态 | `0x00100002` | `0x00f00000` | 2Hz | 电池、电机温度、外设使能 |
|
||
| 异常状态 | `0x0010007f` | `0x00f00000` | 2Hz | 故障列表,状态变化时额外上报 |
|
||
| 导航状态 | `0x00100003` | `0x00f00000` | 1Hz | 导航任务状态、定位状态 |
|
||
|
||
### 4.1 基础状态 `BasicStatus`
|
||
|
||
| 字段 | 含义 | 取值 |
|
||
|---|---|---|
|
||
| `MotionState` | 运动状态 | `-2` 软急停 / `0` 默认 / `1` 站立 / `2` 关节阻尼 / `4` 趴下 / `5` 标零 / `17` RL 控制 / `0x1001` 阻尼趴下 |
|
||
| `Gait` | 步态 | `0x1001` 基础 / `0x1002` 高台 / `0x3002` 平地(导航)/ `0x3003` 楼梯(导航) |
|
||
| `HES` | 硬急停 | `0` 未触发 / `1` 已触发 |
|
||
| `ControlUsageMode` | 使用模式 | `0` 常规 / `1` 导航 / `2` 辅助 |
|
||
| `PowerManagement` | 电源模式 | `0` 常规 / `1` 单电池 |
|
||
| `Sleep` | 休眠 | `0` 非休眠 / `1` 休眠 / `2` 进入休眠中 |
|
||
| `Model` | 型号 | 如 `CD1` |
|
||
| `Version` | 版本 | `STD` 标准 / `PRO` 增强 |
|
||
| `Charge` | 充电状态 | `0x0000` 空闲 / `0x0001` 前往电桩 / `0x0002` 充电中 / `0x0003` 退出电桩 / `0x0004` 异常 / `0x0005` 在桩未充电 / `0x0006` 线充 |
|
||
|
||
> 注意:步态上报里有 `0x1002` 高台,但《运动步态切换》指令表没列出 `0x1002`;下发时以指令表为准。
|
||
|
||
### 4.2 运控状态 `MotionStatus`(10Hz,闭环用)
|
||
|
||
| 字段 | 含义 | 单位 |
|
||
|---|---|---|
|
||
| `LinearX` / `LinearY` | 自身坐标系 x/y 线速度 | m/s |
|
||
| `AngularZ` | yaw 角速度 | rad/s |
|
||
| `Roll` / `Pitch` / `Yaw` | 姿态角 | rad |
|
||
| `OmegaX/Y/Z` | IMU 三轴角速度 | rad/s |
|
||
| `AccX/Y/Z` | 三轴加速度 | m/s² |
|
||
| `Height` | 机身高度 | m |
|
||
| `Payload` | 负载 | kg |
|
||
| `RemainMile` | 预测剩余里程 | km |
|
||
| `Gait` / `MotionState` | 当前步态 / 运动状态 | — |
|
||
| `MotorStatus.Joint` | 16 关节角度数组 | rad |
|
||
|
||
`MotorStatus.Joint` 顺序(16 个):LeftFrontHipX、LeftFrontHipY、LeftFrontKnee、LeftFrontWheel、RightFrontHipX、RightFrontHipY、RightFrontKnee、RightFrontWheel、LeftBackHipX、LeftBackHipY、LeftBackKnee、LeftBackWheel、RightBackHipX、RightBackHipY、RightBackKnee、RightBackWheel。
|
||
|
||
### 4.3 异常状态 `ErrorList`
|
||
|
||
每组含 `Code`、`Name`、`Severities`(`3` WARN / `4` ERROR / `5` FATAL)、`Resources`、`Source`、`Timestamp`、`Type`(`1` 开始/等级变化,`2` 消除)。遥控常见故障码:
|
||
|
||
| 码 | 含义 | 码 | 含义 |
|
||
|---|---|---|---|
|
||
| `0x8001` | 电机温度过高 | `0x8101` | 电池电量低 |
|
||
| `0x8002` | 驱动器温度过高 | `0x8108` | 电池温度过高 |
|
||
| `0x8014` | 关节位置超限 | `0x810A` | 放电电流过大 |
|
||
| `0x8016` | 关节数据无效 | `0x8201` | IMU 发布超时/无更新 |
|
||
| `0x8006` | 驱动器通信超时 | `0x8204` | IMU 数据无效 |
|
||
| `0x8301` | CPU 温度过高 | `0x8304` | 可用内存过低 |
|
||
|
||
---
|
||
|
||
## 5. 通用返回与错误码
|
||
|
||
除轴指令、速度指令外,所有控制指令都会返回同 Type/Command 的通用状态响应:
|
||
|
||
```json
|
||
{"PatrolDevice":{"Type":1048676,"Command":5,"Time":"2026-10-29 19:50:18.403","Items":{"ErrorCode":0,"ErrorMessage":"Success"}}}
|
||
```
|
||
|
||
| ErrorCode | ErrorMessage | 含义 |
|
||
|---|---|---|
|
||
| `0x0000` | Success | 成功 |
|
||
| `0xE001` | Unsupported data format | 数据格式不支持(非 XML/JSON) |
|
||
| `0xE002` | Data parsing failed | 解析失败(缺 PatrolDevice/Items/Type/Command) |
|
||
| `0xE003` | Unsupported protocol type | 找不到 Type+Command 对应协议 |
|
||
| `0xE004` | Missing necessary fields | 缺少必要字段 |
|
||
| `0xE005` | Mismatched data type | 字段类型不匹配 |
|
||
| `0xE006` | Mismatched request client | 请求客户端不匹配(如 2 秒内轴指令来自不同客户端) |
|
||
| `0xE007` | No operation permission | 无操作权限 |
|
||
| `0xE008` | Not allowed operation | 不允许的操作 |
|
||
| `0xE009` | Operation failure | 操作失败 |
|
||
| `0xE00A` | Unsupported function | 不支持的功能(如标准版不支持导航) |
|
||
| `0xE00B` | Internal error | 内部错误 |
|
||
|
||
> 实测返回里 `Items` 可能只带 `ErrorCode` 而不带 `ErrorMessage`,解析时两者都要兼容。
|
||
|
||
---
|
||
|
||
## 6. 注意事项汇总
|
||
|
||
1. **心跳是前提**:≥1Hz,2 秒断流即关闭上报并需重连。
|
||
2. **mTLS 是强制的**:无客户端证书连不上;明文 TCP 直接被拒。
|
||
3. **JSON 数值必须写整数**,不能用文档示例里的 `0x0010 0064` 带空格写法。
|
||
4. **轴指令/速度指令没有响应帧**,必须靠状态上报验证;且 2 秒内必须同一客户端。
|
||
5. **轴指令 vs 速度指令**:轴指令 = [-1,1] 比例、常规/辅助模式;速度指令 = 物理量、仅导航模式。
|
||
6. **步态切换要停机**,否则被缓存延后执行。
|
||
7. **楼梯步态先进后退**:必须在进入楼梯前切到 `0x3003`,严禁楼梯上切换。
|
||
8. **基础步态只有 X/Y/Yaw 有效**,Z/Roll/Pitch 需要特殊步态。
|
||
9. **站立后模式差异**:ASDU 站立自动进 RL 控制;ROS2 话题站立需手动补 RL 控制。
|
||
10. **`Charge=2` 有风险**:强制断电、状态归零、清错误记录。
|
||
11. **导航功能仅 PRO 版**,标准版会返回 `0xE00A`。
|
||
12. 报文 ID 请求/响应同值,便于把异步上报与请求响应区分开。
|
||
|
||
---
|
||
|
||
## 7. 配合 `send_adsu.py` 使用
|
||
|
||
`send_adsu.py` 已实现帧封装 + mTLS 连接,`--type/--command` 接受任意进制写法,`Items` 用 JSON 传入。
|
||
|
||
```bash
|
||
# 心跳
|
||
python3 send_adsu.py --type 0x00100064 --command 0x00000005 --items-json '{}'
|
||
|
||
# 常规模式
|
||
python3 send_adsu.py --type 0x00100002 --command 0x00500002 --items-json '{"Mode":0}'
|
||
|
||
# 站立
|
||
python3 send_adsu.py --type 0x00100001 --command 0x00200002 --items-json '{"MotionParam":1}'
|
||
|
||
# 基础步态
|
||
python3 send_adsu.py --type 0x00100001 --command 0x00300002 --items-json '{"GaitParam":4097}'
|
||
|
||
# 前进(轴指令,无响应,需脚本循环维持)
|
||
python3 send_adsu.py --type 0x00100001 --command 0x00100002 \
|
||
--items-json '{"X":0.3,"Y":0.0,"Z":0.0,"Roll":0.0,"Pitch":0.0,"Yaw":0.0}'
|
||
|
||
# 导航模式下的速度指令(m/s、rad/s)
|
||
python3 send_adsu.py --type 0x00100001 --command 0x00110002 \
|
||
--items-json '{"X":0.5,"Y":0.0,"Z":0.0,"Roll":0.0,"Pitch":0.0,"Yaw":0.0}'
|
||
|
||
# 趴下
|
||
python3 send_adsu.py --type 0x00100001 --command 0x00200002 --items-json '{"MotionParam":4}'
|
||
```
|
||
|
||
脚本当前默认**不校验证书链**(根 CA 缺 keyUsage 扩展,Python 3.13+ 严格校验会拒绝);已用 `openssl s_client` 单独确认服务端证书可信。需要严格校验时加 `--verify`,但部分 Python 版本会失败。
|
||
|
||
> 做遥控闭环时不要每条指令新建连接:轴指令要求 2 秒内同一客户端,应在同一个 TLS 会话里循环发送,并同时读状态上报。
|