OpenCV实验箱---机械臂自由抓取例程开发使用手册

news2024/11/24 14:21:49

目录

一、项目介绍

        项目背景:

        相机型号:

二、机械臂自由抓取演示 

        使用注意事项:

         操作步骤:

三、核心代码讲解

① 机械臂相关运动驱动代码

② BGR图像转换伪彩色深度图像代码

③ 目标跟随及抓取动作代码


开发者:居正

如果大家对这个项目感兴趣的话,可以评论或私聊我,加群进行交流。同时也可以关注3D视觉开发者社区哦。

一、项目介绍

        项目背景:

        基于奥比中光OpenCV实验箱,配合六自由度机械臂实现360度物体自由抓取,同时设置两种姿态配合桌面抓取和自由抓取,使机械爪能够精准的对目标进行抓取。

OpenCV实验箱套装
OpenCV实验箱套装

        相机型号:

        OpenCV实验箱搭配了奥比中光目前最新的深度相机Gemini2,它十分小巧,方便嵌入到任何设备中,同时对图像深度信息采集十分精准,经过测试Gemini2可支持2米以上超长距离的物体识别与跟踪。

二、机械臂自由抓取演示 

机械臂自由抓取演示视频

        使用注意事项:

        因为机械臂长度有限制,所以在使用药瓶自由抓取的时候,尽可能与摄像头保持水平,过高过远都无法准确抓取。因为角度限制,使用大药瓶在进行桌面抓取时,会发生滑爪现象,所以尽量使用小药瓶进行桌面抓取,大药瓶仅可进行自由抓取,小药瓶无限制。

机械臂抓取范围
范围 \ 目标类型大药瓶小药瓶
高度30---40cm30---35cm
距离以自身为圆心,半径为31cm以内距离以自身为圆心,半径为30cm以内距离

         操作步骤:

        首先找到例程运行所在的文件夹Code202308,打开终端(Ctrl+alt+T),输入命令cd Desktop/,接着cd Robotic_arm_apps,运行例程文件 python3 free_pickup.py

        显示上图界面代表运行例程成功,可以进行实验了。

三、核心代码讲解

        我将这里分成三个部分,分别是 ① 机械臂相关运动驱动代码 ② BGR图像转换伪彩色深度图像代码 ③ 目标跟随及抓取动作代码。

① 机械臂相关运动驱动代码

        下面代码是用来控制舵机对抓取动作位置的控制。x是中心铜柱到目标的抓取距离,y是抓取高度。

import math

def step(x = None, y = None):

    pi = 3.14

    L1 = 105     # L1
    L2 = 110     # L2
    L3 = 110     # L3

    if x is None:
        x = int(input("x:"))
    if y is None:
        y = int(input("y:"))
    theta = math.radians(0)

    Bx = x - L3 * math.cos(theta)
    By = y - L3 * math.sin(theta)

    lp = Bx**2 + By**2
    alpha = math.atan2(By, Bx)
    tmp = (L1*L1 + lp - L2*L2) / (2*L1*math.sqrt(lp))
    if tmp < -1:
        tmp = -1
    elif tmp > 1:
        tmp = 1
    beta = math.acos(tmp)
    q1 = -(pi/2.0 - alpha - beta)
    tmp = (L1*L1 + L2*L2 - lp) / (2*L1*L2)
    if tmp < -1:
        tmp = -1
    elif tmp > 1:
        tmp = 1
    q2 = math.acos(tmp) - pi
    q3 = - q1 - q2 - pi/2

    step_5 = int(2047 + int(math.degrees(q1) * 11.375))
    step_4 = int(2047 + int(math.degrees(q2) * 11.375))
    step_3 = int(2047 - int(math.degrees(q3) * 11.375))

    return step_3, step_4, step_5

        L1、L2、L3 是自定义连杆长度(标定值,提前测量好),接着定义好关节姿态theta坐标(x,y),接着计算中间位置Bx,By,即第二个关节的位置。这里用三角函数和末端关节的位置和姿态来求解,包括后面的所有动作基本上都是用三角函数逆解运算。

        计算第一个和第二个关节的角度q1,q2,使用二连杆机械臂的逆运动学公式。这里用math.acos 和 math.atan2 函数来求解反余弦和反正切,使用math.sqrt函数求平方根。

        计算第三个关节的角度q3,使用末端关节的姿态(预先定义,theta)减去前两个角度得到。math.degrees 函数将弧度转换为角度。

        接着用底层舵机控制库,传送舵机姿态,并返回舵机姿态。

