
2024年电赛H题“自动行驶小车”出题方向一出来参赛群里就炸了。倒不是题目本身有多难而是这套题的考察点非常综合机械结构、传感器选型、控制算法、现场调试一个环节掉链子整车就趴窝。很多队伍从拿到题目那一刻就乱了节奏有人死磕视觉有人埋头改机械结果四天三夜下来连基本功能都没跑通。这篇文章我按自己的参赛和指导经验把H题从拆题到调试的完整链路拆开讲一遍。不仅说清楚要做什么更会把方案背后的选择逻辑、实测算法和现场容易踩的坑讲透。适合第一次参加电赛控制类题目的队伍参考也适合想搞懂自动循迹小车完整技术栈的初学者收藏。1. 先吃透题目H题到底考了什么1.1 每年必考的“控制老三样”变体电赛控制类题目多年来核心考察点向来是固定的感知、决策、执行。H题“自动行驶小车”也不例外——让小车在指定赛道上自动循迹行驶完成停障、绕障、转运等动作。听起来像智能车竞赛的低配版但实际上电赛H题最折磨人的地方不是让你把某个单项做到极致而是要求你在四天三夜里把所有子系统捏合成一台稳定可靠的小车。和智能车竞赛相比电赛的赛道场景更贴近工程实际。2024年H题中小车不仅要沿黑线跑还要处理直角转弯、T字路口、障碍物停车等复合工况。这就意味着从硬件选型到控制策略都不能只用一套通用方案硬撑必须针对每种场景单独设计逻辑和参数。1.2 评分导向跑得快不如跑得稳很多新手队伍容易陷入一个误区——拼命调高速觉得速度越快得分越高。这在电赛里是大忌。H题的评分逻辑是按功能点逐项计分完成一个动作得一项分。你小车直道能跑出3m/s的极速但路口识别偶尔失误冲出赛道丢的分比多拿的附加分还多。实际比赛经验是评分标准的权重排序大约为稳定性 动作完成度 行驶速度。另外一个容易被忽略的点是时间成本。四天三夜看着很长但分配下来非常紧张第一天定方案、搭硬件第二天写基础循迹代码第三天调复杂场景第四天必须留出至少半天用来模拟比赛跑全程和做备份。如果你纠结于某一个细节的完美比如摄像头曝光参数调了五小时那你大概率会在最后发现整体系统根本没时间联调。1.3 平台限制与技术路线选择H题在2024年指定了主控平台——MSPM0G3507。这颗芯片是TI新推出的Cortex-M0内核MCU主频80MHz片上资源对于做小车控制完全够用但远达不到“随便挥霍”的程度。如果你之前只玩过STM32第一次接触MSPM0系列需要重点适应它的开发环境和外设库函数风格。从技术路线来说参赛队伍的选择一般集中在两个方向摄像头视觉循迹和红外光电循迹。两者方案我都带队试过给后来者的建议是除非你们队伍有深厚的图像处理功底否则不要轻易在电赛里选摄像头。四天时间想把车跑稳红外光电是性价比最高、最不容易翻车的路线。这个决策至关重要后面我会详细对比两者的优劣。2. 硬件选型与机械结构搭建2.1 主控与驱动板的黄金搭配先说结论我建议采用“MSPM0G3507核心板 独立电机驱动模块 独立电源模块”的三层结构。不要在画PCB上浪费时间电赛四天最宝贵的是调试时间不是焊板时间。用市面成熟的模块拼装稳定性反而更高。电机驱动方面DRV8701或TB6612是主流选择。TB6612耐压高、内阻小逻辑电平兼容性比老掉牙的L298N好太多。我当时队伍用的是TB6612模块稳定性和发热控制都很出色。另一个细节一定要给驱动模块加散热片比赛现场环境温度往往偏高长时间运行下驱动芯片发热导致过温保护的案例并不少见。供电是整个系统的命脉。小车的动力电池组和控制电路最好分开供电避免电机瞬间大电流拉低MCU工作电压造成复位。我用的是两节18650约7.4V给电机供电再通过降压模块稳定到3.3V给主控和传感器供电。实测下来这个方案干净利落续航和稳定性都达标。2.2 传感器布局是决定成败的一半即使是同一套传感器安装位置不同效果天差地别。红外光电循迹模块一般选用5路或7路阵列安装在前轮前方尽量贴近地面的位置。高度控制在1~2厘米之间是关键太高会引入环境光的干扰太低又可能在过减速带或轨道接缝时误触发。两轮差速底盘的传感器要装在车体正中心线上否则转弯时左右探测不对称车会跑偏。四轮底盘要注意前后轴距对压线判断的影响传感器应安装在后轮稍微偏前方的位置——因为车的转向是以后轮为支点转动的传感器位置贴近转向中心才能更真实地反映车头指向。关于红外光电和摄像头路线之争我直接给结论红外光电是“下限高”方案抗干扰强、代码简单、逻辑直观摄像头是“上限高”方案能处理更复杂的坡道、断线和交叉赛道但对算力、调参和光线鲁棒性要求极高。电赛四天时间对绝大多数队伍来说红外逻辑代码足够应付H题的赛道复杂度。2.3 车架改装的三个注意事项很多队伍直接买现成小车底盘回来拆了装、装了拆时间全浪费在这了。我复盘多年参赛经验底盘改造只需要重点关注三处重心高度、轮距宽度、轮胎摩擦系数。重心要低这是基础。电池组尽量平铺在底盘下层传感器和驱动板固定在中间层不要堆成“小蛮腰”否则高速过弯时离心力会让内侧轮悬空直接失去牵引力。轮距方面前后轮距大一些对直道稳定性有帮助但牺牲了转弯灵活性左右轮距宽一些会提升抗侧倾能力代价是赛道内弯半径大时可能需要额外减速。轮胎方面原厂发泡轮或硬质橡胶轮在赛道上容易打滑建议直接换硅胶轮或涂覆一层热缩管增加摩擦力。我们测试过更换硅胶轮后从0.7m/s到1.2m/s的极限弯道速度提升非常明显这个改动是所有机械调整里投入产出比最高的一项。3. 核心控制算法循迹、路口与状态机3.1 PID控制器的参数工程化整定循迹小车的“大脑”其实是PID控制器——即使是智能车竞赛出身的老选手调PID时也不敢说自己一次就能调好。我们需要的是工程化整定流程而不是玄学调参。位置式PID公式就不赘述了关键讲参数选择。P项是对偏差的实时响应P过大车会左右剧烈震荡P过小车过弯时反应迟钝。I项用来消除静差——对于循迹车来说直道上传感器读数可能会因为轮径不一致产生恒定偏差I项能稳稳地把它拉回来。D项是“阻尼”抑制超调这在高速入弯时特别明显。初始参数可以先从“Kp15Ki0.05Kd8”起步然后逐步增大至车体出现轻微高频抖动此时将Kp回调20%~30%作为安全余量。Kd的调整要看入弯响应如果车头过冲明显说明Kd偏小如果入弯发“肉”则是Kd过大压制了响应速度。Ki只在直道跑偏的情况下微调切忌一次加大太多否则弯道时积分累积会带来严重的过弯过冲。更稳定做法是把PID输出映射到左右轮PWM的差速值上。比如PID输出范围是-255到255左轮PWM基础速度输出右轮PWM基础速度-输出输出为正时左快右慢车向右转反之左慢右快车向左转。这样的结构直观并且可以通过限制PWM上下限防止小车原地转圈或飞车。3.2 路口识别不只是“数黑线”H题赛道中必然会包含十字路口、T字路口以及可能出现的直角弯。对于5路红外传感器来说路口识别的本质是“哪几个探头的读数同时变黑”。假设5路探头编号L2、L1、C、R1、R2当L2、C、R2同时为黑时可能判断为十字路口。但只靠“同时黑”判断路口并不健壮——小车稍微偏离中心线时可能只有L2和C同时黑此时容易误判为T字路口。更可靠的做法是“顺序识别连续帧确认”设定一个状态记录变量当某一路探头从未触发变为触发时记录上升沿连续3次采集到相同的高电平状态后再判定为有效。这样可以滤掉抖动和轻微偏移带来的误触发。T字路口和十字路口的区分需要根据任务要求做分支处理。若任务要求小车在T字路口右转那就不需要区分方向直接右转即可但要提醒的是如果在T字路口左转车头会短暂经过一段完全没有黑线的区域这时需要保持当前转向并附加一个“巡线丢失计时器”超过50ms仍未检测到黑线则立即停车或执行强制转向恢复逻辑。3.3 状态机让小车从“会跑”到“会办事”状态机是H题四天里最值得投入时间的设计环节。很多队伍代码写到后面乱成一团就是没有状态机的概念。状态机的本质是把小车的行为拆分为离散阶段阶段之间通过既定条件切换避免“所有代码堆在一个循环里”的野路子思维。拿2024年H题举例一个实用的状态机可能包含START: 等待按键启动或蓝牙指令LINE_FOLLOW: 正常循迹行驶状态默认主状态STOP_BEFORE_OBSTACLE: 检测到障碍物前的减速停车状态OBSTACLE_AVOID: 绕障或等待避障指令状态TURN_LEFT / TURN_RIGHT: 路口转向专项状态STOP_AT_END: 到达终点停车每个状态内部独立运行自己的控制和传感器逻辑状态切换通过标志位触发。这样做的好处非常明显你能单独测试每个状态而不影响全局某个状态出问题时只需要看触发条件是否满足排查速度翻倍。我最想提醒的是状态机里的“退出条件”要比“进入条件”写得更谨慎。很多队伍状态能进不能出原因就是断线重判逻辑没有考虑好。比如进入TURN_RIGHT状态时先强制转向500ms然后再进入LINE_FOLLOW状态重新巡线。这里500ms是经验值要根据自己的转向速度和路径半径实测调整。如果转向还没完成就提前回到循迹状态车会沿着错误方向重新找线直接跑飞。4. 程序框架与代码细节4.1 主循环的时间规划MSPM0G3507主频80MHz看似很快但如果代码写得不讲究一次整循环跑完也会花费几十毫秒直接拉低控制频率。在循迹小车程序里我推荐主循环采用固定时间片调度用定时器中断作为时间基准主循环每5ms执行一次控制运算约200Hz传感器采集在控制运算前完成PWM输出在控制运算后更新。200Hz的控制频率对红外循迹绰绰有余就算高速跑1m/s5ms内小车只前进5mm足够精细。不建议把控制频率拉得过高反而容易让PID微分项对噪声过度敏感产生不必要的高频抖动。传感器采样要注意防抖。红外传感器输出本质上是电压阈值比较如果阈值设置得不好会在临界状态反复跳变。我的做法是采样时连读三次取两次以上相同结果作为有效读数这个滤波逻辑写在底层函数里上层控制代码拿到的永远是稳定的0或1信号。uint8_t read_sensor_filtered(uint8_t ch) { uint8_t cnt 0; for (int i 0; i 3; i) { if (read_sensor_raw(ch)) cnt; delay_us(100); } return cnt 2 ? 1 : 0; }这段代码简单实用三行逻辑省掉一多半信号抖动问题。它在实际调试中的意义是我反复强调的让上面的PID控制器输入的永远是最佳质量的信号不要在控制层再做过多滤波处理。4.2 转向执行时的动态限速有经验的队伍会意识到小车在不同场景应该有不同速度。直道上可以冲弯道要减速停止区前要提前刹车。如果全程恒定速度要么弯道飞线要么直道浪费宝贵的比赛时间。动态限速的实现不复杂在状态机中为每个状态绑定一个目标速度值循迹状态的速度由当前传感器偏差的绝对值实时计算。例如当5路传感器只有中央C检测到黑线时认为车在直道上目标速度设为1.2m/s当偏差从C扩大到R1时目标速度降为0.6m/s当偏差到R2时目标速度进一步降为0.3m/s。然后再把目标速度作为基础值输入PID这样从高速直道进入急弯时小车会先减速再转向极大减小过弯飞线的概率。刹车逻辑也要提前量。停止区前如果直接一脚急刹电机瞬间反转会产生很大冲击严重时可能让小车点头甚至翻车。我的处理方式是用分段减速检测到停止线前约20cm时先把目标速度降至0.2m/s等到压线时执行零速刹车实测停车位置误差可以控制在±1cm以内。void speed_profile_update(void) { int deviation get_line_deviation(); if (deviation 0) { target_speed SPEED_FAST; } else if (abs(deviation) 1) { target_speed SPEED_MEDIUM; } else { target_speed SPEED_SLOW; } }4.3 蓝牙调试通道现场救命的家伙调试小车最痛苦的事情是什么是看它跑偏了却不知道内部状态是什么。加装一个蓝牙模块将实时状态数据无线传输回电脑这个投入绝对值得。电赛现场允许使用无线调试工具。蓝牙回传数据的格式建议用最简单的文本帧状态名、左轮速度、右轮速度、传感器原始值、PID输出一秒钟回传20帧。你在电脑串口监视器上就能实时看到小车到底处于什么状态、传感器读到什么值、PID在往哪个方向输出。调试效率翻倍还不止。回传代码只需要一个简单的格式化函数串口波特率设到115200数据量完全够用。但注意蓝牙回传会占用一定主控时间调试时可以开启正式比赛时最好关掉或降低频率避免影响控制循环时间片。void debug_send_status(const char *state_name) { printf(%s,L:%d,R:%d,S:%d,%d,%d,%d,%d,PID:%d\r\n, state_name, motor_left_speed, motor_right_speed, sensor_values[0], sensor_values[1], sensor_values[2], sensor_values[3], sensor_values[4], pid_output); }5. 实战调试从空赛道到满分动作5.1 先单测子系统再整体联调四天三夜的调试节奏如果控制不好很容易陷入“改一下、试一次、跑飞、再改”的死循环。我的建议是第一天就不要让车完整跑起来而是先做子系统验证。第一步单独测电机带载PWM响应确认左右轮在相同PWM下转速是否一致如不一致需要在代码里设定两侧校正系数。第二步单独测传感器让小车静止拿黑色胶带在传感器下方移动观察串口数据是否按预期变化。第三步PID空调——把小车架起来轮子悬空用手模拟偏移看PWM输出是否正确响应。只有三个子系统都通过后才把车放回赛道上真正跑。这一步我甚至会在第一天晚上就完成剩下三天半完全留给整系统迭代。5.2 现场环境对传感器的“魔法干扰”电赛现场和实验室环境有个巨大不同光线。赛道的黑白对比在自然光和场馆灯光下完全不同。红外的误判往往不是电子问题而是环境光里的红外成分直接照射到传感器接收管引起的。赛前提前一晚到场地用赛道角料的底板重新标定传感器的阈值这是经验之外最重要的安排。标定方法是在同一光照条件下分别采集白色底和黑色线上的传感器ADC值取中间值作为阈值两套值之间至少要保留15%的裕量。如果现场光线没法保证稳定可以在传感器外面加遮光罩用热缩管或3D打印件把探头四周包起来只留底部开口。这个小改动在光线较杂的场地非常有效。5.3 常踩的坑与排查速查表以下这些问题是我和参赛队伍在调试中最常遇到的列成表格方便快速自查。排查顺序建议从简单到复杂先检查机械后检查电子先检查硬件后检查代码。现象可能原因排查方法解决措施小车上电后不动电池电压不足万用表测电池端电压更换电池或充电至8V以上左右轮转速差明显轮胎打滑或电机阻力不同空载测速对比修正代码转速系数画龙严重左右抖动PID的Kp或Kd过大串口看PID输出震荡频率降低Kp至无高频抖动再微调Kd入弯急速飞线弯道未提前减速观察检测到偏移后目标速度是否下降增加动态限速档位或降低弯道目标速度过十字路口误判传感器同时触发多路查看路口状态进入记录增加连续帧确认逻辑停车过冲刹车力矩不足或检测距离太近测量停车线前实际减速距离增加减速副区域提前200ms降速偶发死机电源跌落导致复位万用表测MCU供电轨在电机启动瞬间的电压跌落电源分路并加大储能电容5.4 比赛当天的应急预案电赛有两个赛段封闭评测和现场评测现场评测是不可重来的“一锤子买卖”。所以除了技术现场流程管理和备份策略同样重要。我会假设所有可能出问题的环节都制定了应急预案。第一层预案是程序备份。四天代码迭代N版带三份U盘和设备本身构建好的固件分别放在不同文件目录。赛前最后一次全流程测试后把可用的固件hex文件单独导出文件名写成 FINAL_可用版本_时间戳。这个细节能救命的场景是开赛前2小时手滑改坏了一个参数发现后立刻回退到最近可用版本。第二层预案是硬件备件。电机驱动模块和传感器模块至少各备两套电池至少准备3组并提前充满。虽然不一定会坏但电赛现场的紧张氛围下人手混乱比硬件故障更常见备件极大缓解心理压力。第三层预案是“策略降级”。如果现场赛道的光线、材质或场地尺寸与练习时差别较大快速调整方案比临时改代码更靠谱。例如摄像头方案切换为红外方案不现实但可以把红外阈值调整从自动标定切换为手动标定在备用小车上提前写好一个只跑直道的简化模式保证基础分不丢。拿不到满分动作不要慌先拿满基础分再去冲附加分。6. 赛场的最后一夜效率与心态的平衡6.1 最后24小时的时间分配四天三夜的最后24小时是整场比赛的胜负手。很多队伍这时候还在疯狂改参数这是大忌——每个参数改了之后至少要留出半小时完整路测验证离评测还有6小时时所有参数应该已经冻结只做硬件的最终检查和路线演练。最后24小时的时间分配可以参考前6小时最后一次全项功能测试记录每项动作的成功率中间12小时集中修复成功率低于80%的动作按“丢分风险”从高到低排序处理最后6小时不再改代码只重复跑完整流程三遍以上记录每遍的成功率和稳定性并检查电池满电、传感器清洁、轮胎无磨损。6.2 压力下的调试纪律比赛现场最影响判断力的是情绪。每次小车跑飞时第一反应不应该是零散改动而是拿笔记本记下失败的现象再对照排查表。无论时间多紧贯彻“一次只改一个变量”的纪律永远优于“顺手调两下碰运气”。还有一个很容易忽略的点要有人在旁边专门记录测试日志。现场日志包括当次测试的小车状态、速度档位、赛道特征、发生了什么事、我们动了哪些参数、结果如何。三小时以后回头看这日志能帮你迅速分辨哪两个参数组合是有效的、哪一次改动其实是在原地打转。6.3 给明年参赛队伍的三句话第一句别做“全能型”队伍四天时间做不完所有事。你需要的不是每一项都精通而是做一个稳定到无聊的系统。第二句硬件方案尽早定型哪怕它在理论上不是最优的。后期换传感器就是重写一半代码。第三句稳定压倒一切。最完美的动作是评测现场能从起点稳稳走到终点的动作不是调了三小时才调出来一次满分的动作。7. 写在复盘之后比赛真正结束的那一刻你会复盘很多细节某个弯道的速度还能削得更极限一点某个传感器阈值还能卡得更紧一些。但真正让我印象深刻的从来不是某个技术点的炫技而是整个队伍在四天三夜里如何一步步把一个又一个“为什么”解决掉——为什么电机换了轮胎就安静了为什么PID参数调了一下午最后还是回到最初的那组为什么赛道上一缕莫名其妙的光会让传感器集体失明。这些问题的答案才是电赛送给你最值钱的礼物。