3D深度视觉与myCobot 320机械臂无序抓取

news2024/9/20 6:00:17

今天我记录使用myCobot320 M5跟FS820-E1深度相机进行一个无序抓取物体的分享。

为什么会选择深度相机和机械臂做一个案例呢?

2D相机(最常见使用的相机)可以捕捉二维图像,也就是在水平和垂直方向上的像素值。它们通常用于拍摄静态场景或移动的物体,并且无法提供深度信息。在机器视觉应用中,2D相机可以用于图像分类、目标检测和识别等任务。

相比之下,深度相机可以捕捉深度信息,因此可以获得物体的三维信息。这些相机使用各种技术来测量物体的深度,如结构光、时间飞行和立体视觉等。在机器视觉应用中,3D相机可以用于点云分割、物体识别和3D重建等任务。

2D相机捕获到的信息已经满足不了一些特殊的情况,所以换上深度相机获得的更多的信息,比如说物体的长宽高。

让我们开始今天的主题。

FS820-E1

相机的环境搭建

首先我要搭建FS820-E1的开发环境,使用的是相机提供的RVS进行开发。可以利用RVS中的视觉算子写成节点(Node)快速搭建抓取功能。

RVS工作界面

实时采集数据

在左上角窗口资源中,找到TyCameraResource 算子添加到算子图中的 ResourceGroup 中,在算子列表搜索TyCameraAccesstrigger 算子分别添加到算子图中,并根据需要调整算子参数。然后点击运行和属性面板Trigger->ture即可查看可视化数据。没有报错能正常显示即可进行下一步。

TyCameraResource 算子

● start 以及 stop 分别用于开启、关闭资源算子的线程。auto_start 也是用于开启资源算子,如果勾选,则仅在打开 RVS 软件后第一次进入运行状态时自动开启资源线程。

● reset:在打开资源线程后如果需要更改属性参数,需要选中该选项进行重置。

TyCameraAccess 算子

● 打开cloud、rgb、depth可视化属性,将 cloud_color设置为-2,代表真实颜色

myCobot 320-M5Stack

myCobot 320 是面向用户自主编程开发的实践型机器人,产品最大有效臂展 350mm,最大负载 1KG,重复定位精度 ±0.5mm。

环境搭建

需要python 编译环境以及控制机器人的库pymycobot

pip install pymycobot --upgrade

复制

ps:使用的PC的显卡最好是1060 2G独显以上,因为需要锻炼图片识别等操作,显卡的性能越好运行得越快

无序抓取

接下来是实现机械臂的无序抓取,无论物体处于何种姿态都能过精准的抓到。下图是整体的算子图,也就是unstacking.xml工程文件

手眼标定

用棋盘格来进行手眼标定

准备:

● 准备棋盘格,算好棋盘格行列数,以及棋盘格边长(mm)

● 手眼标定分为眼在手上(eye in hand)、眼在手外(eye to hand)。根据不同情况将标定板和相机固定好。这里选择eye to hand

数据录制

点击左上角加载,打开unstacking_runtime/HandEyeCalibration/HandEyeCalibration.xml

在属性面板正确填写标定板的行列数,和标定板格子的单位长度,和数据保存的文件路径

启动相机工程和机械臂开始进行标定.

标定前确保相机能完整识别完整的棋盘格,以及标定过程中,棋盘格是固定的,不能发生移动。运行完成会得到18组数据。

计算标定结果

positional error 在 0.005(5 毫米)以内,则比较理想

坐标系转换

此操作旨在将点云所处的坐标系——相机 rgb 镜头坐标系转换至机器人坐标系,这一转换涉及相机外参及手眼标定结果。

步骤:

● 1)在算子图中右键选择在此处导入Group XML,导入RVSCommonGroup 中的HandToEye_Depth2Robot.group.xml。需要注意的是,除了该文件之外 ,还有HandInEye_Depth2Robot.group.xml。

