基于OpenMV 双轴机械臂 机器学习

发布于:2024-05-02 ⋅ 阅读:(27) ⋅ 点赞:(0)


一、项目简要

两套二维云台设备,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°,满足需求
在这里插入图片描述

四、效果演示

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到