1. 项目概述:大一新生的智能小车挑战
去年冬天,我和三位同学组队参加了深圳大学AL&开放原子俱乐部举办的冬令营。作为刚入学的大一新生,我们决定挑战一个看似不可能完成的任务——在12天内从零开始打造一辆具备巡线、避障、物体识别与夹取功能的智能小车。最终我们交出了一份令人惊喜的答卷:基于RDK X5(上位机)、STM32(下位机)和YOLOv5视觉算法的智能控制系统。
这个小车的核心能力包括:
- 精准巡线:通过二值化处理识别黑色引导线,ROI区域限制确保稳定性
- 智能避障:采用"三角形避障算法",通过y轴坐标阈值触发避障动作
- 物体识别:部署在RDK X5上的YOLOv5模型实现90%+识别准确率
- 机械臂控制:20kg舵机驱动的夹爪可精准夹取3.5cm立方体物块
作为项目的主要开发者,我将从机械设计、电控系统、视觉处理和算法实现四个维度,详细解析这个项目的技术细节与实战经验。特别说明:虽然我们提供了完整工程文件,但强烈建议读者根据自身环境重新训练模型和调整参数,因为我们的解决方案高度依赖特定摄像头角度和环境光线条件。
2. 机械结构设计与实现
2.1 分层式架构设计
我们采用双层结构设计,将不同功能模块物理隔离,既保证结构强度又便于维护:
第一层(驱动层):
- 前方预留的摄像机安装孔采用可调角度设计,通过M3螺丝固定,便于后期微调视角
- TB6612驱动板下方设计蜂窝状散热孔(直径3mm,间距5mm),实测可降低板温8-12℃
- 独创的"悬空式"STM32安装支架,使用尼龙柱抬高2cm,有效防止电路短路
- 后部电池仓采用滑轨设计,配备XT30接口,更换电池只需5秒
第二层(处理层):
- 机械臂底座采用4点固定,使用M3*12mm螺丝配合防松螺母
- RDK X5安装平台设计有2mm凸起边缘,防止板卡移位的同时不影响散热
- 立体走线槽设计使所有线缆隐藏于平台下方,整体厚度控制在5mm内
机械设计心得:使用Fusion 360进行建模时,务必为所有螺丝孔添加1mm的工艺余量。我们第一版设计因未考虑3D打印收缩率,导致多个孔位需要重新扩孔。
2.2 关键部件选型
-
驱动电机:
- 选用MG310编码电机(6V/300RPM)
- 搭配64CPR编码器,理论定位精度达0.28mm(轮径65mm)
- 实测带载情况下扭矩可达3kg·cm,满足1.5kg车重需求
-
万向轮:
- CY-15A尼龙万向轮(直径50mm)
- 选用带弹簧复位结构版本,过坎能力提升40%
-
机械臂:
- 20kg数字舵机(0.16s/60°)
- 3D打印的平行夹爪,夹持力经测试可达1.2kg
- 关键改进:在夹爪内侧粘贴1mm厚硅胶垫,防滑效果提升显著

