拆垛搭建准备
数据准备
获取离线数据
RVS开发者社区提供拆垛离线工程数据包,帮助用户快速上手、验证功能并节省时间。点击 unstacking_runtime.zip 下载,解压后包含以下内容:
文件说明
文件 | 说明 |
---|---|
data | 该文件夹包含本案例中所使用的 Elite 机器人模型,如果您需要其他模型请前往 RVS 软件发布模型网站下载。 |
group | 该文件夹包含常用的一些 Group 组,包含加载、手眼标定转换等 Group,根据需要进行导入。 |
MaskRCNN | 该文件夹内容用于 AI 推理。其中,ty_ai_savedata.rvs 用于AI图像录制。ty_ai_train.rvs 用于AI训练。 |
unstacking_data | 该文件夹为拆垛程序离线模式数据的加载,使用时请注意路径正确。 |
rgb2tcp.txt | 该文件为本案例中 Elite 机器人 EyeInHand 的手眼标定结果。 |
ty_color/depth_calib.txt | 该文件为本案例中相机的彩色图标定参数与深度图标定参数 。 |
unstacking.rvs | 该工程用于拆垛程序,可做参考,当加载离线数据时,请先确定 TyCameraSimResource 与 LoadLocalTCP Group 中离线数据的路径是否正确。 |
本案例所有使用到的文件均保存在 unstacking_runtime 下,请放在 RVS 安装目录下运行。
备注
运行时确保算子文件路径加载正确,若不想修改文件路径,可将文件内文件放入运行程序的同级目录下。
本文档所使用RVS软件版本为 1.8.321,若在使用中出现问题或版本不兼容问题,请及时与我们反馈,发送邮件 rvs-support@percipio.xyz !
软件准备
下载RVS_AI软件
面对复杂场景,可以下载 RVS_AI 软件重新进行标注、AI 训练,在此基础上进行推理。
备注
请参考 RVS 安装教程,以验证您的电脑配置是否满足 AI 训练的要求。
RVS_AI 软件下载地址如下。
下载文件解压后,文件夹中 RVS_AI_Center.exe 为 RVS-AI 运行文件。AILibrary 文件夹存放训练好的 AI 模型,用于后续推理。
本案例中,需将拆垛离线工程数据包中 MaskRCNN 文件夹内的 unstacking.mask
压缩文件移动到 AILibrary 文件夹下。
真实场景作业
真实场景作业需要准备真实场景机器人手眼标定文件,并确保使用时路径正确。
拆垛流程
拆垛流程概览
自动拆垛的实际目标为找到箱型几何中点并根据一定顺序进行抓取。具体拆垛流程可分为以下步骤:
通讯接收:根据机器人发送的通讯指令触发工程。
本案例使用的通讯字符串格式为 “ROBOT_TCP,X,Y,Z,RX,RY,RZ#”。其中,X,Y,Z,RX,RY,RZ 为拍照时的机器人TCP位姿。
加载本地数据:本案例中使用离线数据完成拆垛项目。
坐标系转换:将相机坐标系下的点云转到机器人坐标系下。
AI 推理分割点云:箱子摆放紧密时使用 AI 推理并将箱子点云进行分割。
筛选定位:识别到目标点云进行筛选排序后进行定位。
通讯发送:将目标定位的位姿发送至机器人。
发送的字符串格式为“ROBOT_TCP,X,Y,Z,RX,RY,RZ#”。其中,X,Y,Z,RX,RY,RZ 为目标的定位位姿。
机器人抓取:本案例中使用机器人仿真进行顺序拆垛抓取。
拆垛工程演示
操作流程
开启 RVS_AI 推理服务。
小技巧
RVS_AI 软件操作指南详见:操作指南。
打开 RVS,加载工程。
点击加载按钮,选择 unstacking.rvs 并打开。
运行工程。
点击 RVS 运行按钮。
触发工程。
离线触发。
点击交互面板上
离线触发
按钮进行触发。
在线触发。
在 Resource Group 中连接图漾相机。
备注
自动启动:运行工程自动连接图漾相机。
启动:运行工程后手动连接相机。
在交互面板中调整模式,刷新组合框,选择图漾相机资源。
机器人发送“ROBOT_TCP,X,Y,Z,RX,RY,RZ#”。其中,X,Y,Z,RX,RY,RZ 为拍照时的机器人 TCP 位姿。
运行结果。
离线模式下,每点击一次
离线触发
,机器人进行顺序拆垛。在 3D 视图中看出仿真机器人的抓取姿态。在交互面板中查看 AI 结果已经具体位姿信息。
拆垛工程搭建
通讯接收
本案例工程通过机器人发送的通讯指令触发工程。此案例为眼在手上模式,需要发送当前的拍照位姿进行计算。
操作流程
新建工程项目并保存为 unstacking.rvs。
添加 TCPServerConnectionResource 算子至 Resource Group ,用于建立TCP通讯服务端。
设置 TCPServerConnectionResource 算子参数:
自动启动→是
端口→7000
添加 TCPServerReceive 算子至算子图,用于通讯指令触发工程运行。
右击 TCPServerReceive 算子,打开算子面板:
点击
指令→ROBOT_TCP
指令分隔符→,
包含数据→pose
数据分隔符→,
后缀→#
TCPServerReceive算子面板配置如下:
小技巧
TCPServerReceive算子中具体参数介绍见:TCPServerReceive面板。
离线/在线数据
本案例中,离线数据在 unstacking_data 文件夹下,数据内容包含点云、joints、2d 图像、tcp。在线数据需要连接图漾相机以及机器人通讯来实时获取。
备注
若需要根据现场的实际情况进行拆垛流程,可连接相机与相机资源完成在线拆垛。
操作流程
添加 两个Trigger 算子至算子图,用于触发离线/在线工程运行。
设置 Trigger 算子参数:
算子名称 → 离线触发
设置 Trigger_0 算子参数:
算子名称 → 在线触发
从 group 中导入 LoadLocalTCP.group,用于离线遍历离线机器人TCP数据。
设置 LoadLocalTCP.group 的参数:
父目录→unstacking_data
备注
注意此工程的运行路径。
添加 Selector 算子至算子图,用于选择离线或在线机器人TCP数据作为后续计算。
设置 Selector 算子参数:
算子名称→Selector_TCP
类型→坐标
添加 TyCameraResource、TyCameraSimResource 算子至 Resource Group。其中,TyCameraResource 用于连接图漾相机,TyCameraSimResource 用于遍历离线点云、彩色图、深度图等数据。
设置 TyCameraSimResource 算子参数:
自动启动→是
加载模式→目录
目录→unstacking_data
彩色图像文件→rgb.png
深度图像文件→depth.png
点云文件→cloud.pcd
深度图标定文件→ty_depth_calib.txt
彩色图标定文件→ty_color_calib.txt
备注
注意此工程的运行路径。
设置TyCameraResource算子参数:
根据实际的图漾相机进行设置。
添加 TyCameraAccess 算子至算子图,用于输出点云、彩色图、深度图等数据。
设置 TyCameraAccess 算子参数:
相机资源→TyCameraSimResource
添加 Load 算子至算子图,用于加载手眼标定结果。
设置 Load 算子参数:
算子名称→Load_HandEyeResult
类型→坐标
文件→rgb2tcp.txt
备注
注意此工程的运行路径。
连接算子
算子图连接如下图所示:
坐标系转换
加载数据后,需进行坐标系转换,将相机内参结合手眼标定参数转换到机器人坐标系。这一转换涉及相机外参及手眼标定结果。
备注
请参考手眼标定工具在线文档获得实际标定结果。 离线标定结果数据存在 rgb2tcp.txt 中。
操作流程
在算子图空白处右键选择“在这里创建新 Group ”,用于将点云转换至机器人坐标系。
设置新建 Group 参数:
算子名称→点云转换至机器人坐标系
连接算子端口:
连接
TyCameraAccess 的结束端口
至Group 的开始端口
连接
TyCameraAccess 的点云端口
至Group 的 Input 区域
连接
Selector_TCP 的坐标端口
至Group 的 Input 区域
,右击Group内侧的坐标端口
进行重命名,重命名为 tcp2robot连接
Load_HandEyeResult 的坐标端口
至Group 的 Input 区域
,右击Group内侧的坐标端口
进行重命名,重命名为rgb2tcp算子图连接如下图所示:
添加眼在手上坐标转换、transform 至点云转换至机器人坐标系 Group 中。其中,眼在手上坐标转换用于计算转换矩阵,transform用于根据计算出的转换矩阵进行点云转换。
设置 Transform 算子参数:
类型→点云
点云→ 可视 → -2
连接算子端口:
连接
Group 的启动端口
至眼在手上坐标转换的启动端口
连接
眼在手上坐标转换的结束端口
至Transform 的启动端口
连接
Transform 的结束端口
至Group 的结束端口
连接
Group的点云端口
至Transform的点云端口
连接
Group的彩色图标定参数端口
至眼在手上坐标转换的彩色图标定参数端口
连接
Group的 tcp2robot 端口
至眼在手上坐标转换的 tcp2robot 端口
连接
Group的 rgb2tcp 端口
至眼在手上坐标转换的 rgb2tcp 端口
连接
眼在手上坐标转换的 depth2robot 端口
至Transform 的坐标端口
连接
Transform 的点云端口
至Group 的 Output 区域
连接
眼在手上坐标转换的 rgb2robot 端口
至Group 的 Output 区域
连接
Group的彩色图标定参数端口
至Group 的 Output 区域
算子图连接如下图所示,双击 Group 空白处可进行折叠。
AI 推理分割点云
实际工作中箱型摆放较为紧密,多个箱子的上表面点云会连在一起变成不易分割的一大块点云。针对这个问题,可训练 AI 模型,在此基础上进行 AI 推理,便可获取箱子的点云列表。
AI 训练需要一定配置,如果未能满足配置要求,可以使用离线数据包中的.mask
文件直接进行推理。整个流程分为四个主要步骤:录制、标注、训练和推理。
操作流程
添加 AI 推理分割点云 group 至算子图中,用于彩色图 AI 识别并将相应识别区域的点云分割为点云列表。
连接算子端口:
连接
点云转换至机器人坐标系的结束端口
至AI推理分割点云的启动端口
连接
TyCameraAccess算子的彩色图端口
至AI推理分割点云的彩色图端口
连接
点云转换至机器人坐标系的rgb2robot
端口至AI推理分割点云的相机坐标端口
连接
点云转换至机器人坐标系的彩色图标定参数端口
至AI推理分割点云的彩色图标定参数端口
算子图连接如下图所示:
设置 AI 推理分割点云 group 中 AI推理算子参数:
服务端 IP 地址→127.0.0.1
服务端端口号 → 2024
模型序号→0
识别结果图像→ 可视
打开 RVSAI,进入
推理服务
界面。添加 MaskRCNN 网络,设置参数:
TCP 服务端口 → 2024
模型名 → 拆垛
运行设备 → cuda 0 (根据实际配置进行设置)
分数阈值 → 0.8
模型文件 → unstacking.mask
筛选定位
通过 AI 推理获得机器人坐标系下所有检测目标的点云列表后,需获得点云中心坐标。
操作流程
在算子图空白处右键选择“在这里创建新 Group ”,用于对箱子进行筛选排序后并进行定位。
设置新建 Group 参数:
算子名称→筛选定位
连接算子端口:
连接
AI推理分割点云的结束端口
至Group 的开始端口
连接
AI推理分割点云的结束端口的点云列表端口
至Group 的 Input 区域
算子图连接如下图所示:
添加 FilterBoxList 算子至筛选箱子 Group 中,用于将 Z 值最上层的箱子筛选处理,同时将筛选出的箱子按 Y 轴进行排序。
设置 FilterBoxList 算子参数:
类型→ByAxisZ
选择模式→Z_MAX
选择阈值→0.07
X权重→0
Y权重→-1
连接算子端口:
连接
Group 的启动端口
至FilterBoxList的启动端口
连接
Group 的点云列表端口
至FilterBoxList的点云列表端口
算子图连接如下:
添加 AtList 算子至筛选箱子 Group 中,用于将排序完的箱子提取第一个目标进行定位。
设置 AtList 算子参数:
算子名称→GetFirstInList
类型→点云
模式→单个索引提取
索引→0
连接算子端口:
连接
FilterBoxList的结束端口
至GetFirstInList的启动端口
连接
FilterBoxList的点云列表端口
至GetFirstInList的点云列表端口
算子图连接如下:
添加 FindElement 算子至筛选箱子 Group 中,用于对点云进行查找平面。
设置 FindElement 算子参数:
算子名称→FindPlane
类型→平面
距离阈值→0.003
连接算子端口:
连接
GetFirstInList的结束端口
至FindPlane的启动端口
连接
GetFirstInList的点云端口
至FindPlane的点云端口
算子图连接如下:
添加 MinimumBoundingBox 算子至筛选箱子 Group 中,用于对点云进行最小包围盒定位中心。
设置 MinimumBoundingBox 算子参数:
算子名称→FindPlane
类型→快速
模式→X > Y > Z
距离阈值→0.003
Z 轴朝向→世界坐标系 Z 轴负向
X 轴朝向→世界坐标系 X 轴正向
RX参考值→0
连接算子端口:
连接
FindPlane的结束端口
至MinimumBoundingBox的启动端口
连接
FindPlane的点云端口
至MinimumBoundingBox的点云端口
连接
MinimumBoundingBox的结束端口
至Group的结束端口
连接
MinimumBoundingBox的包围立方体中心坐标端口
至Group的Output区域
算子图连接如下:
通讯发送
操作流程
添加 TCPServerSend 算子至算子图,用于将定位出的位姿发送至机器人。
右击 TCPServerSend 算子,打开算子面板:
点击
端口名→ROBOT_TCP
数据类型→Pose
前缀→ROBOT_TCP,
数据分隔符→,
后缀→#
TCPServerReceive算子面板配置如下:
备注
通讯字符串格式可自定义。本案例格式为:“ROBOT_TCP,X,Y,Z,RX,RY,RZ#” 。
连接算子。
算子图连接如下图所示:
机器人仿真抓取
在完成上述操作后,获得了目标点坐标,需要通过加载机器人模型,模拟抓取。
操作流程
添加 SimulatedRobotResource 至 Resource Group中,用于加载仿真机器人模型。
设置 SimulatedRobotResource 算子参数:
自动启动→是
机器人模型文件→data/EC66/EC66.rob
工具模型文件→data/Tool/EliteRobotSucker2.tool.xml
机器人→ 可视
添加 Trigger 算子至算子图,用于初始化触发运行。
设置 Trigger 算子参数:
算子名称→InitTrigger
类型→初始化触发器
添加 RobotMovement 算子至算子图,用于仿真机器人移动关节,通过自定义关节值运行至初始位姿。
设置 RobotMovement 算子参数:
算子名称 → MoveToJoints
类型 → 移动关节
关节 → 0 -1.495489955 1.512199998 -1.627550006 1.499660015 -0.04329660162
连接算子端口。
连接
InitTrigger 的结束端口
至MoveToJoints 的开始端口
算子连接如下:
添加 RobotMovement 算子至算子图,用于仿真机器人移动 TCP,通过定位位姿将仿真机器人进行运动。
设置 RobotMovement 算子参数:
算子名称 → MoveToPose
类型 → 移动TCP
关节 → 0 -1.495489955 1.512199998 -1.627550006 1.499660015 -0.04329660162
作为工具坐标→是
连接算子端口。
连接
筛选定位的结束端口
至MoveToPose的开始端口
连接
筛选定位的包围立方体中心坐标端口
至MoveToPose的goal_pose端口
连接
MoveToJoints的关节端口
至MoveToPose的参照关节端口
连接算子图如下:
完整的 XML 已提供在unstacking_runtime/unstacking.xml 路径下。
交互面板创建
交互面板中的工具可以与算子图中算子属性的曝光和输出进行绑定,输入工具可以快速修改算子属性参数,输出工具可以快速查看算子的输出结果。
编辑交互面板。
右击交互面板,选择
解锁
,此时交互面板进入编辑状态。
添加输入工具的
标签
、组合框
至交互面板中。标签
双击 “label”,修改名称为“模式:”。
组合框
在算子图中找到 TyCameraAccess 算子,在属性面板中将相机资源的曝光打开。
右击
组合框
,选择显示控件面板
。在曝光参数中选择 MainGroup/TyCameraAccess 参数框,点击绑定按钮。
点击
确定
,该算子参数与该控件绑定成功。
添加输入工具
按钮
(两个)。按钮
双击 “button”,修改名称为“离线触发”。
在算子图中找到 离线触发算子,在属性面板中将触发器的曝光打开。
右击
按钮
,选择显示控件面板
。在曝光参数中选择 MainGroup/离线触发参数框,点击绑定按钮。
点击
确定
,该算子参数与该控件绑定成功。
按钮
双击 “button”,修改名称为“在线触发”。
在算子图中找到 在线触发算子,在属性面板中将触发器的曝光打开。
右击
按钮
,选择显示控件面板
。在曝光参数中选择 MainGroup/在线触发参数框,点击绑定按钮。
点击
确定
,该算子参数与该控件绑定成功。
添加输入工具的
标签
、输出工具的2D图片
至交互面板中。标签
双击 “label”,修改名称为“AI结果:”。
2D 图片
在算子图中找到 AI 推理分割点云,在属性面板中将 show_result_visibility 的可视化打开。
右击
2D图片
,选择显示控件面板
。在曝光参数中选择 MainGroup/AI 推理分割点云/AIDetect 参数框,点击绑定按钮。
点击
确定
,该算子参数与该控件绑定成功。
添加输入工具的
表格
至交互面板中。表格
在算子图中找到 MinimumBoundingBox 算子,在属性面板中将包围立方体中心坐标的可视化打开。
右击
表格
,选择显示控件面板
。在曝光参数中选择 MainGroup/筛选定位./MinimumBoundingBox 参数框,点击绑定按钮。
点击
确定
,该算子参数与该控件绑定成功。
交互面板创建如下:
AI训练
本章节主要讲解如何采集训练图像。完整的流程分为三个步骤:采集、标注和训练。有关标注训练图像和训练AI模型的详细信息,请参考以下指定的在线文档:标注训练图像和训练AI模型 。
采集训练图像
打开 unstacking_runtime/MaskRCNN/ty_ai_savedata.xml,内容基本与录制 RGB 图像一致,在这里我们只需要调整 Emit 中的 string 参数,设置为我们想要的路径即可。点击 Capture 按钮录制图像。录制图像数量保证在 10 张以上,越多越好。
在图像采集时,我们应注意以下几点:
背景光照
单一稳定光源,亮暗适宜且没有过多反光。
户外光照情况变化过大,不建议。
复杂工况考虑:尽量使得采样样本对实际运行的全局样本有足够的代表性而不仅仅是全局样本的一种特例。
目标物件多样化,尽量不选用固定单一目标物体。如果当前可供使用的样本数目比较少,可以考虑将样本正反两个面(两个面一样)都使用来倍增样本。
工况多样化,对于目标物体,尽可能多的考虑其在工况中出现的情形,多情况拍摄:
如果项目中垛车大小、垛车姿态、目标在垛车中的姿态、目标外形外观等有多种情形,则我们采集的训练数据应该把这些多样化的情形都囊括到。
要充分考虑训练样本同实际运行样本的偏差余量。比如垛车只有水平摆放一种姿态,我们在训练数据的时候也要考虑到给垛车增加小角度的倾斜,因为实际中不可能完美水平。再比如实际运行的都是机器摆放,目标两两比较贴近,在我们在录制训练集数据的时候,如果用的是人为摆放,则一定要保证目标两两比较贴近,而不是随意摆放导致目标两两之间间隙松散。
对于少部分的可能出现的目标破损褶皱等情况,虽然很少出现,但是如果项目实际有识别的需要,则要专门寻找较多的破损目标进行数据采集,虽然最后在训练样本中破损目标占的比例大于破损目标在实际样本中占有的比例,但是这也很有意义。
图像质量
人眼需清晰可见目标边缘,尤其是距离相机最远的那层目标,否则考虑更换相机具体图像录制可以参考 unstacking_runtime/unstacking_data 中的 rgb 图像。
拆垛结果
如下图所示,在3D视图中最终显示,机器人末端工具准确指向识别物体中心。 通过上述可视化结果,可以清晰地评估自动拆垛的的性能和准确性。