全国大学生智能汽车竞赛的“讯飞组”前几篇解读,把规则、硬件、环境和最基础的巡线都过了一遍。到第五篇,我发现很多队伍恰恰在这个阶段卡住:车已经能跑了,但离“稳定完赛”还差一口气。这篇我打算换一种写法,不按照官方手册逐条念,而是站在“带完一整届队伍”的角度,把讯飞组整个备赛周期里最关键的任务拆解、软硬件分工、语音与视觉双链路联调,以及最后阶段踩过的坑,全部倒出来说说。适合正在备赛、手里已经有车在调的同学,也适合刚入坑想看明白这个组别到底在练什么的观望者。
1. 先把任务拆透:讯飞组到底考的什么
1.1 这个组和传统竞速组的本质区别
全国大学生智能汽车竞赛的传统组别,核心就是两个字:快。赛道元素再多,最终目标仍是更短的圈速。讯飞组的出发点不一样,它把“语音交互”和“视觉认知”同时塞进了智能车这个小载体里。也就是说,你的车不能只是一个闭着眼睛冲圈的机器,它必须能听指令、能看懂路况、能根据任务切换行为模式。
先把三个核心能力标签列出来:
- 感知能力:通过摄像头识别赛道边界、停止线、特殊标志区或引导标签,相当于车的眼睛。
- 交互能力:通过语音模块识别预设指令,比如“启动”、“靠边停车”、“切换任务”,相当于车的耳朵。
- 决策与控制能力:根据视觉和语音的综合输入,决定加速、减速、转向还是停车,相当于车的脑子和小脑。
如果你只把它当成一个“加了语音模块的竞速车”,备赛方向会跑偏。你会花大量时间抠速度,却忽略了语音指令稳定识别、视觉与语音同时触发时的优先级冲突处理,而这些恰恰是讯飞组真正拉开差距的地方。
1.2 从规则倒推系统需求
看任何竞赛任务,第一步不是动手,而是把规则里能拿到的信息全部列出来,倒推系统需求。拿通常的赛道模型来说,任务模块大概包括:
| 任务模块 | 典型特征 | 对系统的要求 |
|---|---|---|
| 正常循迹 | 直道、弯道、十字路口 | 稳定识别赛道边界,平滑控制转向 |
| 语音指令触发 | 赛道某处语音播报或人工发令 | 可靠拾音、快速识别、动作切换 |
| 特殊区域提示 | 减速带、坡道、停止线 | 低速通过或定点停车 |
| 终点停车 | 终点斑马线/停止线 | 精确检测、准确刹车 |
把这些任务映射到功能模块,马上能得出一个关键结论:系统不是单线程的“摄像头—控制”,而是多模态的“感知—融合—决策”结构。语音识别的结果可能改变目标速度或目标状态,视觉检测的结果决定基础路径,二者必须统一在一个状态机里管理。这套结构如果等联调阶段才临时拼装,必定出问题。
所以我的建议是,备赛第一天就在代码里把“任务状态机”这个骨架搭好。每个状态对应一个行为,比如“正常巡线”“语音等待”“减速状态”“停车状态”,状态切换的事件就是视觉检测或语音识别回调。这样后面所有功能开发都是往状态机里填内容,而不是不断打补丁。
2. 软硬件架构:一辆小车的分工艺术
2.1 不要再纠结“谁的配置更高”
很多同学刚拿到套件,第一反应是换更好的主控、更清晰的摄像头、更贵的语音模块。但我带过几届队伍之后,必须泼一盆冷水:讯飞组的比赛难度通常不会高到需要极限硬件才能过,真正难的是软硬件之间的配合,还有实时性。
一套合理的讯飞组系统,通常包含几个固定角色:
- 主控单元:负责图像处理、路径决策、电机和舵机控制、与语音模块通信,相当于中央大脑,要求运算能力够用、外设接口够全、开发环境成熟。
- 图像传感器:负责采集赛道图像,通常用灰度摄像头或RGB摄像头,重点在于帧率和曝光可控,而不是单纯追求分辨率。
- 语音识别单元:独立于主控工作,完成拾音、唤醒、识别,把结果通过串口或IIC发给主控。这个模块最好带离线识别能力,因为比赛现场网络环境不稳定,在线识别会翻车。
- 执行机构:包含舵机和驱动电机,响应要线性,控制周期要稳定。
- 电源模块:这个最容易被忽略。电机大电流、语音模块瞬间功耗、主控电压跌落,任何一路波动都会导致复位或者识别异常。
2.2 架构设计里最重要的两个原则
第一个原则是“处理器专职化”。不要把语音识别算法硬塞进主控里跑。语音识别的计算密集度很高,尤其在噪声环境下做特征提取和匹配,会大量抢占主控时间片。一旦抢占发生,图像处理的帧率就会波动,巡线就会发飘。正确做法是语音识别交给独立模组,主控只负责读结果、做状态迁移,两边通过稳定的串口协议通信。
第二个原则是“图像处理要控制变量”。很多人喜欢在摄像头画面上叠加一堆调试信息,这没问题,但一定要保证这些调试代码只在“调试模式”下生效。比赛中跑的是“竞速模式”,任何多余计算都要砍掉。每一帧图像处理耗时多少、主循环周期多少,这两个数字要作为核心指标盯住,而不是只看车跑得稳不稳。
选型方面,建议以官方推荐的套件为主,只改必要部分。非必要不换主控,因为换主控意味着全部底层驱动重写,备赛时间有限,性价比很低。真到瓶颈期,优先查算法,而不是抱怨硬件。
3. 三块硬核链路:视觉、语音、控制逐段打通
3.1 视觉循迹:从抓线到理解路况
视觉是整个系统的地基,因为车辆绝大多数时间在正常循迹,一旦视觉不稳,后面什么都白搭。
先普及一个小白容易踩的坑:摄像头图像不是拿来直接用的。无论是灰度图还是RGB图,第一步永远是“感兴趣区域提取”,只保留赛道中下方的一段区域,去掉天空、场地外杂物等干扰信息。然后用阈值分割或者边缘检测把赛道边界找出来,计算中线和偏差值。
具体流程大概是这样:
- 固定摄像头安装角度,让画面中赛道占据视野的60%以上,同时能看到近处的入弯趋势。
- 在调试界面冻结一帧图像,调整曝光和阈值,让赛道边界和背景的对比度最明显。
- 从图像底部向上扫描,逐行提取左右边界点,计算每行的中心点。
- 对中心点序列做滤波平滑,去掉因为噪点产生的跳变。
- 根据中心点的横向偏差和弯道趋势,输出转向控制量。
这一段基础巡线内容,前几篇已经反复讲过了。第五篇我想说的是进阶问题:特殊区域的识别。停止线、斑马线、特殊标志区,本质上都是“非正常赛道纹理”。建议单独设置一个检测线程,不要和巡线逻辑混在一起。比如停车线检测,可以定期扫描一个固定行区域,统计亮度跳变次数,超过阈值就判定为停车线,然后触发状态迁移。
注意:特殊区域检测的置信度非常重要。宁可偶尔漏检,也不要频繁误检。漏检最多是冲过停车线扣分,误检会导致车辆在正常赛道乱停车或者急减速,后果严重得多。所以检测逻辑一定要加“连续多帧确认”机制,简单说就是连续3帧都检测到才相信。
3.2 语音交互:识别只是起点,容错才是关键
语音模块是讯飞组和传统组最大的区别。很多人以为把语音识别例程跑通就万事大吉,实际上从“听到”到“做对”还有很长一段路。
首先说拾音。麦克风的位置和朝向影响巨大。如果麦克风被车壳遮挡或者朝向错误,现场嘈杂环境下识别率会断崖式下降。一般建议把麦克风朝向上方或者前方,减少车轮电机噪音的直接拾取,同时对拾音做简单的环境噪声预判。
其次是命令词表设计。比赛用的指令通常是固定几个词,比如“启动”、“停车”之类。命令词表要短、要清晰、发音区分度要大。相似发音的词不要同时出现,否则识别很容易混淆。比如“启动”和“停车”如果口音含混,短时识别容易搞混,那就要在词表设计阶段避开这种风险。
接下来是主控和语音模块之间的协议。推荐用结构化串口帧,帧头、指令类型、结果内容、校验位各占一个明确字段。主控收到帧先做校验、再解析,解析完必须做“同一指令去重”处理。原因很简单,语音模块通常会连续上报多次识别结果,如果不做去重,状态机会被反复触发。
这里分享一个我强调很多遍的心得:语音识别结果一定不要直接驱动动作。正确的做法是,识别结果进来之后,先更新一个“意图变量”,状态机到下一个决策周期再读取这个意图并执行。好处有两个,一是避免串口数据到达的随机时序打乱控制周期,二是给上层决策留一个“最终否决权”。比如车辆正在急转弯,这时候就算识别到“停车”指令,也应该等出弯进入直道再执行,而不是立刻原地急刹。
3.3 控制执行:让转向和速度听指挥
视觉和语音最终都要落到执行层。讯飞组的执行控制,核心还是经典PID,但有两个细节要特别注意。
第一是转向控制和速度控制的耦合。很多新手的做法是转向只根据偏差做比例控制,速度保持恒定。这在弯道稍多一点的赛道上会衰减明显,因为入弯速度太快,即使转向角度给够,车辆也会因为惯性冲出去。正确做法是做一个简单的“弯道速度规划”:偏差大时降低目标速度,偏差小时恢复目标速度。速度规划和转向PID同时运行,互相引用,但调节方向要独立。
第二是舵机响应频率。控制周期至少要达到50Hz以上,也就是20毫秒更新一次转向命令。控制周期太快或太慢都会出问题:太快会导致舵机抖动,太慢会导致转向滞后。主循环里最好用一个定时器中断或者高精度延时来保持周期稳定,不要在循环里穿插耗时操作。这就是为什么前面强调语音模块必须独立处理,否则一个阻塞调用就可能毁掉整个控制周期。
我实测中比较顺的一套参数思路,是先整定转向P,让车在低速下能平稳过急弯,再加入微分项抑制摆动,最后才加入速度规划。不要一上来就同时调三套参数,否则互相干扰,根本定位不到问题。
4. 全流程联调实录:从勉强能跑到稳定完赛
4.1 单元联调:把每个模块单独逼到极限
很多队伍在备赛后期才发现问题,根源在于单元联调阶段偷懒了。第五篇这个节点,我建议把全流程拆成四段,逐段验证。
第一段是图像链路联调。在主控上运行调试程序,读取一帧图像,画出边界和中线,放到大屏幕上观察。重点不是“能不能看到线”,而是在不同光照强度下,边界提取是否稳定。我通常会在上午、下午、傍晚三个时段分别跑一遍,因为比赛现场灯光分布可能非常不均匀。
第二段是语音链路联调。大声朗读命令词、正常音量朗读、距离远近、是否对着麦克风,每种情况都要模拟。还要测试连续误识别之后,系统能不能通过超时机制回到待命状态。语音模块不能只测“识别率”,要测“鲁棒性”和“恢复能力”。
第三段是控制链路联调。在车辆后轮悬空的情况下,测舵机左中右三个位置的响应角度和回正速度。然后在地上放两条平行胶带,模拟赛道,慢速推车观察转向是否跟手。
第四段是电源稳定性测试。这是我最想强调的。用示波器或者万用表监测主控供电电压,在电机全速启动和急停瞬间抓波形。如果电压跌落超过5%,就要考虑加电容或者重新分配供电。很多车辆跑着跑着突然重启,十有八九是电源问题。
4.2 综合路测:把单元联调的结果放进真实任务流
单元联调没问题,还不代表整车能跑。综合路测的真正难点在于多任务并发。比如正常巡线过程中突然出现语音指令,视觉任务还在跑,主控要同时处理语音、图像、控制三路信息,这时候优先级怎么排?
我的方案是在主循环顶部加一个“事件查询表”,按优先级排序:急停类语音指令最高,特殊区域标志次之,普通巡线最低。每个周期先查高优先级事件,如果有动作要执行,直接更新目标状态;如果没有,再进入普通巡线流程。
综合路测要特别关注的是“状态切换的平滑性”。从“正常巡线”切到“停车”再到“重新启动”,速度和转向不能突变。我一般会给每个状态切换加一个过渡过程,比如停车后重新启动,速度从零慢慢爬升,而不是直接给满油门。这个细节在比赛现场非常加分,因为起跑稳不稳直接影响后续摄像头视野的稳定性。
联调期间还要养成记录日志的习惯。每次跑完,把关键事件、时间戳、速度值、舵机值全部存下来。排查诡异问题的时候,日志比直觉可靠得多。我自己遇到过一辆车在同一个弯道偶尔冲出去,现场反复看都发现不了问题,最后翻日志发现是某一次语音误识别触发了速度重置,导致入弯速度异常。没有日志,这种灵异问题根本查不出来。
5. 我踩过的坑:常见问题速查与排错思路
5.1 高频故障速查表
把带比赛几年遇到的高频问题汇总一下,方便大家对着查。
| 故障现象 | 可能原因 | 排查思路 |
|---|---|---|
| 车突然重启 | 电机启动瞬时压降过大 | 查电源波形,加储能电容,分路供电 |
| 语音指令没反应 | 麦克风被遮挡、串口波特率不匹配、指令去重写错 | 先短接测试语音模块单独是否正常,再查主控串口接收缓冲区 |
| 语音指令频繁误触发 | 命令词表相似度太高、环境噪音太大 | 优化词表、调整麦克风位置和增益、加连续确认机制 |
| 巡线抖动严重 | 图像阈值不稳定、控制周期波动 | 固定曝光自适应阈值,检查主循环是否被阻塞 |
| 弯道冲出去 | 入弯速度过快、转向响应滞后 | 增加弯道减速规划,检查舵机控制频率 |
| 停车线不停 | 检测阈值过低、多帧确认不足 | 降低检测触发条件、提高确认帧数,重新标定检测区域 |
| 状态切换卡死 | 状态机缺少超时保护 | 所有等待类状态加超时自动退出逻辑 |
5.2 排查方法论:看现象、理链路、分变量
最后聊一点方法论。很多人调试的时候喜欢同时改好几个参数,然后看车有没有变好。这在简单场景可能碰运气成功,但在多模态系统里基本行不通,因为变量太多,你根本不知道是哪个改动起的作用。
我自己的排查套路是“看现象定层级”。车跑飞了,先问是感知问题、决策问题还是执行问题。方法很简单:把视频录下来,回放时分析是图像已经丢失赛道、还是图像正常但舵机没转、还是图像正常舵机也转了但车就是没按照路径走。这三级一划分,问题范围立刻缩小一大半。然后每级各保留一个关键日志输出,跑一圈后看日志定位到具体模块。整个过程类似二分查找,效率比乱试高得多。
另外一个经验是,比赛前最后一个晚上不要做大改动。每年都有队伍赛前灵机一动换了一套参数,结果现场彻底跑不起来。稳定完赛靠的是反复验证过的默认配置,而不是临时灵感。我会在赛前一周就固定一套“保底参数”,最后几天只做微调,且每次微调都在模拟赛道完整跑通两轮才算数。
这个项目做到后面,越来越像一次软件工程和系统工程实践。讯飞组表面上比的是车,实际上比的是任务拆解能力、多模块协同能力和调试排错效率。语音、视觉、控制这三条链路单独拿出来都不是最难的,真正考验人的是它们在十万火急的赛场上互相干扰时,你还能不能保持冷静、按照日志一层层定位问题。希望这篇复盘能帮还在调试的同学们少走一点弯路。