Files
Gimbal/ARCHITECTURE.md
T
2026-05-29 17:36:34 +08:00

330 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 项目架构分析报告:Basic_Framework_MC02 (RoboMaster 云台机器人)
## 概览
这是一个基于 **STM32H723** (Cortex-M7) 的 RoboMaster 竞赛机器人控制项目。项目采用 FreeRTOS 实时操作系统,目前配置为**单板控制整车**(`ONE_BOARD` 模式),代码组织呈分层架构。项目由 **湖南大学岳麓电气 (HNU YueLu EC)** 开发。
---
## 一、硬件与通信总览
| 资源 | 用途 |
|------|------|
| **FDCAN1/2/3** | 电机控制总线(DJI 电机、达妙电机等) |
| **USART1** | 板间通信 (BoardComm) |
| **USART5** | 遥控器 (DBUS/DR16) |
| **USART7** | VoFA 调试输出 |
| **USART10** | 视觉/上位机 (OpenCV 通信) |
| **SPI1/2** | BMI088 IMU 传感器、OLED |
| **I2C2** | 通用 I2C |
| **OCTOSPI2** | 外部 Flash (W25Qxx) |
| **TIM1/2/3/12** | PWM 输出、编码器输入、DWT 时钟基准 |
| **USB Device** | 虚拟串口 (CDC) |
| **ADC1** | 模拟量采集 |
| **GPIO** | 电源控制、激光器等 |
---
## 二、分层架构
项目采用 **4 层架构**:
```
┌──────────────────────────────────────────────────────────┐
│ application/ 应用层 │
│ robot.c → robot_cmd → gimbal / chassis / shoot │
├──────────────────────────────────────────────────────────┤
│ modules/ 模块层 │
│ motor, imu, referee, remote, vision, algorithm, ... │
├──────────────────────────────────────────────────────────┤
│ bsp/ 板级支持包 │
│ can, usart, spi, iic, pwm, dwt, log, gpio │
├──────────────────────────────────────────────────────────┤
│ Drivers/ HAL 驱动层 (CubeMX 生成) │
│ STM32H7xx_HAL, CMSIS, FreeRTOS, USB, SEGGER RTT │
└──────────────────────────────────────────────────────────┘
```
---
## 三、启动与初始化流程
### 3.1 main() 启动序列
```
HAL_Init() → SystemClock_Config() → MX_GPIO_Init() → MX_DMA_Init()
→ MX_ADC1_Init() → MX_USB_DEVICE_Init() → MX_TIM/SPI/USART/UART/FDCAN/..._Init()
→ RobotInit() ← 唯一的用户初始化入口
→ while(1) {} ← 空循环,所有逻辑在 RTOS 任务中
```
### 3.2 RobotInit() 初始化链
```
RobotInit()
├── __disable_irq() // 关中断,保证初始化原子性
├── BSPInit()
│ ├── DWT_Init(480) // 时钟周期计数器 (CPU=480MHz)
│ └── BSPLogInit() // 日志系统(SEGGER RTT + 串口)
├── RobotCMDInit() // 核心命令任务初始化
│ ├── RemoteControlInit(&huart5) // 遥控器 (DBUS)
│ ├── PubRegister() x6 // 注册 6 个消息话题:
│ │ gimbal_cmd / gimbal_feed // 云台控制/反馈
│ │ shoot_cmd / shoot_feed // 发射控制/反馈
│ │ chassis_cmd / chassis_feed // 底盘控制/反馈
│ ├── PIDInit() x2 (yaw + pitch 跟踪PID) // 视觉跟踪 PID 初始化
│ ├── VisionKalmanFilterInit() // 视觉误差卡尔曼滤波器
│ ├── Vision_Uart_Init(&huart10) // 视觉串口通信
│ └── BoardCommInit(&huart1) // 板间通信
├── GimbalInit() // 云台电机初始化
│ ├── INS_Init() → BMI088 SPI 初始化 // IMU 惯导
│ ├── PubRegister("gimbal_feed") / SubRegister("gimbal_cmd")
│ ├── DJIMotorInit(GM6020) → yaw 电机 // Yaw: GM6020 直驱
│ └── DMMotorInit() → pitch 电机 // Pitch: 达妙电机
├── OSTaskInit() // 创建 RTOS 任务
│ ├── INS Task (1kHz, AboveNormal) // 姿态解算最高优先级
│ ├── Motor Task (1kHz, Normal) // 电机控制
│ ├── Daemon Task (100Hz, Normal) // 看门狗/蜂鸣器
│ ├── Robot Task (500Hz, Normal) // 机器人核心控制
│ └── DMMotorControlInit() // 达妙大电机初始化
└── __enable_irq() // 开中断
```
---
## 四、FreeRTOS 任务架构
| 任务 | 频率 | 优先级 | 功能 |
|------|------|--------|------|
| **INS Task** | 1kHz | AboveNormal | 阻塞读取 BMI088,进行四元数 EKF 姿态解算 |
| **Motor Task** | 1kHz | Normal | DJI/LK/HT 电机 PID 闭环计算与 CAN 发送 |
| **Robot Task** | 500Hz | Normal | 调用 `RobotTask()` 串联各应用层任务 |
| **Daemon Task** | 100Hz | Normal | 模块看门狗喂狗检查 + 蜂鸣器控制 |
---
## 五、消息中心 (Pub-Sub)
位于 `modules/message_center/`,这是应用层内部的核心通信机制:
- **发布者 (Publisher)**:以**话题名 (topic name)** 标识,通过**链表**管理订阅者
- **订阅者 (Subscriber)**:每个订阅者维护一个长度为 1 的 **FIFO 队列**
- 支持最多 **12 个话题**,话题名最长 **32 字符**
### 当前消息流:
```
robot_cmd (CMD) ──→ gimbal_cmd ──→ gimbal 应用
├── chassis_cmd → chassis 应用
└── shoot_cmd ──→ shoot 应用
gimbal ──→ gimbal_feed ──→ robot_cmd (CMD)
chassis ──→ chassis_feed ──→ robot_cmd (CMD)
shoot ──→ shoot_feed ──→ robot_cmd (CMD)
```
---
## 六、应用层模块
### 6.1 RobotCMD (`application/cmd/`) — 机器人大脑
核心决策模块,集成以下功能:
| 功能 | 说明 |
|------|------|
| **遥控器解析** | DBUS 协议,摇杆/开关/键鼠 |
| **视觉跟踪** | OpenCV 视觉数据 → 卡尔曼滤波 → PID 跟踪 → 云台角度控制 |
| **画圆模式** | 遥控器拨轮控制画圆轨迹跟踪 |
| **题号状态机** | 竞赛自动任务状态机,支持 6 种题号,含转向/搜索/跟踪子状态 |
| **急停处理** | 遥控器右侧开关拨下 → 所有电机零力输出 |
| **激光控制** | GPIO 控制激光笔开关 |
`RobotCMDTask()` 执行流程(500Hz):
```
读取底盘/发射/云台反馈消息 → 判断控制模式(手动/自动/视觉)
→ EmergencyHandler(急停检测) → 推送控制消息给各应用
```
**题号状态机** (YunTaiState):
```
YUNT_IDLE
→ NO1: 零力模式
→ NO2: 视觉跟踪 + 激光 (等待1.5s后开启激光)
→ NO3: 转向0度 → 视觉跟踪/搜索 → 激光 (3.5s后)
→ NO4_1: 转向-45度 → 视觉跟踪 + 前馈
→ NO4_3: 转向-45度 → 视觉跟踪 (error=60) + 画圆前馈
```
### 6.2 Gimbal (`application/gimbal/`) — 云台控制
- **Yaw 轴**:GM6020 (DJI 直驱电机),CAN1 ID=0x01,IMU 反馈替代电机编码器
- **Pitch 轴**:达妙电机 (DM Motor),CAN1 ID=0x06/0x16,IMU 反馈
- **控制模式**:
- `GIMBAL_ZERO_FORCE`:零力
- `GIMBAL_GYRO_MODE`:陀螺仪姿态闭环 (使用 IMU Pitch + YawTotalAngle)
- **特点**:角度/角速度反馈均来自 IMU(替代电机编码器),带有速度和电流前馈
### 6.3 Chassis (`application/chassis/`) — 底盘控制
- 麦克纳姆轮底盘 (Mecanum),4x GM6020 电机
- 运动学解算:正逆运动学,云台→底盘坐标系变换
- 支持裁判系统功率限制和超级电容管理
### 6.4 Shoot (`application/shoot/`) — 发射控制
- **摩擦轮**:2x M3508 (CAN2 ID=1,2),速度串联电流闭环
- **拨盘电机**:M2006 (CAN2 ID=3),多模式:
- `LOAD_STOP`:停止
- `LOAD_1_BULLET`:单发(角度闭环,加减角度 = ONE_BULLET_DELTA_ANGLE)
- `LOAD_3_BULLET`:三连发
- `LOAD_BURSTFIRE`:连发(速度闭环,可调射频)
- `LOAD_REVERSE`:反转
- **弹速模式**:15m/s / 18m/s / 30m/s
- 弹舱盖开关控制
---
## 七、模块层 (modules/)
| 分类 | 模块 | 功能 |
|------|------|------|
| **电机** | `dji_motor` | DJI GM6020/M3508/M2006 标准电机驱动,串级 PID (角度→速度→电流) |
| | `DMMotor` | 达妙电机 (DM Motor) 驱动 |
| | `LKmotor` (LK9025) | LK 电机驱动 |
| | `HTmotor` (HT04) | HT04 电机驱动 |
| | `step_motor` | 步进电机 (含 X_V2 变体) |
| | `servo_motor` | 舵机控制 |
| | `motor_task` | 电机控制统一调度 (`MotorControlTask`) |
| **姿态** | `imu/ins_task` | 惯导解算:四元数 EKF,BMI088 传感器 |
| | `imu/BMI088driver` | BMI088 SPI 底层读取 |
| | `imu/BMI088Middleware` | BMI088 数据换算 |
| **算法** | `controller` | 通用 PID 控制器(支持变积分、梯形积分、微分先行、输出滤波等改进) |
| | `kalman_filter` | 标准卡尔曼滤波器 + 自适应 (`UseAutoAdjustment`) |
| | `QuaternionEKF` | 四元数扩展卡尔曼滤波 |
| | `crc8/crc16` | CRC 校验 |
| | `user_lib` | 通用数学/工具函数 |
| **通信** | `remote/remote_control` | DJI DBUS 遥控器解析 (位域优化) |
| | `master_machine` | 视觉上位机通信 (SeaSky 协议) |
| | `referee` | 裁判系统 (RM Referee Protocol, UI 绘制) |
| | `can_comm` | CAN 通信抽象层(双板情况下的数据转发) |
| | `board_comm` | 板间通信(固定帧格式: 帧头 + 2x int32 + 2x float + 校验) |
| | `bluetooth/HC05` | HC05 蓝牙模块 |
| | `opencv` | OpenCV 视觉数据处理 |
| **辅助** | `message_center` | Pub-Sub 消息中间件(伪发布订阅,仅做应用间隔离) |
| | `daemon` | 看门狗守护进程(在线检测 + 异常回调) |
| | `alarm/buzzer` | 蜂鸣器告警 |
| | `vofa` | 调试数据可视化 (VoFA+ FireWater) |
| | `oled` | OLED 显示屏 |
| | `super_cap` | 超级电容管理 |
---
## 八、BSP 驱动层
所有 BSP 驱动采用**实例化注册**模式(不注册不初始化):
| 模块 | 功能 |
|------|------|
| `bsp_dwt` | DWT 时钟周期计数器(精确延时 μs/ms,时间戳获取) |
| `bsp_can` | CAN 总线收发封装(FIFO+中断,实例化注册) |
| `bsp_usart` | 串口收发封装(DMA+环形缓冲区,实例化注册) |
| `bsp_spi` | SPI 通信封装 |
| `bsp_iic` | I2C 通信封装 |
| `bsp_pwm` | PWM 输出(支持 DMA 传输) |
| `bsp_gpio` | GPIO 管理 |
| `bsp_log` | SEGGER RTT + 串口日志输出(LOGINFO/LOGERROR/LOGWARNING) |
| `bsp_tools` | RTOS 任务创建工具 (`CreateCallbackTask`) |
---
## 九、数据流与控制流总结
```
┌─────────────┐
│ 遥控器DBUS │
│ (USART5) │
└──────┬──────┘
↓
┌────────────────────────┐
│ RobotCMD │
│ ┌─────────────────┐ │
│ │ RemoteControlSet│ │ ← 手动模式 (遥控器调试)
│ │ AutoSet (题号) │ │ ← 自动模式 (竞赛任务)
│ └───────┬─────────┘ │
│ ↓ │
│ 发布: gimbal_cmd │──→ Gimbal (云台 PID → IMU 反馈)
│ chassis_cmd │──→ Chassis (运动学 → 麦轮)
│ shoot_cmd │──→ Shoot (摩擦轮/拨盘)
└────────────────────────┘
↑
┌────────────┴───────────┐
│ 反馈: gimbal_feed │ ← 云台姿态 + 电机角度
│ chassis_feed │ ← 底盘速度 + 热量
│ shoot_feed │ ← 发射状态
└────────────────────────┘
视觉/OpenCV (USART10) ──→ 卡尔曼滤波 ──→ PID ──→ 云台角度控制
板间通信 (USART1) ──→ BoardComm ──→ 题号/坐标数据
裁判系统 ──→ 热量/弹速/UI 绘制
```
---
## 十、关键设计特点
1. **IMU 替代电机反馈**:云台 Yaw/Pitch 使用陀螺仪角度/角速度替代编码器,实现更高精度姿态闭环
2. **伪 Pub-Sub 模式**:应用间通过 `message_center` 解耦,支持单板/双板条件编译切换(`ONE_BOARD` / `GIMBAL_BOARD` / `CHASSIS_BOARD`)
3. **Daemon 看门狗**:每个外设模块注册独立的 `DaemonInstance`(重载计数 + 离线回调),模块离线时自动触发异常处理
4. **BSP 实例化注册**:CAN/串口等外设不注册不初始化,避免资源浪费
5. **竞赛状态机**:完整的题号自动任务流程(转向→搜索→跟踪→激光打击)
6. **卡尔曼滤波 + PID 级联**:视觉误差经过 KF 平滑后由 PID 计算输出,带前馈补偿
7. **位域优化**:遥控器键盘状态使用位域 (`Key_t`),空间减少 8 倍
8. **条件编译**:单板/双板/电机类型/视觉通信方式均通过宏定义切换
---
## 十一、项目规模统计
| 类别 | 数量 |
|------|------|
| C 源文件 | 115 个 |
| ASM 源文件 | 2 个 |
| 应用层模块 | 4 (robot_cmd, gimbal, chassis, shoot) |
| 模块层子模块 | 20+ (电机×6, 姿态×3, 算法×5, 通信×7, 辅助×5) |
| BSP 驱动模块 | 10 |
| FreeRTOS 任务 | 4 (默认) |
| 最高控制频率 | 1kHz |
| CPU 频率 | 480MHz (PLL = HSE 8MHz / 2 × 40 / 2) |
| FLASH 使用 | 161,556 B / 1 MB (15.41%) |
| DTCMRAM 使用 | 60,920 B / 128 KB (46.48%) |
---
## 十二、电机配置速查
| 电机 | 类型 | CAN 总线 | TX ID | 控制闭环 | PID 级联 |
|------|------|----------|-------|----------|----------|
| Yaw (云台) | GM6020 | CAN1 | 0x01 | 角度+速度 | Angle → Speed (IMU 反馈) |
| Pitch (云台) | DM Motor | CAN1 | 0x06/0x16 | 角度+速度 | Angle → Speed (IMU 反馈) |
| 摩擦轮 左 | M3508 | CAN2 | 0x01 | 速度+电流 | Speed → Current |
| 摩擦轮 右 | M3508 | CAN2 | 0x02 | 速度+电流 | Speed → Current (反转) |
| 拨盘 | M2006 | CAN2 | 0x03 | 角度/速度+电流 | Angle/Speed → Current |
---
## 十三、关键配置宏 (`robot_def.h`)
```c
#define ONE_BOARD // 单板控制整车
#define VISION_USE_UART // 使用串口发送视觉数据
#define YAW_CHASSIS_ALIGN_ECD 2711 // 云台底盘对齐编码器值
#define PITCH_HORIZON_ECD 3412 // 云台水平位置编码器值
#define ONE_BULLET_DELTA_ANGLE 36 // 单发弹丸拨盘转动角度
#define WHEEL_BASE 350 // 纵向轴距 (mm)
#define TRACK_WIDTH 300 // 横向轮距 (mm)
#define RADIUS_WHEEL 60 // 轮子半径 (mm)
```