● 2)加载手眼标定数据组的pose端口与HandToEye_Depth2Robot组的rgb2robot 端口连接。

● 3)拖入 LoadCalibFile 算子,用于加载标定文件,finshed 端口连接至HandToEye_Depth2Robot组的start端口;extrinsic_pose端口与rgb2depth 端口连接;start端口与InitTrigger端口finished端口连接。具体连接如下:

点击 Group,找到 rgb2tcp 算子,在属性面板的 pose 属性处,粘贴手眼标定的结果。

● 5)通过前述步骤,我们已经获取了相机 rgb 镜头转机器人坐标系的矩阵 rgb2robot 和相机深度镜头转机器人坐标系的矩阵 depth2robot,此处我们将相机深度镜头坐标系下点云转换至机器人坐标系下。

● 6)首先拖入 Transform 算子,type 属性选择“PointCloud”,将 depth2robot 端口连接至该算子的pose 输入端口,将 LoadLocalData 算子组的 pointcloud 端口连接到本算子的同名输入端口。

AI训练

采集训练图像

打开 unstacking_runtime/MaskRCNN/ty_ai_savedata.xml,内容基本与录制 RGB 图像一致,在这里我们只需要调整 EmitSring 中的 string 参数,设置为我们想要的路径即可。点击 Capture 录制图像。当然数据越多那是越好,越稳定。

标注训练模型

目前为已录制好的 RGB 标注,我们推荐使用 labelme 这款软件,本文档提供一种 labelme 的安装方法。

● 1.按照官网安装pip

Installation - pip documentation v23.1.2

● 2.安装PyQt5

pip install PyQt5

复制

● 3.安装labelme

pip install labelme

复制

标注前准备

首先确定任务目标,明确在检测过程中什么物体需要被检测,什么物体不需要被检测,从而有针对性的进行标注。

给定的标注条件无需过分苛刻,不要按照人的思维去考虑,而是按照自己主观设定的标注思路是否便于落实代码。

标注过程

● 终端输出labelme,打开软件点击OpenDir,选择我们标注的路径(在3.2.1采集训图像Emit算子string路径)

● 点击Create Polygons,为木块绘制红色的边框

● 完成后会弹出命名框,第一次请命名 wooden block,后续同类直接选择

● 当图像内所有箱子标注完成后,点击 Save 进行保存,默认当前文件夹,默认名称,随后选择 Next Image 切换到下一个图像

训练AI模型

开unstacking_runtime/MaskRCNN/ty_ai_train.xml,这里只需要调整 data_directory 和classnames _filepath 路径。点击 start_train按钮即开始训练。

最终会生成一个 train output 文件夹在这个文件夹中有命名为 model fial,pth是所需要的权重文件。

AI推理

1)拖入一个 Emit 算子,type 属性选择“pose”,重命名为“抓取参考Pose”,将 pose_roll 输入入“3.141592654”。这个算子在后续的算子中使用。将该算子中 pose 端口与计算抓取点组down_pose 端口连接

2)双击展开计算抓取点组,需要预先使用 MaskRCNN 网络对数据进行训练,将其中的AIDetectGPU 算子的 type 更改为MaskRCNN 并对应修改其余配置文件参数。由于 AI 推理算子在正式运行前需要初始化运行一次,所以需要在算子前额外添加一个 Trigger(type 为 InitTrigger)。

3)AI 推理算子会获得目标在 2D 图像中的位置区域(即掩码图,对应的是 obj_list 端口),之后我们需要将这些位置区域转换到 3D 点云中,这一环节对应的是 计算抓取点 组中的 ProjectMask 算子。对于 ProjectMask 算子,不仅需要给入 AI 推理算子获得的 obj_list,还需要给入 2D 图对应的点云、2D图采图时所用的 rgb 镜头坐标系同点云坐标系的转换矩阵、相机 rgb 镜头的内参。这里已经将点云转换到了机器人坐标系,所以需要输入 rgb 镜头到机器人坐标系的转换矩阵。相机的 rgb 镜头内参可以直接从相机参数文件中读取。算子运行完成后,会获得所有检测目标的点云列表。

