[Halcon3D] 3D手眼标定理论与示例解析

news2024/11/18 15:44:02
  • 📢博客主页:https://loewen.blog.csdn.net
  • 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
  • 📢本文由 丶布布原创,首发于 CSDN,转载注明出处🙉
  • 📢现在的付出,都会是一种沉淀,只为让你成为更好的人✨

文章预览:

      • 一. 3D手眼标定理论基础
      • 二. 3D手眼标定流程(eye-to-hand)
        • 1、创建标准件的点云模型
        • 2、创建手眼标定模型、多角度匹配标准件的实例点云数据
        • 3、开始手眼标定
        • 4、获得各坐标系之间的姿态关系
        • 5、物体在机器人基础坐标系下的姿态求解


一. 3D手眼标定理论基础

因为3D相机知道的是点云坐标,机械手是空间坐标系,分为基础(底座)坐标系和工具(末端)坐标系,手眼标定目的就是将相机的图像坐标系的坐标和机械手的基础坐标系的坐标进行相互转化即求空间变换矩阵)。

在实际控制中,3D相机对场景中的物体扫描,并进行「三维匹配」,获取到物体的「姿态Pose」后,以3D点云的形式交给机械臂,通过标定好的坐标转换矩阵将相机获取到的3D点云坐标变换到机械手的基础坐标系中,然后根据机械手坐标系计算出各个电机该如何运动,从而控制机械手到达指定位置,可以用于物体抓取、无序分拣、装配、打磨等工作。

注:

1、如果是直接购买市面上的3D相机使用,在其生成对象的点云数据时,其内部已经完成了图像坐标系到世界坐标系的标定转换,所以需要我们做的就变成了求对象所在的世界坐标系(传感器坐标系)和机械手所在的基础坐标系之间的转换矩阵本文默认相机内部已经完成图像坐标系到世界坐标系的标定,即相机坐标系(传感器坐标系)等价于世界坐标系
2、若机械手中心不在法兰中心,需要做TCP(Tool Center Point)标定,得到机械手中心和法兰中心之间的相对位置关系,有四点法、六点法等。

场景示意图:

在这里插入图片描述

2D标定一样,根据相机的装载位置分为两种情况:

  • eye-to-hand(眼在手外):相机固定在一个地方,机械手的运动不会带着相机一起移动;
    在这里插入图片描述

  • eye-in-hand(眼在手上):相机安装在机械手上,随着机械手一起移动;
    在这里插入图片描述

本质都是为了在机器人基础坐标系下,获取物体的姿态Pose情况(注意区分:2D手眼标定得到的是XY坐标位置和角度),便于机械手完成抓取等任务。本文主要介绍的是eye-to-hand


二. 3D手眼标定流程(eye-to-hand)

参考示例:`分类 — 方法 — 三维匹配(基于表面)` —— `calibrate hand eye stationary 3d sensor.hdev`

1、创建标准件的点云模型

* 1.读入点云以及创建模型
read_object_model_3d ('handeye/robot_gripper_3d_model.om3', 1, [], [], OM3DModel, Status)
create_surface_model (OM3DModel, 0.03, [], [], SurfaceModelID) //0.03代表采样距离在点云最小外界球体直径所占的比例
* 简化点云(针对散点),提高匹配速度
sample_object_model_3d (OM3DModel, 'fast', 0.0009, [], [], SampledObjectModel3D) //0.0009代表采样距离

PS:

  • simplify_object model_3d:也是简化点云,和上面sample_object_model_3d算子区别是它针对三角化之后的点云进行简化。
  • create_surface_model:创建点云模板,算子各个参数的含义:传送门。

读取的点云模型如图所示:

在这里插入图片描述


2、创建手眼标定模型、多角度匹配标准件的实例点云数据

流程梳理

  1. 获取tool_in_base_pose,即工具坐标系相对于机器人基础坐标系下的姿态Pose —可从机器人示教器上读取到;
    PS:可通过write_pose将机器人工具坐标系的默认姿态通过机器人示教器获取到,然后保存至本地,最后通过read_pose读取出来即可。
  2. 匹配标准件的实例点云数据,获取标准件的姿态Pose
  3. 将步骤1和步骤2获取到的姿态Pose,设置进标定模型中;