② BGR图像转换伪彩色深度图像代码

        下面的代码是将相机采集到的深度信息配合BGR图像转换成伪彩色深度图像。 

ret_bgr, bgr_image = orbbec_cap.retrieve(None, cv.CAP_OBSENSOR_BGR_IMAGE)
ret_depth, depth_map = orbbec_cap.retrieve(None, cv.CAP_OBSENSOR_DEPTH_MAP)
            
if ret_depth:
    depth_map_8U = depth_map * 255.0 / 5000 
    depth_map_8U = np.clip(depth_map_8U, 0, 255) 
    depth_map_8U = np.uint8(depth_map_8U) 

    color_depth_map = cv.applyColorMap(depth_map_8U, cv.COLORMAP_JET) 
    cv.imshow("Depth: ColorMap",  color_depth_map) 

        首先对图像进行归一化和均值处理,强制转换类型,并显示图像。

 ③ 目标跟随及抓取动作代码

         此处代码是核心运动及抓取动作,包括了目标跟随代码还有旋转同步抓取动作代码。

def track_arm(packetHandler, bbox, frame_size,pid_errorx,pid_errory):
    c = frame_size[0] + 25
    s = frame_size[1] + (frame_size[1]/2)

    centerx = bbox[0]   
    centery = bbox[1] 
    stepx = int((centerx - c /2))
    stepy = int((centery - s /2))
    
    P_x = 0.2
    P_y = 0.3

    I_x = 0.05
    I_y = 0.06

    errorx = stepx - pid_errorx
    errory = stepy - pid_errory

    scs_present_position_3, scs_comm_result, scs_error = packetHandler.ReadPos(SCS_ID_3)
    scs_present_position_6, scs_comm_result, scs_error = packetHandler.ReadPos(SCS_ID_6)

    ACC_X = int (abs(P_x * stepx) + I_x * abs(errorx))
    if ACC_X > 256:
        ACC_X = 255
    elif ACC_X < 0:
        ACC_X = 0
    ACC_Y = int (abs(P_y * stepy) + I_y * abs(errory))
    if ACC_Y > 256:
        ACC_Y = 255
    elif ACC_Y < 0:
        ACC_Y = 0

    if scs_present_position_3 + stepy >= 3070:
        scs_comm_result, scs_error = packetHandler.WritePosEx(SCS_ID_5, 2480, SCS_MOVING_SPEED, SCS_MOVING_ACC)
        #packetHandler.WritePosEx(SCS_ID_2, 2048, SCS_MOVING_SPEED, SCS_MOVING_ACC)
    if scs_present_position_3 + stepy <= 2550:
        scs_comm_result, scs_error = packetHandler.WritePosEx(SCS_ID_5, 2900, SCS_MOVING_SPEED, SCS_MOVING_ACC)
    else:
        scs_comm_result, scs_error = packetHandler.WritePosEx(SCS_ID_3, scs_present_position_3 + stepy, SCS_MOVING_SPEED, ACC_Y)
        scs_comm_result, scs_error = packetHandler.WritePosEx(SCS_ID_6, scs_present_position_6 + stepx, SCS_MOVING_SPEED, ACC_X)

    pid_errorx = stepx
    pid_errory = stepy

    return pid_errorx, pid_errory

        上面的是目标跟随代码,实现原理是将目标始终固定到图像的中央,在利用PID算法对舵机进行移动,消除舵机抖动。 

        下面的是舵机跟随旋转代码,原理是利用掩膜目标坐标进行三角函数逆解运算,求出目标旋转角度,再将角度传送给舵机进行同步旋转。

