简介:这份资料来自第十七届全国大学生智能汽车竞赛完全模型组,由湖北工业大学蓝电YYDS Car队整理,面向备赛智能车竞赛的同学和指导教师,也适合嵌入式与视觉算法入门者学习工程实现。压缩包共539个文件,以C/C++源码为主体:包含262个h头文件、150个c源文件,以及hpp、cpp、XML、JSON等配置与工程文件,还附有演示视频、图片和说明文档,整体大小约69.67MB。目前已有881人学习浏览,说明该赛队方案受到一定关注。内容覆盖整车控制、传感器采集、底层驱动、通信协议和调试配置等关键环节,基本还原了一支参赛队的完整工程结构;借助随附的视频和图片,研究者可对照代码理解实际运行效果,便于进行代码复现、参数调整和方案优化。无论是用于赛后复盘、代码比对,还是为下一届比赛积累设计思路,都具有不错的参考价值。 第十七届全国大学生智能汽车竞赛的完全模型组,湖北工业大学蓝电YYDS Car队的那台小车,在备赛圈里其实挺有代表性。很多关注智能车的朋友一听到“完全模型组”,第一反应就是“摄像头识别+深度学习模型”,但真正把小车从能跑到能稳定完赛,中间的坑远比你想象的多。这篇文章我就以这支队伍的车为主线,把完全模型组的赛制要点、软硬件选型、模型部署和实车调试的完整链路拆开讲清楚,给准备参加下一届比赛或者正在做类似“视觉识别+运动控制”项目的朋友一份可以直接抄作业的参考。
完全模型组和传统的电磁组、摄像头组最大的区别在于“算力平台+模型车模”的组合。比赛允许使用指定竞赛车模,核心计算单元从MCU升级到带GPU的嵌入式平台,识别目标也从赛道边界升级为锥桶、红绿灯、人行道、减速带等交通元素。这意味着整个技术栈从“单片机控制”一下子跳到了“嵌入式Linux+深度学习推理”,对队伍的知识结构要求变化很大。如果你是第一次参赛,或者刚接触这类视觉机器人项目,这篇内容会帮你避开不少弯路。
1. 完全模型组到底在比什么:赛制与场景拆解
1.1 比赛任务背后的真实需求
完全模型组模拟的是“L4级自动驾驶在封闭园区的落地场景”。赛道上有锥桶围成的引导路径、红绿灯、通过线、人行道、减速带、施工绕行区域等元素,小车需要从起点出发,在尽量短的时间内完成一圈或多圈运行,同时不能违反交通规则(比如闯红灯、压线、碰锥桶)。听起来像自动驾驶的简化版,但比赛现场的难度一点也不“简化”。
从任务拆解来看,车要解决三个核心问题:我在哪、前方有什么、下一步怎么走。第一个问题靠定位与里程计,第二个问题靠摄像头与深度学习模型,第三个问题靠路径规划与运动控制。很多队伍前期只盯着模型识别率,结果上了赛道发现车跑着跑着就偏了,因为模型再准,控制环跟不上也白搭。完全模型组本质上是“感知-决策-控制”三环的系统工程,任何一环掉链子都会体现在圈时上。
1.2 车模与算力平台的限制条件
完全模型组对车模有严格规定,一般使用指定厂商提供的竞赛车模(某款1/16比例四轮小车),电机、舵机型号固定,允许改装空间集中在底盘、悬挂、轮胎和传感器支架上。算力平台则从英伟达Jetson系列、Intel NUC等几个指定范围内选择,绝大多数队伍最终都选了Jetson Nano或Jetson TX2,蓝电YYDS Car队用的是Jetson Nano(后来升级到TX2做对比测试)。
这里的核心矛盾是“功耗与算力”和“稳定与激进”的平衡。Jetson Nano的Max功耗只有10W,INT8算力大约472 GFLOPS,跑YOLOv5s大约能到20-30 FPS,但你不可能把GPU吃满去跑一个超大模型,否则发热降频后帧率更不稳定。所以模型选型、输入分辨率、推理框架都要围绕这个算力上限来设计,这也直接决定了后续的模型剪枝和TensorRT加速策略。
2. 从零搭一套可跑的感知系统:硬件与数据准备
2.1 传感器安装与标定实操
完全模型组的车载传感器核心就是摄像头,一般选用USB接口的广角工业摄像头(比如OV5640芯片的型号),安装在车模前上方,俯仰角大约15°到25°,这样既能看清近处的锥桶,又能保留远处的红绿灯信息。安装时有两个容易被忽略的点:一是镜头要避开LED指示灯和阳光直射角度,否则逆光时画面过曝,模型基本全废;二是固定支架必须用金属件加螺丝锁死,扎带一旦松动,摄像头角度漂移导致的识别失败会让你排查到怀疑人生。
标定方面,先用棋盘格标定相机内参,借助OpenCV的calibrateCamera拿到焦距和畸变系数,然后做透视变换,把图像投影到“俯视”视角,便于后续路径拟合。因为比赛场地地面是平整的,透视变换的固定矩阵可以直接离线算好写入配置。我建议标定时把锥桶放在不同距离拍照,至少采集30张以上,畸变矫正效果才稳定。现场如果换了摄像头或者改了安装角度,一定要重新标定,这一步偷懒后期全找回来。
2.2 数据采集与标注的工程化思路
深度学习模型不能靠想象,得靠数据。完全模型组的交通元素其实有限:红色锥桶、蓝色锥桶、红绿灯(红/绿/黄三色)、人行道斑马线、减速带、施工指示牌。每个类别采集500到1000张现场照片,再用LabelImg或X-AnyLabeling标注成YOLO格式的矩形框即可。采集时注意变换角度、距离和光照,最好把上午、下午、室内灯光、阴天都覆盖到,因为比赛现场光线往往和训练采集环境不一致。
标注是纯体力活,但有一个技巧值得分享:先拿一个初步训练好的模型做自动预标注,人工只负责修正。这样能把标注效率提升3到4倍。另外,数据增强要围绕比赛场景来做,不要用随机旋转90度这种破坏语义的增强,推荐加入HSV微调、随机亮度和轻微透视扰动。蓝电YYDS Car队当时在训练集里还专门混入了十几张“逆光+过曝”的现场照片,就是为了防止模型在室外强光下翻车。
3. 模型选型、训练与推理部署全记录
3.1 为什么选了YOLOv5s而不是更重的模型
在Jetson Nano这类边缘设备上,模型每大一点,帧率就掉一截。YOLOv5s在COCO上的mAP已经够用,模型体积约14MB,INT8量化后推理只需要几十毫秒。对比过YOLOv7-tiny和YOLOv8n,效果差距不大,但YOLOv5的部署资料和TensorRT支持最成熟,队友之间交流成本低,有问题能快速查到方案。这里我建议新队伍不要盲目追新架构,稳定可复现比单点精度更重要。
训练时输入尺寸设置为640x640,batch size 16,用预训练权重微调,优化器选择SGD,初始学习率0.01,配合余弦退火。训练轮数不用太多,200轮左右就能收敛,因为类别少且特征明显。重点是把置信度阈值调到0.4到0.5之间,既避免漏检,又不会因为误检造成车辆误动作。还有一个经验:如果锥桶在远距离时框不稳定,可以在后处理里加一个“小目标增强”逻辑,对面积小于一定像素的框做二次放大推理,虽然多花一点时间,但识别稳定性提升非常明显。
3.2 TensorRT加速与INT8量化的注意事项
部署环节是整个项目的分水岭。直接用PyTorch推理在Jetson Nano上YOLOv5s只能跑到8到12 FPS,对于比赛来说完全不够。必须把模型转成TensorRT的engine格式,开启FP16或INT8推理,帧率能立刻拉到25到30 FPS,整个系统才“活”过来。转换流程是:.pt权重先导出为.onnx,再用trtexec或Python API生成TensorRT engine。注意ONNX导出时要把opset版本设高一点,否则某些算子不支持会导致转换失败。
INT8量化需要一组校准图片,一般取200到500张有代表性的训练图片。这里有个坑:如果校准图片里锥桶颜色不够多样,量化后模型对蓝色锥桶的召回率会明显下降。建议校准集把红蓝锥桶数量配平,并且混入不同光照条件的样本。实测下来,FP16精度损失几乎可忽略,INT8在部分类别上mAP掉1到2个百分点,但对比赛来说完全可接受,真车跑起来,速度快了之后你根本不会在意那点精度差。
初始化推理引擎时也有讲究。TensorRT的engine构建非常耗时,第一次跑可能花5分钟以上,所以务必把序列化后的.engine文件存到磁盘,下次直接反序列化加载。蓝电YYDS Car队是开机就把engine加载进内存,然后把摄像头和串口初始化也做完,保证从按下启动开关到第一帧推理结果出来不超过8秒。这个“启动时间”在比赛中也是计入准备环节的,别忽略。
4. 决策规划与运动控制:让车真正跑稳跑快
4.1 路径决策:从“识别结果”到“方向盘转角”
感知输出的是每个目标的类别和框坐标,接下来要把它转换成车的控制量。完全模型组的路径决策可以拆成两条线:一条是“近场路径拟合”,核心是锥桶围成的通道中心线;另一条是“远场语义检测”,对应红绿灯、人行道等需要提前减速或停车的元素。
近场处理时,把图像中锥桶检测框的底边中点投影到世界坐标(透视变换后的俯视图),然后按横向位置分成左右两组,分别对左右锥桶做多项式拟合,再取两条拟合曲线中线的横向偏移量,作为转向控制的误差输入。这样做比直接拿中心点求平均值更稳,因为即使个别锥桶漏检或者误检,单侧拟合曲线也不会剧烈跳变。蓝电YYDS Car队在这里加了一个滑动窗口滤波:取最近5帧的误差做加权平均,权重越靠当前帧越大,这样转向既跟手又不会抖。
4.2 串级PID与速度规划参数整定
转向控制我用的是串级PID:外环是横向偏差比例控制,内环是舵机角度PD控制。外环P大概在1.2到1.8之间,内环P在0.8左右,D设0.05,输出限幅在±30度。速度控制则用一个目标速度表:进入弯道前减速到0.8m/s,直道可以跑到1.5m/s,遇到人行道前500ms减速到0.4m/s,停车线前完全刹停等红灯。这些速度表的设定,与其说是算法问题,不如说是实车反复测试的经验值。
我调试速度时习惯用“先低速跑通逻辑,再逐步加速”的顺序。一开始把所有目标速度都设成0.5m/s,确认每个交通元素都能正确触发动作,然后弯道速度每次加0.1m/s,直到出现转向不足或甩尾,记录下临界速度再往回退一档。这个方法比较笨,但非常有效,避免了一上来就高速跑导致根本分不清是感知问题还是控制问题。如果基础控制不稳,建议优先把舵机打角调平滑,再考虑极限速度。
5. 实车调试的常见问题与排查速查表
实车调试和仿真环境完全是两个世界,很多问题在模拟器里根本不会出现。我这里把现场最容易踩的坑汇总成一个速查表,每一行都是真金白银换来的经验。
| 症状 | 可能原因 | 排查与解决 |
|---|---|---|
| 锥桶频繁漏检 | 曝光过高/逆光/摄像头角度偏移 | 手动/自动曝光补偿,调整安装俯仰角,重新标定 |
| 红绿灯不触发 | 目标太小或颜色误检 | 提高输入分辨率或对小目标做二次放大推理 |
| 直道跑偏 | 摄像头标定不准或PID外环P太小 | 重新做透视变换标定,加大外环P |
| 弯道甩尾 | 过弯速度过快或转向打角饱和 | 降低弯道目标速度,增大舵机限幅 |
| 整车卡顿掉帧 | TensorRT推理帧率低或CPU占用高 | 检查是否真正加载了engine,开启FP16/INT8,关闭后台无用进程 |
| 电机抖动 | 电池电压不稳或控制频率过低 | 更换高C数电池,保证控制循环在50Hz以上 |
| 发车后10秒无动作 | Java/Python进程崩溃或模型加载失败 | 查看日志,确认engine文件路径正确,增加异常重启机制 |
| 人行道前不减速 | 检测框置信度低被过滤 | 降低置信度阈值,或者对特定元素单独调阈值 |
排查时有个总原则:先确认感知输出正确,再查决策逻辑,最后才查运动控制。每次只改一个变量,不要同时调PID和曝光,否则出了问题根本没法定位。我给队伍定的流程是,先开一个调试模式,在屏幕上实时叠加显示检测框、路径拟合线、目标速度和当前速度,跑一圈下来回看录屏,基本一眼就能看出问题出在哪个环节。
6. 一个容易被忽略的关键:系统稳定性和容错设计
比赛现场和实验室最大的区别是“你只有两次正式发车机会”,任何一次中途死机或卡死都直接影响到最终成绩。所以系统稳定性不是加分项,而是底线性要求。蓝电YYDS Car队在这方面吃过亏:第一次省赛,赛前测试都正常,正式发车时摄像头突然无图像,整个车在原地傻了三秒才被判罚。后来排查是USB接口松动导致摄像头掉线,从那以后所有线束都做了防脱处理。
针对稳定性,我建议至少做四件事:第一,摄像头运行状态监控,无图像超过1秒就自动重启摄像头并恢复到安全停车状态;第二,推理进程异常时自动重启,而不是整个系统崩溃;第三,串口或控制指令增加心跳包,上位机和下位机任何一方掉线都能在500ms内检测到并刹车;第四,核心代码用systemd配置成服务,开机自启并带自动重启策略。这些容错设计不需要多高深的技术,但能把“概率性故障”变成“可恢复故障”,在比赛里价值极大。
另外锂电池电量管理也容易被忽视。电量低于一定阈值时,舵机供电不足会导致转向响应变慢,车辆表现和满电时完全不一样。我们会在程序里读取电池电压,低于7.4V时自动降速并提示更换电池,避免电量不足导致发挥失常。这些小细节累积起来,才能保证每次上场都是最好的状态。
7. 赛后复盘与可扩展方向
比赛结束不等于项目结束。蓝电YYDS Car队赛后做了一次完整的代码和资料归档,把模型、数据集、标定参数、PID参数、赛道录屏全部打包好,这样后面每一届的队员都能快速接手,不用重复踩坑。如果你也是刚比完赛,强烈建议花半天时间做同样的事,你可能会发现很多“当时没时间整理”的配置和代码其实非常有价值。
从技术演进角度看,完全模型组这个项目后续可以做很多扩展:比如把YOLOv5换成更轻量化的模型并结合硬件NPU加速;加入全局路径规划和动态避障,让车在遇到突发障碍时能自动绕行;甚至可以用强化学习训练端到端控制策略,替代手动整定的PID参数。这些方向对后续做机器人、自动驾驶相关课题或者找相关工作,都是很好的项目经历。
最后分享一点个人感受:参加这类比赛,最有价值的不是那张奖状,而是逼着你在有限时间内把一个系统工程从零做到能稳定运行,这中间的过程管理、团队协作和问题定位能力,才是真正能带走的东西。希望这篇文章能给正在准备比赛或做类似项目的你一些实实在在的帮助。
本文还有配套的精品资源,点击获取