Files
Vision/docs/底盘通信协议指南.md
dev01 0d40e0fabf docs: 文档整理,与前端对接文档.md 替换为 API.md + front-end_ROS.md
- 新增 docs/API.md(HTTP API 数据格式)
- 新增 docs/front-end_ROS.md(前端 ROS 话题格式)
- 新增 docs/底盘通信协议指南.md(底盘串口协议)
- 删除 docs/与前端对接文档.md
- 云台通信协议指南补充 0xA9 前馈帧说明
- 修正 README API 路径及 ROS 话题引用
- .gitignore 添加 workspace/data/
2026-06-07 13:54:07 +08:00

9.3 KiB
Executable File
Raw Permalink Blame History

串口通信协议

概述

  • 物理层: UART2,引脚 TX=B15 / RX=B16
  • 波特率: 115200 bps
  • 数据位: 8,无校验,1 停止位(默认 UART 配置)
  • 字节序: 多字节数值均采用小端序 (little-endian)
  • 校验方式: 累加和校验(checksum = 帧内校验位之前所有字节之和,截断为 uint8_t)
  • 软件 FIFO: 16 字节环形缓冲区,UART RX 中断中写入,主循环 command_task() 中解析

工作模式

系统有三种工作模式,通过命令帧切换:

模式 枚举值 说明 使能的控制环
自动模式 COMMAND_MODE_AUTO (0) 视觉追踪 / 全闭环 电机速度环 + 角度环 + 位置环
手动模式 COMMAND_MODE_MANUAL (1) 手动遥控 电机速度环 + 角度环
调试模式 COMMAND_MODE_DEBUG (2) PID 参数整定 无(所有控制环关闭)

数据帧定义

1. 命令帧 0xA7(3 字节)

切换工作模式。

┌────────┬───────┬──────────┐
│  SOF   │  cmd  │ checksum │
│ 0xA7   │  1 B  │   1 B    │
└────────┴───────┴──────────┘
偏移 长度 字段 类型 说明
0 1 SOF uint8_t 帧头,固定值 0xA7
1 1 cmd uint8_t 命令码
2 1 checksum uint8_t (0xA7 + cmd) & 0xFF

cmd 取值:

值 功能 对应函数
0x01 切换到自动模式 SwitchToAutoMode()
0x02 切换到手动模式 SwitchToManualMode()
0x03 切换到调试模式 SwitchToDebugMode()

示例(切换手动模式): A7 02 A9


2. 手动控制帧 0xA6(8 字节)

仅在手动模式下生效,用于实时控制底盘运动。

┌────────┬────────────────────┬─────────────────────┬──────────┐
│  SOF   │ motor_speed_base   │   angle_velocity    │ checksum │
│ 0xA6   │    int16_t (2 B)   │    float (4 B)      │   1 B    │
└────────┴────────────────────┴─────────────────────┴──────────┘
偏移 长度 字段 类型 说明
0 1 SOF uint8_t 帧头,固定值 0xA6
1 2 motor_speed_base int16_t (LE) 基础直行速度,范围 -50~+50
3 4 angle_velocity float (LE) 角度速率,单位 °/s
7 1 checksum uint8_t (0xA6 + 前 6 字节之和) & 0xFF

控制算法:

motor_speed_left_ref  = motor_speed_base - speed_dif
motor_speed_right_ref = motor_speed_base + speed_dif

其中 speed_dif 由角度环 PID 根据 yaw_ref 与当前 imu_angle.yaw 计算得出。手动模式下 yaw_ref 以 angle_velocity 速率持续累加:

yaw_ref += angle_velocity * dt    (dt = 0.02s)

3. 调试调参帧 0xA8(38 字节)

仅在调试模式下生效,一次性更新所有 PID 参数(Kp / Ki / Kd)。

┌────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┬──────────┐
│  SOF   │ Kp_speed │ Ki_speed │ Kd_speed │ Kp_yaw   │ Ki_yaw   │ Kd_yaw   │ Kp_pos   │ Ki_pos   │ Kd_pos   │ checksum │
│ 0xA8   │ float(4) │ float(4) │ float(4) │ float(4) │ float(4) │ float(4) │ float(4) │ float(4) │ float(4) │   1 B    │
└────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┴──────────┘
偏移 长度 字段 类型 说明
0 1 SOF uint8_t 帧头,固定值 0xA8
1 4 Kp_speed float (LE) 电机速度环比例系数(左右共用)
5 4 Ki_speed float (LE) 电机速度环积分系数
9 4 Kd_speed float (LE) 电机速度环微分系数
13 4 Kp_yaw float (LE) 角度环比例系数
17 4 Ki_yaw float (LE) 角度环积分系数
21 4 Kd_yaw float (LE) 角度环微分系数
25 4 Kp_position float (LE) 位置环比例系数
29 4 Ki_position float (LE) 位置环积分系数
33 4 Kd_position float (LE) 位置环微分系数
37 1 checksum uint8_t (0xA8 + 前 36 字节之和) & 0xFF