代码展示

* 2.创建手眼标定模型
create_calib_data ('hand_eye_stationary_cam', 0, 0, HECCalibDataID)
for I := 1 to 15 by 1
    * 读取工具坐标系相对于机器人基础坐标系下的姿态
    read_pose ('tool_in_base_pose_' + I$'02d' + '.dat', ToolInBasePose)
    * 重新读取物体三维点云模型呢,通过对物体进行三维匹配获得其相对于世界坐标系(或传感器坐标系)下的姿态
    filename := 'handeye/robot_gripper_3d_scene_' + I$'02d'
    read_object_model_3d (filename, 1, [], [], OM3DScene, Status1)
    * 0.05也是一个比例,因为前面我们创建模板的时候对采样点进行了缩减,所以这里在重新读取一个点云模型时,也适当忽略一些点进行匹配
    * 输出获取匹配对象的姿态ObjInCamPose
    find_surface_model (SurfaceModelID, OM3DScene, 0.05, 1, 0, 'false', [], [], ObjInCamPose, Score, SurfaceMatchingResultID)
    * 判断模型是否被找到
    if (|Score|)
        * 将上面的工具坐标系相对于基础坐标系的姿态以及匹配对象的姿态设置到标定模型中
        set_calib_data (HECCalibDataID, 'tool', I, 'tool_in_base_pose', ToolInBasePose)
        set_calib_data_observ_pose (HECCalibDataID, 0, 0, I, ObjInCamPose)
    endif
    clear_object_model_3d (OM3DScene)
endfor

3、开始手眼标定

 * 3.开始手眼标定
calibrate_hand_eye (HECCalibDataID, HECPoseError)

标定完之后:

  • 可以获得世界坐标系(传感器坐标系)相对于机器人基础坐标系下的姿态;
  • 又已知工具坐标系相对于机器人基础坐标系下的姿态;

所以可知工具坐标系相对于世界坐标系(传感器坐标系) 下的姿态,从而完成机器手的抓取


4、获得各坐标系之间的姿态关系

* ⑴机器人基础坐标系相对于相机(传感器)坐标系的姿态 
get_calib_data (HECCalibDataID, 'camera', 0, 'base_in_cam_pose', BaseInSensorPose)
* ⑵物体所在的世界坐标系相对于工具坐标系的姿态
get_calib_data (HECCalibDataID, 'calib_obj', 0, 'obj_in_tool_pose', ObjInToolPose)

5、物体在机器人基础坐标系下的姿态求解

步骤:

  1. 对物体进行三维点云匹配获取物体相对于传感器的姿态ObjInCamPose
  2. 对标定得到的基础坐标系相对于传感器坐标系的姿态BaseInSensorPose进行翻转,获取传感器坐标系相对于基础坐标系的姿态SensorInBasePose
  3. SensorInBasePose联合的三维匹配得到的物体相对于传感器的姿态ObjInCamPose,最终求出物体在机器人基础坐标系下的姿态ObjInBasePose
  4. 最终将物体相对于机器人基础坐标系下的姿态信息通过通讯传给机器人,从而命令其完成相关指令;

代码:

* 1.相机3D扫描,获取物体点云数据
read_object_model_3d (filename, 1, [], [], OM3DScene, Status1)
*   对物体进行3D点云匹配,获取物体在传感器坐标系下的姿态ObjInCamPose
find_surface_model (SurfaceModelID, OM3DScene, 0.05, 1, 0, 'false', [], [], ObjInCamPose, Score, SurfaceMatchingResultID)
* 2.物体在机器人基础坐标系下的姿态求解
*   翻转标定得到的基础坐标系相对于传感器坐标系下的姿态BaseInSensorPose,获得SensorInBasePose
pose_invert (BaseInSensorPose,SensorInBasePose)  
*   SensorInBasePose联合ObjInCamPose,求解物体在机器人基础坐标系下的姿态
pose_compose (SensorInBasePose, ObjInCamPose, ObjInBasePose)

