
去年备赛期间的一个傍晚我们为卡丁快跑组做赛前最后一轮联合调试。小车在直道上跑得稳稳当当但一进连续弯道就开始“画龙”队友开玩笑说这车跟刚学驾照的人似的方向盘在手里来回折腾。当时我们都以为是转向PID没调好后来排查了一整天才发现问题根本不在控制层而是感知输出的分割掩码在光照变化时出现了像素级抖动。那一刻我意识到卡丁快跑组真正考验的从来不是某个单点技术而是整条链路的配合能力。“自动驾驶”和“人车交互”这两条线看似独立实际在比赛中会深度耦合自主模式要稳定跑完赛道但系统又必须随时准备把控制权交还给人类驾驶员并且在切换的瞬间不能失控。这种“既要全自动又要可接管”的矛盾正是这个赛题组最迷人的地方。这篇文章是我从读规则、选硬件、搭感知模型、设计交互逻辑到实车联调的完整复盘内容包括规则拆解、技术选型、实操步骤和踩坑记录。无论你是刚进实验室准备打下一届比赛的本科生还是已经在调车的老队员应该都能从里面找到和自己情况对应的方案和教训。1. 卡丁快跑组的规则底层逻辑与技术需求推导1.1 规则到底在考什么全国大学生智能车竞赛每个组别的规则看似年年变但背后的人才培养导向是清晰的。卡丁快跑组这几年不断调整细节核心逻辑始终围绕三件事展开第一验证自动驾驶在低速结构化场景下的感知与规划能力第二把“人”拉进控制回路考察人机共驾场景下系统的切换和响应能力第三控制硬件成本和算法门槛让普通高校队伍也能玩得起。以第二十一届的规则也是我主要备赛的一届为例场地是一条模拟卡丁车赛道的封闭路径赛道边界有明显标识车辆需要在无人干预的情况下完成若干圈计时。同时在一些版本中比赛设立了人车交互环节车辆开到指定区域后要识别交互标志停车等待操作指令或者允许遥控接管通过一段复杂区域。这个设计的意图很明确——现实中的自动驾驶不会完全脱离人的监督系统必须知道“什么时候该自己开”“什么时候该把控制权交出去”。这个规则导向直接决定了技术方案的走向你不可能只写一个简单的循迹算法就拿高分必须有一套可以在“自动驾驶”和“人类控制”之间平滑切换的系统架构。1.2 把规则条款翻译成技术需求清单我拿到规则文本后做的第一件事不是翻芯片手册而是把每一条规则翻译成一张技术需求清单然后根据清单推导出模块划分和任务优先级。这套方法可以说贯穿了整个备赛周期规则条目技术需求涉及模块自主循迹若干圈稳定的视觉感知 路径跟踪控制感知、规划、控制减速/停车标志识别标志物检测 状态机切换感知、决策遥控接管复杂区域无线通信链路 模式切换通信、交互状态上报/屏幕显示状态机可视化展示交互、嵌入式这张表是团队从零开始的“作战地图”。有了它你就能明确资源应该投到哪里而不是漫无目的地在一堆细枝末节上浪费精力。我们当时的优先级排序是感知的稳定性 控制的极限速度 交互的花活。这个排序在后面的备赛中被证明非常正确——赛场上百分之六十的意外都源于感知抖动控制参数调得再激进也弥补不了感知给出的错误输入。我建议每支队伍在备赛第一周就做同样的事把规则文本逐条拆解做成一个需求追踪矩阵然后让每个模块负责人对着这张表认领任务。这不仅能防止需求遗漏还方便后期评审和问题回溯。2. 自动驾驶链路落地传感器选型到线控底盘2.1 传感器与算力平台的选型决策卡丁快跑组的传感器方案几乎绕不开摄像头。原因很简单赛道边界、交通标志、交互区域这些信息本质上是视觉语义而低速结构化行车场景又不需要激光雷达那样昂贵的深度感知。很多队伍纠结要不要加超声波或TOF做辅助避障我们实测后的结论是可以加但别指望它兜底——它的探测范围有限在激烈转向时根本来不及给出有效干预。我们最终选定的传感器配置如下主摄像头全局快门工业摄像头分辨率1280x720最高帧率60fps以上。全局快门能有效避免高速运动时的果冻效应这一点在过弯时尤其重要。我们搭配6mm定焦镜头摄像头安装高度约35厘米视野刚好覆盖车前约2.5米区域。算力平台Jetson Nano4GB版本。选它是因为要跑语义分割模型而树莓派4B的CPU推理帧率只有个位数完全不够用。Jetson Nano的GPU可以稳定跑到15-20fps功耗10W上下配合小型锂电池组刚好合适。编码器后轮双编码器用于速度闭环和简单的里程计估算。这个容易被新人忽略但没有轮速反馈速度环控制就是空中楼阁。这里要给出一个选型对比帮你建立更直观的判断方案优势劣势适用场景树莓派4B 轻量分类网络功耗低、生态成熟CPU推理帧率低复杂模型跑不动对感知要求不高的简单巡线Jetson Nano 语义分割GPU推理快、可跑轻量分割网络功耗高、启动慢、需要散热卡丁快跑组主流方案上位机笔记本 无线图传算力最强、调试方便延迟高、依赖无线链路稳定性实验室调试不适合比赛2.2 语义分割在赛道感知中的实际角色卡丁快跑组里语义分割是赛道感知的核心手段。原因是赛道边界、路面和背景的区分本质上是像素级语义问题分割网络输出的掩码可以直接用于路径拟合和边界判断远比传统HSV颜色阈值处理要鲁棒。我们采用的方案是轻量级分割网络MobileNetV2编码器加轻量解码器输出两类分割掩码赛道/背景交互标志物单独作为第三类。输入分辨率768x432单帧推理时间约40-60ms整体感知帧率稳定在15fps左右配合底层控制周期完全够用。分割掩码如何使用这里有一个关键经验不要直接在像素坐标上做路径跟踪一定要先做透视变换把掩码投影到车体坐标系的鸟瞰图。因为摄像头是斜向下安装的像素坐标中赛道宽度在不同距离上不一致直接提取中心线会引入系统性偏差——近处看起来准确远处偏移严重。具体做法分两步标定单应性矩阵在车体前方地面贴一块已知尺寸的标定布手动标注对应点用OpenCV的findHomography算出单应矩阵。标定一次后固定摄像头位置即可长期使用。鸟瞰图路径拟合在鸟瞰图上按行扫描提取每行的赛道中心像素然后用滑动窗口或最小二乘拟合出一条平滑路径曲线。我们实测下来滑动窗口方法在赛道边缘不规则时更稳定。2.3 底盘线控改造与底层控制链路市面上能买到的卡丁车模型底盘绝大多数是玩具级遥控车。要实现自动驾驶底盘必须支持两路底层控制转向和驱动。我们使用1/10比例电动遥控车底盘转向采用舵机驱动采用无刷电机加电调改造核心工作有三块舵机控制从遥控接收机取出PWM信号改为由STM32单片机直接输出PWM。舵机PWM频率50Hz脉宽范围约1ms-2ms。这里有一个值得注意的细节舵机中位校准要做扎实。我们第一次调车时舵机中位偏了约15度导致车辆在直道上一直轻微左偏排查了很久才发现是机械中位而不是控制算法问题。速度闭环在底层MCU上实现电机的速度闭环控制周期定在5-10ms。编码器反馈换算成米每秒与上位机下发的目标速度做PI控制。这个底层速度环是整个系统的基石——如果速度环不稳上层路径规划质量再好也会被底层执行损耗掉。我们在调参时发现P增益过大容易导致速度振荡I增益过大会导致响应迟滞最终定在一组中间参数Kp0.8Ki0.05效果比较理想。上位机-底层通信采用UART串口波特率115200自定义数据帧格式。上位机每20ms下发一组期望速度和期望转向角底层MCU返回当前速度、转向角、电池电压等状态信息。实车联调阶段我们测过一次完整的端到端延迟摄像头采集约10ms分割推理约50ms路径规划约5ms串口下发约2ms底层执行约10ms整体约80-100ms。在竞赛场景下的低速行驶2-3m/s这个延迟完全可以接受。但如果想上4m/s以上的速度就得考虑更高帧率摄像头和更快的推理框架同时把底层控制周期压缩到5ms以内。3. 人车交互设计从遥控接管到状态可视化3.1 竞赛中人车交互到底在解决什么问题很多人以为卡丁快跑组的“人车交互”就是给车加个遥控器这是误解。比赛语境下的人车交互实际是考察自动驾驶系统在真实人机共驾场景下的能力边界具体包括三类场景遥控接管车辆在自动驾驶过程中出现险情例如即将冲出赛道或到达指定交互区操作员通过遥控器接管车辆完成脱困或特殊动作之后切回自动驾驶模式。这个过程中最关键的是切换瞬间不能有明显的控制偏差——如果车辆正在高速过弯突然切到手动模式但遥控器初始输入和当前自动控制输出不一致车会猛打方向。状态上报车辆需要把当前状态实时显示在车载屏幕或通过无线模块上报给场外电脑。裁判和队员要能一眼看出车辆在自动模式还是手动模式、当前速度如何、感知置信度是否健康。我们早期没有做这块直到有一次车辆在自动模式下冲出了赛道但裁判认为我们操作员手动干预了双方来回拉扯——如果有清晰的状态记录这个问题就不存在了。指令响应外部系统向车辆下发“停车”“起步”“切换模式”“紧急制动”等指令车辆按优先级执行。这里的关键是优先级仲裁。3.2 状态机的设计与仲裁逻辑人车交互的核心是一个健壮的状态机。我在这次备赛中最深的体会是交互逻辑千万别用一堆if-else硬怼在主循环里否则某条状态分支跑飞时根本无从定位。我们最终设计了一个四状态状态机AUTO自动驾驶感知-规划-控制全链路工作。MANUAL手动接管遥控器直接控制转向和油门底层MCU执行遥控指令。WAITING等待指令车辆停在安全位置等待外部指令。EMERGENCY紧急制动任何状态下检测到急停命令立即执行制动。状态切换的触发源包括遥控指令、感知模块输出的交互标志信号、以及外部串口指令。这里有一个非常重要的工程细节状态机必须设置输入仲裁层明确定义优先级。当AUTO模式下车辆接近交互区感知模块输出“检测到交互标志”状态机从AUTO切到WAITING此时如果操作员同时按下遥控器接管键系统必须按优先级决定进入MANUAL还是维持WAITING。我们定义的优先级是EMERGENCY MANUAL WAITING AUTO。这个仲裁逻辑确保紧急制动永远第一时间响应其次是人工接管然后才是感知触发的停车等待。实测下来这套仲裁机制在指令冲突场景中表现稳定没有出现过一次误触发或卡死。3.3 可视化调试界面和AR辅助的加分价值可视化调试界面是我强烈建议每支队伍都花时间做的东西。很多队伍调车时只能通过串口打印一个浮点数根本不知道摄像头看到了什么、分割掩码到底对不对。我们花了一个下午做了一套实用可视化方案电脑端实时显示摄像头画面、分割掩码叠加层、规划路径曲线右上角显示车辆当前状态AUTO/MANUAL/WAITING/EMERGENCY每200ms刷新一次这套界面的价值在联调阶段体现得淋漓尽致。比如车辆出现“画龙”现象时我们不再需要猜测是控制参数问题还是感知延迟问题直接看路径曲线和分割输出的时间对齐关系就能定位。有一次我们发现路径曲线总是滞后约300ms顺藤摸瓜发现是可视化线程和推理线程之间消息队列积压修正后问题立刻消失。再说AR辅助。热搜词里有“增强现实 虚拟现实 自动驾驶”这个组合这个方向在竞赛中的应用确实很有意思——通过AR技术在真实赛道画面上叠加虚拟路径和虚拟交通标志可以低成本模拟更多交互场景。我们当时做了一个小Demo用手机相机对着赛道实时渲染分割结果和虚拟锥桶虽然没进正式比赛但作为技术探索和答辩展示非常有价值评委对这种“能看见系统内部状态”的展示方式印象很深刻。4. 从自定义数据集到实车推理训练与部署的完整链路4.1 自采数据集的组织策略智能车竞赛很少直接用公开数据集训练分割模型原因很现实竞赛场地的光照、视角、赛道颜色和公开数据差异太大。你必须采集自己的数据这个环节越早开始越好。我们的数据采集流程有三个关键环节采集阶段在相近的赛道环境里跑车用Python脚本按10fps保存摄像头画面。注意画面的多样性比总帧数更重要——尽量覆盖不同光照、直道、弯道、交互区、阴影区。我们总共采集了约3000张原始图片通过筛选和去重后保留约1500张用于标注。标注阶段使用LabelMe逐帧标注语义类别就是三类赛道区域、背景区域、交互标志物。1500张图、3个人标了两天左右人均速度大约每小时60张。这里建议标注时保持一致性——比如赛道边界画到哪一层、阴影下的赛道是否算赛道这些标准要在团队内对齐否则模型会学到矛盾信息。增强阶段随机亮度对比度调整、随机裁剪、水平翻转。注意水平翻转只适用于没有方向性标志物的场景如果交互标志有方向属性比如箭头翻转后语义就会出错这时候只能对非标志物的样本做翻转。4.2 模型训练与调参的具体参数训练直接用PyTorch的轻量分割框架即可无需从头搭建。我们的训练配置如下优化器SGD momentummomentum0.9初始学习率0.01采用余弦退火调度批大小16训练轮数100个epoch损失函数交叉熵损失 Dice loss辅助训练中最值得分享的两个经验类别不平衡卡丁快跑组的典型画面中赛道像素占比约30%-50%不算极度不平衡但直接用普通交叉熵训练模型还是会出现把暗处赛道预测为背景的倾向。加入Dice loss后小目标的召回率提升明显验证集mIoU从0.86提升到0.92。过拟合处理我们早期训练100个epoch后出现明显过拟合训练集mIoU 0.98验证集却只有0.85。解决方案有三步增大数据增强强度尤其是随机亮度对比度、降低模型容量压缩解码器通道数、提前停止epoch 75上下。三个措施组合后验证集mIoU稳定在0.90以上。4.3 模型部署的推理优化训练完的模型要部署到Jetson Nano上不能直接用PyTorch原版跑否则帧率会很难看。我们的优化步骤是将模型导出为ONNX格式再通过TensorRT转换引擎开启FP16精度。输入分辨率从训练时的768x432维持不变但将输出mask缩小到输入的一半再上采样减少解码器计算量。将推理线程与控制线程分离用队列传递推理结果避免推理阻塞影响控制周期。经过TensorRT加速后单帧推理时间从约60ms降到约35ms感知帧率提升到20fps左右。如果你用的是Jetson Nano 2GB版本或树莓派建议使用更轻量的编码器例如MobileNetV3-small并进一步降低输入分辨率。4.4 实车推理时最容易被忽视的三个鲁棒性问题模型在训练集和验证集上指标再好也不代表在实车上能稳定运行。我们实测中遇到的最典型问题有三个光照突变从室内灯光切换到太阳直射的赛道区域画面整体过曝分割模型开始把高光区域预测为赛道。解决办法不是换模型而是给摄像头加自动曝光限制——锁定曝光时间上限和增益或者做简单的白平衡校正。我们最终锁定了参数比赛过程中画面稳定分割输出不再剧烈抖动。动态模糊车速上去后摄像头画面出现运动模糊分割边缘破碎、掩码不完整。全局快门加锁定曝光能缓解但最佳手段还是让帧率和车速匹配——保证单帧对应的水平位移不超过画面宽度的15%。说白了速度越快对帧率要求越高否则感知信息在时间轴上就是“稀疏的”控制稳定性必然下降。遮挡与边缘干扰对手车辆或自己的车尾进入视野造成分割掩码断裂。比赛中通过“只信任车体前方一定ROI区域”来规避——把边缘区域的输出忽略掉只在核心ROI内做路径拟合。这个判断基于一个朴素的常识近距离的赛道语义才是控制的关键远处的干扰不应影响当前决策。5. 实车联调踩坑记录三轮几乎拖垮进度的疑难杂症5.1 第一坑摄像头自动曝光把模型坑了这个坑我们花了将近三天才定位。现象是车辆在室内跑得很好一上室外赛道就疯狂偏航。一开始怀疑模型泛化差后来通过可视化界面发现室外强光下摄像头自动曝光把曝光时间压得很短虽然帧率上去了但画面变得很暗分割掩码丢失了大量赛道细节而室内光照不足时自动曝光又把曝光时间拉得很长画面出现拖影模型把拖影边缘当成了赛道边界。完整排查链路第一步看串口日志发现模型输出的赛道中心点坐标在室外场景频繁跳变第二步看分割掩码叠加图发现掩码在光线变化时出现大片空洞第三步检查摄像头参数发现曝光时间和增益在自动调节第四步固定曝光和增益后复测问题消除。这个案例的典型性在于自动曝光是“感知-控制”链路里最隐蔽的干扰源。它不属于模型或控制算法的问题但影响却比参数调优大得多。我们后来在比赛前把所有摄像头参数固定并在代码里禁用自动调节这个失误再没出现过。5.2 第二坑底盘机械间隙导致转向失控车辆过弯时总是转向过度无论怎么调PID都救不回来。我们一度以为是控制参数不匹配连续调了两天无果。后来用手把舵机摆到中位、把车轮摆正发现车轮实际上还有大约8度的自由旷量——这是转向结构齿轮间隙造成的。低速时这个间隙不明显车速上来后旷量导致的转向误差就被放大成明显的延迟与超调。完整排查链路第一步把PID的输出调到极低车辆仍然无法回正第二步在可视化界面中叠加“期望路径”和“实际轨迹”发现车辆实际轨迹在出弯时始终比期望路径更靠外第三步断开控制回路单独测试舵机响应发现转向指令已经归零但车轮没有回到中位第四步拆开转向结构找到齿轮间隙过大的根因。解决方案分两步一是加固转向结构更换配合更紧密的舵机摇臂和齿轮把旷量从8度压缩到3度以内二是在控制器里加入“间隙补偿”——每次转向方向改变时额外增加一个小的固定修正量补偿齿轮间隙带来的误差。这两项措施做完后同样的PID参数下车辆过弯轨迹明显变得更干净。5.3 第三坑无线模块电磁干扰产生“鬼数据”我们做遥控接管时用的是2.4G无线模块。有一次联调时车辆莫名其妙地自动制动时好时坏。第一次怀疑是代码逻辑bug排查状态机半天没找到问题第二次怀疑是遥控器误触但确认没有操作员按下制动键第三次通过录屏和串口日志比对发现底层MCU确实收到了“急停指令”但该指令并非遥控器发出。完整排查链路第一步在串口日志中给每条收到的指令加时间戳和来源标签第二步发现有异常指令帧的校验码是错误的第三步定位到无线串口模块和摄像头USB线在机械结构上靠得太近电机启动时电磁干扰导致串口数据误码第四步把天线和数据排线分离、加磁环并在通信协议中增加CRC16校验、校验失败直接丢弃。这事最大的教训是两条硬性规则第一所有无线模块的天线必须远离数据排线和电机电源线第二通信协议必须带校验位校验失败直接丢弃帧数据绝不能盲目解析执行。现在每当我看到有人用裸串口发指令而没有任何校验时都会想起那个下午对着“中邪”的车发呆的经历。6. 备赛节奏、团队分工与资源投入的优先序6.1 团队分工建议与时间线管理卡丁快跑组的技术链路很长从感知到控制到交互到机械单靠一个人扛完全不现实。我们队伍一共5人分工如下硬件/底盘两人整车改装、电路设计、底层MCU、通信协议感知/算法两人数据采集、标注、模型训练、推理部署系统集成/交互一人状态机、可视化调试、遥控接管逻辑这个分工最大的坑在于前四周大家都在各自为战没有人负责“整系统集成”。到第五周第一次全链路联调时才发现算法同学交付的模型输出格式和交互同学设计的状态机接口完全对不上底层MCU的通信帧协议也改了三个版本。如果你还在备赛初期务必从第一周就指定一位“系统集成负责人”每周做一次全流程联调——哪怕很粗糙也要让整辆车能动起来。我们的时间线大致如下第1-2周规则拆解、需求列表、硬件采购第3-5周底盘改装、底层控制、数据采集启动第6-8周模型训练迭代、状态机设计、交互逻辑开发第9-10周全链路联调、可视化调试、赛道测试第11-12周可靠性测试、备用方案准备、答辩材料6.2 回报率最高的五项投入复盘整个备赛周期我会把资源投入按回报率排序供后来者参考一、稳定的底盘执行。这是所有上层技术的基石。把速度环、转向响应调稳后续所有算法的验证才有意义。我们在底盘上投入的时间约占整个项目30%回报远超预期。二、靠谱的感知鲁棒性。与其在模型结构上追求刷点不如花时间做曝光锁定、ROI设计、多场景数据采集。感知稳定了控制算法才能安全地激进才能真正跑出好成绩。三、可复现的训练与推理流程。把数据采集、标注、训练、导出、部署的整个过程脚本化让任何一位队员在半天内都能跑通。这个投入在换人交接时价值巨大——我们中途一位算法同学因故退出新队友靠着文档和脚本只用了两天就接上了。四、交互状态机的健壮性。状态机的分支覆盖要全尤其测试“切换失败”“指令冲突”这类极端情况。我们专门花了一个晚上对状态机做了穷举测试把所有可能的输入组合和切换路径都过了一遍确保没有死锁分支。五、可视化调试界面。投入产出比极高能省下无数调试时间。没有可视化界面你只能对着串口数字猜问题有了可视化界面问题定位效率提升三倍以上。6.3 最后想分享的一点体会卡丁快跑组对我最大的影响不是拿了什么名次而是让我理解了一个系统工程在资源受限条件下如何做取舍哪些模块必须做到完美哪些只需要做到能用哪些干脆不做。这个判断力在后续的学习和工作中非常受用。我建议下一届备赛的同学别一上来就追最新的模型或者最贵的设备。先把一条最简单的自动驾驶链路完整跑通——摄像头采集、分割、路径拟合、底盘控制、状态上报——然后再一步步迭代。整套系统能稳定跑完一圈的那一天你会发现自己对“自动驾驶与人车交互”的理解已经远超代码本身了。备赛过程中难免有反复调试到崩溃的时刻但那些深夜在实验室里盯着可视化界面等待车辆平稳过弯的日子恰恰是整个竞赛最值得回味的经历。