MATLAB - 机械臂手眼标定(眼在手外) - 估算固定相机相对于机器人基座的姿态

news2024/10/4 10:36:11

系列文章目录


前言

        在拾取和放置任务中,例如垃圾桶拾取,通常会在环境中的固定位置安装摄像头,以便机器人操纵器检测工作区中的物体。基本感知管道使用该摄像头来估计目标物体相对于摄像头坐标系的姿态。然后将该姿态转换到机器人的基准坐标系,使机器人能够成功地用末端执行器拾取物体。要将物体的姿态转换到机器人基座坐标系,首先必须确定摄像机相对于机器人基座的姿态。本图显示了这种拾放构型以及所需的同质变换矩阵 TCameraToBase,它可将摄像机坐标系中的姿势变换到机器人底座坐标系中。

        由于这些因素的影响,确定相机坐标系的准确姿态成为难题:

        照相机制造商通常不会在设备上直接标系照相机坐标系,也不会提供相关规格或物理指标。此外,与取放操作相关的坐标系并不是相机坐标系本身,而是位于图像传感器或平面中心的坐标系。

        假定相机坐标系以镜头为中心,并依靠人工用尺子测量的估算方法很容易出现误差。

        鉴于上述挑战,本示例展示了通过使用手眼校准工作流程确定变换矩阵的过程,即安装在横梁上的摄像头相对于机器人底座的姿态。

        本示例与 “为带摄像头的机械臂执行手眼校准 ”示例相关,后者展示了带直接安装在机械臂上的摄像头(即手眼构型)的机械臂的校准过程。本示例展示了如何解决眼到手构型的摄像头校准问题。

 


一、估算相机固有参数

        了解摄像机的固有参数(如焦距和光学中心)对于准确解读图像至关重要。本示例在 estimateCameraPoseWrtRobotBase.mat 文件中提供了此设置的相机固有参数。但是,对于不同的相机和设置,您必须在收集手眼校准数据之前确定相机本征。您可以使用 Camera Calibrator(计算机视觉工具箱)应用程序来估算固定摄像头的这些参数。有关如何使用此应用程序的更多详情,请参阅使用单摄像头校准器应用程序(计算机视觉工具箱)。

二、收集手眼校准数据

        要收集手眼构型的校准数据,必须遵循以下步骤:

  1. 将校准板安装在机器人的末端执行器上。
  2. 将机器人移动到一个构型,在该构型中,安装的摄像头可以完全看到校准板的图案。
  3. 从摄像头捕捉校准板的图像,并记录机器人相应的关节构型。
  4. 重复步骤 1-3,收集至少 15 张此类图像和相应的机器人关节构型。

        在此示例设置中,校准数据已收集到 calibrationData.zip 文件中。该文件包含校准图像和相应的机器人关节构型。

        解压缩校准数据并显示所有校准图像。

unzip("calibrationData.zip")
calibimgds = imageDatastore('calibrationData/*.jpg');
figure(Name="Calibration Images")
montage(calibimgds);

        从 jointAngles.mat 文件中加载并显示相应的关节构型。每个关节构型的行号与相应校准图像的名称一致。例如,关节角度的第 10 行对应校准图像 10.jpg。关节角度以度为单位。

load("calibrationData/jointAngles")
disp(jointAngles)
  346.8241  352.5997  191.5695  212.1722  355.5775   38.5151  184.8700
  346.8241  352.5996  191.5695  212.1724  355.5776   20.6987  184.8699
  346.8241  352.5996  191.5695  212.1723  355.5775   55.1762  184.8699
  346.8241  352.5996  191.5695  212.1723  355.5775   55.1761  159.7137
  344.9588  352.5997  191.5695  212.1723  355.5775   47.9125  202.4223
  344.9591  350.7478  191.5696  212.1723  334.9004   43.3278  191.6003
  344.9592  350.7479  191.5696  212.1722   22.5804   43.3278  191.6003
  344.9592  350.7477  191.5696  212.1723   14.6105   17.6080  191.6004
  344.9592  350.7478  191.5696  212.1723   65.1178   27.7940  121.8693
    9.4972  350.7477  191.5696  212.1723   65.1178   27.7940  121.8693
    2.4139  356.8379  179.3088  225.4389   79.5231   35.3008  125.8531
   15.2262  356.8380  179.3092  225.4386   48.9265   55.5291  125.8531
   15.2261    4.5792  179.3092  225.4386   48.9264   55.5291  175.2737
   31.0168    4.5793  179.3092  225.4386   48.9263   55.5291  174.4471
   34.9532  358.5155  179.3093  225.4386   48.9264   55.5294  145.9294

        要以某种关节构型显示机器人,请加载相应的机器人模型,并以所需的关节构型显示机器人模型。

        加载 KINOVA® Gen3 机器人的刚体树形机器人模型,并将其可视化为第 7 个关节构型。

