GahooChan
GahooChan
Skip to content

大疆机甲大师自动瞄准系统

编程教育期间课余项目 · 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 三个参数各自的物理意义和调参方法
  • 归一化思想——把绝对量转成相对量——在后续很多场景中都派上了用场