3. 电控系统详解
3.1 硬件架构
采用经典的上下位机架构:
code复制[摄像头] → [RDK X5] → (UART) → [STM32F103C8T6] → [TB6612] → [电机/舵机]
↑
[蓝牙模块]
电源管理方案:
- 主电源:7.4V 2550mAh锂电池
- 一级降压:P05C降压模块 → 5V(供RDK X5)
- 二级降压:AMS1117 → 3.3V(供STM32)
- 关键改进:在TB6612的VM输入端增加470μF电容,有效抑制电机启停时的电压波动
3.2 通信协议设计
自定义的串口通信协议格式:
code复制[HEAD][LEN][CMD][DATA][CRC]
0xAA 1B 1B N B 1B
- 波特率:115200
- 关键指令示例:
- 0x01:设置电机速度(DATA:左PWM, 右PWM)
- 0x02:机械臂控制(DATA:角度0-180)
- 0x03:紧急停止
避坑指南:STM32的HAL库默认使用中断接收模式,在处理图像数据时极易丢失数据包。我们最终改用DMA+空闲中断方式,接收稳定性提升90%。
4. 视觉处理全流程
4.1 RDK X5环境配置
模型部署的完整流程:
-
基础环境:
- Ubuntu 20.04 + Python 3.8
- 安装Rockchip NPU驱动(版本1.7.3)
-
模型转换:
code复制yolov5s.pt → export.py → yolov5s.onnx → rknn-toolkit → yolov5s.rknn关键参数:
python复制rknn.config(mean_values=[[0, 0, 0]], std_values=[[255, 255, 255]], quant_img_RGB2BGR=True) -
部署优化:
- 使用int8量化,模型大小从14MB→3.5MB
- 推理速度从120ms→45ms(输入尺寸640x640)
4.2 YOLOv5模型训练
我们的数据集特点:
- 自建3000张图像(含多种光照条件)
- 标注4类目标:红/蓝/绿方块、障碍物
- 数据增强策略:
- 50%概率应用色彩抖动(±20%饱和度/亮度)
- 随机添加高斯噪声(σ=0.01)
训练参数:
yaml复制lr0: 0.01
lrf: 0.1
epochs: 100
batch: 16
imgsz: 640
最终在验证集上达到:
- mAP@0.5: 0.94
- Precision: 0.91
- Recall: 0.89
经验分享:我们发现摄像头在近距离(<30cm)时会产生明显畸变。通过在数据集中加入20%的畸变样本(使用OpenCV的鱼眼变换),近距离识别准确率提升35%。
5. 核心算法解析
5.1 巡线算法实现
改进的二值化巡线方案:
- ROI区域设置(占画面下部1/3)
- 自适应阈值计算:
python复制cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU) - 中心线计算:
- 对每列像素求和,找到左右边缘
- 计算中线偏差:Δx = (左边缘+右边缘)/2 - 图像中心
PID控制参数:
c复制float Kp=0.8, Ki=0.01, Kd=0.2;
int base_speed = 1500; // PWM值
5.2 三角形避障算法
创新性的y轴触发机制:
- 在画面y=400处设置触发线
- 当障碍物底部接触该线时:
- 记录当前坐标(x1,y1)
- 向右转30度,前进1秒
- 再次检测障碍物,记录(x2,y2)
- 计算避障路径:
python复制avoid_angle = atan2(y2-y1, x2-x1) avoid_dist = sqrt((x2-x1)**2 + (y2-y1)**2)
5.3 物体夹取逻辑
七步夹取流程:
- 红线识别(HSV范围:H0-10/160-180, S>100, V>50)
- 停车(延时300ms防抖)
- 左转45度(寻找侧方物块)
- YOLO检测目标物
- 视觉伺服控制:
- 调整角度直到目标居中(|Δx|<20像素)
- 前进直到目标高度达120像素(约15cm)
- 夹爪闭合(保持2秒)
- 原路返回
6. 项目优化建议
根据我们的测试数据,后续可从以下方面改进:
-
动态ROI调整:
- 当前固定ROI在复杂弯道易丢失路线
- 可增加路线预测算法,动态调整ROI位置
-
多传感器融合:
- 增加IMU(如MPU6050)补偿视觉盲区
- 测试显示:200Hz的陀螺仪数据可将转向抖动降低60%
-
模型量化优化:
- 尝试混合精度量化(部分层保持fp16)
- 实测可提升小目标检测精度约15%
-
机械臂强化:
- 当前舵机在连续工作时有约3°的漂移
- 建议改用闭环舵机或增加位置反馈
这个项目让我们深刻体会到:工程实践就是不断在理想方案与现实约束之间寻找平衡。虽然我们的方案还有很多不足,但通过清晰的模块划分和持续迭代,最终实现了所有基础功能。特别感谢我的队友们,这段熬夜调参、一起解决问题的经历,将成为我们大学生活最珍贵的记忆之一。