1. OpenMV激光打靶系统设计思路
去年带队参加电赛时,我们组选择了激光打靶题目。当时最大的挑战是如何让OpenMV摄像头稳定识别靶框,并精确控制激光头完成循迹。这里分享下我们最终采用的方案:将摄像头光轴与激光发射器同轴安装,这样图像坐标系和物理坐标系就能保持线性关系,省去了复杂的坐标变换。
实际调试中发现,靶框识别稳定性直接影响整个系统性能。我们尝试过多种图像预处理方法,最终确定的工作流程是:
- 使用RGB565格式捕获图像
- 开启镜头畸变校正(strength=1.8)
- 二值化处理(阈值100-255)
- 矩形检测(阈值设为30000)
python复制# 硬件初始化代码片段
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA)
sensor.set_auto_gain(False) # 必须关闭自动增益
sensor.set_auto_whitebal(False) # 关闭白平衡
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 靶框角点检测的实战技巧
在矩形检测环节,我们踩过几个坑:
- 环境光变化会导致边缘检测失效
- 靶框倾斜时角点坐标跳动严重
- 相邻边斜率计算误差累积
解决方案是采用动态阈值补偿:当检测到四个角点后,取每个角点周围7个像素的RGB均值作为局部参考值。这里有个细节处理:对角点坐标进行±3像素的微调,可以显著提升直线方程计算精度。
python复制# 角点坐标补偿算法
for i in range(4):
if i==1: # 右上角点
point[i][0] -= 3
point[i][1] -= 3
elif i==2: # 右下角点
point[i][0] -= 3
point[i][1] += 3
elif i==3: # 左下角点
point[i][0] += 4
point[i][1] += 4
3. 路径规划算法详解
循迹控制的核心是计算相邻角点间的直线方程。我们采用分阶段PID控制策略:
- 粗定位阶段:快速移动到目标边附近(误差>10像素)
- 精调阶段:沿边移动(2<误差≤10像素)
- 锁定阶段:精确到达角点(误差≤2像素)
每条边的控制逻辑略有不同。以右边为例,其直线方程计算方式为:
python复制# 右边直线方程计算
k1 = (point[1][1]-point[2][1])/(point[1][0]-point[2][0]+0.0001) # 避免除零
xp1 = k1*k1 + 1
yp = ((80*k1 + (60-point[2][1])*(xp1-1) - point[2][0]*k1)/xp1 + point[2][1]) + (l1*k1)/math.sqrt(xp1)
4. 串口通信协议设计
与下位机的通信采用自定义协议:
- 起始符:'%'
- 数据长度:1字节
- 坐标数据:浮点数字符串
- 结束符:'&'
实测发现,传输前对坐标值取整能降低通信错误率。例如x坐标82.356应处理为:
python复制uart.write('%')
uart.write(str(len(str(round(xp,1))))) # 写入数据长度
uart.write(str(round(xp,1))) # 写入x坐标
uart.write(str(len(str(round(yp,1))))) # 写入数据长度
uart.write(str(round(yp,1))) # 写入y坐标
uart.write('&')
5. 调试过程中的关键发现
- 镜头畸变校正:开启后直线检测精度提升约40%,但会消耗15%的帧率
- 动态阈值:在光照变化环境下,误检率从32%降至7%
- 机械安装:激光器与摄像头间距控制在5-8cm时系统稳定性最佳
- 运动控制:采用3mm/s的移动速度时,轨迹跟踪误差最小
调试时建议先用img.draw_line()可视化检测结果,确认算法正确后再接入执行机构。我们团队在最终比赛时,系统完成了连续50圈循迹无丢靶的稳定表现。
