docs(GML670x4_V2):移动文档到doc目录下

This commit is contained in:
2026-05-06 18:11:41 +08:00
parent a7c6e51ba5
commit 2ab146b49c
+198
View File
@@ -0,0 +1,198 @@
# 平衡板协议说明
本文说明当前固件里的数据包格式和 BLE 通讯方式。
## 1. BLE 通讯方式
平衡板工作在 BLE `Peripheral` 角色,通过 Nordic UART ServiceNUS)与基站通信。
- 上行方向:平衡板 -> 基站,使用 NUS `Notify`
- 下行方向:基站 -> 平衡板,使用 NUS `Write`
- 广播内容:包含设备名和 NUS 128-bit UUID
### 1.1 NUS UUID
| 项目 | UUID | 方向 | 说明 |
|------|------|------|------|
| Service | `6E400001-B5A3-F393-E0A9-E50E24DCCA9E` | - | NUS 主服务 |
| TX Characteristic | `6E400003-B5A3-F393-E0A9-E50E24DCCA9E` | 平衡板 -> 基站 | Notify,上报 CoP 和编码器数据 |
| RX Characteristic | `6E400002-B5A3-F393-E0A9-E50E24DCCA9E` | 基站 -> 平衡板 | Write,下发阻力参数和控制命令 |
### 1.2 当前连接行为
- 连接建立后,平衡板会请求 `7.5-15 ms` 连接区间(`min=6, max=12`)。
- 所有数据通过 NUS 二进制帧发送,不走文本协议。
## 2. 数据包总览
当前协议使用双帧头 `0xAA 0x55` 作为包起始标记。所有多字节字段按 Little Endian 编码。
| 类型名 | 值 | 方向 | 长度 | 频率 | 说明 |
|--------|----|------|------|------|------|
| `PROTO_TYPE_COP` | `0x01` | 平衡板 -> 基站 | `17` | 50 Hz | 压力中心帧 |
| `PROTO_TYPE_ENCODER` | `0x02` | 平衡板 -> 基站 | `13` | TBD | 电机编码器帧(预留) |
| `PROTO_TYPE_RESISTANCE` | `0x10` | 基站 -> 平衡板 | `15` | 按需 | 阻力参数帧 |
| `PROTO_TYPE_SPOTTER` | `0x11` | 基站 -> 平衡板 | `8` | 按需 | 保护模式帧 |
| `PROTO_TYPE_HEARTBEAT` | `0x20` | 基站 -> 平衡板 | `4` | ~1 Hz | 心跳帧 |
## 3. 上行数据包
### 3.1 压力中心帧 (CoP)
CoP 帧固定 17 字节,结构如下:
| 字节偏移 | 字段 | 类型 | 值/范围 | 说明 |
|----------|------|------|---------|------|
| `0` | `sync0` | `uint8` | `0xAA` | 帧头第 1 字节 |
| `1` | `sync1` | `uint8` | `0x55` | 帧头第 2 字节 |
| `2` | `type` | `uint8` | `0x01` | CoP 包类型 |
| `3` | `seq` | `uint8` | `0-255` | 包序号,循环递增 |
| `4` | `flags` | `uint8` | 见下表 | 状态标志位 |
| `5-8` | `cop_x` | `float32 LE` | - | 压力中心 X 坐标 (mm) |
| `9-12` | `cop_y` | `float32 LE` | - | 压力中心 Y 坐标 (mm) |
| `13-16` | `force` | `float32 LE` | - | 总压力 (N) |
#### flags 位定义
| 位 | 名称 | 说明 |
|----|------|------|
| bit0 | `COP_FLAG_FORCE_VALID` | `1` 表示总力超过阈值,CoP 坐标有意义 |
| bit1-7 | 预留 | 填 `0` |
#### CoP 解算公式
传感器布局(俯视):
```text
S4 (FL) -------- S1 (FR)
| center |
S3 (BL) -------- S2 (BR)
```
传感器坐标(单位:mm,板面中心为原点):
| 传感器 | 位置 | X | Y |
|--------|------|---|---|
| S1 | 右前 (FR) | `+200` | `+200` |
| S2 | 右后 (BR) | `+200` | `-200` |
| S3 | 左后 (BL) | `-200` | `-200` |
| S4 | 左前 (FL) | `-200` | `+200` |
计算公式:
```text
F_total = F0 + F1 + F2 + F3
CoP_X = (F0 * x0 + F1 * x1 + F2 * x2 + F3 * x3) / F_total
CoP_Y = (F0 * y0 + F1 * y1 + F2 * y2 + F3 * y3) / F_total
```
`F_total < COP_MIN_FORCE_THRESHOLD` 时,CoP 坐标无意义,`flags.bit0 = 0``cop_x``cop_y``0.0f`
#### 示例
下面是一个 CoP 帧示例(CoP 有效):
```text
AA 55 01 2A 01 00 00 F0 41 00 00 48 42 00 80 BB 44
```
含义如下:
- `AA 55`:双帧头
- `01`CoP 包
- `2A`:序号 `0x2A`
- `01`flags = `force_valid`
- `00 00 F0 41``cop_x = 30.0` mmLE float32
- `00 00 48 42``cop_y = 50.0` mmLE float32
- `00 80 BB 44``force = 1500.0` NLE float32
### 3.2 电机编码器帧(预留)
编码器帧固定 13 字节,结构如下。该帧目前仅在协议中预留定义,固件暂不实现。
| 字节偏移 | 字段 | 类型 | 值/范围 | 说明 |
|----------|------|------|---------|------|
| `0` | `sync0` | `uint8` | `0xAA` | 帧头第 1 字节 |
| `1` | `sync1` | `uint8` | `0x55` | 帧头第 2 字节 |
| `2` | `type` | `uint8` | `0x02` | 编码器包类型 |
| `3` | `seq` | `uint8` | `0-255` | 包序号 |
| `4` | `flags` | `uint8` | `0` | 预留 |
| `5-8` | `cable_length` | `float32 LE` | - | 拉索长度 (mm) |
| `9-12` | `velocity` | `float32 LE` | - | 拉索速度 (mm/s) |
## 4. 下行数据包
### 4.1 阻力参数帧
阻力参数帧固定 15 字节,用于基站向平衡板下发电机阻力控制参数。
| 字节偏移 | 字段 | 类型 | 值/范围 | 说明 |
|----------|------|------|---------|------|
| `0` | `sync0` | `uint8` | `0xAA` | 帧头第 1 字节 |
| `1` | `sync1` | `uint8` | `0x55` | 帧头第 2 字节 |
| `2` | `type` | `uint8` | `0x10` | 阻力参数包类型 |
| `3-6` | `K` | `float32 LE` | - | 刚度 (N/m) |
| `7-10` | `B` | `float32 LE` | - | 阻尼 (Ns/m) |
| `11-14` | `Tau` | `float32 LE` | - | 时间常数 (s) |
#### 示例
```text
AA 55 10 00 00 C8 42 00 00 48 41 CD CC 4C 3E
```
含义如下:
- `AA 55 10`:阻力参数帧头
- `00 00 C8 42``K = 100.0` N/m
- `00 00 48 41``B = 12.5` Ns/m
- `CD CC 4C 3E``Tau = 0.2` s
### 4.2 Spotter Mode 帧
Spotter 帧固定 8 字节,用于启用或关闭保护模式。
| 字节偏移 | 字段 | 类型 | 值/范围 | 说明 |
|----------|------|------|---------|------|
| `0` | `sync0` | `uint8` | `0xAA` | 帧头第 1 字节 |
| `1` | `sync1` | `uint8` | `0x55` | 帧头第 2 字节 |
| `2` | `type` | `uint8` | `0x11` | Spotter 包类型 |
| `3-6` | `threshold` | `float32 LE` | - | 保护力阈值 (N) |
| `7` | `enable` | `uint8` | `0``1` | `0` = 关闭, `1` = 启用 |
#### 示例
启用 Spotter Mode,阈值 500 N
```text
AA 55 11 00 00 FA 43 01
```
### 4.3 心跳帧
心跳帧固定 4 字节,基站以约 1 Hz 频率发送,用于活性检测。
| 字节偏移 | 字段 | 类型 | 值/范围 | 说明 |
|----------|------|------|---------|------|
| `0` | `sync0` | `uint8` | `0xAA` | 帧头第 1 字节 |
| `1` | `sync1` | `uint8` | `0x55` | 帧头第 2 字节 |
| `2` | `type` | `uint8` | `0x20` | 心跳包类型 |
| `3` | `counter` | `uint8` | `0-255` | 滚动计数 |
#### 示例
```text
AA 55 20 05
```
含义:心跳包,计数 `5`
## 5. 当前实现约束
- CoP 帧固定 17 字节,可在最小 ATT MTU 23(NUS 有效负载 20 字节)下传输。
- 50 Hz CoP 上行流隐式充当平衡板到基站的活性检测,因此心跳仅为下行。
- 传感器通道到物理位置的映射:MUX `{0x01, 0x23, 0x45, 0x67}` → FL/FR/BR/BL。
- `BOARD_HALF_WIDTH_MM = 200``BOARD_HALF_LENGTH_MM = 200`(后续可能调整)。
- `ADC_TO_FORCE_SCALE` 当前为占位值 `1.0f`,待 10 kg 砝码标定后修正。
- ARM Cortex-M33 为小端架构,`float32` 在 packed struct 中天然符合 Little Endian 要求。