机械臂定位抓取

定位识别

根据 AI 推理后的流程,已经获得了在机器人坐标系下所有检测目标的点云列表。接下来要获得它的点云中心坐标。

1)双击展开 计算抓取点 组中 寻找目标 组。需要先筛选木块,并按照木块列表的 Z 轴坐标值进行筛选,筛选出最上层的木块,并对上层木块进行排序。因此这里使用 FilterBoxList 算子,重命名为“点云高度排序”,该算子的属性值调整如下:

2)获取平面,使用 FindElement,type 选择“Plane”,获得点云中适合抓取的平面。调整算子属性distance_threshold 来调整所选取的平面。打开 cloud 可视化属性来查看选取的平面。

3)获取平面中心点,使用 MInimumBoundingBox 算子,重命名为“获得外包框”,type 属性选择“ApproxMVBB”获得一个方便机器人抓取的坐标中心点。这里需要给该算子一个 ref_pose,这里连接在3.3.4进行AI推理中提到的“TowardsDownPose”,表示绕着 X 轴旋转 180°,使 Z 轴朝下,便于机器人抓取。打开“GetBoxCube”属性面板 box 和 box_pose 可视化属性即可显示计算出的平面中心点。

4)调整木块方向,使用AdjustBoxNode算子,该算子的作用是,选择长度大于宽度的物体,将物体位姿进行改变,这里选择yaw选择90°

这样就能够获取到坐标了

机械臂的抓取

在完成上述操作后,已经获得了目标点坐标,需要通过机器人和RVS软件建立连接并进行 tcp通讯。进行实际抓取。

1)编写TCP通讯代码(RobotControl_Elephant.py),以下部分为截取,该代码实现RVS软件和机械臂的TCP通讯

#CAPTURE
print("***get pose***%s"%time.asctime())
capture_cmd = "GET_POSES \n"
capture_bytes=bytes(capture_cmd,encoding="utf-8")
sock_rvs.send(capture_bytes)
#recv CAPTURE
data = sock_rvs.recv(socket_buf_len)
print("---------------------------接收的数据----------------------------")
print(data)
print("***data end***%s"%data[-1:])

print("***capture_receive***%s"%time.asctime())
if int(data[-1:]) == 1:
    print("***received CAPTURE result***\n")
if int(data[-1:]) == 2:
    print("***All finished!***"
    #P_FLAG = bool(1-P_FLAG)
    #print("切换拍照位")
    continue
    #break

复制

2)将目标点进行调整坐标⽐例,将 ScalePose 算⼦的 type 设置为 Normal ,分别调整 pose 的( X 、Y 、Z )和( Roll 、Pitch 、Yaw)⽐例。scale_rpy :修改 pose 中 r p y 的单位。设:57.2957795 。即从将弧度切换为⻆度。

3)最后,将ScalePose的 finished 和pose_list端口连接到最外层算子组的 MirrorOutput 端口, 并连接回 HandEyeTCPServer算子。至此,项目文件的编辑已经完成。

效果展示

完成以上步骤,在unstacking.xml工程下,点击运行,同时运行RobotControl_Elephant.py文件,识别到多个木块选取其中一个木块位姿就会发送给机械臂进行夹取。

总结

总的来说这只是深度相机的一小点功能,后续甚至考虑将这几个物体叠在一起又或者其他的不规则形状来体现出它性能的强大。提前训练好模型,就能实现想要的效果。你期待我用它来做些什么呢?欢迎在地下留言,你们的点赞和关注将是我更新的动力!

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

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

相关文章

F#奇妙游(5):计算π的值

F#到底有什么用? 奇妙游写到第五篇,前面的几篇都是开场白: 一个用F#编写WinForm的例子donet命令行工具,也就是F#的开发环境关于函数和函数式编程的碎碎念函数式编程的核心概念:值 下面,我们开始正式来搞…