def track_set_2(contours, x, y, w, h):
    arg = 0.0
    X_1 = x
    Y_1 = y
    X_2 = x + w - 1
    Y_2 = y + h - 1
    l = len(contours)
    for i in range(l - 1):
        if contours[i][0][0] == X_1:
            L1 = contours[i][0][1]
            break
    for i in range(l - 1):
        if contours[i][0][0] == X_2:
            L2 = contours[i][0][1]
            break
    for i in range(l - 1):
        if contours[i][0][1] == Y_1:
            R1 = contours[i][0][0]
            break
    for i in range(l - 1):
        if contours[i][0][1] == Y_2:
            R2 = contours[i][0][0]
            break
    '''0--90 AND 90--180 '''
    if R1 > R2 and h / w <= 0.65 * 56 / 22: 
        arg1 = math.acos((R1 - X_1)/math.sqrt((R1 - X_1) * (R1 - X_1) + (Y_1 - L1) * (Y_1 - L1))) / math.pi * 180
        arg2 = math.acos((X_2 - R2)/math.sqrt((X_2 - R2) * (X_2 - R2) + (L2 - Y_2) * (L2 - Y_2))) / math.pi * 180
        arg = (arg1 + arg2) / 2
    if R1 < R2 and h / w <= 0.65 * 56 / 22: 
        arg1 = math.acos((X_1 - R2) / math.sqrt((X_1 - R2) * (X_1 - R2) + (L1 - Y_2) * (L1 - Y_2))) / math.pi * 180
        arg2 = math.acos((R1 - X_2) / math.sqrt((R1 - X_2) * (R1 - X_2) + (Y_1 - L2) * (Y_1 - L2))) / math.pi * 180
        arg = (arg1 + arg2) / 2
    if h / w > 0.65 * 56 / 22:
        arg = 90
    arg = 1024 + int (arg / 180 * 2047)
    return arg

        如果大家对这个项目感兴趣的话,可以评论或私聊我,加群进行交流。同时也可以关注3D视觉开发者社区哦。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/860547.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CLIP论文精度

CLIP论文精度 Zero-shot CLIP多模态模型 Image Endecoder是一个图片编码器&#xff0c;既可以是ResNet,也可以是Vision Transformer. Text Encoder和Image Encoder产生的两组特征进行对比学习&#xff08;无监督训练&#xff09; 分类头&#xff1f;“分类头” 是指网络结…

第02天 什么是JWT ?

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 每天一个知识点 ✨特色专栏&#xff1…

MChat-Gpt V1.0.0 (将ChatGpt机器人接入内网供全体使用)

Github>https://github.com/MartinxMax/MChat-Gpt 首页 MChat-Gpt V1.0.0将ChatGpt机器人接入内网供全体使用 你需要一个ChatGpt账户如果您在中国则需要使用代理访问,设置TUN代理模式 安装依赖 选择你的系统进行安装 服务端配置 #python3 ChatGpt_Server.py -h 使用&a…

cve-2021-2394 weblogic反序列化漏洞分析

前几天weblogic 7月例行更新中&#xff0c;修复了一个Rce漏洞。该漏洞性质属于绕过之前的反序列化漏洞补丁。要了解这个漏洞的原因&#xff0c;我们首先要学习其他几个漏洞的原理。 一 weblogic 反序列化绕过指南 本章节只是大概讲解一下如何绕过weblogic反序列化漏洞的补丁。…

【金融量化】Python实现根据收益率计算累计收益率并可视化

1 理论 理财产品&#xff08;本金100元&#xff09; 第1天&#xff1a;3% &#xff1a;&#xff08;13%&#xff09; ✖ 100 103 第2天&#xff1a;2% &#xff1a;&#xff08;12%&#xff09;✖ 以上 103 2.06 第3天&#xff1a;5% : &#xff08;15%&#xff09;✖ 以上…

【指针模拟实现库函数strlen】

指针模拟实现库函数strlen 1.库函数strlen含义 strlen是用来计算字符串长度的。&#xff08;不包含’\0’) 2.assert断言介绍 assert.h 头⽂件定义了宏 assert() &#xff0c;⽤于在运⾏时确保程序符合指定条件&#xff0c;如果不符合&#xff0c;就报 错终⽌运⾏。这个宏常常…

【算法|数组】滑动窗口

算法|数组——滑动窗口 引入 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl1, ..., numsr-1, numsr] &#xff0c;并返回其长度**。**如果不存在符合条件的子数组&#xff0c;返回 0 。 示例…

putty使用记录

在官网下载并安装putty 一、SSH 二、FTP open 192.168.1.118 put -r C:\Users\Administrator\Desktop\test /opt/lanren312/test # 上传&#xff08;文件夹&#xff09; get -r /opt/lanren312/test C:\Users\Administrator\Desktop\test2 # 下载&#xff08;文件夹&#xff…

Linux Sudo 史上最大bug

自从安全厂商于近期公开了Linux系统中存在Sudo漏洞后&#xff0c;红帽、SUSE、Debian及Ubuntu等相关发行版本便开始相继推出了针对Linux Sudo漏洞的更新补丁&#xff0c;来避免由于Sudo漏洞而将本地端系统的最高权限陷于风险之中。 Sudo是linux系统管理指令&#xff0c;是允许系…

Telerik UI for ASP.NET Core Crack

