最近做了一个基于视觉的五轴机械臂分拣的项目,功能基本完成,现在抽点时间出来做一个总结,算是自己做机械臂的一个记录,在做这个项目之前,你需要先学习一下机械臂的基础知识(运动学),以及摄像头方面的知识和坐标之间的一个变换的使用。

首先说一下我项目用到的材料:openmv摄像头,SD卡,五轴机械臂,舵机驱动板,6v输出的开关电源,以及部分架子,整体如下图

首先我们来介绍一下机械臂,因为我的机械臂的驱动器用的是舵机,那么我们先来介绍一下舵机。

 舵机又称之为伺服电机,伺服电机是一种可以控制旋转角度或者是旋转角速度的电机。一般舵机有90度舵机、180度舵机、270度舵机、360度舵机。

注意的一点:360度舵机,我们无法控制其旋转特定的角度,只能控制其以特定的角速度旋转。

舵机分类

舵机一般分为模拟舵机与数码舵机两种,他们的区别在与舵机内部有无mcu(单片机),有单片机控制的是数码舵机,没有单片机控制的是模拟舵机。

比如传统模拟舵机和数字比例舵机都称之为模拟舵机,数码舵机的电子电路中带有mcu微控制器,跟模拟舵机相比,数码舵机反应速度更快,无反应去范围小,定位精度高,抗干扰性强。

注意区分数字舵机与数码舵机之间的区别,数字比例舵机属于模拟舵机,数码舵机要贵一些,一般售价在两百多,而普通的模拟舵机一般在十几到几十,买那种舵机看个人的经济情况,如果刚刚入门,用低成本的模拟舵机就可以了。

接来下讲讲重点了,舵机的标定(如果舵机不进行标定的话,误差会比较大,到时候抓取的时候,会偏离较大)

我用的是线性回归的方法,尽可能的修正舵机的角度误差

第一步 做一个标定板

 

 这个标定板的话要看大家的舵机角度,我的舵机都是180度,所以我做的标定板是这个样子的,比较简陋。

第二步

你应该知道当我们设置占空比,舵机会转到一个角度,而占空比的取值范围和驱动板有一定关系,我用的驱动板的分辨率是12位的,对应的有效取值(0,4095)。

因为舵机的有效脉宽是0.5ms~2.5ms,脉宽对应的占空比范围是:

 

但是这个是理想情况,与实际上还是有一定误差的。

标定程序如下

'''
测试机械臂的安装
舵机角度标定,记录占空比与角度之间的映射关系
duty reference range 102 511
'''
from machine import Pin, I2C
from easy_pca9685 import PCA9685
from configs import config

i2c = I2C(scl=Pin(config['I2C_SCL']), sda=Pin(config['I2C_SDA'])) #,freq=config['I2C_FREQUENCY'])
# 初始化PCA9685对象
pca9685 = PCA9685(i2c, config['PCA9685_ADDRESS'])
pca9685.freq(50)

# Joint:1
# degree: 180
# range: 0 -
#------------------
# RADIUS    | DUTY
#------------------
# -pi/2     | 145
# -pi/4     | 230
# 0         | 307
# pi/4      | 400
# pi/2      | 468
pca9685.duty(0, 307)


# Joint:2 *
# degree: 180
#------------------
# RADIUS    | DUTY
#------------------
# -pi       | 530
# -3pi/4    | 420
# -pi/2     | 332
# -pi/4     | 220
# 0         | 110

pca9685.duty(1, 327)


# Joint:3  degree: 180*
#------------------
# RADIUS    | DUTY
#------------------
# -pi/6     | 128
# 0         | 172
# pi / 4    | 230
# pi/2      | 305
# 3*pi/4    | 390
pca9685.duty(2, 175)

# Joint:4
# degree: 180
# range: 0 -
#------------------
# RADIUS    | DUTY
#------------------
# -pi/2     | 530
# -pi/4     | 425
# 0         | 318
# pi/4      | 208
# pi/2      | 110
pca9685.duty(3, 318)

#       Joint 5
#------------------
# RADIUS    | DUTY
#------------------
# -pi/2     | 505
# -pi/4     | 406
# 0         | 307
# pi/4      | 218
# pi/2      | 130
pca9685.duty(4, 307)


# 40 OpenS
# 80 Grab Box
# Grapper
#------------------
# WIDTH     | DUTY
#------------------
# 0         | 300
# 0.02      | 280
# 0.035     | 250
# 0.05      | 200
pca9685.duty(5, 280)

线性拟合程序如下

#-*- coding:utf_8 -*-
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
'''
data = [
        [64,500],
        [74,600],
        [85,700],
        [93,800],
        [103,900],
        [112,1000],
        [120,1100],
        [128,1200],
        [135,1300],
        [144,1400],
        [154,1500],
        [160,1600],
        [168,1700],
        [172,1800],
        [186,1900],
        [195,2000],
        [203,2100],
        [210,2200],
        [222,2300],
        [230,2400],
        [240,2500]]
'''
data = [
        [-1.57,545],
        [-1.047,478],
        [-0.785,445],
        [-0.523,407],
        [0,333],
        [0.523,260],
        [0.785,222],
        [1.047,184],
        [1.57,124]
        ]

data = np.array(data)

angles = data[:,0]
pws = data[:,1]
plt.scatter(angles,pws)

x = angles.reshape(len(angles), 1)
y = pws.reshape(len(pws), 1)

model = LinearRegression()

model.fit(x,y)

k = model.coef_[0][0]

b = model.intercept_[0]

print('拟合后的直线 y = {} * x + {}'.format(k,b))

 

标定结果如下

机械臂组装时,我们标定一个舵机,安装一个,安装舵机尽量以0度或90度安装,并且转转范围要在你需要的范围内。

到这里机械臂部分基本安装完成了。