数据库左、右、内、逗号、全连接(mysql不包含全连接)方式

1、准备数据 学生有归属班级 学生表 班级表 2、执行查询语句 2.1执行左关联 select * from student stu left join class cla on (stu.class_idcla.class_id); 结果如下 2.2执行右关联 2.3、执行内连接 2.4执行逗号分隔表的连接方式 和内连接的查询结果是一样的

实训笔记7.3

实训笔记7.3 7.3一、座右铭二、单例模式三、IDEA集成开发环境的安装和基本使用四、Debug断点调试4.1 作用有两个4.2 用法:4.3 IDEA设置step into进入JDK源码4.4 step over4.5 step into 五、Java中的网络编程5.1 网络编程的三个核心要素5.2 通过Java实现网络编程 7.…

第三章 搜索与图论(二)——最短路问题

文章目录 单源最短路朴素Dijkstra堆优化版DijkstraBellman Ford算法SPFASPFA求负环 多源汇最短路Floyd 最短路练习题849. Dijkstra求最短路 I850. Dijkstra求最短路 II853. 有边数限制的最短路851. spfa求最短路852. spfa判断负环854. Floyd求最短路 源点表示起点,汇…

Linux系统远程挂载Mac OS系统目录方法

打开mac文件共享功能 开启共享服务 进入系统偏好设置中的共享选项。勾中文件共享(如下图),之后右边的文件共享的绿灯会点亮,并显示“文件共享:打开”。 添加共享目录 点击在文件共享界面(如下图&#x…

【狂神】MySQL - 数据库级别的外键

1. 外键 FOREIGN KEY (了解) 测试数据 : 学生表 CREATE TABLE IF NOT EXISTS student (id INT(4) NOT NULL AUTO_INCREMENT COMMENT 学号,name VARCHAR(30) NOT NULL DEFAULT 匿名 COMMENT 姓名,pwd VARCHAR(20) NOT NULL DEFAULT 123456 COMMENT 密码,sex VARC…

【数据结构与算法】 完成用十字链表存储的稀疏矩阵的加法运算

题目: Qestion: 完成用十字链表存储的稀疏矩阵的加法运算。 主要思路: 获取两个稀疏矩阵总有多少个非零元素,记作cnt。当cnt 不为零时一直循环,每循环一次i,也就是行循环,每循环一次就转移至下一行。先从…

Git常用指令总结

1、git init&#xff1a;初始化一个Git仓库&#xff1b; 2、git clone&#xff1a;从远程仓库克隆代码到本地&#xff1b; 直接使用网址 git clone <url>or 用a代替网址 git remote add a <url>git clone a3、git add&#xff1a;添加文件到暂存区&#xff1b; 文件…

K8S数据管理

K8S数据管理 1 数据管理1.1 数据持久化1.1.1 存储方案1.1.2 EmptyDir实践1.1.3 hostPath实践1.1.4 NFS实践 1.2 持久化进阶1.2.1 数据对象1.2.2 PV&PVC实践1.2.3 SC解析1.2.4 SC实践 1.3 配置管理1.3.1 配置基础1.3.2 CM1.3.3 CM案例1.3.4 Secret1.3.5 Secret案例 1.4 状态…

36. QT中使用QFtp实现文件传输1 -- 本地文件或文件夹上传到远程服务器

1. 说明 在使用QT进行嵌入式开发或者是使用到TCP控制传输时,有时程序的正常运行会用到某一个文件或者整个文件夹,此时就需要软件方面将需要的文件或者文件夹传输到远程服务器上。在QT中主要有两种方式可以实现这个功能,一个是QT4中使用QFtp这个类来实现,这个类提供了很丰富…

每天一点Python——day48

#第四十八天 #什么是元组为什么元组没有增删改操作和生成式&#xff1f; 元组&#xff1a;Python内置的数据结构之一&#xff0c;是一个不可变序列 不可变序列&#xff1a;没有增删改操作【例如字符串&#xff0c;元组】 可变序列&#xff1a;可以执行增删改操作&#xff0c;操…

记录好项目D21

记录好项目 你好呀&#xff0c;这里是我专门记录一下从某些地方收集起来的项目&#xff0c;对项目修改&#xff0c;进行添砖加瓦&#xff0c;变成自己的闪亮项目。修修补补也可以成为毕设哦 本次的项目是个基于Springbootvue的景区旅游系统 一、系统介绍 本项目分为管理员与…

534 · 打劫房屋 II

链接&#xff1a;LintCode 炼码 - ChatGPT&#xff01;更高效的学习体验&#xff01; 题解&#xff1a;九章算法 - 帮助更多程序员找到好工作&#xff0c;硅谷顶尖IT企业工程师实时在线授课为你传授面试技巧 处理循环数组问题&#xff1a;分类&#xff0c;重复&#xff0c;取反…

信息安全概述笔记

保密性、完整性、可用性是传统的信息安全的原则和目标&#xff0c;目前随着信息安全问题的日益严峻&#xff0c;信息安全的原则和目标衍生为诸如可控性、不可否认性等其他的原则和目标。 保密性&#xff08;Confidentiality&#xff09;:确保信息只能由那些被授权使用的人获取…

Web服务器群集:四层代理与七层代理

目录 一、理论 1.OSI七层模型 2.四层代理 3.七层代理 4.四层代理与七层代理区别 5.负载均衡器 6.常见的代理组件 7.应用场景 二、总结 一、理论 1.OSI七层模型 &#xff08;1&#xff09;概念 标准的七层网络分层是OSI七层模型&#xff0c;TCP/IP五层模型和TCP/IP四…

Android Matrix的理解

文章目录 前言一.基础1.1 Matrix1.2 使用Matrix的准备知识 二.preXXX和postXXX2.1 右乘和左乘2.2 验证规律 三.坐标原点结束 前言 Android绘制中最重要的要算Matrix类了&#xff0c;同时也是不太好理解的。以前也用过&#xff0c;但是掌握的也不是太好&#xff0c;刚好有时间好…

GO语言包相关总结 -引用(本地和远程),自定义,安装,使用

本篇文章总结以下go语言包相关的知识。 目录 一.导入包 &#xff08;1&#xff09;常规导入 &#xff08;2&#xff09;别名导入 &#xff08;3&#xff09;特殊导入 二.自定义包 三.安装自定义包 四.调用自定义包调用 五.获取远程包 六.go中的保留函数 七.实战 - G…

Python自动化测试实战篇(12),一文学完,Pytest 常用11种第三方插件

这些是之前的文章&#xff0c;里面有一些基础的知识点在前面由于前面已经有写过&#xff0c;所以这一篇就不再详细对之前的内容进行描述 Python自动化测试实战篇&#xff08;1&#xff09; Python自动化测试实战篇&#xff08;2&#xff09; Python自动化测试实战篇&#xff…

解决python-opencv:(-215:Assertion failed) _img.empty() in function ‘cv::imwrite‘在将视频分成帧图片,写入时出现的问题

最近在搞视频检测问题&#xff0c;在用到将视频分帧保存为图片时&#xff0c;图片可以保存&#xff0c;但是会出现(-215:Assertion failed) !_img.empty() in function cv::imwrite问题而不能正常运行&#xff0c;在检查代码、检查路径等措施均无果后&#xff0c;了解了视频分帧…

rk3399 调试ap6354

电路如下: wifi&#xff1a; 按照rk3399 sdk默认配置&#xff0c;修改相应的引脚 sdio_pwrseq: sdio-pwrseq { compatible "mmc-pwrseq-simple"; clocks <&rk808 1>; clock-names "ext_clock"; pinctrl-nam…