news 2026/7/23 18:11:09

2025电赛E题_简易自行瞄准装置_STM32F103RCT6方案详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
2025电赛E题_简易自行瞄准装置_STM32F103RCT6方案详解

2025 电赛 E 题「简易自行瞄准装置」全流程复盘:STM32F103RCT6 + K230 + 双轴无刷云台 + 陀螺仪前馈

关键词:2025电赛E题简易自行瞄准装置STM32F103RCT6K230视觉无刷云台PID陀螺仪前馈
适用人群:备赛 / 复盘 / 想快速搭一套“视觉闭环瞄准”系统的同学
主控工程:基于 STM32F103RCT6 标准库(Keil)


一、题目在考什么?先把需求拆开

2025 年 TI 杯全国大学生电子设计竞赛E 题:简易自行瞄准装置,本质是一道“视觉感知 + 两轴运动控制 + 实时闭环”的系统题。

把赛题抽象成工程语言,大致就是:

能力项工程含义
识别目标摄像头/视觉模组给出目标在图像中的坐标
指示落点激光点也要能被识别,作为“当前瞄准点”
二维瞄准水平轴 + 俯仰轴联动,把激光点压到目标上
动态跟踪目标移动时,系统仍能持续对准
可调可测参数可改、状态可看,方便赛场调试

核心控制问题只有一句话:

让图像里的“激光点 (laser)”不断逼近“目标点 (target)”

这和传统“把电机转到某角度”不同——你控制的是图像坐标系里的误差,电机只是执行器。


二、总体方案:我们选了什么,为什么

2.1 硬件架构

┌─────────────┐ 目标/激光画面 → │ K230 视觉 │──USART1(115200)──┐ └─────────────┘ │ ▼ ┌──────────────┐ USART3(115200) ┌──────────────────────────┐ │ 单轴陀螺仪 │ ─────────────────► │ STM32F103RCT6 │ └──────────────┘ │ 视觉PID + 陀螺前馈 │ │ TIM3: 20ms 控制周期 │ ┌──────────────┐ UART4(9600) │ │ │ USB-TTL调参 │ ◄────────────────► │ 遥测/在线改 PID 参数 │ └──────────────┘ └────────────┬─────────────┘ │ USART2 115200 ┌────────────┴────────────┐ │ 串口协议无刷驱动器 │ │ Motor1(水平) Motor2(俯仰)│ └─────────────────────────┘

2.2 选型理由(电赛场景更在意“稳、快、可调”)

模块选型理由
主控STM32F103RCT6外设多(4 路串口很香)、资料多、调试成熟
视觉K230算力够用,识别目标/激光后只发坐标,减轻 MCU 负担
执行双轴无刷云台(串口协议型)驱动器内置换相/闭环,MCU 发速度指令即可
姿态单轴 MEMS 陀螺仪给水平轴做角速度前馈,改善“追不上/晃”的问题
人机OLED / 按键(可选)+ UART4 调参赛场最快的调参方式是串口一行指令

2.3 控制策略总览(方案 A)

本工程采用:

[
v_x = \mathrm{PID}x(target_x, laser_x) + K{ff}\cdot S\cdot (-\omega_z)
]
[
v_y = \mathrm{PID}_y(target_y, laser_y)
]

  • 视觉位置环:激光点当反馈,目标点当设定
  • 陀螺角速度前馈:主要补偿水平方向上的扰动/机架旋转
  • 速度模式驱动无刷:控制量直接是电机目标速度,响应比“位置层层嵌套”更直接

一句话总结:

闭环靠视觉,动态靠前馈,执行靠速度模式无刷。


三、软件工程结构(RCT6 工程怎么拆)

推荐按“硬件驱动 + 算法 + 应用”分层,本工程大致如下:

rct6_E/ ├─ User/ │ └─ main.c # 系统初始化、主循环、TIM3 控制中断 ├─ Hardware/ │ ├─ k230_parser.* # K230 串口协议解析 │ ├─ bldc_motor.* # 无刷串口驱动(组帧/使能/速度/位置) │ ├─ mems_sensor.* # 单轴陀螺协议解析 │ ├─ pid.* # 位置式 PID │ ├─ uart.* # USART1/3/4 │ ├─ timer.* # TIM3 20ms 节拍 │ └─ OLED / Key / LED # 调试辅助 ├─ Library/ Start/ System/ # 标准库与启动文件