下雨天,最惬意的事莫过于躺在床上静静听雨,雨中入眠,连梦里也长出青苔。

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

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

相关文章

NSSCTF刷web(2)

[NISACTF 2022]bingdundun~ bingdundun处感觉像文件包含,改upload为index 发现确实,猜测会补一个后缀.php 那常规文件包含都不行了,这里还有一个文件上传的功能,考虑phar协议 <?php$phar new Phar("test.phar"); $phar->startBuffering(); $phar->setStu…

第十一章:GCN——图卷积神经网络:全面回顾

0.摘要 图在许多应用领域中自然出现&#xff0c;包括社交分析、生物信息学和计算机视觉。图的独特能力使其能够捕捉数据之间的结构关系&#xff0c;从而可以比单独分析数据获得更多的见解。然而&#xff0c;在图上解决学习问题往往非常具有挑战性&#xff0c;因为 (1)许多类型的…

1、Java入门教程【基础】

1、环境搭建 首先java的产品叫JDK&#xff0c;必须安装JDK才能使用Java。 Java的发展史&#xff1a; 其中&#xff0c;LTS是比较稳定的版本&#xff0c;推荐比较新的LTS17版本。 JDK下载&#xff1a;JDK Development Kit 17.0.7 downloads 下载完成后&#xff0c;我们双击安…

第十一章:MULTI-SCALE CONTEXT AGGREGATION BY DILATED CONVOLUTIONS——通过膨胀卷积的多尺度上下文聚合

0.摘要 目前用于语义分割的先进模型是基于最初设计用于图像分类的卷积网络的改进。然而&#xff0c;像语义分割这样的密集预测问题在结构上与图像分类不同。在这项工作中&#xff0c;我们开发了一个专门为密集预测设计的新的卷积网络模块。所提出的模块使用膨胀卷积来系统地聚合…

【深度学习 | 计算机视觉】Focal Loss原理及其实践(含源代码)

参考文献&#xff1a; https://www.jianshu.com/p/437ce8ed0413文章目录 一、导读二、Focal Loss 原理三、实验对比3.1 使用交叉熵损失函数3.2 使用Focal Loss 损失函数3.3 总结 一、导读 Focal Loss 是一个在交叉熵&#xff08;CE&#xff09;基础上改进的损失函数&#xff…

Java正则表达式MatchResult的接口、Pattern类、Matcher类

Java正则表达式MatchResult的接口 java.util.regex.MatchResult接口表示匹配操作的结果。 此接口包含用于确定与正则表达式匹配的结果的查询方法。可以看到匹配边界&#xff0c;组和组边界&#xff0c;但不能通过MatchResult进行修改。 接口声明 以下是java.util.regex.Matc…

spring复习:(34)配置文件的方式创建ProxyFactoryBean

一、配置文件 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xmlns:c"http://www.springframework.org/s…

vscode 无法格式化python代码、无法格式化C++代码(vscode格式化失效)另一种解决办法:用外部工具yapf格式化(yapf工具)

文章目录 我真的解决方法&#xff1a;用yapfyapf工具使用方法示例格式化单个文件&#xff08;格式化前先用-d参数预先查看格式化更改内容&#xff0c;以决定是否要更改&#xff09;格式化某个目录递归格式化某个目录 我真的 神马情况&#xff0c;我的vscode死活不能格式化pyth…

路径规划算法:基于减法平均优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于减法平均优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于减法平均优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化…

用Python自动化处理Excel表格详解

Excel表格基础知识 Excel表格可以帮助用户创建、编辑、格式化和计算数据&#xff0c;并生成各种图表和报表。Excel表格通常用于商业、金融、科学、教育等领域。 Excel表格的常用操作 Excel表格的常用操作包括插入、删除、移动、复制、粘贴、排序和筛选、图表等。这些操作可以…

node操作MySQL数据库