各环默认参数:

控制环 Kp Ki Kd 输出限幅 采样周期 优化环节
电机速度环(左/右) 300.0 150.0 0.0 ±3000 (MOTOR_MAX) 10ms —
角度环 1.0 0.0 0.0 ±25 (°/s) 20ms 偏航角误差修正
位置环 0.5 0.0 0.0 ±90 (°/s) 20ms —

注意:调试模式下所有控制任务已关闭,电机停转。修改参数后需切换到自动或手动模式才能观察效果。修改的参数直接写入 PID 实例的 Kp/Ki/Kd 字段,不清除积分等运行时状态。


4. 角度速率前馈帧 0xA9(6 字节)— MCU → PC

由 MCU 经 DMA 主动发送,上报位置环计算的角度速率,供云台等设备做前馈控制。

┌────────┬─────────────────────┬──────────┐
│  SOF   │   angle_velocity    │ checksum │
│ 0xA9   │    float (4 B)      │   1 B    │
└────────┴─────────────────────┴──────────┘
偏移 长度 字段 类型 说明
0 1 SOF uint8_t 帧头,固定值 0xA9
1 4 angle_velocity float (LE) 角度速率,单位 °/s
5 1 checksum uint8_t (0xA9 + 前 4 字节之和) & 0xFF

发送触发条件:位置环控制任务使能时,每 20ms(50Hz)在 position_control_task() 中调用 command_send_angle_velocity()。


通信流程

┌──────────┐                          ┌──────────┐
│   PC     │ ──── 0xA7 cmd ────────→ │  MSPM0   │
│ (上位机) │ ←─── 0xA9 feedback ──── │ (MCU)    │
│          │ ──── 0xA6 manual ─────→ │          │
│          │ ──── 0xA8 debug ──────→ │          │
└──────────┘                          └──────────┘

典型操作流程:

  1. 上电默认:自动模式,位置环+角度环+速度环全部使能
  2. 切换到手动模式:发送 A7 02 A9,然后周期发送 0xA6 控制帧驱动底盘
  3. PID 调参:发送 A7 03 AA 进入调试模式(电机停转),发送 0xA8 调参帧更新参数,再发 A7 01 A8 或 A7 02 A9 切换回运行模式观察效果

模式切换副作用

每次切换模式时,系统会执行以下操作:

操作 自动模式 手动模式 调试模式
设置 current_mode AUTO (0) MANUAL (1) DEBUG (2)
清除 PID 运行时状态 全部 4 个 PID 速度环+角度环 —
yaw_ref = 当前 imu_angle.yaw = 当前 imu_angle.yaw —
angle_velocity 归零 归零 —
motor_speed_ref 归零 归零 —
motor_speed_base = 10 (AUTO_MODE_BASE_SPEED) 归零 —
电机 PWM 归零 归零 归零
速度环使能 ✅ ✅ ❌
角度环使能 ✅ ✅ ❌
位置环使能 ✅ ❌ ❌
蜂鸣器 100ms 200ms 300ms

C 语言帧构造示例

#include <stdint.h>
#include <string.h>

// --- 构造 0xA7 命令帧 ---
void build_cmd_frame(uint8_t *buf, uint8_t cmd) {
    buf[0] = 0xA7;
    buf[1] = cmd;
    buf[2] = (uint8_t)(0xA7 + cmd);
    // 发送 buf, 长度 3
}

// --- 构造 0xA6 手动控制帧 ---
void build_manual_frame(uint8_t *buf, int16_t speed, float yaw_rate) {
    buf[0] = 0xA6;
    memcpy(&buf[1], &speed, 2);      // int16_t, 小端
    memcpy(&buf[3], &yaw_rate, 4);   // float, 小端
    uint8_t sum = 0xA6;
    for (int i = 1; i < 7; i++) sum += buf[i];
    buf[7] = sum;
    // 发送 buf, 长度 8
}

// --- 构造 0xA8 调试调参帧 ---
void build_debug_frame(uint8_t *buf, float kp_s, float ki_s, float kd_s,
                       float kp_y, float ki_y, float kd_y,
                       float kp_p, float ki_p, float kd_p) {
    buf[0] = 0xA8;
    memcpy(&buf[1],  &kp_s, 4);
    memcpy(&buf[5],  &ki_s, 4);
    memcpy(&buf[9],  &kd_s, 4);
    memcpy(&buf[13], &kp_y, 4);
    memcpy(&buf[17], &ki_y, 4);
    memcpy(&buf[21], &kd_y, 4);
    memcpy(&buf[25], &kp_p, 4);
    memcpy(&buf[29], &ki_p, 4);
    memcpy(&buf[33], &kd_p, 4);
    uint8_t sum = 0xA8;
    for (int i = 1; i < 37; i++) sum += buf[i];
    buf[37] = sum;
    // 发送 buf, 长度 38
}