figure
kinova = loadrobot('kinovaGen3',DataFormat="row");
show(kinova,deg2rad(jointAngles(7,:)));
title("Joint Angles in 7th Configuration")
axis equal

三、计算摄像机外特性和末端执行器姿势

        手眼校准问题需要几组姿势。每组包含两个姿势:

  1. 相机外参照姿态,即棋盘原点相对于相机的姿态。
  2. 末端执行器相对于机器人基本坐标系的姿态。

        您可以使用校准图像和相应的关节构型推导出这两种姿势。

3.1 估算摄像机外特性

        首先计算摄像机外特性,即同质变换矩阵 TWorldToCamera。

        创建用于存储每幅校准图像的相机外特性的相机外特性向量。

numimgs = length(calibimgds.Files);
camextrinsics = repmat(rigidtform3d,1,numimgs);

        在估算摄像机外特性之前,必须确定摄像机的内在参数和每个校准图像中棋盘格的大小。在本示例中,本征参数和棋盘格大小均已计算完毕。有关计算摄像机固有参数的更多信息,请参阅 estimateCameraParameters(计算机视觉工具箱)功能页面上的单摄像机校准示例。

        加载相机固有参数和棋盘格大小。

load("estimateCameraPoseWrtRobotBase","intrinsics");
load("estimateCameraPoseWrtRobotBase","checkerboardSquareSizeInMeters");

        对于数据集中的每幅图像,都要计算相机的外特性。这一估算需要校准图像、校正畸变后的图像以及世界坐标系中棋盘格点的位置。然后使用这些数据来估计摄像机的姿态。

for r = 1:numimgs

    % Load and undistort each calibration image based on precomputed intrinsics.
    fname = fullfile('calibrationData',string(r)+".jpg");
    checkerboardImage = imread(fname);
    checkerboardImageUndistorted = undistortImage(checkerboardImage,intrinsics);

    % Detect the checkerboard corners, discarding partial detections.
    [imgpts,boardsz] = detectCheckerboardPoints(checkerboardImageUndistorted,PartialDetections=false);

    % Generate world coordinates of checkerboard points based on board size and square size.
    worldpts = patternWorldPoints("checkerboard",boardsz,checkerboardSquareSizeInMeters);

    % Estimate the camera extrinsics (pose) from image points and world points.
    camextrinsics(r) = estimateExtrinsics(imgpts,worldpts,intrinsics);
end

3.2 计算末端执行器姿态

        接下来,使用前向运动学计算机器人末端执行器相对于机器人底座坐标系的姿态。表示该姿态的均质变换矩阵为 TEndEffectorToBase。

        在 TEndEffectorToBase 向量中记录末端执行器相对于机器人基本坐标系的位置。

TEndEffectorToBase = repmat(rigidtform3d,1,numimgs);

        对于每个关节构型,使用 getTransform 函数应用前向运动学。这会计算机器人 “EndEffector_Link ”体相对于机器人基本坐标系的姿态。

for r = 1:numimgs
    jointconfig = deg2rad(jointAngles(r,:));
    TEndEffectorToBase(r) = getTransform(kinova,jointconfig,"EndEffector_Link");
end

四、解决校准问题

        利用校准数据中的摄像机外特性和末端执行器姿态,估算摄像机相对于机器人基座的姿态。