本文节选自我的博客&#xff1a;node 操作 MySQL 数据库 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是MilesChen&#xff0c;偏前端的全栈开发者。&#x1f4dd; CSDN主页&#xff1a;爱吃糖的猫&#x1f525;&#x1f4e3; 我的博客&#xff1a;爱吃糖的猫&…

集群基础4——haproxy负载均衡mariadb

文章目录 一、环境说明二、安装配置mariadb三、安装配置haproxy四、验证 一、环境说明 使用haproxy对mysql多机单节点进行负载均衡。 主机IP角色安装服务192.168.161.131后端服务器1mariadb&#xff0c;3306端口192.168.161.132后端服务器2mariadb&#xff0c;3306端口192.168.…

【2023 年第二届钉钉杯大学生大数据挑战赛初赛】 初赛 A:智能手机用户监测数据分析 问题一Python代码分析

2023 年第二届钉钉杯大学生大数据挑战赛初赛 初赛 A&#xff1a;智能手机用户监测数据分析 问题一Python代码分析 1 题目 2023 年第二届钉钉杯大学生大数据挑战赛初赛题目 初赛 A&#xff1a;智能手机用户监测数据分析 一、问题背景 近年来&#xff0c;随着智能手机的产生&a…

STM32F10x外部中断/事件控制器(EXTI)应用

往期文章&#xff1a; STM32F1x固件库函数学习笔记&#xff08;一&#xff09; 文章目录 一、EXTI简介二、EXTI初始化结构体详解三、外部中断&#xff08;EXTI&#xff09;编程要点及例程参考文献 一、EXTI简介 外部中断/事件控制器&#xff0c;简称&#xff1a;EXTI&#x…

Jenkins打包、发布、部署

目录 前言 一、安装jdk 二、安装maven 三、安装git 四、安装jenkins 五、访问jenkins 六、创建用户 七、配置jenkins 八、执行 总结 前言 服务器&#xff1a;CentOS 7.9 64位 jdk&#xff1a;1.8 maven&#xff1a;3.9.1 git&#xff1a;git version 1.8.3.1 jenkins&a…

计算机中的数制与编码(二进制转换)

一、进制表示 1. 十进制表示 使用&#xff08;0&#xff0c;1&#xff0c;2&#xff0c;…&#xff0c;9&#xff09;十位数字表示&#xff0c;十进制运算时逢十进一。 2. 二进制表示 使用(0&#xff0c;1)两个数字表示&#xff0c;二进制运算时逢二进一。 3. 十六进制表示…

AIGC文生图:stable-diffusion-webui部署及使用

1 stable-diffusion-webui介绍 Stable Diffusion Web UI 是一个基于 Stable Diffusion 的基础应用&#xff0c;利用 gradio 模块搭建出交互程序&#xff0c;可以在低代码 GUI 中立即访问 Stable Diffusion Stable Diffusion 是一个画像生成 AI&#xff0c;能够模拟和重建几乎…

宝塔面板清理

查看磁盘使用情况时发现/dev/sda1满了&#xff0c;重启服务器也不行&#xff0c;瞎折腾了半天&#xff0c;才发现是宝塔的回收站占了较大的磁盘&#xff0c;于是按以下操作清理了下&#xff0c;就可以了 1、清除系统监控记录。打开宝塔面板后台&#xff0c;找到监控&#xff0c…

模拟面试2

1.说一说ArrayList的实现原理&#xff1f; ArrayList底层基于数组实现&#xff0c;内部封装了Object类型的数组&#xff0c;实现了list接口&#xff0c;通过默认构造器创建容器时&#xff0c;该数组被初始化为一个空数组&#xff0c;首次添加数据时再将其初始化为容量为10的数组…

变量生命符thread_local

thread_local是c11为线程安全引进的变量声明符。 thread_local是一个存储器指定符&#xff1a; 所谓存储器指定符&#xff0c;其作用类似命名空间&#xff0c;指定了变量名的存储期以及链接方式。同类型的关键字还有&#xff1a; static&#xff1a;静态或者线程存储期&…