
分类
技术干货
2025全国大学生电子设计大赛K题-自动避障小车-(全网行进速度最快)
简介
基于 K230与STM32的视觉导航小车,融合YOLO11识别、A*路径规划与双闭环控制,实现黑白柱检测、地图构建与自主避障导航的完整嵌入式智能系统。
简介:基于 K230与STM32的视觉导航小车,融合YOLO11识别、A*路径规划与双闭环控制,实现黑白柱检测、地图构建与自主避障导航的完整嵌入式智能系统。【2025电赛K题开源】基于 K230 + STM32 的视觉导航自动避障小车|YOLO11识别 + A*路径规划 + 双闭环控制
⭐项目已完整开源
⭐2025全国大学生电子设计竞赛 K 题作品
⭐基于 K230 AI视觉 + STM32 四驱控制平台
⭐实现黑白柱识别、地图构建、路径规划、自主导航全流程
项目演示视频
🎥 B站演示视频:
https://www.bilibili.com/video/BV17XTu65Esx/
开源地址
GitCode:
(https://gitcode.com/Embodied-AI-Workshop/Auto_Hide_Car)
一、前言
每年的电赛智能车题目都非常有意思,而25年 K 题最大的特点就是:
将视觉感知、路径规划和运动控制全部融合到了一辆小车上。
比赛要求小车能够:
-
自动识别地图中的黑白圆柱;
-
自动生成地图;
-
自主规划路径;
-
自动完成避障导航;
-
全程无需人工干预。
题目看起来并不复杂,但真正做起来才发现,这几乎涵盖了一套完整机器人系统所需要的全部核心技术:
✅ AI视觉识别
✅ 地图建模
✅ 路径规划
✅ 运动控制
✅ 多模块通信
✅ 实时系统设计

整个项目从方案设计到最终稳定运行,经历了无数次推倒重来。
这篇文章将完整分享整个项目的设计思路、踩坑过程以及最终实现方案,希望能够帮助后续做电赛、智能车以及机器人方向的同学少走一些弯路。
二、赛题要求
赛场为固定的 3×3 九宫格区域,黑白柱子随机放置,小车需要:
- 自动识别所有柱子位置;
- 建立地图;
- 自主规划路径;
- 避开障碍物;
- 按要求行驶至目标区域。
三、项目效果展示
最终效果
小车上电后:
识别黑白柱
↓
生成九宫格地图
↓
A*搜索最优路径
↓
发送运动指令
↓
自主完成避障导航
整机展示

运行GIF

四、项目整体架构
系统采用双处理器架构:
K230:视觉感知 + 决策规划
STM32:运动控制 + 状态执行
原因非常简单:
视觉任务计算量巨大,而运动控制需要高实时性。
如果全部放在一个处理器上:
视觉卡顿
控制不稳定
实时性下降
因此最终采用:
AI处理器
+
MCU控制器
双核分工方案。
系统框图

五、硬件设计
硬件清单
| 模块 | 型号 |
|---|---|
| AI视觉 | K230 |
| 主控 | STM32F407VET6 |
| 摄像头 | OV5640 |
| 电机 | 四驱减速电机 |
| 编码器 | 霍尔编码器 |
| 电源 | 2S锂电池 |
为什么选择 K230?
最开始我们尝试过:
-
OpenMV
-
树莓派
最终全部放弃。
原因:
OpenMV
色值检测不可靠。
树莓派
功耗高。
而 K230:
✅ 自带AI加速器
✅ 功耗低
✅ 成本低
✅ 部署YOLO非常方便
因此最终选择:
K230

为什么选择 STM32?
运动控制最核心的是:
实时性
STM32:
-
定时器资源丰富;
-
编码器接口丰富;
-
PWM性能稳定;
-
开发生态成熟。
因此最终采用:
STM32F407

六、视觉识别方案
这是整个项目最难的部分之一。
为什么不用颜色识别?
比赛现场:
-
光照变化;
-
阴影;
-
反光;
-
遮挡。
传统阈值算法极不稳定。
最开始:
颜色识别
运行一分钟就开始误检。
因此果断放弃。
采用 YOLO11 方案
最终采用:
YOLO11
训练:
黑柱
白柱
两个类别。
训练数据集截图。

标注截图。

训练结果截图。


识别效果
多目标检测截图。

推理流程

七、最大的坑:斜视摄像头
比赛中摄像头安装在小车前方。
看到的是:
斜视图
而不是:
俯视图
直接按X排序?
不行。
直接按Y排序?
也不行。
因为透视关系:
远处柱子距离非常近。
拍摄原始画面

标出检测框

画出错误分组结果

最终解决方案
自适应聚类。
核心思想:
按照空间分布自动分组。
成功解决:
-
柱子错位;
-
遮挡;
-
透视变形。
八、地图构建
最终地图:
white black white
black white black
black black None
地图生成流程

九、路径规划
地图生成后:
下一步就是:
A*
为什么选择 A*?
优点:
-
快;
-
稳;
-
最优。
非常适合电赛。
A*流程

路径规划示意图。

九(补充):路径规划方法二(规则路径模板直接输出)
1️⃣ 方法一回顾(A*路径规划)
在原始方案中,系统采用:
A*搜索最优路径
📌 工作方式:
- 将九宫格建模为图结构
- 黑色柱子作为不可通行节点
- 通过启发式函数(Manhattan距离)进行搜索
- 输出一条从起点到终点的最优路径
📊 特点:
优点:
- 可处理任意障碍分布
- 理论最优路径
- 泛化能力强
缺点:
- 计算开销较大
- 路径结果不完全固定
- 在嵌入式端实时性压力较大
2️⃣ 方法二核心思想(规则路径模板)
方法二不再进行路径搜索,而是:
❗直接根据当前九宫格状态 → 映射预定义路径(Route1~Route4)
📌 本质变化
| 项目 | 方法一(A*) | 方法二(规则映射) |
|---|---|---|
| 计算方式 | 图搜索 | 规则决策 |
| 输出方式 | 动态路径 | 固定Route编号 |
| 实时性 | 中等 | 极高 |
| 复杂度 | O(n log n) | O(1) |
3️⃣ 系统输入(视觉层输出)
方法二的输入为:
current_map = [9] # 九宫格状态
其中:
0 = white(可通行)1 = black(障碍)
4️⃣ 关键判断区域
✔ 前方区域(最关键)
current_map[6:9]
用于判断:
- 前方是否可通行
- 是否需要绕行策略
- 是否可直行通过
✔ 辅助区域
- 左列
- 中列
- 右列
用于判断:
- 左绕 / 右绕选择
- 对称路径选择
- 备用路径选择
5️⃣ 路线体系定义(Route层)
系统最终仅使用四条预定义路径:
- Route1:左偏绕行路线
- Route2:右偏绕行路线
- Route3:直行优先+轻微调整路线
- Route4:复杂场景备用绕行路线
这些路线本质是:
✔ 提前设计好的“稳定运动轨迹模板”
✔ STM32仅执行,不参与规划
6️⃣ 路线映射逻辑(核心贡献点)
方法二的核心思想:
将九宫格状态压缩为有限规则集合 → 直接映射Route编号
🔷(1)前方完全阻挡
current_map[6:9] == [1, 1, 1]
表示:
前方不可通行
此时根据左右结构判断:
- 左侧可通 → Route1
- 右侧可通 → Route2
- 复杂/不确定 → Route4
🔷(2)前方部分阻挡(双障碍结构)
[1, 1, 0] → Route3[0, 1, 1] → Route4
说明:
存在局部通道,需要调整路径方向
🔷(3)前方单障碍结构
[1, 0, 0][0, 0, 1][0, 1, 0]
说明:
前方存在局部遮挡
此时结合左右列信息:
- 决策左绕 or 右绕
- 或进入 Route3 直行调整
🔷(4)前方完全通畅
[0, 0, 0]
说明:
当前前方无障碍
通常选择:
- Route3(直行优先路径)
7️⃣ Route1 ~ Route4 的工程作用
| Route | 作用 | 使用场景 |
|---|---|---|
| Route1 | 左绕长路径 | 左侧通道优先 |
| Route2 | 右绕长路径 | 右侧通道优先 |
| Route3 | 直行/轻微调整 | 通畅或轻度障碍 |
| Route4 | 复杂避障备用 | 不确定或冲突场景 |
8️⃣ 方法二本质总结
方法二本质是:
将“路径规划问题”从搜索问题降维为“规则决策 + 模板执行问题”
最终流程为:
九宫格识别 ↓特征提取(前方+左右) ↓规则判断 ↓Route1~4选择 ↓STM32执行轨迹
9️⃣ 四条路线图
路线一

路线二

路线三

路线四

十、STM32运动控制(从“能跑”到“走准”的核心)
视觉只是让小车“看见世界”,而真正决定比赛成绩的,是控制系统能不能让它“稳定走到终点”。
🧠 控制问题的本质
当 K230 端完成:
- 目标点生成
- 路径规划(A*)
- 方向指令输出
之后,STM32 接管的任务其实只有一句话:
👉 让车严格按照目标路径运动
但实际情况远比想象复杂:
- 电机非线性
- 地面摩擦变化
- 编码器噪声
- 转向惯性延迟
这些都会导致:
“理论路径 ≠ 实际轨迹”
❌ 第一版:单环 PID(最直觉方案)
📉 控制结构
目标位置 → PID → PWM → 电机
⚠️ 实际表现
- 小车能动
- 但轨迹严重偏移
- 到目标点疯狂抖动
- 无法稳定停下
🔍 本质问题
单环PID存在一个核心缺陷:
❗没有“速度层”,系统是直接硬拉到目标位置
导致:
- 加速过猛
- 减速滞后
- 误差震荡放大
💡 结论
单环 PID ≠ 可用运动控制系统
❌ 第二版:位置 PID(加入位置约束)
📉 改进思路
引入位置反馈,希望解决“乱冲”的问题:
目标位置 → PID → PWM ↑ 编码器反馈
⚠️ 实际表现
- 超调严重
- 到点后回摆
- 轨迹呈“S型修正”
🔍 本质问题
问题从“无约束”变成了:
❗系统仍然缺少“速度约束层”
位置误差被直接转成电机输出:
- 控制过激
- 没有缓冲
- 动态不稳定
💡 结论
位置控制不能单独作为底层控制
✅ 第三版:双闭环控制(最终稳定方案🔥)
这是整个项目真正稳定运行的关键优化。
🧩 控制结构(核心)
目标位置
↓
位置误差计算
↓
PD控制(输出目标速度)
↓
速度误差计算(目标速度 - 编码器速度)
↓
PI控制(输出PWM占空比)
↓
电机驱动输出
↓
编码器采样反馈
↓
回到速度环 + 位置环
🚀 控制逻辑拆解
🟦 1. 位置环(PD)
作用:
- 计算当前位置误差
- 输出“期望速度”
特点:
- 响应快
- 不引入积分避免积累误差
位置误差 → 合理速度指令
🟩 2. 速度环(PI)
作用:
- 精确控制电机转速
- 抑制扰动
特点:
- P 提供响应
- I 消除稳态误差
目标速度 → 稳定PWM输出
十一、踩坑记录
这一部分是整个项目最关键的经验总结,从“能跑”到“稳定运行”的核心过程。
❌ 坑一:颜色识别在真实环境完全失效
📉 现象
最初使用传统视觉方案:
- HSV阈值分割
- OpenCV颜色识别
实验室表现正常,但实际环境中:
- 光照变化 → 误检严重
- 阴影影响 → 目标消失
- 白柱与地面混淆
🔍 本质问题
颜色特征 = 强依赖环境变量
真实场景中:
- 光照不是固定值
- 反光不可控
- 阴影随机变化
👉 导致传统方法鲁棒性极差
✅ 解决方案
- 放弃传统颜色识别
- 使用 YOLO11 目标检测
- 重新构建数据集训练
- 加入 NMS + 置信度过滤
💡 总结
在工程视觉中,“能跑”不等于“可靠”。
❌ 坑二:九宫格映射错位(致命问题)
📉 现象
- 检测框正常
- 但地图输出完全错乱
表现为:
实际布局:1 2 3 4 5 6 7 8 9输出结果:随机排列
🔍 本质问题
错误使用:
- 按 X 排序
- 按 Y 排序
忽略关键事实:
📷 摄像头是斜视角,不是俯视角
导致:
- 远处压缩
- 近处拉伸
- 坐标非线性
✅ 解决方案
- 使用聚类替代排序
- 引入空间分布约束
- 使用相对距离建模
最终:
排序 → 聚类映射
💡 总结
坐标正确 ≠ 空间正确
❌ 坑三:转向严重过冲
📉 现象
小车表现:
- 左右来回摆动
- 无法稳定对准方向
- 甚至原地震荡
🔍 本质问题
仅使用:
角度误差 → PID控制
忽略:
- 摩擦差异
- 惯性
- 电机死区
✅ 解决方案
- 降低 D 项影响
- 引入死区控制
- 分阶段控制:
粗调 → 停顿 → 微调
💡 总结
控制问题往往不是 PID 参数问题,而是模型不完整。
❌ 坑四:积分项导致系统震荡
📉 现象
加入 I 项后:
- 小车持续抖动
- 无法稳定停止
- 输出周期性震荡
🔍 本质问题
积分项本质:
误差累计 = 能量积累
问题来源:
- 编码器噪声
- 采样误差
- 延迟效应
✅ 解决方案
- 限幅积分(Anti-windup)
- 误差死区过滤
- 静止时冻结积分
💡 总结
I 项不是越大越好,而是越克制越稳定。
❌ 坑五:状态机偶发死锁(最隐蔽问题)
📉 现象
运行中偶发:
- 小车停止运动
- UART无报错
- 系统“假死”
🔍 本质问题
状态机设计问题:
- 状态切换条件不完整
- 异常无出口
- 通信丢包未处理
✅ 解决方案
- 增加超时机制
- watchdog 状态监控
- fallback 恢复状态
最终形成:
强制可恢复状态机
💡 总结
工程系统中,“不会死锁”比“功能完整”更重要。
十二、开发历程(从“能跑”到“稳定运行”的演进过程)
这一部分记录的是整个系统从0到稳定运行的完整演化过程,而不是简单版本迭代。
🧩 起点:最初的想法(快速验证可行性)
最开始我们的目标很简单:
先让小车“动起来 + 能识别目标”
因此第一版方案非常直接:
- 使用颜色识别
- 使用简单逻辑控制
- 手动设定路径
❌ 第一阶段:颜色识别方案(快速失败)
📉 结果表现
- 在实验室可以运行
- 一到复杂环境直接崩溃
- 光照变化即失效
🔍 问题本质
这个阶段我们忽略了一个关键事实:
真实比赛环境 ≠ 实验室环境
颜色识别对以下因素极其敏感:
- 光照
- 阴影
- 反光
- 摄像头角度
💥 结论
传统视觉方案不可用于复杂比赛场景
🚀 第二阶段:引入 YOLO(从规则到学习)
📈 改进动机
既然规则方法不稳定,那么:
直接用“学习型视觉模型”
📌 改动内容
- 引入 YOLO11
- 重新采集数据集
- 标注黑柱 / 白柱
- 加入 NMS后处理
✅ 结果
- 识别稳定
- 抗光照能力增强
- 基本解决误检问题
💡 关键变化
规则视觉 → 数据驱动视觉
⚠️ 第三阶段:YOLO + A*(系统开始完整)
📈 新目标
识别解决后,我们开始做:
“让小车自己找到路”
📌 引入内容
- 九宫格地图建模
- A*路径规划
- 起点终点自动搜索
⚠️ 新问题出现
虽然路径能算出来,但出现新问题:
- 路径正确
- 但车走不对
- 角度偏差累计严重
💡 关键认知
算法正确 ≠ 系统正确
⚠️ 第四阶段:加入双闭环控制(进入系统工程阶段)
📈 问题升级
此时我们发现:
- 不是“不会规划”
- 而是“走不准”
📌 引入控制系统
- 位置环 PD
- 速度环 PI
- 编码器反馈闭环
📉 调试过程
经历了典型问题:
- 震荡
- 超调
- 抖动
- 响应慢
🔥 最终调整结果
- PD控制位置
- PI控制速度
- 分层控制解耦
💡 关键变化
从“算法驱动” → “控制系统驱动”
🧠 第五阶段:整车联调(最难阶段)
📈 真实情况
这个阶段没有新算法,但问题最多:
- 通信延迟
- 状态机卡死
- 指令丢失
- 控制抖动叠加
📌 本质问题
系统开始暴露一个核心问题:
所有模块单独正常,但组合后不稳定
🔧 解决方式
- UART协议重构
- 状态机加 watchdog
- 控制指令解耦
- 增加异常恢复机制
💡 最终结果
系统从:
“模块正确”
变成:
“整体稳定运行”
🧭 总结:真正的开发演进
十三、最终效果展示
整车运行GIF。

十四、项目总结
这个项目让我们真正体验到了:
视觉
+
算法
+
控制
+
系统工程
一套完整机器人系统的开发流程。
从最开始的:
识别失败
到最后:
稳定运行
经历了无数次调试。
但正是这些踩坑过程,让我们对:
-
AI视觉;
-
路径规划;
-
控制系统;
-
嵌入式开发;
有了更加深入的理解。
十五、开源资料
项目全部开源:
✅ K230源码
✅ STM32源码
✅ YOLO模型
✅ 数据集
✅ 原理图
✅ 技术文档
✅ 调试记录
十六、致谢
感谢 K230 社区。
感谢所有开源项目作者。
也感谢电赛,让我们有机会完成这样一个有趣的作品。
如果这篇文章对你有所帮助:
⭐欢迎点赞
⭐欢迎收藏
⭐欢迎Fork
⭐欢迎交流讨论
2025全国大学生电子设计竞赛 K 题
基于 K230 + STM32 的视觉导航自动避障小车







评论