模块职责要清晰
解析协议的别掺 PID,PID 别掺串口寄存器操作。后期改视觉协议或换电机时,改动面最小。


四、串口资源分配(RCT6 的关键一刀)

STM32F103RCT6 串口资源较富,正好把四类通信拆开:

串口引脚波特率功能
USART1PA9/PA10115200K230 视觉坐标
USART2PA2/PA3115200双无刷驱动总线
USART3PB10/PB11115200单轴陀螺仪
UART4PC10/PC119600上位机调参 / 遥测

中断优先级建议(本工程实际配置思路):

  1. USART1(视觉)最高—— 坐标丢包直接等于“瞎了”
  2. USART2 / USART3 次之 —— 电机与陀螺
  3. UART4 最低 —— 调参可以慢一点
  4. TIM3 控制中断也要低于视觉接收,避免“算 PID 时把串口顶飞”

五、K230 视觉链路:只给 MCU 最需要的东西

5.1 设计原则

视觉端负责“看”,主控负责“追”。
K230 不要往 MCU 塞图像,只发:

  • 目标点坐标 ((x_1, y_1))
  • 激光点坐标 ((x_2, y_2))
  • (可选)距离/深度 (z)

5.2 通信协议(状态机解析)

本工程k230_parser采用帧头 + 数据 + 帧尾的短帧:

类型帧格式含义
目标0xFF + XH XL YH YL + 0xFE目标点 (x1,y1)
激光0xFD + XH XL YH YL + 0xFC激光点 (x2,y2)
Z 值0xFB + ZH ZL + 0xFA可选深度

坐标均为大端 int16

解析核心逻辑(概念伪码):

// type=1: 目标; type=2: 激光; type=3: Z// 收到完整合法帧后:g_rect_data.x1/y1 或 x2/y2 或 z 更新;g_rect_data.type=current_type;g_rect_data.is_updated=1;

5.3 主循环如何消费视觉数据

主循环只做“取最新坐标 + 清标志 + 偶尔发遥测”,不在主循环里控电机

