文章目录
- 一、项目简要
- 二、目标追踪
- 1. 色块识别与最大色块筛选
- 2. PID位置闭环
- 三、机器学习
- 1. Device1
- 2. Device2
- 四、效果演示
一、项目简要
两套二维云台设备,Device1通过摄像头捕捉目标物块点位进行实时追踪,再将自身点位传到Device2,Device2学习Device1动作,控制误差<=1°。
二、目标追踪
以摄像头左上角为坐标原点建立坐标系,通过识别目标物块 获取物块的中心坐标点位,以识别到的点位作为实际点位,摄像头的中心坐标作为目标点位,引用PID算法分别在x轴和y轴上设计两套位置闭环,将输出信号赋给舵机,使其收敛于目标点位。
在物块识别中,是通过颜色进行区分,所以这里难免会出现误差,为了避免一些小杂物扰乱采集,则在图像中使用物块面积计算过滤掉小的物块,筛选出最大的目标物块
1. 色块识别与最大色块筛选
red_threshold = (4, 92, -103, 104, -18, -99) #色块阈值
def find_max(blobs): #寻找最大色块函数
max_size=0
for blob in blobs:
if blob[2]*blob[3] > max_size:
max_blob=blob
max_size = blob[2]*blob[3]
return max_blob
while(True):
clock.tick() #帧率控制
img = sensor.snapshot() #图像截取
blobs = img.find_blobs([red_threshold]) #发现色块
if blobs:
max_blob = find_max(blobs) #筛选色块
2. PID位置闭环
pan_servo=Servo(1) #水平方向的舵机
tilt_servo=Servo(2) #垂直方向的舵机
pan_pid = PID(p=0.07, i=0, imax=90) #水平PI参数调整
tilt_pid = PID(p=0.05, i=0, imax=90) #垂直PI参数调整
pan_error = max_blob.cx()-img.width()/2 #水平方向误差
tilt_error = max_blob.cy()-img.height()/2 #垂直方向误差
pan_output=pan_pid.get_pid(pan_error,1)/2 #水平PID计算
tilt_output=tilt_pid.get_pid(tilt_error,1) #垂直PID计算
pan_servo.angle(pan_servo.angle()+pan_output) #水平舵机反馈
tilt_servo.angle(tilt_servo.angle()+tilt_output) #垂直舵机反馈
三、机器学习
在目标追踪的基础上,第二套设备只需要去模仿第一套设备的动作,两者之间通过串口传输数据,再计算出实际角度与目标角度之间的误差。
1. Device1
将Device1的自身点位发送到Device2
from pyb import UART
uart = UART(3, 115200)
#获取本装置二维云台实时转动角度
data = str(int(pan_servo.angle())) + ':' + str(int(tilt_servo.angle()))
data_bytes = data.encode() #格式转换
uart.write(data_bytes) #串口发送
2. Device2
- 接收来自Device1发过来的实时点位
# 将接收到的字节串解码为字符串并去除首尾的空白字符
received_data = uart.readline().decode().strip()
num1, num2 = map(int, received_data.split(':')) #解析数据
- 控制二维云台学习Device1
pan_servo.angle(num1) #水平转动
tilt_servo.angle(num2) #垂直转动
- 计算转动误差并发送到PC上位机
a=num1-pan_servo.angle() #获取自身水平转动角度误差
b=num2-tilt_servo.angle() #获取自身垂直转动角度误差
data = str(int(a)) + ':' + str(int(b))+' ' #数据打包
data_bytes = data.encode() #格式转换
uart.write(data_bytes) #串口发送
如下图可见,水平误差和垂直误差 控制在1°,满足需求