chore: upgrade FreeRTOS to v2 (CMSIS-RTOS_V2), update CubeMX project config
- Remove CMSIS-RTOS v1 (cmsis_os.h/cmsis_os.c), add CMSIS-RTOS v2 (cmsis_os2.c/freertos_os2.h/mpool.h) - Update FreeRTOS kernel, port, and headers to match v2 integration - Remove unused heap implementations, keep heap_4 - Update CubeMX project config (.mxproject, .ioc, CMakeLists.txt) - Update FreeRTOSConfig.h, freertos.c, main.c, stm32h7xx_it.c - Update application modules (master_machine, dmmotor) - Add CMSIS-RTOS2 headers, mpu_syscall_numbers.h, newlib/picolibc support
This commit is contained in:
+228
-247
@@ -1,329 +1,310 @@
|
||||
# 项目架构分析报告:Basic_Framework_MC02 (RoboMaster 云台机器人)
|
||||
# 项目架构:Basic_Framework_MC02 (DM 云台控制系统)
|
||||
|
||||
## 概览
|
||||
|
||||
这是一个基于 **STM32H723** (Cortex-M7) 的 RoboMaster 竞赛机器人控制项目。项目采用 FreeRTOS 实时操作系统,目前配置为**单板控制整车**(`ONE_BOARD` 模式),代码组织呈分层架构。项目由 **湖南大学岳麓电气 (HNU YueLu EC)** 开发。
|
||||
基于 **STM32H723** (Cortex-M7, 480MHz) 的达妙电机云台控制系统。采用 FreeRTOS,通过 IMU 反馈实现角度闭环,通过串口接收上位机指令实现视觉追踪。项目源自 HNU YueLu EC RoboMaster 项目,经重构精简为纯云台控制。
|
||||
|
||||
---
|
||||
|
||||
## 一、硬件与通信总览
|
||||
## 一、硬件与通信
|
||||
|
||||
| 资源 | 用途 |
|
||||
|------|------|
|
||||
| **FDCAN1/2/3** | 电机控制总线(DJI 电机、达妙电机等) |
|
||||
| **USART1** | 板间通信 (BoardComm) |
|
||||
| **USART5** | 遥控器 (DBUS/DR16) |
|
||||
| **FDCAN1** | 电机控制总线 (DM-G6220 yaw, DM-J4310-2EC pitch) |
|
||||
| **USART10** | 上位机通信 (master_machine 协议) |
|
||||
| **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** | 电源控制、激光器等 |
|
||||
| **USART1** | 板间通信 (BoardComm) |
|
||||
| **SPI2** | BMI088 IMU 传感器 |
|
||||
|
||||
---
|
||||
|
||||
## 二、分层架构
|
||||
|
||||
项目采用 **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 │
|
||||
└──────────────────────────────────────────────────────────┘
|
||||
┌──────────────────────────────────────────────┐
|
||||
│ application/ 应用层 │
|
||||
│ robot.c → robot_cmd → gimbal │
|
||||
├──────────────────────────────────────────────┤
|
||||
│ modules/ 模块层 │
|
||||
│ motor, imu, master_machine, algorithm, ... │
|
||||
├──────────────────────────────────────────────┤
|
||||
│ bsp/ 板级支持包 │
|
||||
│ can, usart, spi, dwt, log, gpio │
|
||||
├──────────────────────────────────────────────┤
|
||||
│ Drivers/ HAL 驱动层 (CubeMX 生成) │
|
||||
│ STM32H7xx_HAL, CMSIS, FreeRTOS │
|
||||
└──────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、启动与初始化流程
|
||||
|
||||
### 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 任务中
|
||||
main()
|
||||
├── HAL_Init() → SystemClock_Config() → MX_*_Init() // CubeMX 外设初始化
|
||||
└── RobotInit()
|
||||
├── BSPInit() // DWT + Log
|
||||
├── RobotCMDInit() // pub-sub, 视觉PID, 串口初始化
|
||||
├── GimbalInit() // IMU + DM 电机初始化
|
||||
└── OSTaskInit() // 创建 4 个 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 任务架构
|
||||
### 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 | 模块看门狗喂狗检查 + 蜂鸣器控制 |
|
||||
| **INS Task** | 1kHz | AboveNormal | BMI088 读取 → 四元数 EKF 姿态解算 |
|
||||
| **Motor Task** | 1kHz | Normal | DM 电机角度 PID → CAN 速度指令发送 |
|
||||
| **Robot Task** | 500Hz | Normal | 上位机命令处理 + 模式切换 + 控制执行 |
|
||||
| **Daemon Task** | 100Hz | Normal | 模块看门狗 + 蜂鸣器 |
|
||||
|
||||
---
|
||||
|
||||
## 五、消息中心 (Pub-Sub)
|
||||
|
||||
位于 `modules/message_center/`,这是应用层内部的核心通信机制:
|
||||
|
||||
- **发布者 (Publisher)**:以**话题名 (topic name)** 标识,通过**链表**管理订阅者
|
||||
- **订阅者 (Subscriber)**:每个订阅者维护一个长度为 1 的 **FIFO 队列**
|
||||
- 支持最多 **12 个话题**,话题名最长 **32 字符**
|
||||
|
||||
### 当前消息流:
|
||||
## 四、PID 双环架构
|
||||
|
||||
```
|
||||
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)
|
||||
┌──────────────────────────────────────────────────────┐
|
||||
│ application/cmd/robot_cmd.c (外环, 500Hz) │
|
||||
│ │
|
||||
│ 上位机 0xA5 帧 → error_x/y → KF → vision PID │
|
||||
│ → 角度增量 → 累计 angle ref │
|
||||
│ 上位机 0xA6 帧 → yaw_ref/pitch_ref 直接设定 │
|
||||
│ │
|
||||
│ ProcessCommand() 处理模式切换 / 激光控制 │
|
||||
└──────────────────────┬───────────────────────────────┘
|
||||
│ gimbal_cmd (pub-sub)
|
||||
▼
|
||||
┌──────────────────────────────────────────────────────┐
|
||||
│ application/gimbal/gimbal.c (传递, 500Hz) │
|
||||
│ │
|
||||
│ DMMotorSetRef(yaw, cmd.yaw) │
|
||||
│ DMMotorSetRef(pitch, cmd.pitch) │
|
||||
│ 反馈: gimbal_feed → gimbal_IMU_data 指针 │
|
||||
└──────────────────────┬───────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────────────────────────────────────────┐
|
||||
│ modules/motor/DMmotor/ (内环, 1kHz) │
|
||||
│ │
|
||||
│ IMU 角度反馈 → angle PID → velocity output │
|
||||
│ → DMMotorSendVelocity() → CAN 速度模式 │
|
||||
│ output_reverse 控制输出方向 │
|
||||
└──────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、应用层模块
|
||||
## 五、上位机串口协议
|
||||
|
||||
### 6.1 RobotCMD (`application/cmd/`) — 机器人大脑
|
||||
位于 `modules/master_machine/`。三种帧类型,通过帧头区分。
|
||||
|
||||
核心决策模块,集成以下功能:
|
||||
### 自动/视觉追踪数据帧 `0xA5` (10 字节)
|
||||
|
||||
| 功能 | 说明 |
|
||||
| 字节 | 0 | 1-4 | 5-8 | 9 |
|
||||
|------|---|-----|-----|---|
|
||||
| 内容 | 0xA5 | error_x (float) | error_y (float) | checksum |
|
||||
|
||||
### 手动控制数据帧 `0xA6` (11 字节)
|
||||
|
||||
| 字节 | 0 | 1 | 2-5 | 6-9 | 10 |
|
||||
|------|---|-----|-----|-----|----|
|
||||
| 内容 | 0xA6 | zero_force | yaw_ref (float) | pitch_ref (float) | checksum |
|
||||
|
||||
### 命令帧 `0xA7` (3 字节)
|
||||
|
||||
| 字节 | 0 | 1 | 2 |
|
||||
|------|---|-----|----|
|
||||
| 内容 | 0xA7 | cmd | checksum |
|
||||
|
||||
命令码:`0x01` 切换到自动模式, `0x02` 切换到手动模式, `0x03` 激光开, `0x04` 激光关
|
||||
|
||||
### 数据流
|
||||
|
||||
```
|
||||
上位机 USART10 → DecodeVision() → vision_data (全局结构体)
|
||||
├── 0xA5 → auto_updated=1, error_x/y
|
||||
├── 0xA6 → manual_updated=1, zero_force, yaw_ref/pitch_ref
|
||||
└── 0xA7 → cmd_pending=1, cmd
|
||||
|
||||
robot_cmd 每轮:
|
||||
ProcessCommand() → 模式切换 / 激光
|
||||
AUTO: vision_data.error_x/y → KF → vision PID → 角度增量
|
||||
MANUAL: vision_data.yaw_ref/pitch_ref → 直接设定
|
||||
PubPushMessage(gimbal_cmd) → gimbal 执行
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、DM 电机驱动
|
||||
|
||||
位于 `modules/motor/DMmotor/`。基于 DM_6220 参考协议。
|
||||
|
||||
### 速度模式 (当前默认)
|
||||
|
||||
CAN ID = motor_id + 0x200,发送 float velocity (4 bytes)。
|
||||
|
||||
```
|
||||
DMMotorControl() @ 1kHz:
|
||||
PIDCalculate(angle_PID, IMU_angle, pid_ref) → velocity
|
||||
output_reverse? → DMMotorSendVelocity() → CAN
|
||||
```
|
||||
|
||||
### 电机配置
|
||||
|
||||
| 电机 | CAN ID | 反馈 ID | 模式 | MIT KP/KD |
|
||||
|------|--------|---------|------|-----------|
|
||||
| DM-G6220 (Yaw) | 0x01 | 0xF1 | Velocity | — |
|
||||
| DM-J4310-2EC (Pitch) | 0x02 | 0xF2 | Velocity | — |
|
||||
|
||||
### API
|
||||
|
||||
| 函数 | 说明 |
|
||||
|------|------|
|
||||
| **遥控器解析** | 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
|
||||
- 弹舱盖开关控制
|
||||
| `DMMotorInit()` | 初始化电机实例 (CAN 注册, PID 初始化, daemon) |
|
||||
| `DMMotorSetRef()` | 设定角度参考值 (degrees) |
|
||||
| `DMMotorControl()` | 1kHz 控制循环 (所有电机) |
|
||||
| `DMMotorSetMode()` | 发送命令 (使能/停止/清零/清除错误) |
|
||||
| `DMMotorSendVelocity()` | 速度模式 CAN 发送 |
|
||||
| `DMMotorSendMIT()` | MIT 模式 CAN 发送 |
|
||||
| `DMMotorSendPosVel()` | 位置-速度模式 CAN 发送 |
|
||||
|
||||
---
|
||||
|
||||
## 七、模块层 (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 底层读取 |
|
||||
| **电机** | `motor/DMmotor` | 达妙电机驱动 (MIT/PosVel/Velocity 三模式) |
|
||||
| | `motor/motor_task` | 电机控制统一调度 (`DMMotorControl`) |
|
||||
| **姿态** | `imu/ins_task` | 惯导解算 (四元数 EKF, 返回 INS_t 指针) |
|
||||
| | `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` | 超级电容管理 |
|
||||
| **算法** | `algorithm/controller` | PID 控制器 (梯形积分/变速积分/微分先行/输出滤波) |
|
||||
| | `algorithm/kalman_filter` | 卡尔曼滤波器 (自适应) |
|
||||
| | `algorithm/QuaternionEKF` | 四元数 EKF (陀螺零偏估计/卡方检验) |
|
||||
| | `algorithm/crc8/crc16` | CRC 校验 |
|
||||
| | `algorithm/user_lib` | 数学/工具函数 |
|
||||
| **通信** | `master_machine` | 上位机通信 (0xA5/0xA6/0xA7 协议, 接收+解析) |
|
||||
| | `timachine/board_comm` | 板间通信 |
|
||||
| | `message_center` | Pub-Sub 消息中间件 (链表, FIFO) |
|
||||
| **系统** | `daemon` | 看门狗 (重载计数+离线回调) |
|
||||
| | `alarm/buzzer` | 蜂鸣器 |
|
||||
| | `vofa` | VoFA+ 调试输出 |
|
||||
|
||||
---
|
||||
|
||||
## 八、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`) |
|
||||
| `bsp_dwt` | DWT 周期计数器 (μs/ms 延时, 时间戳) |
|
||||
| `bsp_can` | FDCAN 收发 (FIFO+中断) |
|
||||
| `bsp_usart` | 串口收发 (DMA+环形缓冲区) |
|
||||
| `bsp_spi` | SPI 通信 |
|
||||
| `bsp_log` | SEGGER RTT + 串口日志 |
|
||||
| `bsp_pwm` | PWM 输出 |
|
||||
|
||||
---
|
||||
|
||||
## 九、数据流与控制流总结
|
||||
## 九、数据流
|
||||
|
||||
```
|
||||
┌─────────────┐
|
||||
│ 遥控器DBUS │
|
||||
│ (USART5) │
|
||||
└──────┬──────┘
|
||||
↓
|
||||
┌──────────────┐
|
||||
│ 上位机 │
|
||||
│ (USART10) │
|
||||
└──────┬───────┘
|
||||
│ 0xA5 / 0xA6 / 0xA7
|
||||
▼
|
||||
┌────────────────────────┐
|
||||
│ RobotCMD │
|
||||
│ ┌─────────────────┐ │
|
||||
│ │ RemoteControlSet│ │ ← 手动模式 (遥控器调试)
|
||||
│ │ AutoSet (题号) │ │ ← 自动模式 (竞赛任务)
|
||||
│ └───────┬─────────┘ │
|
||||
│ ↓ │
|
||||
│ 发布: gimbal_cmd │──→ Gimbal (云台 PID → IMU 反馈)
|
||||
│ chassis_cmd │──→ Chassis (运动学 → 麦轮)
|
||||
│ shoot_cmd │──→ Shoot (摩擦轮/拨盘)
|
||||
│ ProcessCommand() │ ← 模式切换/激光
|
||||
│ VisionTrackingSet() │ ← KF → vision PID → 角度增量
|
||||
│ ManualModeSet() │ ← 直接角度参考
|
||||
│ PubPushMessage() │
|
||||
└───────────┬────────────┘
|
||||
│ gimbal_cmd
|
||||
▼
|
||||
┌────────────────────────┐
|
||||
│ Gimbal │
|
||||
│ DMMotorSetRef() │
|
||||
│ 反馈: gimbal_feed │ ← INS_t* 指针
|
||||
└───────────┬────────────┘
|
||||
│ angle ref
|
||||
▼
|
||||
┌────────────────────────┐
|
||||
│ DMMotor │ (1kHz Motor Task)
|
||||
│ IMU angle → PID │
|
||||
│ → Velocity mode CAN │
|
||||
└────────────────────────┘
|
||||
↑
|
||||
┌────────────┴───────────┐
|
||||
│ 反馈: gimbal_feed │ ← 云台姿态 + 电机角度
|
||||
│ chassis_feed │ ← 底盘速度 + 热量
|
||||
│ shoot_feed │ ← 发射状态
|
||||
│
|
||||
┌───────────┴────────────┐
|
||||
│ DM-G6220 DM-J4310 │
|
||||
│ (Yaw) (Pitch) │
|
||||
└────────────────────────┘
|
||||
|
||||
视觉/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. **条件编译**:单板/双板/电机类型/视觉通信方式均通过宏定义切换
|
||||
1. **IMU 反馈替代编码器** — 云台 Yaw/Pitch 使用 INS_t 中的 YawTotalAngle/Pitch 和 Gyro[]
|
||||
2. **速度模式控制** — MCU 跑角度 PID,电机内部处理速度闭环
|
||||
3. **伪 Pub-Sub** — 应用间通过 message_center 解耦
|
||||
4. **Daemon 看门狗** — 每个外设模块独立 DaemonInstance,离线自动回调
|
||||
5. **BSP 实例化注册** — CAN/串口不注册不初始化
|
||||
6. **KF + PID 级联** — 视觉误差经 KF 平滑 → vision PID → 角度增量 → 内环角度 PID
|
||||
7. **模式切换重置** — 切换到自动模式时重置 KF 状态 (x=0, P=diag(5,5)) 和 PID 积分项
|
||||
8. **串口命令控制** — 模式切换、激光控制均通过 0xA7 命令帧触发
|
||||
9. **output_reverse** — PID 输出方向统一通过单标志位控制
|
||||
|
||||
---
|
||||
|
||||
## 十一、项目规模统计
|
||||
## 十一、项目规模
|
||||
|
||||
| 类别 | 数量 |
|
||||
|------|------|
|
||||
| C 源文件 | 115 个 |
|
||||
| ASM 源文件 | 2 个 |
|
||||
| 应用层模块 | 4 (robot_cmd, gimbal, chassis, shoot) |
|
||||
| 模块层子模块 | 20+ (电机×6, 姿态×3, 算法×5, 通信×7, 辅助×5) |
|
||||
| BSP 驱动模块 | 10 |
|
||||
| FreeRTOS 任务 | 4 (默认) |
|
||||
| C 源文件 | 96 |
|
||||
| ASM 源文件 | 2 |
|
||||
| 应用层模块 | 3 (robot, robot_cmd, gimbal) |
|
||||
| 模块层子模块 | 10 (motor, imu, algorithm, master_machine, message_center, daemon, buzzer, vofa, board_comm) |
|
||||
| BSP 驱动模块 | 8 |
|
||||
| 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%) |
|
||||
| CPU 频率 | 480MHz |
|
||||
| FLASH 使用 | ~133 KB / 1 MB (13%) |
|
||||
| DTCMRAM 使用 | ~59 KB / 128 KB (46%) |
|
||||
|
||||
---
|
||||
|
||||
## 十二、电机配置速查
|
||||
|
||||
| 电机 | 类型 | 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)
|
||||
// INS 惯导实例 (ins_task.h)
|
||||
typedef struct {
|
||||
float q[4]; // 四元数
|
||||
float Gyro[3]; // 角速度 (rad/s)
|
||||
float Accel[3]; // 加速度 (m/s²)
|
||||
float Roll, Pitch, Yaw;
|
||||
float YawTotalAngle; // 多圈 yaw (degrees)
|
||||
} INS_t;
|
||||
|
||||
// 云台控制指令 (robot_def.h)
|
||||
typedef struct {
|
||||
float yaw; // yaw 目标角度 (degrees)
|
||||
float pitch; // pitch 目标角度 (degrees)
|
||||
} Gimbal_Ctrl_Cmd_s;
|
||||
|
||||
// 上位机数据 (master_machine.h)
|
||||
typedef struct {
|
||||
float error_x, error_y; // 自动模式: 归一化误差
|
||||
uint8_t auto_updated;
|
||||
uint8_t zero_force; // 手动模式: 零力标志
|
||||
float yaw_ref, pitch_ref; // 手动模式: 角度参考
|
||||
uint8_t manual_updated;
|
||||
uint8_t cmd, cmd_pending; // 命令
|
||||
float frequency;
|
||||
} VisionData_t;
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user