zoukankan      html  css  js  c++  java
  • 基于视觉的机械臂分拣(一)

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

    首先说一下我项目用到的材料: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度安装,并且转转范围要在你需要的范围内。

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

  • 相关阅读:
    MySQL与Oracle 差异比较之七其它
    MySQL与Oracle 差异比较之七用户权限
    MySQL与Oracle 差异比较之六触发器
    MySQL与Oracle 差异比较之五存储过程&Function
    MySQL与Oracle 差异比较之四条件循环语句
    MySQL与Oracle 差异比较之三函数
    MySQL与Oracle 差异比较之二基本语法
    MySQL与Oracle 差异比较之一数据类型
    Nginx、fastCGI、php-fpm关系梳理
    RTSP服务器之————rtsp-server(轻量级RTSP / RTP流媒体服务器)
  • 原文地址:https://www.cnblogs.com/tanshengjiang/p/14225664.html
Copyright © 2011-2022 走看看