2024电赛H题自动行驶小车完整方案:从选型到调参的踩坑实录
2024年电赛H题出结果的那天晚上我们实验室三个人谁都没睡盯着小车在测试赛道上一遍一遍跑。说实话H题“自动行驶小车”在当年所有题目里看起来是最“亲民”的一个——不用高频电路、不用复杂算法、不用昂贵的模块但真正上手才发现越是这种谁都能做的题越容易在细节上翻车。赛场上有人小车直接冲出赛道有人到终点不停车有人转弯转了一半卡死在路肩上。这篇文章不聊虚的把我从拿到题目到最终提交作品的完整思路、选型理由、踩坑记录和现场策略全部拆开来讲给后面备赛的朋友一份能直接“抄作业”的参考。1. 2024年H题到底在考什么——从规则反推设计重点1.1 任务框架里的隐藏信息量电赛的题目描述通常很短但每一句都有含义。H题的核心任务框架是设计并制作一辆能沿指定路径自动行驶的小车完成直行、转弯、路口识别、定点停车等一系列动作。听起来简单但“自动”两个字就过滤掉了一大批遥控车方案。我分析赛题时习惯做一件事把任务要求拆成“必须满足”和“加分发挥”两层。必须满足的是基础路径跟随和基本动作执行加分项往往是速度、准确性、稳定性这些“比赛之外”的指标。2024年H题的拿分逻辑很清晰基础分不跑丢 准确分停车准、转向准 速度分跑得快。如果你连赛道都跑不完速度快没有任何意义。1.2 赛题隐含的三个技术考点第一是路径检测能力。赛道通常用黑白对比色或者电磁线引导但考场的光线条件、地面的反光程度都是未知数传感器必须有足够的冗余和抗干扰能力。第二是运动控制能力。小车在直道上能不能走直、转弯时能不能稳住不漂这取决于电机驱动方案和闭环控制算法而不是简单的PWM开环输出。第三是逻辑决策能力。路口怎么判断左转还是右转、什么时候该停车、遇到异常情况怎么处理这些需要一套状态机或者决策流程而不是“一遇到黑线就打方向”这种单一反应。我们组最后能拿到省奖核心原因就是对这三个考点的权重分配非常清楚花了大概30%的时间搭硬件70%的时间全部砸在调控制逻辑和现场稳定性上。2. 主控、传感器与底盘方案——我们组为什么这样选型2.1 主控方案对比STM32依旧是首选赛前我们组经历了三轮主控选型讨论。最初有人提议用Arduino理由是开发快、资料多也有人想直接上OpenMV做纯视觉方案觉得视觉看起来“高级”。最后我们统一意见主控用STM32F103C8T6循迹用灰度传感器视觉只作为辅助扩展。主控方案优点缺点适合场景Arduino上手快库函数丰富定时资源少复杂控制吃力基础循迹、低难度赛道STM32F103性价比高定时器/PWM资源充足需要自己配库上手门槛略高需要闭环控制的进阶小车OpenMV/K210能识别复杂元素帧率受限依赖光照视觉组、竞赛发挥部分选择STM32的核心理由是它的定时器和PWM通道足够支撑四路编码器反馈和双电机驱动这为后面的速度闭环和转向控制留足了余地。而且HAL库加CubeMX的配置方式对准备时间紧张的学生队伍来说完全够用。2.2 传感器组合灰度循迹为主编码器做闭环2024年H题的主流赛道形式是白底黑线或者黑底白线灰度传感器红外对射反射式是最直接有效的手段。我们用的是8路灰度传感器模块安装在前端间距大约1.2cm正好覆盖2cm宽的黑线。这里有一个很关键的设计取舍为什么要8路而不是5路因为8路可以更早地检测到赛道边缘尤其是在弯道中多出的两路给了转向控制更多的提前量。而且路口检测时需要同时判断左右两侧传感器是否同时触发8路的冗余让状态判断更可靠。编码器我们选了霍尔式编码器电机AB双相输出可以同时检测转速和方向。这玩意儿在比赛中的价值极大——没有编码器你只能用开环PWM控制小车在电池电压下降时会越来越慢转弯角度也会漂移有了编码器速度闭环和里程检测都能做停车精度和转向一致性会有质的提升。2.3 底盘与驱动三轮还是四轮底盘结构我们纠结了整整一天。三轮结构两个驱动轮加一个万向轮转向灵活、机械结构简单非常适合需要频繁转弯的赛道四轮结构稳定性好但转向时容易打滑对差速控制的要求更高。最终选了三轮结构理由很实际H题的赛道以直角弯、T型路口为主几乎没有高速蛇形弯三轮的灵活性优势远大于稳定性劣势。电机选用带编码器的N20微型减速电机减速比1:30配合65mm直径的橡胶轮。这个组合的线速度大概在0.5m/s左右对于室内赛道来说是一个既保证速度又容易控制的范围。电机驱动模块用的是TB6612双路H桥最大驱动电流3.2A对比常用的L298N它的内阻更小、发热更低、体积也更小。实测下来同样的电机和电压TB6612驱动的扭矩表现比L298N明显更稳PWM频率设置在10kHz左右不会产生尖锐噪音。3. 机械装配与电路焊接——真正拉开差距的地方3.1 底盘重心分布是第一道考题很多队伍车跑偏第一反应是算法问题但实际是重心和轮距调校的问题。我们的第一个版本小车电池放在车尾正上方结果过弯时后轮抓地力骤减经常出现“甩尾”冲出赛道。后来把电池移到两个驱动轮之间的底盘下方并且让灰度传感器支架尽量靠近前轮轴心整车重心明显下降弯道稳定性好了不止一个档次。经验总结重心越低越好电池和主控板尽量对称放置传感器支架要硬连接不能用弹簧减震——灰度传感器需要稳定的离地高度任何震动都会造成误判。3.2 电路连接中的三个容易翻车的细节第一个细节是电源分配。电机启动瞬间电流很大会导致电压跌落如果主控和传感器与电机共用电源线复位和误触发几乎是必然的。我们的做法是7.4V锂电池直接给电机驱动模块供电驱动模块上的5V输出给主控和传感器独立供电并用一个大容量的电解电容并联在电源两端做滤波。开始用1000uF后来实测2000uF的效果更稳。第二个细节是灰度传感器的阈值校准。模块上有可调电位器但很多队伍只在室内调好就上场到了赛场发现光线不同、地面反光不同传感器数值漂移严重。我们的习惯是模块灵敏度不要调到最大预留20%左右的余量每次到赛场的第一件事就是用黑胶带和白纸分别测一次原始ADC值然后手动设置阈值而不是依赖自动校准。第三个细节是编码器的信号线走线。编码器输出的是高频脉冲信号如果和电机电源线绑在一起电磁干扰会导致脉冲丢帧速度环计算的结果会完全失真。信号线必须单独走线并且在主控端加上拉电阻和RC滤波。我们第一次实测时发现右轮编码器数值波动很大排查了半天才发现就是线缆交叉绑扎导致的串扰。3.3 电池不要小看电压曲线的变化锂电池的放电曲线不是一条直线满电8.4V和快没电的7.2V下同样的PWM占空比对应的电机转速差异巨大。如果不做速度闭环小车前10分钟和跑30分钟之后的性能完全是两台车。我们用的方案是代码里不做电池电压采集补偿而是依靠编码器速度闭环自动调节PWM。PID控制器的输出会自动适应电压变化所以哪怕电池从满电跑到低电车速始终稳定在设定值。这一点在长时间调试和比赛轮候的时候优势非常明显。4. 控制算法与代码实现——核心逻辑逐层拆解4.1 速度闭环先保证“走直”再谈“转弯”H题小车的底层控制必须是双闭环内环是速度环外环是转向环。速度环的作用是让左右两个轮子的实际转速跟上设定值转向环的作用是根据传感器数据动态调整左右轮的差速。速度环我们用的是增量式PIDint Speed_PID(int target_speed, int current_speed) { int error target_speed - current_speed; static int last_error 0; float Kp 1.2f; float Ki 0.05f; float Kd 0.1f; float output Kp * error Ki * (error - last_error) Kd * error; last_error error; return (int)output; }注意这里用了增量式PID的简化写法输出的是PWM调整量而不是直接输出值。这样做的好处是天然带有积分效果误差累积体现在占空比的逐步调整中而且不会出现积分饱和的问题。4.2 转向控制位置式PD核心是“偏差权重”有了速度环打底转向环就可以专门处理赛道位置偏差。灰度传感器8路输出可以转换为一个位置误差值当小车正好在黑线正上方时中间的传感器第3、4路触发误差接近0当车子偏左时左侧传感器触发误差为正值或负值取决于定义。转向控制的核心思想是误差越大差速越大。但这里有个关键细节——差速不能直接加在左右电机的目标速度上而是要用“一个加、一个减”的方式保持平均速度不变否则小车在纠正偏航方向的同时整体速度会突然变化导致过弯速度不稳定。int error get_line_position(); // 返回-3到3 int base_speed 300; // 编码器计数值为目标速度 // PD控制 float Kp 40.0f; float Kd 15.0f; int turning Kp * error Kd * (error - last_error); int left_speed base_speed turning; int right_speed base_speed - turning; // 速度限幅 left_speed constrain(left_speed, -500, 500); right_speed constrain(right_speed, -500, 500); set_motor_speed(LEFT, left_speed); set_motor_speed(RIGHT, right_speed); last_error error;PD控制的D项微分作用非常关键尤其是在弯道中有连续误差变化时D项相当于给转向加了“阻尼”抑制小车来回摆头。如果只有P控制小车很容易在直线段出现S形振荡当Kp调大时尤其明显。4.3 路口检测与状态机不是所有“同时触发”都是路口灰度传感器在路口和弯道都会出现多路同时触发的现象如何区分这是H题最容易出问题的地方之一。我的做法是维护一组状态判断标志直道状态只有中间1到2路传感器触发误差绝对值小。弯道状态传感器偏向左或右误差绝对值变大但未达到“切断”状态。路口状态左右两侧传感器同时触发持续超过一定时间比如50ms并且此时误差不是单侧偏转导致的。路口判断必须加“持续时间”条件因为高速通过弯道时车身倾斜可能导致两侧传感器同时压线但那种情况下误差的方向一直偏向一边。而真正的十字或T型路口两侧传感器会在一个时间段内同时稳定触发。状态机大致是这样START - RUNNING - LEFT_TURN / RIGHT_TURN / STOP每个状态对应不同的转向逻辑遇到T型路口根据赛题规则判断是左转还是右转遇到十字路口则通常直行或按指定方向转终点区域需要停车时根据编码器累计里程控制停车位置。这里有一个我们调试很久才发现的坑路口转弯的控制策略不能和弯道一样用PD差速因为路口转弯需要的转向角度接近90度甚至更大必须用“先减速、再原地/小半径转向、再恢复直行”的流程。我们实现了转向动作等待函数通过编码器判断是否达到目标转角而不是用延时——延时受电池电压影响太大高电压下转动角度会明显偏大。4.4 里程计与终点停车编码器给的不仅是速度编码器的另一个重要用途是里程计。每检测到一次脉冲轮子前进固定距离累积脉冲数就能估算行驶距离。我们用这个功能实现了终点停车和区间测速。但里程计有一个致命问题容易累积误差。轮子打滑、路面不平等都会造成脉冲数和实际距离的偏差。解决办法有两个方向一是用起点到终点之间的标记线重新校正里程计经过特定位置时清零二是在最终停车前用灰度传感器检测终点标志线然后以标志线为基准做短距离PID减速停车。2024年H题的关键动作之一是定点停车如果只用里程计跑五圈可能第二圈就偏移到停不准了。我们采用的方式是“里程预判 终点线校正 短距减速”实测停车误差控制在±3cm以内比单纯靠里程计稳定得多。5. 路面实测中的经典故障与排查路径——每一台车都有它的脾气5.1 故障一直线走不直车头来回摆动现象小车在直道上呈S形前进速度越快摆动越明显。排查过程刚开始我们以为是灰度传感器阈值问题重新标定后没有改善然后怀疑轮子打滑检查了轮胎表面发现没有问题最后用串口打印实时误差数据发现误差在小范围内快速震荡左右轮速度也在剧烈变化——问题出在PID参数上。根因分析Kp过大D项阻尼不够。直道上传感器误差本身就小但P控制对这个小误差的放大过于敏感导致转向输出频繁跳变。解决办法是降低Kp增大Kd再把速度环的响应速度稍微调慢一点增大PID的积分时间。这条经验值很大如果你的车在直道上画龙99%不是硬件问题是转向PID参数激进了。5.2 故障二直角弯转不过去冲出赛道现象入弯时车头转到了但车身在过弯过程中继续偏移最后冲出赛道外侧。排查过程我们先用慢速测试发现在40%速度下转弯完全正常一旦提到70%以上就开始冲出去。这说明转向能力不足以维持高速过弯要么降低入弯速度要么增强差速输出。我们最后采取的组合方案是在进入直角弯前提前检测到“弯道信号”传感器偏到一侧然后自动降低目标速度到40%同时将转向PD的Kp临时调大1.5倍出弯后恢复。这套逻辑本质上是“动态参数调节”经验证比固定PID参数的高速转向方案稳定很多。5.3 故障三路口左转偶尔会识别成右转现象同一个T型路口跑十次有七八次正确偶尔会转反。这个坑特别隐蔽光看代码根本发现不了。最后的定位过程是用逻辑分析仪抓取灰度传感器的8路信号对比正常跑圈和错误跑圈时的信号时序发现错误的那几次左右传感器不是同时触发的而是先右后左中间隔了大概30ms。原因是小车轮子存在转速差异左右轮编码器显示速度相同但轮胎直径有微小误差过丁字路口时车头不是正对路口而是有一点偏斜导致“同时触发”的标志位没有被正确置位。我们修复的方式不是在传感器判断上做文章而是强行让进入路口状态的判定条件更严格在检测到左右两侧都有触发后增加一个短暂延时80ms等两侧都稳定触发后再执行转向动作转向时先回正车头再转弯转错的概率基本降到了零。这个排查过程让我意识到很多偶发故障靠肉眼和试错很难定位用串口或逻辑分析仪把关键信号波形抓出来是最快的路径。5.4 故障四电池电压对转向角度的隐形影响现象满电测试时转弯正常跑了几圈之后转弯角度越来越大到了最后直接过冲。根因是电压下降后电机输出扭矩降低同样的PWM占空比下转速明显下降但转向时间或者转向目标的编码器计数值没有变化所以实际转角不足。这个问题在加入速度闭环后得到一定缓解但没有完全解决因为速度环只能保证轮子转速一致不能保证转向过程的角速度一致。最终的解决方案是不再用固定时长的转向动作而是用IMU惯性测量单元作为转向角度的反馈源。在转向时读取陀螺仪的Z轴角速度积分值到达目标角度就立刻停止转向。这个方案比任何“延时 编码器估算”的方案都精准。不过IMU也有它的问题——零偏漂移。每次上电后需要静止一段时间做零偏校准否则角速度数据会带着一个固定偏移导致积分角度不准确。6. 比赛现场的时间管理与最后冲刺技巧6.1 赛前最后的参数标定流程比写代码更重要到了赛场你会发现所有队伍的技术路线都差不多拼的就是临场标定的效率和参数调整的快速迭代能力。我们总结了现场三十分钟内的固定操作流上电静止5秒完成IMU零偏校准。用白纸和黑胶带测试灰度传感器ADC值手动写入阈值。慢速跑一圈完整赛道确认所有路口和停车点都被正确识别。根据第一圈表现分三段调参直道稳定度、弯道跟线能力、路口转向精度。重复跑圈直到连续三圈无失误。每一步都必须有对应的代码调试接口。我们组在代码里做了按键切换参数预设的功能用三个按键分别调节基础速度、弯道速度和转向力度省去了反复插线下载程序的繁琐操作。这个设计在赛场上节省了至少半小时。6.2 多预案比赛不是验证最优解而是选择最不坏的方案很多人准备比赛时只准备了一套代码、一套参数一旦赛场环境与预期不符就会崩盘。我们组准备了三套预设参数方案A高速模式适合直道多、弯道缓的赛道速度快但对传感器要求高。方案B均衡模式速度中等转向平稳是默认首选。方案C低速稳定模式适合光线差、反光大、赛道磨损严重的环境牺牲速度换可靠性。比赛当天我们先用方案B跑了一轮测试圈发现赛场光线比平时暗不少灰度传感器读数比平时低了20%左右就果断切到方案C并把阈值下调到暗光参数。结果虽然全场速度看起来不快但我们每一圈都完赛了而不少高速队伍在半程就冲出了赛道。6.3 备用硬件的思维只带一套小车去赛场等于裸奔电赛现场最惊险的时刻是你的小车在现场跑得好好的突然一个轮子卡住了——检查发现是电机减速箱齿轮崩了一个齿。从那之后我的原则是至少带一套完整的备用驱动系统电机、驱动模块、电池、主控板而不是带一套完整的小车。因为备用小车往往和主车存在个体差异现场换车意味着所有参数都要重新调而换掉一个电机只需要重新标定对应的编码器方向改动量小得多。另外一个容易被忽略的备用件是轮胎。橡胶轮在高速摩擦下会磨损直径的变化直接影响速度和编码器里程的准确性。我们带了两组备用轮胎赛前如果发现车跑圈时间比平时慢了5%以上就会优先检查轮胎磨损。最后留给大家的几句实在话电赛H题是一个典型的“入门容易精通难”的题目它不像信号类题目那样有非常高深的理论门槛但想要拿高分拼的是系统工程的细致程度。从传感器标定到机械重心从PID参数到状态机逻辑任何一个薄弱环节都可能把整台车拉垮。我个人最大的体会是做这题绝对不能“重代码轻硬件”也不能“重硬件轻代码”硬件决定了你的上限软件决定了你能否把这个上限稳定发挥出来。调试过程中一定要习惯用数据和波形说话别凭感觉调参。如果你正在准备下一届电赛的类似题目我建议从现在开始就把编码器、IMU和灰度传感器的调试基本功练扎实尤其是数据可视化的能力——串口屏、蓝牙、上位机都行能实时看到传感器数据你的调车效率至少翻一倍。祝每一份调车的夜晚都能换来赛场上那稳稳跑完的一圈。