if(g_rect_data.is_updated==1){s_vision_age_ticks=0;// 刷新“视觉新鲜度”if(g_rect_data.type==1){target_x=g_rect_data.x1;target_y=g_rect_data.y1;}elseif(g_rect_data.type==2){laser_x=g_rect_data.x2;laser_y=g_rect_data.y2;}// 降频遥测...g_rect_data.is_updated=0;}

5.4 视觉丢失保护(非常重要)

TIM3 每 20ms 把s_vision_age_ticks++
若连续约5 个周期(≈100ms)都没有新视觉帧:

  • PID_Reset清空积分,防止“瞎了还猛冲”
  • 双轴速度置 0,安全停车

赛场上灯光一变、识别丢几帧很常见,没有丢帧保护等于定时炸机


六、无刷云台驱动:串口协议 + 速度模式

6.1 为什么选“串口一体无刷”

电赛四天三夜,时间极紧。串口协议型驱动器的好处:

  • 换相、电流环/速度环很多已经在驱动板里
  • MCU 侧更像“发指令的上位机”
  • 双电机可挂同一 UART 总线,靠 ID 区分

6.2 帧格式

帧头 0x7A | ID | CMD | 数据区 | BCC(异或) | 帧尾 0x7B BCC = 从帧头到数据末字节逐字节 XOR

常用指令(以本工程为准,具体仍以电机手册为准):

CMD功能
0x00设置模式
0x01设置速度
0x02设置位置
0x06使能
0x07设置加速度
0x0E请求位置反馈

接收侧可用DMA + USART 空闲中断(IDLE)抓完整反馈帧,解析出Current_Position

6.3 上电初始化顺序(建议照这个来)

BLDC_Enable(id);BLDC_Set_Mode(id,0);// 本方案瞄准时用速度模式BLDC_Set_Acceleration(id,50);// 加速度别太大,云台更柔顺

双电机(Motor1 / Motor2)分别对应水平轴与俯仰轴,ID 必须与驱动器拨码一致

6.4 速度模式下发

控制周期里最终只做:

BLDC_Set_Speed(Motor1.ID,(int)out_speed_x);BLDC_Set_Speed(Motor2.ID,(int)out_speed_y);

注意:两帧之间可加极短延时(如 2ms),避免总线抢发导致偶发丢指令。


七、核心算法:视觉 PID + 陀螺前馈

7.1 控制节拍:TIM3 = 20ms

// 72MHz, psc=7200-1, arr=200-1 → 20ms (50Hz)Timer3_Init(200-1,7200-1);

固定周期是 PID 能复现、能调的前提。不要在主循环里随缘算 PID

7.2 位置式 PID(带限幅)

位置式 PID 公式:

[
u(k)=K_p e(k)+K_i\sum e + K_d\bigl(e(k)-e(k-1)\bigr)
]

工程上必须有两道“保险丝”:

  1. 积分限幅(Anti-windup):防止卡死/丢目标后积分爆掉
  2. 输出限幅:把速度指令限制在驱动器可接受范围

本工程默认参数示例(一定要按你的云台/镜头重调):

KpKiKd输出限幅
X(水平)0.100.0020±150
Y(俯仰)-0.0900±150

Y 轴 Kp 为负,是因为图像坐标方向与电机正方向可能相反
方向反了先改符号,再谈调参,不然会越追越远。

7.3 误差定义(别搞反)

PID_SetTarget(&pid_x,target_x);// 目标out_speed_x=PID_Calc(&pid_x,laser_x);// 反馈=激光点

即:

[
e_x = target_x - laser_x
]

语义是:激光偏左就往右赶,偏上就往下赶(再叠加电机方向符号)。

7.4 陀螺仪前馈(方案 A 的加分项)

协议简述

单轴陀螺串口帧:

0x5A | TYPE | DataL | DataH | SUM TYPE=0xAA → 角速度 gyro_z (°/s),raw/32768*2000 TYPE=0xBB → 偏航角 yaw (°),raw/32768*180 SUM = 前面字节累加和低 8 位
为什么要前馈?

纯视觉闭环有延迟:

曝光/推理 → 串口 → PID → 电机动作

当底座晃动、目标快速横向移动时,视觉环容易“慢半拍”。
陀螺测的是机体/云台水平旋转角速度,可以提前给出补偿速度:

gyro_rate=s_gyro_z_filt-s_gyro_bias;if(fabs(gyro_rate)<GYRO_DEADZONE_DPS)gyro_rate=0;// 死区去抖v_ff=GYRO_FF_GAIN*GYRO_FF_SIGN*gyro_rate;out_speed_x=clamp(out_speed_x+v_ff,-SPEED_OUT_LIMIT,SPEED_OUT_LIMIT);

关键参数:

参数示例作用
GYRO_FF_GAIN0.10前馈强度
GYRO_FF_SIGN-1方向匹配(装反就改符号)
GYRO_DEADZONE_DPS8°/s静止噪声抑制
GYRO_LPF_ALPHA0.35一阶低通,降噪

上电建议:

  1. 解锁陀螺
  2. 发送 Z 轴置零指令
  3. 静止采样约 800ms 估计零偏s_gyro_bias

前馈不是越大越好:过大云台会“发飘”,应在视觉环基本稳后再微调 (K_{ff})。


八、调参与遥测:赛场救命功能

8.1 UART4 遥测格式

一行 ASCII(约每 N 帧视觉更新上报一次):

T,tx,ty,A,ax,ay,PX,0.100,IX,0.002,DX,0.000,PY,-0.090,IY,0.000,DY,0.000

含义:

  • T,tx,ty:目标坐标
  • A,ax,ay:激光(Aim)坐标
  • PX/IX/DXPY/IY/DY:当前 PID 六参数

8.2 在线改参

通过串口助手下发(示例):

PX=0.12 IX=0.003 PY=-0.10 LIST

主循环里UART4_PollTune()解析即可,不必每次改参都重新编译烧录
电赛调试效率,有时比算法本身更决定上限。

8.3 一套可复制的调参顺序

  1. 先对方向:手动拨目标,看激光是否朝正确方向追
  2. 只开 P:从小到大,直到响应够快但不剧烈震荡
  3. 加一点 I:消除稳态偏差(长期差几像素)
  4. D 慎用:视觉噪声大时 D 容易放大抖动
  5. 最后加陀螺前馈:先符号,后增益
  6. 加输出限幅与丢帧停车,保证安全

经验口诀:

先正方向,再调 P,I 消静差,D 看噪声,前馈补动态。


九、主程序时序(从开机到闭环)

上电 ├─ NVIC 分组、四路串口初始化 ├─ 陀螺解锁 / Z 轴置零 ├─ 双电机 Enable → Mode(速度) → Acceleration ├─ 陀螺零偏标定(静止采样) ├─ PID_Init(X/Y) ├─ TIM3 启动(20ms 控制中断) └─ while(1) ├─ 陀螺一阶低通 ├─ UART4 调参轮询 └─ 消费 K230 最新坐标 + 遥测 TIM3_IRQ (20ms) ├─ 视觉超时? → PID复位 + 双轴速度0 └─ 否则: ├─ PID_X / PID_Y ├─ 陀螺前馈叠加到 X └─ BLDC_Set_Speed(Motor1/2)

十、关键代码片段(可直接对照工程)

10.1 控制中断核心

voidTIM3_IRQHandler(void){if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET){if(s_vision_age_ticks>=VISION_LOST_TICKS){PID_Reset(&pid_x);PID_Reset(&pid_y);BLDC_Set_Speed(Motor1.ID,0);BLDC_Set_Speed(Motor2.ID,0);TIM_ClearITPendingBit(TIM3,TIM_IT_Update);return;}PID_SetTarget(&pid_x,target_x);PID_SetTarget(&pid_y,target_y);out_speed_x=PID_Calc(&pid_x,laser_x);out_speed_y=PID_Calc(&pid_y,laser_y);gyro_rate=s_gyro_z_filt-s_gyro_bias;if(gyro_rate>-GYRO_DEADZONE_DPS&&gyro_rate<GYRO_DEADZONE_DPS)gyro_rate=0.0f;v_ff=GYRO_FF_GAIN*GYRO_FF_SIGN*gyro_rate;out_speed_x=clampf(out_speed_x+v_ff,-SPEED_OUT_LIMIT,SPEED_OUT_LIMIT);BLDC_Set_Speed(Motor1.ID,(int)out_speed_x);BLDC_Set_Speed(Motor2.ID,(int)out_speed_y);TIM_ClearITPendingBit(TIM3,TIM_IT_Update);}}

