从看见赛道到稳定过弯:一辆高速视觉循迹智能车的实现
在第 20 届智能汽车竞赛缩微光电组的开发中,我们做的是一辆以摄像头为主要传感器的缩微智能车:它需要在黑白赛道上自主识别道路、判断即将到来的弯道,并通过舵机和双电机完成稳定循迹。
这个项目最有意思的地方在于,它不是“识别到线就转向”这么简单。随着速度提高,图像采集和处理的延迟、舵机响应滞后、左右电机的个体差异,以及弯道中的动力学效应都会被迅速放大。最终稳定运行的工程将任务拆成四层:视觉规划路径、舵机控制方向、编码器闭环控制轮速、差速辅助过弯。这样,车辆既能看懂前方道路的趋势,也能把这个趋势可靠地变成实际运动。
![]()
项目概览
最终工程运行在英飞凌 Traveo II CYT2BL3 的 CM4 核心上,系统时钟为 160 MHz。车头安装 MT9V03X 灰度摄像头,底盘由舵机、两台直流电机和两路编码器组成;IPS114 屏幕与四个按键则承担现场观测和调参任务。
| 模块 | 作用 | 当前配置 |
|---|---|---|
| 主控 | 图像处理、状态判断与控制调度 | CYT2BL3 CM4,160 MHz |
| 摄像头 | 获取赛道灰度图 | MT9V03X,188 × 120,120 FPS 配置 |
| 图像处理 | 提取赛道边界与参考路径 | 底部 90 行裁剪、固定阈值 155 |
| 转向 | 将横向偏差转换为舵机 PWM | PD 控制,中心 PWM 740 |
| 驱动 | 保持两侧轮速并辅助转弯 | 双编码器、双路增量 PI、17 kHz PWM |
| 赛道元素 | 处理不同道路拓扑 | 普通循迹、预入环、左右环岛 |
最终版本的默认编码器目标速度为 120,实车验证目标区间约为 120~140。这里的数值是工程内部的编码器速度设定,并不直接等同于 km/h。单轮目标速度会被限制在 0~180 的安全范围内。
让小车“看懂”赛道
摄像头每获取一帧图像,主循环只处理这帧新数据。程序首先保留原始灰度图,再截取画面底部 90 行:近场区域包含更直接的横向位置信息,而丢弃最上方较远、细节较少的区域,也能降低后续计算量。
随后采用固定阈值将灰度图转换为黑白图。当前稳定赛道环境下,像素灰度小于 155 记为黑色,大于等于 155 记为白色。工程中保留了 Otsu 自动阈值的尝试,但最终版本选择了更直接、可预期的固定阈值方案。代价是光照条件大幅变化时,需要重新标定阈值。
单纯从每一行找一个“赛道中点”在高速场景下很容易跳变:弯道、环岛入口和局部反光都会让中点突然偏移。因此,项目使用了左右边界双路跟踪:
- 从图像下方搜索左右边界的黑白跳变,找到可靠起点;
- 分别以迷宫跟踪法向前追踪左右边界;
- 在两条边界汇合或到达停止条件时,得到道路前方的汇合位置;
- 以近场起点中点和前方汇合点为端点,用 Bresenham 算法生成一条连续参考线。
这条参考线比瞬时中线更重要。它描述的是车辆从“当前位置”向“前方道路趋势”应当采取的路径,而不是只反映眼前一小段赛道。
用前瞻思路解决高速转弯
参考线生成后,程序不会机械地平均所有点,而是对不同位置的横坐标施加非均匀权重,再计算 Mid_point。权重峰值被安排在路径更靠前的位置,等价于让小车把注意力放在更远的道路趋势上。
这就是项目高速循迹的关键取舍:车速越高,越不能等到车头附近的边界已经大幅偏移才开始纠正。提前感知弯道,能显著减少转向滞后、左右摇摆和冲出赛道的风险。实际调试中,前瞻范围、舵机增益和差速强度不是彼此独立的参数,而是一组需要协同调整的系统参数。
整个实时决策链路可以概括为:
MT9V03X 灰度图
→ 裁剪与二值化
→ 左右边界迷宫跟踪
→ 生成前瞻参考线
→ 加权计算横向目标 Mid_point
→ 舵机 PD + 双轮 PI + 差速
→ PWM 输出到舵机与电机转向与速度:两个闭环共同工作
视觉模块提供的是“该往哪里走”,但它不会直接决定电机 PWM。控制层将方向和速度分开处理。
舵机 PD:把偏差变成转角
图像水平中心设为 MID_W = 93。Mid_point 偏离这个中心的距离,就是转向误差。舵机采用位置式 PD 控制:比例项负责快速建立转向,微分项抑制突变与振荡;微分部分还加入低通滤波,以减弱图像噪声带来的抖动。
当前初始参数为 Kp = 0.8、Kd = 4.9,积分项关闭。输出先限制在 ±50,再叠加到舵机中心 PWM;最终舵机 PWM 被硬性限制在 705~785,避免机构到达危险行程。
双轮增量 PI:把目标速度变成稳定的轮速
两侧电机由编码器独立反馈,每 10 ms 更新一次速度。由于电机、齿轮箱、轮胎和装配状态都可能不同,左右轮使用了不同的 PI 参数:左轮 Kp=15, Ki=2,右轮 Kp=18, Ki=2。控制器采用增量式 PI,将本周期的修正量累加到 PWM 占空比中,并将输出限制在 ±6000。
这种设计的意义是:即使同样给出目标速度,两侧电机也不会因为机械差异而长期跑偏。直线时它保持车辆姿态,转弯时则为差速策略提供可靠的执行基础。
差速:让内外轮协同过弯
仅靠舵机强行拉动车头,高速时往往会让车辆的转弯显得迟钝或不稳定。因此,工程将视觉转向误差同时用于修正两侧轮目标速度:一侧加速,另一侧减速。其关系可理解为:
左轮目标速度 = 基础速度 + 差速系数 × 转向误差
右轮目标速度 = 基础速度 - 差速系数 × 转向误差当前差速系数为 0.7。这样一来,舵机负责改变前轮方向,电机差速负责配合车辆绕弯,两套执行机构不再互相“硬扛”。
环岛不是普通弯道:用状态机切换策略
环岛的画面拓扑与普通赛道不同。如果始终沿用普通边界逻辑,车辆在入口、环内或出口很容易选错边界。因此项目把环岛作为独立状态机处理。
系统通过图像顶部、底部以及左右边缘的黑白跳变特征判断环岛方向;确认后依次进入普通循迹、入环、环内、第一阶段出环和第二阶段出环等状态。每个状态都重新选择可用边缘点,并生成对应的专用参考线。更进一步,工程启用了预入环:在真正进入环岛前就先调整参考路径,让车辆不会在入口突然大幅打方向。
普通循迹
→ 预入环(提前修正目标路径)
→ 入环
→ 环内循迹
→ 分阶段出环
→ 回到普通循迹当前最终工程已启用普通循迹、预入环与左右环岛。仓库中还保留了断路惯导、Flash 路径记录与十字处理代码,它们属于开发过程中的探索,但在当前稳定版本中通过宏开关关闭,不应视为实车最终能力。
实时调度与现场调试
系统将不同时间尺度的任务拆开执行:摄像头新帧到来后,主循环完成图像处理与状态机更新;10 ms 定时中断读取编码器、扫描按键、执行电机 PI、差速和速度保护;20 ms 定时中断执行舵机 PD。分层调度避免把图像处理与底层控制完全绑定在同一个周期内。
屏幕会显示二值图像、环岛方向与状态、控制参数和目标速度。按键也可以在现场调整舵机 Kp、Kd、差速系数与目标速度:KEY1 启停,KEY2 切换参数项,KEY3/KEY4 增减参数。对竞赛类项目而言,这套最朴素的在车调参方式往往非常实用——赛道材质、环境光和电池状态的变化,都可能让实验室中的最佳参数不再完全适用。
从验证模块到最终工程
仓库保留了完整的开发脉络,而不只是最终代码:
motro_pid/:电机 PID 与底盘控制验证;mt9v034_imag_analyse/:灰度图传输、裁剪、二值化和迷宫寻线分析;OpenCV图片寻迹显示_整合/:在 PC 端可视化正常赛道与环岛的拟合路径;many_open_road_success/:多断路区的惯导与 Flash 路径存储尝试;120_140_success/:当前用于稳定运行的高速视觉循迹最终工程。
这套目录也记录了一个很实际的工程结论:最终版本不一定是功能最多的版本。相比同时启用所有试验功能,集中验证“视觉前瞻、舵机 PD、双轮 PI、差速与环岛状态机”这条主链路,更容易获得可复现的稳定表现。
复现与继续优化
最终工程可通过 IAR 打开 120_140_success/36_new_track_6.13_pre_3success/iar/cyt2bl3.eww。首次复现时,建议不要直接追求最高速度,而应按以下顺序推进:
- 固定摄像头高度、俯角与画面构图,确认黑白阈值在赛道上稳定;
- 分别整定左右电机 PI,先让直线行驶的实际轮速一致;
- 在低速下调舵机 PD,确保连续弯道不振荡、不丢线;
- 逐步升速,并配合调整前瞻权重、舵机限幅和差速系数;
- 最后在直道、连续弯、急弯与环岛上反复测试。
后续可以继续探索自适应阈值、曲率相关的动态速度规划、将菜单索引与舵机使能解耦,以及避免同一控制周期重复更新舵机 PID 历史状态等改进。这些方向并不改变项目的核心思路:让视觉看得更早,让控制执行得更稳,再让每个模块的边界保持清晰。
结语
这辆小车的价值不只在于“能沿线跑起来”,而在于把嵌入式视觉、路径规划、闭环控制和赛道状态识别真正串成了一套可调试、可验证的系统。高速循迹的本质不是让某一个模块更激进,而是让感知的前瞻性、转向的响应和动力的执行彼此匹配。对我们而言,这也是从功能验证走向系统工程的一次完整练习。