TCameraToBase = helperEstimateHandEyeTransform(camextrinsics,TEndEffectorToBase,"eye-to-hand");

        接下来,计算校准棋盘点相对于机器人基本坐标系的位置。

TWorldToBase = rigidtform3d(TCameraToBase.A*camextrinsics(end).A);
worldpts3d = transformPointsForward(TWorldToBase,[worldpts,zeros(size(worldpts,1),1)]);

        用棋盘格点显示机器人,并放大与校准图像进行比较。

tiledlayout(1,2)
nexttile
show(kinova,deg2rad(jointAngles(r,:)));
hold on
scatter3(worldpts3d(:,1),worldpts3d(:,2),worldpts3d(:,3),'*')
view(95,45)
axis([-0.05 0.95 -0.65 0.35 0.25 0.75])
zoom(2.5)
hold off
nexttile
imshow("calibrationData/"+string(r)+".jpg")
sgtitle("Computed Checkerboard Points vs Calibration Image")

五、可视化摄像机坐标系与机器人基本坐标系的关系

        绘制摄像机、机器人和棋盘格点在机器人基准坐标系中的解析图。

figure
show(kinova,deg2rad(jointAngles(r,:)));
hold on
scatter3(worldpts3d(:,1),worldpts3d(:,2),worldpts3d(:,3),'*')
plotCamera(AbsolutePose=TCameraToBase,Size=0.05,Label="Fixed Camera");
title("Estimated Camera Frame With Respect to Robot Base")
view([-40,10])
zoom(1.5)
axis equal
hold off

        与实际设置进行比较后发现,相对于机器人基座,摄像机的估计姿态是正确的。

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

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

相关文章

360浏览器时不时打不开csdn

从百度或者csdn的搜索中打开,会发现打不开网页,以前也出现过,只是以为这篇文章被删了,昨天接连多个文章打不开,怀疑的浏览器的问题,复制网址到edge浏览器就打开了 刚刚又出现了,怀疑360会拦截某…

探索TOGAF理论的实践应用:企业数字化转型的深度指南

数字化转型的迫切性与路径选择 随着全球化进程和技术革命的加速,企业正面临前所未有的挑战和机遇。数字化转型已成为企业保持竞争力、创新业务模式、优化客户体验的核心手段。然而,企业在实施数字化转型时,往往面临路径不清、技术与业务脱节…

高性能防静电主轴4033 AC-ESD 在线路板切割中的非凡表现

随着电子产品的日益小型化/集成化,线路板的制造也面临着更高的挑战。线路板分板作为电子制造流程中的关键环节,其效率和精度直接影响到最终产品的质量和市场竞争力。因此专用的高性能防静电主轴SycoTec 4033 AC-ESD凭借其卓越的性能,成为众多…

多系统萎缩患者必知的营养补充指南

亲爱的朋友们,今天我们要聊的是一个较为少见但影响深远的疾病——多系统萎缩(Multiple System Atrophy, MSA)。这是一种成年期发病的神经系统退行性疾病,给患者的日常生活带来了诸多不便。但别担心,通过合理的营养补充…

JAVA开源项目 旅游管理系统 计算机毕业设计

本文项目编号 T 063 ,文末自助获取源码 \color{red}{T063,文末自助获取源码} T063,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析5.4 用例设计 六、核…

QGIS中怎么裁剪与掩膜提取

最近,我接到了一个关于QGIS中矢量与栅格与栅格数据怎么裁剪与掩膜提取到自己想要区域的咨询。 其实这个操作,与arcgis中的操作其实是类似的 下面是我对这个问题的解决思路: 首先得把栅格与矢量数据加载进去,如下图:…

基于SSM的农家乐预约系统

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…

【JavaEE】——CAS指令和ABA问题

阿华代码,不是逆风,就是我疯 你们的点赞收藏是我前进最大的动力!! 希望本文内容能够帮助到你!! 目录 一:CAS指令 1:概念 2:伪代码例子说明 3:优点 二&am…

《向量数据库指南》——Mlivus Cloud:优惠大放送,向量数据库新体验