10.2 PID 计算核心(位置式 + 双限幅)

floatPID_Calc(PID_TypeDef*pid,floatactual_val){pid->actual=actual_val;pid->error=pid->target-pid->actual;pid->integral+=pid->error;// 积分限幅 ...pid->output=pid->kp*pid->error+pid->ki*pid->integral+pid->kd*(pid->error-pid->last_error);pid->last_error=pid->error;// 输出限幅 ...returnpid->output;}

十一、调试清单(建议打印贴桌上)

硬件

  • 所有模块共地
  • 电机驱动供电功率足够,避免电压塌陷
  • 串口 TX/RX 交叉正确,波特率一致
  • 云台机械无死点、激光与摄像头相对固定

视觉

  • 固定曝光/白平衡(赛场灯光变化大)
  • 目标与激光都能稳定出框,坐标不乱跳
  • 图像中心与云台零位大致标定

控制

  • 先单轴再双轴
  • 确认 X/Y 方向符号
  • 丢帧后能停
  • 输出限幅生效,电机不狂转
  • 陀螺静止时前馈≈0(零偏与死区)

系统

  • 中断优先级:视觉 > 电机/陀螺 > 控制/调参
  • 控制周期稳定(用示波器/GPIO 翻转看 TIM3)
  • UART4 能看到 T/A 坐标随动

十二、常见问题与对策

现象可能原因处理
越追越远坐标轴/电机方向反了改 Kp 符号或电机正方向
来回抖P 过大 / 视觉噪声 / D 过大降 P,滤坐标,D 置 0
总差几像素I 不够或有机械间隙略增 I,检查安装
快速跟丢纯视觉延迟加陀螺前馈、提高视觉帧率
偶发乱飞丢帧未保护 / 积分饱和丢帧停车 + 积分限幅
电机不转未使能 / 模式不对 / ID 错查 Enable、Mode、拨码
串口错乱优先级/重入/缓冲不够调 NVIC,缩短中断处理

十三、可扩展与加分方向(有余力再做)

  1. 坐标低通 / 中值滤波:抑制视觉毛刺
  2. 变结构 PID:大误差时主用 P,小误差时加 I
  3. 前馈自适应:根据 (|e|) 或目标速度调整 (K_{ff})
  4. 俯仰轴也做辅助传感(若有双轴 IMU)
  5. OLED 显示误差/模式,按键切换“校准 / 瞄准 / 锁定”
  6. 记录一帧“标定偏移”:补偿摄像头光轴与激光轴不重合

十四、总结

2025 电赛 E 题「简易自行瞄准装置」,并不是单纯的“电机题”或“视觉题”,而是:

用视觉建立误差,用固定周期 PID 消误差,用执行器把误差变成机械运动,用惯性传感补视觉延迟。

本方案的关键闭环是:

K230 输出目标/激光坐标 → STM32 做图像误差 PID → 速度模式驱动双轴无刷 → 陀螺对水平轴前馈补偿 → UART4 在线调参

如果你也在用STM32F103RCT6 + K230 + 串口无刷云台备赛,可以按本文的模块边界直接拆工程:

  1. 先打通四路串口与协议
  2. 再做单轴视觉闭环
  3. 再合双轴
  4. 最后上前馈和赛场保护

十五、参考与声明

  • 赛题名称:2025 年全国大学生电子设计竞赛E 题:简易自行瞄准装置
  • 本文基于作者备赛工程rct6_E(STM32 标准库)整理,参数与引脚以实际硬件为准
  • 电机协议字节、陀螺指令码请以对应模块手册最终确认为准
  • 转载请注明出处;用于学习交流,注意遵守竞赛规则与学术诚信

如果这篇文章对你备赛有帮助,欢迎点赞收藏。
你在 E 题里卡在视觉、云台,还是 PID 调参?评论区一起讨论。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/23 18:10:26

服务器六层板单一电源层架构下PDN优化方案

服务器硬件普遍采用多相 Buck 降压方案&#xff0c;CPU、内存、各类芯片存在多组独立电源轨&#xff0c;瞬时电流变化剧烈&#xff0c;di/dt 极高。六层板仅有一层专用电源平面&#xff0c;对比八层板可设置双层电源层的架构&#xff0c;电源分配网络设计约束显著增加。很多设计…

作者头像 李华
网站建设 2026/7/23 18:08:40

软路由系统 --- OpenWrt下载安装中文语言包

刚安装好的OpenWrt登录Web管理后台后&#xff0c;发现界面是英文的&#xff0c;在系统的语言选项也只有English&#xff0c;没有中文可切换&#xff0c;那该如何呢&#xff1f;那我们就给它安装个中文的语言包&#xff0c;再来进行切换&#xff0c;看看能行不能行&#xff01;如…

作者头像 李华
网站建设 2026/7/23 18:07:21

GB/T 4857.23随机振动介绍,GB/T 4857.23-2021标准及附录D谱图说明

一、标准基础概况与核心作用GB/T 4857.23-2021 全称《包装 运输包装件基本试验 第 23 部分&#xff1a;垂直随机振动试验方法》&#xff0c;2021 年 10 月 11 日发布&#xff0c;2022 年 5 月 1 日正式实施&#xff0c;替代旧版 GB/T 4857.23-2012&#xff0c;修改采用 ISO 133…

作者头像 李华
网站建设 2026/7/23 18:04:08

Tiva ADC采样序列配置详解:从多路复用器到数字比较器的数据流控制

1. 项目概述与核心价值 在嵌入式系统开发中&#xff0c;模数转换器&#xff08;ADC&#xff09;扮演着将现实世界连续变化的模拟信号&#xff08;如温度、压力、光照强度&#xff09;转换为微控制器能够处理的离散数字信号的关键角色。其技术价值直接决定了系统感知外部世界的精…

作者头像 李华
网站建设 2026/7/23 18:02:18

Keil C51工程转VSCode Keil Assistant开发全过程

Keil C51工程转VSCode Keil Assistant开发全过程✨这里以stc15W408AS为例。&#x1f4cc;相关篇《【开源分享】自制STC15W408AS开发板》 &#x1f4fa;编译-烧录演示&#xff1a; ✨目前Keil Assistant插件已经停止更新&#xff0c;但是还是可以继续使用。基本可以满足一般的需…

作者头像 李华