Telerik UI for ASP.NET Core Crack Telerik ASP.NET Core还包括MVC和Kendo UI捆绑包(用于JavaScript)、Figma的设计工具包以及文档处理库、用于ASP.NET Core的Telerik REPL、RTL支持、辅助功能和键盘导航、主题化、虚拟课堂培训、详细文档、演示、KBs和世界级支持。使用一整套…

树结构--介绍--二叉树遍历的递归实现

目录 树 树的学术名词 树的种类 二叉树的遍历 算法实现 遍历命名 二叉树的中序遍历 二叉树的后序遍历 二叉树的后序遍历迭代算法 二叉树的前序遍历 二叉树的前序遍历迭代算法 树 树是一种非线性的数据结构&#xff0c;它是由n(n≥0)个有限节点组成一个具有层次关系…

Java基础篇--基本数据类型

目录 前言&#xff1a; 内置数据类型 类型默认值 示例: 内置数据类型转换 自动类型转换&#xff08;隐式类型转换&#xff09;&#xff1a; 强制类型转换&#xff08;显式类型转换&#xff09;&#xff1a; 隐含强制类型转换&#xff1a; 引用类型 前言&#xff1a; …

Java基础练习八(二维数组)

1.装水问题 有一个 异形 容器&#xff0c;用一个 n * n 的二维数组来表示。其中 1 表示容器实心部分&#xff0c; 0 表示空心部分。现使用此容器装水&#xff0c;能装多少水&#xff08;每个元素都表示一份水&#xff0c;只有有挡板的部分能装水&#xff09;&#xff1f; publi…

【学习】若依源码(前后端分离版)之 “ 获取角色权限信息及动态路由”

大型纪录片&#xff1a;学习若依源码&#xff08;前后端分离版&#xff09;之 “ 获取角色权限信息及动态路由” 获取用户信息获取路由信息 承接上回&#xff0c;我们发现在login请求后面跟了两个请求&#xff0c;今天我们就来了解一下两个请求的含义。 获取用户信息 先看 ‘…

Vulhub之Apache HTTPD 换行解析漏洞(CVE-2017-15715)

Apache HTTPD是一款HTTP服务器&#xff0c;它可以通过mod_php来运行PHP网页。其2.4.0~2.4.29版本中存在一个解析漏洞&#xff0c;在解析PHP时&#xff0c;1.php\x0A将被按照PHP后缀进行解析&#xff0c;导致绕过一些服务器的安全策略。 1、docker-compose build、docker-compo…

yolov5的报错

【定期水一期】 &#xff08;这个问题很抓马&#xff0c;可以看一下这篇文章&#xff1a;Git Bash 教程&#xff01;【不是所有人都会用Git】&#xff09; 一&#xff1a;没有cv2这个模块 解决方案&#xff1a; pip install opencv-python -i http://pypi.douban.com/simple/…

Java用方法实现数组拷贝

Java用方法实现数组拷贝 需求分析代码实现小结Time 需求分析 1.首先&#xff0c;考虑方法是否需要接收数据处理&#xff1f; 该方法的目的是拷贝数组&#xff0c;拷贝哪一个数组呢&#xff1f; 需要调用者传递 所以&#xff0c;参数应该是一个数组 2.接着&#xff0c;考虑方法是…

k8s常用资源管理

目录 Pod&#xff08;容器组&#xff09;&#xff1a;Pod是Kubernetes中最小的部署单元&#xff0c;可以包含一个或多个容器。Pod提供了一种逻辑上的封装&#xff0c;使得容器可以一起共享网络和存储资源 1、创建一个pod 2、pod管理 pod操作 Pod&#xff08;容器组&#xff…

单机游戏防破解方案解析

近年来&#xff0c;游戏市场用户规模趋于稳定&#xff0c;游戏市场进入了存量时代&#xff0c;各赛道“人满为患”&#xff0c;如何在一片红海中站稳脚跟成了厂商的必修课。 而在快节奏的社会环境下&#xff0c;脱离了网游社交粘性&#xff0c;主打清爽、自由的单机游戏&#…

软考圈地震!2023年下半年软考改为机考,报名时间推迟到9月4日

【1】通知原文 关于2023年下半年计算机软件资格考试有关工作调整的通知 各省、自治区、直辖市及计划单列市、新疆生产建设兵团&#xff0c;香港、澳门计算机软件资格考试考务管理机构: 为全面做好计算机软件资格考试安全防控工作&#xff0c;确保考试公正、公平。现将有关工…