简介:2017电赛B题基础题资源包,面向参加电子设计竞赛、需要快速上手STM32嵌入式开发的参赛者与备赛团队。项目以STM32F103ZET6为核心,融合山外OV7725二值化图像采集、OLED坐标显示、红外任务选择与舵机控制,覆盖从图像处理到机械执行的关键环节。压缩包共237个文件,约6.32MB,包含C语言源文件、头文件、Keil工程配置及编译中间产物等,便于直接查看代码结构、恢复工程并理解各模块调用关系。资源内文件组织较完整,能帮助读者厘清摄像头数据流、传感器触发逻辑与舵机驱动方式,适合希望在赛题基础上进行扩展或复现完整方案的开发者。已有796人学习下载,可作为2017年B题基础任务设计的重要参考。 2017年电赛B题“滚球控制系统”,我到现在还记得赛场上那些队伍的表情。拿到题目时感觉这题真简单,无非是让一个小球在一块平板上停住、画圆、走路线,但真正调起来才发现,机械、图像、控制三块哪一块拉胯都会让小球原地抽搐。这篇文章我按当年参赛再加后来带队的经验,把B题基础题的完整思路从头到尾捋一遍,重点讲清楚为什么这么做、怎么做、以及踩过的坑,希望准备这个题目的队伍能少熬几个通宵。
开头先给个定调:B题基础题要解决的核心问题,是让一个小球在二维平板上按指定的轨迹运动,并满足一定的精度和稳定性要求。基础部分通常包含定点停稳、圆周运动、直线或折线寻迹这几个环节。你别看只是“让球转个圈”,背后牵涉到机械倾斜机构、视觉定位、闭环控制整套系统,任何一个环节出问题,小球就会教你怎么做人。
1. 题目拆解与整体方案
1.1 基础题到底在考什么
2017年这道题给的是一个平板结构,平板中间放一个小球,通过控制平板的倾斜角度来让小球滚动。基础题几问,说白了就是这几种任务:让小球从某个位置出发到达指定坐标点并稳定停留;让小球在平板上做圆周运动;让小球按照直线或折线路线走一段。评分看的是稳定时间、轨迹贴合误差和是否越界。
很多队伍栽在第一步:小球在平板上稳定不下来。原因很简单,整套系统是一个闭环,视觉给位置、控制算角度、电机执行倾斜,任何一环有延迟或者误差,小球就跑偏。基础题如果只做到“能走起来”远远不够,你要做到“停在目标点不抖、画圆误差不夸张、走线不冲出去”,这才有分。
1.2 系统架构与方案选型
围绕这个任务,系统可以拆成四个模块:视觉定位模块负责读取小球坐标,控制核心负责根据误差计算平板倾角,执行机构负责把倾角落实到平板上,平板与支架是整个机构的骨架。
我当时选的控制核心是STM32F407,图像处理放在笔记本上用OpenCV跑,通过串口把小球坐标发给单片机。为什么这么选?因为比赛时间只有四天三夜,STM32直接跑摄像头图像处理的话,开发效率和调试便利性都会大打折扣,而OpenCV调试起来所见即所得,还能顺便做可视化监控。控制频率不需要太高,20ms一个控制周期足够,这个频率串口完全能顶住。
执行机构我推荐步进电机加连杆的方案,理由后面细说,但先记住一点:整个方案里最怕电机响应慢、有回差,这两个问题会直接吃掉你的控制性能。
2. 机械结构:先打好底子
2.1 结构方案怎么选
控制算法再强,机械结构不行就是白搭。B题的平板倾斜机构常见的有三种:舵机直驱摇臂、步进电机加丝杠、步进电机加连杆。舵机方案结构最简单,但角度分辨率受限,且舵机内部位置闭环在频繁调整时会有一点迟滞,小球比较容易出现低频抖动。步进电机加丝杠方案精度高,但丝杠回差如果处理不好,加上装配麻烦,四天时间比较紧张。我自己最推荐步进电机加连杆,用步进电机转动带动连杆推动平板边缘,结构简单可靠,回差可以通过结构设计和软件补偿来控制。
平板的支撑点非常关键。我见过不少队伍直接用合页或者普通轴承做中心支撑,结果平板平面自由度不够,或者支撑点间隙太大,小球一跑起来就抖。正确做法是使用一个球头关节轴承作为万向支撑,让平板可以绕着中心点在两个方向上自由倾斜。间隙大的支撑点就是你PID怎么调都压不住抖动的一号嫌疑犯。
2.2 关键尺寸与选型计算
平板尺寸大概35cm×35cm比较合适,太大惯性大,电机响应慢;太小活动范围小,基础题里画圆和走线都不方便。平板材质选5mm铝板或亚克力板,重量控制在1kg以内。小球选直径20mm左右的钢球或者玻璃球,表面要光滑均匀。这里说个细节:换球等于换系统参数,球径变了、摩擦变了,PID参数和运动特性完全两回事,比赛期间盯紧一个球用。
连杆作用点离中心支撑点距离L一般取满量程边缘到中心的1/3到1/2。以15cm为例,平板倾角θ大约等于连杆位移δ除以L,小角度下跟弧度近似相等。如果你想获得±8°的倾角范围,那么连杆需要提供的直线位移就是δ=L×tan(θ),代进去算大约是±2.1cm。这个公式非常实用,选舵机臂长或者步进电机丝杠行程的时候直接用。
2.3 机械装配的几个坑
装配环节第一个坑是两轴垂直度。X轴和Y轴的驱动机构要尽量垂直,不垂直的话两个方向的运动会耦合,小球走出来的轨迹会歪。第二个坑是连杆关节处的虚位,虚位大的话,电机即使微调角度,平板也会顿一下才动。最简单的处理是关节处用带轴承的鱼眼接头,比直接用螺丝孔穿销子好很多。
还有一个小细节:平板表面贴一层磨砂贴膜或者喷哑光漆。一来减少反光,方便摄像头识别;二来增加一点摩擦力,小球更容易被控制停稳。光溜溜的板子虽然好看,但小球在上面跟溜冰一样,想停住很难。
3. 图像识别:坐标是怎么来的
3.1 图像方案怎么选
图像识别模块的目标非常纯粹:实时输出小球在平板坐标系下的坐标。可选方案有这么几条:OpenMV独立识别,STM32加摄像头模块,树莓派加OpenCV,笔记本加USB摄像头加OpenCV。如果你的图像部分跑在STM32上,对代码效率和内存都是考验,但很多学校习惯单片机上做全部,也能做出来。如果现场允许使用笔记本,我强烈建议用笔记本加USB摄像头加OpenCV,开发效率高出好几倍。
有人担心笔记本处理图像延迟太高。实测320×240分辨率下,用颜色阈值分割加轮廓提取,一帧处理时间在5ms到10ms之间,加上串口传输和控制计算,整体延迟控制在20ms以内完全没问题。帧率不必追求60帧,稳定在30帧以上就够了,关键是每帧的处理要稳定,不能忽快忽慢。
3.2 识别算法流程
小球识别的经典流程是这样:先把图像从BGR转到HSV,通过阈值把目标颜色从背景中分离出来。为什么用HSV不用RGB?因为光照变化时,HSV里的H通道相对稳定,调阈值更容易。以红色小球为例,设定红色的H范围,配合S和V的上下限,就能把小球分割出来。
分割之后图像上会有很多噪点,我用形态学开运算去噪,也就是先腐蚀后膨胀,把零散的小点滤掉。接着用轮廓查找函数找到最大轮廓,那个就是小球。最后算轮廓的质心或者拟合外接圆圆心,得到小球在图像中的像素坐标。
这一步里有个工程经验:不要只算一帧就输出坐标,最好做一个3到5帧的均值滤波。小球运动时图像中会出现拖影或者偶尔漏检,均值滤波可以显著提高坐标稳定性,代价只是增加十几毫秒延迟,完全值得。
3.3 标定与坐标映射
图像坐标到平板坐标的映射,很多人随便写个比例系数就完事,这其实是个大坑。因为摄像头不是正对着平板平面的,通常有一个倾斜角度,直接用比例换算出来的坐标在平板边缘会差很多。正确方式是标定仿射变换:用四个角点做标记,识别出它们在图像中的坐标,再用OpenCV的getPerspectiveTransform得到变换矩阵,之后每个像素坐标都能映射到平板物理坐标。
标定的时候要注意,摄像头位置一旦动了就得重新标。我建议摄像头固定好之后,标记点贴在平板四个角,代码里留一个标定模式,一键采集角点、一键生成矩阵,这样比赛现场万一摄像头被碰歪了也能快速恢复。
光照稳定性是视觉模块最大的敌人。窗户光、顶灯、人影晃过都会让阈值失效。最省心的办法就是把摄像头和平板放在一个半封闭的盒子里,减少环境光干扰,昏暗一点没关系,只要光源稳定就行。
4. PID控制与轨迹跟踪
4.1 控制对象与结构设计
小球的运动模型看着简单,但严格建模很难,因为滚动摩擦、平板形变、空气阻力都会影响。工程上根本不跟它客气,直接把两个轴向解耦,X轴倾斜只控制X方向位移,Y轴倾斜只控制Y方向位移,各自独立用PID控制。基础题里倾角范围很小,两轴耦合很弱,解耦方案足够用。
控制结构是串级还是单环?我直接用单环位置PID:输入是目标坐标与小球当前坐标的差,输出是平板倾角指令。电机带着平板去执行这个倾角,虽然没有倾角传感器做反馈,但因为执行机构装配完成后来回动作的重复性还行,半开环的方式也能达到基础题精度。如果你用的舵机,本身就是位置闭环,更省事;用步进电机,只要不失步,重复定位也没问题。
4.2 参数整定顺序
PID参数整定是有顺序的,千万别一上来三个参数一起试。先用纯P控制,把小球的静止稳定性调出来。P太小,小球有气无力地慢慢挪;P太大,小球会跑来跑去停不下来,像极了你在桌上拨弄一粒豆子。找到一个临界值,让它能在目标点附近做小幅等幅振荡,这就是P的基准。
然后加D,D的作用是压住振荡,让小球快速停下来。D太大会引入噪声,反而抖动得更厉害,所以D要配合滤波一起用,比较常用的是对微分项做一阶低通。I参数放到最后,只在静态误差比较明显时才加,一般取很小的值。我调过的系统里,I太大了最典型的症状是小球在目标点附近做低频游走,极其难受。
这里分享一组初始参考值,控制周期20ms、输出为平板倾角百分比时,可以从KP=50、KD=500、KI=0开始调,D项明显压住振荡之后再一点一点加。换机构、换小球后参数都要重新走一遍这个流程,没有捷径。
4.3 圆形轨迹与折线轨迹的实现
基础题里最常见的圆形轨迹,实现思路跟定点控制还不一样,核心是轨迹规划和前视跟踪。先把圆轨迹离散成一系列目标点,用一个随时间变化的参数方程实时生成,小球当前跟踪的目标不是圆心,而是圆上的一个移动点。每20ms把目标点沿圆移动一小步,PID控制小球不断追这个点。
生成轨迹的伪代码并不复杂,大概是这样的:
# 圆轨迹目标点生成 while running: omega = 0.6 # 角速度 rad/s,可调 t = get_elapsed_time() target_x = center_x + radius * cos(omega * t) target_y = center_y + radius * sin(omega * t) send_to_controller(target_x, target_y) sleep(control_period) # 20ms圆轨迹最容易出现的问题是起步瞬间小球往圆外冲。原因很简单,起点位置和圆轨迹上的第一个目标点距离太远,PID误差一大,输出倾角就大,小球被猛然推出去。解决办法是先让小球从起点走到圆上的一个进入点,等小球到了进入点附近再启动圆周跟踪,相当于一个缓启动过程。
直线和折线轨迹跟定点控制思路一样,把路径分成若干段,逐段给出目标点。折线拐弯处要提前减速的做法是,当小球离拐点还有一段距离时,目标点就提前转向,让轨迹圆滑过渡。不然直角拐弯时球很容易冲出路径线。
5. 基础题逐项通关实录
5.1 阶段一:先把静止稳定搞定
别急着走轨迹,第一件事是让小球能够在平板中心附近稳住。我当时拿到平台的第一个晚上,就是在跟静止稳定较劲。你把小球放在中心,它如果自己跑去一边,或者在一个点周围不停画小圈,说明参数和机械还不行。
这个过程主要调P和D,调的时候要有耐心。每调一次参数,放球观察十几秒记录下来,再改。我习惯用表格记录参数和小球表现,比如KP=40时小球大幅度来回跑,KD加到300后明显收敛,再加到500时出现高频颤振,那就退回到450。这一步调好了,后面所有环节的基础就牢了。
5.2 阶段二:定点移动
静止稳定之后,开始做定点移动。先做一个简单的目标点,比如从(0,0)走到(10,0),看看小球能不能平稳过去并在终点停稳。这个过程中你会看到小球在目标点附近过冲、回头、再过冲,慢慢收敛。想让它在目标点快速停稳,主要靠D和一点I。
还有一个必须处理的问题是容差环。当小球进入目标点附近一个半径2cm的圆内,就认为它已经到达,不要再频繁更新目标点了,否则小球会一直在目标点附近打转。这个道理很简单,PID是连续控制器,它永远在追目标,追到了也要让它“下班”。
5.3 阶段三:圆周与折线
做完定点,圆周运动就是个水到渠成的事。先把圆轨迹的参数写好,半径取12到15cm,角速度从0.3rad/s开始慢慢加,看看小球能不能一直咬住轨迹。误差看什么?看小球到理论圆的径向距离,这个值用代码实时算出来,打到上位机里看曲线。
折线运动我建议延后到系统已经很稳定的时候再做,因为折线的拐弯是最考验整套系统响应速度的。如果拐弯总是冲出去,优先检查拐点前有没有提前减速,以及D参数是不是偏小导致反应慢。基础题到这里,整套系统就应该能拿得出手了。
6. 常见问题与排错手册
6.1 典型问题速查
下面这些是我在比赛和带队伍过程中反复遇到的问题,整理成一张速查表,现场调试时对着查非常管用。
| 现象 | 主要原因 | 解决思路 |
|---|---|---|
| 小球高频抖动 | P过大、D滤波不足、机械虚位 | 先降P,再加D低通滤波,检查关节间隙 |
| 小球低频游走 | I过大、平板不平、静态摩擦力大 | 减小I,重新调平底板,适当增加起始驱动力 |
| 圆轨迹走成椭圆 | 两轴增益不一致、标定不准 | 分别标定XY映射,单独微调每轴P |
| 图像识别丢球 | 光照变化导致阈值失效 | 遮光处理,固定摄像头曝光,适当放宽阈值范围 |
| 电机发热异响 | 长时间堵转或超行程 | 软件里做倾角软限幅,加机械限位保护 |
| 起步冲出去 | 目标点距离过远、初速太快 | 先定位到轨迹起点,再做缓启动 |
6.2 调试环境搭建技巧
比赛调试最大的痛点就是“看不到系统在想什么”。我强烈建议把上位机调试界面做起来。界面左边是摄像头画面加小球识别框,右边是平板平面坐标图,把目标点和实际位置同时画上去,再开一个PID输出的曲线窗口。这样小球一跑偏,你立刻能看出来是视觉问题、控制问题还是机械问题。
另外,所有控制参数要留成上位机可调的模式,串口发个指令就能改KP、KD,不用每次改完都重新烧程序。我在比赛后期基本上都是边看球跑边调参,五秒钟改一次参数,效率比传统改代码烧录高太多了。调试的时候养成分步记录参数的习惯,哪组参数表现好就存下来,防止后面调乱了回不去。
写到这里,我把2017年电赛B题基础题从题目拆解到机械、视觉、控制、调试的全部关键环节都过了一遍。回想起当时赛场上的经历,这个题带给我最大的收获不是某段代码多厉害,而是让我知道了做一个闭环系统该怎么去权衡各个模块的短板。准备这道题的队伍,我的建议很简单:从最扎实的机械开始,把图像标定做仔细,PID参数耐心地一点点凑,调试界面一定要可视化。把这四件事做到位,基础题拿高分是真的不难。
本文还有配套的精品资源,点击获取