2024年电赛H题自动行驶小车考完那天,我的朋友圈基本被两种内容刷屏:一种是队员抱在一起庆祝跑完完整赛道的照片,另一种是深夜还在调PID救场的哀嚎。这道题在当年把“工程化能力”这四个字体现得淋漓尽致,不是说你写得出多复杂的算法,而是你能否在三天的极限时间里把所有环节像链条一样咬合起来,做成一台能在现场稳定跑完规定路线、完成指定动作的小车。
这篇文章我想把整套比赛经验完整写下来,从读题、拆解需求、硬件选型,到图像处理、运动控制、现场调参和常见故障排查,都按我们当年实际踩过的路子讲一遍。无论你是准备参加下一届国赛的队伍,还是单纯对自动行驶小车感兴趣的嵌入式爱好者,这套“先跑通、再提速、最后才求漂亮”的思路都值得参考。
1. 破题思路:先把赛题要求翻译成技术指标
1.1 2024年H题自动行驶小车到底考什么
很多队伍拿到题目第一反应是“这不就是循迹吗”,然后直接开写巡线代码,结果三天后死得很难看。H题的难点从来不是“循迹”本身,而是题目里那些容易被忽略的细节约束。
从公开的题目信息看,这个任务的赛道包含直线、弯道、十字路口等常见元素,还会要求小车完成停车、倒车入库或者定点停止这类的动作。这意味着你面对的不是一条无限长的黑线,而是一个有起点、有终点、有特殊标记、有明确交付动作的完整场景。赛题表面上在考“自动行驶”,实际上在考的是三件事:
第一,感知环节的鲁棒性。现场光照不可能让你慢慢调阈值,赛道颜色、摄像头曝光、环境反光都在变化,图像处理如果只靠死阈值,基本等于赌运气。
第二,控制环节的稳定性。小车要既能走直线不画龙,又要过弯道不飞线,这背后是转向PID和速度PID的协同问题。很多队伍栽在“直道很稳、一进弯就冲出去”,或者“弯道能过、直道开始蛇形走位”。
第三,整个系统的现场抗压能力。电赛三天时间里有大量不确定性,机械装配松动、电池电压跌落、蓝牙干扰、摄像头帧率下降,任何一个环节崩了,前面的算法再完美也没用。
1.2 评分逻辑决定设计优先级
在动硬件之前,先把评分点吃透,这是整个项目最关键的策略判断。电赛小车题的评分大体上分几个梯队:
第一梯队是“能不能完整跑下来”。能全自动跑完规定路线,就已经击败了相当多连完整一圈都跑不完的队伍。很多组在第一天就追求高速,结果一直到交作品那天都还在处理飞线问题。
第二梯队是“能不能准确完成动作”。停车准不准、倒库进不进得去、能不能在指定区域停下,这类细节动作的分数通常占比不低,而且在赛场上差距往往就拉在这里。
第三梯队才是“速度够不够快”。速度分当然重要,但它的前提是已经能稳定完赛和完成动作。你跑得再快,停过了停车线,分数反而更低。
所以我们的策略很明确:第一天把能跑通完整赛道的硬件和基础巡线做出来,第二天优化动作完成率,第三天最后才去提速度和调整细节。宁可慢5秒,不要中途飞车一次。这个优先级放在这里,是因为赛场上概率问题永远是最大的敌人,你跑十次能成八次,远比跑三次成两次要稳。
1.3 团队分工与开发节奏建议
一支标准的电赛队伍通常三人,H题这种软硬结合特别紧密的题目,如果三个人技术栈完全重叠,后面会很痛苦。建议按这条主线分工:
一个队员全力负责硬件与底盘,包括电机驱动、电源、传感器接线、机械固定、整车重心优化,这些是所有人都依赖的底座,出问题会连锁反应。一个队员负责图像与算法,包括图像采集、二值化、边线提取、中线生成、元素识别,这个模块决定小车的“眼睛”是否清楚。一个队员负责控制与逻辑,包括PID调参、速度规划、状态机、起停逻辑,这个模块决定小车的“大脑”是否灵活。
开发节奏上有个重要经验:从第一天起就建立联调和版本管理。不要各写各的代码最后强行拼装,而是当天写的每一段代码都立刻放到车上去跑,哪怕只是让轮子转起来、让摄像头看到画面。电赛三天最怕的不是工作量大,而是模块之间互相不兼容,最后所有问题同时爆出来。
2. 硬件选型与底盘装配:稳定压倒一切
2.1 主控选型:不要陷入性能焦虑
主控板的选择是第一步,但也是最容易被纠结耽误的一步。H题这种小车任务,算力需求并没有想象中高,关键是要选一个团队里有人熟的平台,而不是选一个纸面上最强的平台。
常见方案有这么几类。第一类是MSPM0或者STM32这种单片机平台,优点是稳定、开发资料多、电赛指定板卡有现成例程,缺点是图像处理需要自己控制好分辨率,跑裸机裸屏、做二值化和边线提取完全够用,但别想在单片机上跑复杂的深度网络。第二类是K210这种带AI加速器的板子,适合在赛题限定条件下做某些目标检测,但开发环境和调试成本偏高,如果团队没人用过,三天里很可能被环境问题拖垮。第三类是树莓派这类准PC级平台,如果赛题没有禁止,体验自然好,但处理实时性和现场稳定性也意味着更多的踩坑可能。
我给的建议是:如果赛题有指定的主控平台,比如要求用某款单片机,那就老老实实围绕它做全文工程,把图像分辨率降到够用的程度,帧率优先级高于分辨率。32x24的灰度图一样能巡线,160x120的图像对单片机来说压力就很大了。如果是自由选型,那就选你昨天还在用、闭着眼睛都能配环境的那块板子,比赛不是炫技,是求稳。
2.2 传感器组合:摄像头为主,其他打辅助
H题赛道上最核心的感知源是摄像头,但仅有摄像头是不够的。要在复杂赛道和动作要求下稳定运行,传感器布局一般遵循“主传感器负责方向、辅助传感器负责状态”的原则。
摄像头选型上,我们用的是无畸变摄像头加灰度信号输出,直接用单片机的DMA接收比较省CPU。摄像头安装的经典问题是高度和俯仰角。装得太低,看不到远处的弯道,过弯时反应不及;装得太高,视野里全是背景环境,二值化容易把外界光线误判为赛道。比较稳的初始参数是高度15到20厘米,俯仰角向下倾斜10到15度,让画面里赛道占比60%以上,前视距离大约能覆盖30到50厘米的赛道。
辅助传感器里,编码器是不可缺少的。很多队伍觉得有了摄像头就不需要轮子反馈,实际上在停车、倒库、坡道起步这些需要精确位移判断的场景里,编码器的累计脉冲能提供比纯摄像头识别稳定得多的距离信息。另外,车头底部装几个灰度传感器也有奇效,可以作为停车线、起跑线的“最后一道卡点”来判断,摄像头视野被遮挡或者丢线时能救场。
2.3 电机、驱动和电源的搭配细节
底盘我们用的是四轮小车,选择带编码器的N20减速电机,配TB6612双路驱动模块。四轮的好处是动力足、走线方便,坏处是转向灵活性不如两轮差速,但应对电赛赛道完全够用。如果追求更好的方向控制,转向轮方案也可以,但要舍得花时间调整机械结构。
电源是整个系统里最容易被忽视的坑。电机、单片机、摄像头如果全挂在一块电池上,电机启动瞬间的电流冲击会导致主控电压跌落,表现就是小车一加速摄像头画面就开始闪烁,严重时直接复位重启。我们的做法是分两路供电:一路7.4V锂电池直接给电机驱动供动力,另一路经过降压模块稳定输出5V给主控、摄像头和传感器,两路电在整车上共地。这样电机的瞬态大电流就不会拖垮逻辑电路的电压。
机械装配上的几个细节值得多说一句。第一,摄像头支架一定要用金属件或3D打印加螺丝锁死,胶带固定一开始还行,激烈运动之后会松动到怀疑人生。第二,四个轮子的离地间隙要一致,否则跑起来会偏,图像上体现为赛道中线有固定偏移,会误导你调PID。第三,整车重心尽量低,电池尽量贴在底盘板上而不是叠在板子上面,重心高了过弯容易侧倾甚至翻车。
3. 图像处理与控制算法:从看到走到闭环
3.1 图像预处理:二值化阈值自适应是底线
摄像头原始画面进来,第一步是转灰度图,第二步是二值化。这一步看起来简单,但电赛现场最容易翻车的就是这里。
用固定阈值二值化,比如大于128算白色、小于128算黑色,在实验室阴天环境下可能没问题,但现场灯光一换、赛道反光一变,同一条赛道可能就变成了一半黑一半白。比较稳的做法是自适应阈值,常见手段有大津法(OTSU),每次取帧后根据当前图像的灰度直方图自动计算分割阈值。
二值化之后还要做一步去噪处理。赛道上可能有一些杂色区域、反光光斑或者细碎垃圾,典型的表现就是二值图里出现孤立的小白点或者小黑点。由于我们用的是低分辨率灰度图,直接用形态学开闭运算的开销也不大,可以先用一个3x3的腐蚀腐蚀掉少量孤点,再用膨胀恢复赛道宽度。这一步不要省,很多奇怪的控制抖动的根源都在这里。
3.2 赛道中线提取:不只是求平均值
有了干净的二值图,下一步就是提取赛道中线。网上很多教程教的是逐行扫描,从左往右找第一个白色像素作为左边界,再从右往左找第一个白色像素作为右边界,两边取中点。这个思路本身没错,但在弯道里会因为视角关系出现很大的失真。
关键在于“不同行的重要性是不同的”。画面底部的行离车最近,反映的是当前车头位置关系;画面顶部的行离车最远,反映的是远处弯道的趋势。近处的信息可靠性高,远处的信息容易受到透视变形和丢线的干扰。我们当时实现的是一个加权中线法:从图像底部往顶部扫,对每一行的中线点给予不同权重,最近的行权重最大,最远的行权重最小,最终得到一个加权平均的横向偏差值。
另一个细节是:当某一行只有左边界没有右边界时,比如急弯时一边赛道已经超出画面,就不要强行用整幅图像宽度去补中值,否则会引入极大噪声。正确的做法是把只有单边界的行标记为无效行,在有效行里做加权平均;极端情况下全部行都只有单边界,再启用边缘跟踪模式,比如直接用左边界的位置变化量来计算转向趋势。
3.3 特殊元素识别:十字、停车线、坡道的判断
H题的赛道不会只是一圈环路,还包含十字路口、停车区、可能还有坡道。这些元素本质上是“二值图上的特定模式”,理论上都能用规则识别,但现实里规则之间会互相干扰,所以状态机是关键。
先说十字路口。十字的典型特征是:画面近处赛道正常,远处一行的左右边界突然同时消失,或者赛道宽度突然暴增。控制上要注意的是,十字区域不能像普通急弯那样猛打方向,而是应该保持当前方向直行穿越。我们的做法是:当检测到赛道宽度连续若干行超过正常宽度的1.5倍以上,就判定进入十字状态,这个状态下不再更新转向PID的偏差,而是保持进入前的方向输出,直到赛道宽度恢复正常。
再说停车线。停车往往不靠图像硬找,而是结合编码器推算距离到达停车区域附近后,再用图像或者车底灰度传感器精确定位。编码器计算的位移要和轮胎周长校准,每周脉冲数要以实测为准,不要只看减速电机标称值。
坡道的识别相对直观,坡道区域的灰度特征和正常赛道有明显的整体跳变,且赛道宽度会因透视变化发生规律性收缩。进坡前要提前加速,下坡后要立刻收油减速,防止落地后猛冲一段直接冲过停车区。这里没有复杂的算法,依靠状态机的提前判断比临时反应稳得多。
3.4 转向与速度控制:PID三环其实是两条腿走路
控制部分是“大脑”落到“四肢”上的关键一环。对于自动行驶小车,最核心的是两个PID环:转向环和速度环,它们之间是解耦配合关系,而不是嵌套关系。
转向环通常用PD控制就够了。输入是前面提到的横向偏差error(正负代表中线在画面中心的左右),输出是舵机角度或差速比例。P给的是基本回正力度,D给的是抑制震荡的阻尼。P太大会在直道上高频摆头,D太大会让转向变得迟钝。常见的调参现象是:只加P,车左右振荡,车身像蛇一样走;加了合适D之后,振荡被压住,车身迅速收敛到中线。
速度环用PI控制,输入是期望速度与当前编码器实测速度的误差,输出是PWM占空比。P负责基本驱动力,I负责消除稳态误差,让车在上坡时自动补油、下坡时自动减油。速度环的P不需要特别激进,否则电机会啸叫,车身会一顿一顿冲。
速度与转向的配合是调参里最玄学也最关键的部分。一个简单的公式化做法是:动态限制最高速度——横向偏差大的时候,说明车在弯道或者状态不稳定,最高速限制下调;偏差小的时候,最高速上调。我们实现的是一个非常轻量的模糊规则表,把偏差分成大、中、小三档,每档配不同的最高速限制,实测效果比一个固定的“全局限速”好太多。
3.5 状态机:让逻辑层层递进而不是堆满if else
如果整辆车的逻辑全部写成平面if else,到后期一定崩溃:十字判断和停车判断可能会同时为真,普通弯道和坡道中的宽度变化也可能误触发。更稳的做法是引入状态机,把运行过程拆成几个明确的阶段。
核心状态至少包含:START(等待起跑信号)、TRACKING(正常赛道循迹)、CROSS(正在过十字)、SLOPE_UP(正在上坡)、SLOPE_DOWN(正在下坡)、STOPPING(正在停车/倒库)、FINISH(完成)。每个状态只关心自己需要处理的传感器信息,状态之间的切换靠专门的标志位来触发。
状态机还有一个附加价值是方便调试。赛场上如果车出了问题,看一眼当前状态就知道是感知误判还是控制输出异常,大大缩短定位问题的路径。
4. 实测调参与问题排查实录
4.1 调参的正确顺序:先内环后外环、先原地后动态
调PID的失败经验几乎都一样:所有人同时上手,车在地上乱跑,谁也看不懂哪里出了问题。正确的调参顺序应该是从内往外、从静态到动态。
第一步,先测电机死区。给一个极小的PWM比如10%,看轮子动没动,记录每个轮子刚能转动的最小PWM值。四个轮子的死区往往不一致,这会表现为直线走歪,不是PID能完全纠正的。第二步,原地测试转向响应:给定一个固定的横向偏差,看轮子是否立刻做出对应的转角动作,确认转向方向没有反。第三步,低速直道巡线:速度固定在一个很慢的值,只调转向PD,直到车能在直道上走得笔直。第四步,加入弯道,观察过弯响应速度和出弯回正的态度。最后才逐步提速,观察高速下的表现。
这个顺序的核心逻辑是:每一步只引入一个新变量,否则出了问题你根本不知道是机械、感知、转向还是速度的锅。
4.2 常见问题排查速查表
下面这些问题我们在三天时间里基本全都遇到过,整理成一个速查表,现场出了状况可以对照着排查。
| 故障现象 | 常见原因 | 排查方向 |
|---|---|---|
| 小车左右摆头、蛇形走位 | 转向P过大或D不够 | 调低P,逐步增加D |
| 直道偏但稳定 | 轮子死区不一致或重心偏 | 校准轮子死区,检查四轮离地间隙 |
| 过弯直接冲出赛道 | 前视距离太短,速度过快 | 抬高摄像头或增大俯仰角,降低过弯限速 |
| 画面一闪一闪、主控重启 | 电源共地不全或降压不稳 | 分两路供电,共地,加大电容 |
| 二值化全黑或全白 | 曝光时间或阈值失效 | 打开自动曝光,或改用大津法 |
| 十字路口猛拐 | 十字误判为普通弯道 | 加入宽度突变检测,进入CROSS状态直行 |
| 上坡没力 | 速度环I不够或电池电量不足 | 增加速度环I值,准备满电备用电池 |
| 停车冲过头 | 编码器测距不准或刹车太晚 | 重新校准每圈脉冲数,提前刹车点 |
| 运行中偶发复位重启 | 电机冲击干扰或线缆松动 | 检查共地、接插件是否压线松动、加大电源电容 |
| 同一位置反复出问题 | 赛道污渍或反光点 | 用湿布清洁赛道,优化去噪算法 |
4.3 现场调试的保命技巧
三天里可以准备一些额外的调试手段,在现场会非常救命。
建议备一块无线串口蓝牙模块,把车里的关键变量实时传回电脑,比如当前状态、横向偏差、设定速度和实际速度、PID输出值。很多画面里看不出来的问题,一上数据链路就非常清楚。
还有一个非常推荐的动作:每次调完参数,跑一次完整赛道并把数据记录下来,跑完以后回放数据,而不是靠肉眼记忆。电赛现场太吵、太累,人的记忆力完全不靠谱,数据回放才是唯一能精确对标判断的依据。
现场环境光照变化快,可以准备一块白色反光板和一块黑色哑光布,模拟不同的极端光照条件提前测试二值化效果,确认自适应采阈值在各种亮度下都能稳定输出赛道边界。
4.4 心态与作息安排的实战感受
最后这部分写点非技术但影响极大的经验。电赛三天的作息安排,几乎和算法一样重要。很多组前两夜不睡猛调车,第三天下午交作品时人已经恍惚了,现场出了低级错误反而没法冷静排查。
我们队伍前两晚保证至少有一个人能值夜,但每个人每天强制睡够6小时,白天精神状态好了,调参效率特别高。真正到比赛的最后六小时,比的更多的是谁还能保持清醒的判断力,而不是谁的阈值调得精准。一次调参失误花掉的时间可能是十分钟,一次大脑短路需要重新接线跳线可能就是一个小时。
另外一个心态上的误区是“越复杂越高分”。很多队伍喜欢在作品里堆功能,比如加上语音播报、加上OLED动画界面,但比赛评分看的是基础功能完成度和稳定性,不是功能数量。能让车稳定跑完,比什么都强。
5. 从H题往后看:这些能力是通用的
2024年电赛H题尘埃落定之后,很多人开始关注下一年的题目。其实每年题目名字都不同,但小车类题目的底层逻辑高度重合:感知、决策、控制、系统集成,哪一年都绕不开。
很多今年没来得及做的优化,比如赛道记忆、路径规划、每圈最优速度曲线,放到明年同样有价值。如果在做H题的过程中,能把图像处理、PID控制、状态机调度这三个方向吃透,无论明年题目换成无人机、送药小车还是别的什么形态,底层能力都能迁移过去。
我个人的体会是,电赛拿什么奖不是终点,三天时间里形成的调试方法论才是更值钱的东西。学会怎么在压力下拆解问题、怎么在各个模块之间定位故障、怎么把系统设计得“坏起来好查”,这套功夫从比赛里带出来,以后做任何嵌入式项目都受用。
按这套思路把基础做好,你的小车在赛场上大概率也能稳稳地跑完那一条赛道。