大疆机甲大师自动瞄准系统
编程教育期间课余项目 · 2022 年
起因
大疆 RoboMaster 机甲大师是我带的课程之一。为了让课更有实战性和吸引力,我在课余时间基于机甲大师平台做了一个自动瞄准系统。
整体思路
整个过程是一个闭环控制系统——图像处理提供"眼睛",PID 控制提供"大脑",云台电机提供"手脚"。
算法细节
第一步:图像采集
通过 OpenCV 实时捕获机甲大师战车自带的摄像头视频流。每一帧都是一个 numpy 数组(BGR 格式)。
第二步:目标检测
在图像中识别对方机甲大师战车。我用少量图片训练了一个分类器模型来做检测,而不是简单的颜色阈值分割——
python
# 伪代码示意
# 用少量标注图片训练的分类器
classifier = cv2.CascadeClassifier('robo_detector.xml')
targets = classifier.detectMultiScale(frame, scaleFactor=1.1, minNeighbors=3)
# 取置信度最高作为目标
x, y, w, h = max(targets, key=lambda r: r[2]*r[3])
cx = x + w // 2
cy = y + h // 2第三步:偏移计算(关键步骤)
以图像中心为坐标原点 (width/2, height/2),计算目标中心相对于画面中心的二维偏移向量:
python
dx = cx - frame_width / 2 # 水平偏移(右正左负)
dy = cy - frame_height / 2 # 垂直偏移(下正上负)第四步:归一化处理
这是整个算法最关键的一步——把像素偏移转换成比例值:
python
norm_x = dx / (frame_width / 2) # 范围 [-1, 1]
norm_y = dy / (frame_height / 2) # 范围 [-1, 1]为什么要归一化?因为不同分辨率下像素偏移的绝对值差别很大,但比例值是统一的。这样 PID 参数就不会因为摄像头分辨率变化而需要重新调参。
第五步:PID 控制
将归一化的偏移向量 (norm_x, norm_y) 作为 PID 控制器的输入:
python
# yaw 轴(水平转动)
error_yaw = norm_x # 当前误差
integral_yaw += error_yaw # 积分累计
derivative_yaw = error_yaw - last_error_yaw # 微分(误差变化率)
output_yaw = Kp * error_yaw + Ki * integral_yaw + Kd * derivative_yaw
last_error_yaw = error_yaw
# pitch 轴(俯仰转动)同理PID 的三项各自的作用:
| 项 | 公式 | 作用 | 调大了会怎样 | 调小了会怎样 |
|---|---|---|---|---|
| P(比例) | Kp × e | 快速响应当前误差 | 响应快但可能超调震荡 | 响应迟钝 |
| I(积分) | Ki × ∫e | 消除稳态误差 | 可能积分饱和导致超调 | 稳态误差消不掉 |
| D(微分) | Kd × de/dt | 根据变化趋势提前修正 | 对噪声敏感,抖动 | 超调抑制不足 |
第六步:闭环跟踪
云台根据 PID 输出转动 → 目标在画面中的位置变化 → 新的偏移量 → 新的控制输出 → 循环往复。
当偏移量收敛到接近零的时候,说明云台已经对准目标了——此时触发发射指令。
已知问题:敌我不分
这个系统有一个明显的缺陷——它无法区分敌我双方战车。
当时没解决,原因两个:
- 课余时间本来就有限,没精力深入优化
- 不可能给对方战车刷个特殊颜色来区分(实际比赛中对方不会配合)
所以这个问题不了了之了。但作为一个教学演示项目,能让学生直观看到"图像识别 → 控制输出 → 机械动作"这条完整链路已经足够了。
技术栈
| 模块 | 技术 |
|---|---|
| 图像采集 | RoboMaster SDK / OpenCV VideoCapture |
| 目标检测 | 级联分类器 / 少量图片训练 |
| 控制算法 | PID(手写实现,没用第三方库) |
| 开发语言 | Python |
收获
- 第一次把机器视觉和实时运动控制串起来做一个完整的闭环系统
- 理解了 PID 三个参数各自的物理意义和调参方法
- 归一化思想——把绝对量转成相对量——在后续很多场景中都派上了用场
← 返回个人经历