哈哈,各位向量数据库领域的探索者和实践者们,大家好!我是大禹智库的向量数据库高级研究员王帅旭,也是《向量数据库指南》的作者,今天咱们来聊聊Mlivus Cloud这个让人眼前一亮的向量数据库服务。特别是它那诱人的优惠放送,简直是给咱们这些热衷于技术创新的朋友们送上了一…

微信小程序使用picker,数组怎么设置默认值

默认先显示请选择XXX。然后点击弹出选择列表。如果默认value是0的话&#xff0c;他就直接默认显示数组的第一个了。<picker mode"selector" :value"planIndex" :range"planStatus" range-key"label" change"bindPlanChange&qu…

一些 Go Web 开发笔记

原文&#xff1a;Julia Evans - 2024.09.27 在过去的几周里&#xff0c;我花了很多时间在用 Go 开发一个网站&#xff0c;虽然不知道它最终会不会发布&#xff0c;但在这个过程中我学到了一些东西&#xff0c;想记录下来。以下是我的一些收获&#xff1a; Go 1.22 现在有了更…

【ubuntu】ubuntu20.04 install vscode

1.download Visual Studio Code - Code Editing. Redefined download .deb. 2.install or intsall by ternimal: sudo dpkg -i code_1.93.1-1726079302_amd64.deb 3.open vscode 4. install some extensions c , python or GitLens.

SpringMVC2~~~

数据格式化 提交数据(比如表单)&#xff0c;对提交的数据进行转换和处理 基本数据类型可以和字符串自动转换 <a href"<%request.getContextPath()%>/addMonsterUI">添加妖怪</a> Controller Scope(value "prototype") public class …

spring揭秘25-springmvc03-其他组件(文件上传+拦截器+处理器适配器+异常统一处理)

文章目录 【README】【1】文件上传与MultipartResolver【1.1】使用MultipartResolver进行文件上传【1.2】springmvc处理multipart多部件请求流程【1.3】使用springmvc上传文件代码实现&#xff08;springmvc6.10版本&#xff09;&#xff1a; 【2】Handler与HandlerAdaptor&…

遮罩解决图片悬浮操作看不到的情况

未悬浮效果 悬浮效果 如果仅仅是添加绝对定位&#xff0c;那么遇到白色图片&#xff0c;就会看不到白色字体。通过遮罩&#xff08;绝对定位透明度&#xff09;就可以解决这个问题。 <script setup> </script><template><div class"box"><…

protobuf 讲解

一、序列化概念回顾 二、什么是PB 将结构化数据进行序列化的一种方式 三、PB的特点 语言无关、平台无关&#xff1a;即PB支持Java&#xff0c;C、Python等多种语言。支持多个平台 高效&#xff1a;即比XML更小&#xff0c;更快&#xff0c;更为简单。 扩展性、兼容性好&am…

MATLAB使用眼图分析QPSK通信系统接收端匹配滤波后的信号

文章目录 前言一、MATLAB仿真代码二、仿真结果 前言 本文完成以下内容&#xff1a; &#xff08;1&#xff09;建立一个QPSK传输系统&#xff0c;并引入EsNo20dB&#xff08;SNR0dB&#xff09;的噪声&#xff0c;接收端对带噪信号进行匹配滤波。 &#xff08;2&#xff09;分…

Python并发编程挑战与解决方案

Python并发编程挑战与解决方案 并发编程是现代软件开发中的一项核心能力&#xff0c;它允许多个任务同时运行&#xff0c;提高程序的性能和响应速度。Python因其易用性和灵活性而广受欢迎&#xff0c;但其全局解释器锁&#xff08;GIL&#xff09;以及其他特性给并发编程带来了…

CSS实现服务卡片

CSS实现服务卡片 效果展示 CSS 知识点 回顾整体CSS知识点灵活运用CSS知识点 页面整体布局 <div class"container"><div class"card"><div class"box"><div class"icon"><ion-icon name"color-pal…

python集合set

1、集合是无序的&#xff0c;所以集合不支持下标访问索引 2、集合的常见操作 3、集合内不允许重复元素 4、注意