基于FANUC工业机器人的坐标系转换、多视角拼接与三维重建

0.简介

  • 总体任务:机械臂末端安装三维相机,绕着工件进行拍摄,并在计算机中将每次拍摄的点云合并在同一个坐标系下,从而获得更加完整全面的点云。
  • 机械臂:FANAUC
  • 相机:梅卡曼德
  • 技术方案:使用相机外参、机械臂位姿进行坐标系转换,将不同视角点云坐标系都转换到机器人基座(基于ICP或深度学习的点云匹配也可以实现类似效果,但实际应用鲁棒性不够,对视角间点云的重叠度要求较高或是难以获取相似度高的大量训练数据)

1.多位姿点云拍摄与读取

  • 机械臂移动拍摄工件不同视角,记录下每个视角的点云、机械臂位姿
  • 相关数据
  • 在这里插入图片描述
  • 点云读取及简单处理可以参考这里
  • 注意:梅卡曼德拍摄后点云的xyz坐标单位是m,而FANUC等转换矩阵的单位是mm,所以要注意单位统一
pcd = o3d.io.read_point_cloud('datasFANUC/' + 'point_cloud_00000' + '.ply')
pcd_np = np.array(pcd.points) * 1000
pcd.points = o3d.utility.Vector3dVector(pcd_np)
pcd.paint_uniform_color([0, 1.0, 0])
o3d.visualization.draw_geometries([pcd])

在这里插入图片描述

2.手眼标定的外参转换矩阵

  • 通过梅卡曼德官方软件与FANUC配合完成相机内外参的标定,外参标定结果如下(使用和FANUC相同的表示方式):
x,y,z,w,p,r = 70.5, 269.927, -33.947, -0.85, 0.78, 147.95

3.FANUC机械臂转换矩阵

  • FANUC工业机器人采用的是定角旋转方式,法兰(机械臂末端坐标系)到机械臂基座坐的相对位置由X- Y-Z,W-P-R表示,W表示绕X轴旋转的角度;P表示绕Y轴旋转的角度;R表示绕Z轴旋转的角度;它们的旋转方向由右手定则判断。(参考资料)
  • 定角旋转:定角旋转与欧拉角旋转类似,只不过定角旋转的转轴一直是最原始的坐标系转轴(该轴不随着旋转而变化)
  • 三次绕固定轴旋转(定角旋转)的最终姿态和以相反顺序三次绕运动坐标轴旋转(欧拉角旋转)的最终姿态相同(机器人学——姿态描述方法(欧拉角,固定角,D-H法,绕定轴旋转))
  • 机器人默认显示旋转顺序是WPR,即依次绕XYZ轴进行旋转,对应的旋转矩阵为RZRYRX
  • 绕定轴旋转的相关程序如下:
'''
旋转矩阵相关
'''
def Rx(theta):'''绕X轴旋转矩阵'''RX = np.array([[1, 0, 0],[0, math.cos(theta), -1*math.sin(theta)],[0, math.sin(theta), math.cos(theta)]])return RX
def Ry(theta):'''绕Y轴旋转矩阵'''RY = np.array([[math.cos(theta), 0, math.sin(theta)],[0, 1, 0],[-1*math.sin(theta), 0, math.cos(theta)]])return RY
def Rz(theta):'''绕Z轴旋转矩阵'''RZ = np.array([[math.cos(theta), -1*math.sin(theta), 0],[math.sin(theta), math.cos(theta), 0],[0, 0, 1]])return RZ
  • FANUC机械臂转换矩阵相关程序:
'''
机械臂转换矩阵相关
'''
def WPR2R(w,p,r):'''定角旋转WPR转为旋转矩阵(角度)'''R = Rz(r/180*math.pi)@Ry(p/180*math.pi)@Rx(w/180*math.pi)return R
def FANUC2trans(x,y,z,w,p,r):'''FANUC转换矩阵(mm,角度,wpr)'''t = np.zeros((4, 4))t[0:3, 0:3] = WPR2R(w,p,r)t[:,3] = x,y,z,1t[3,0:3] = 0,0,0return t

4.多视角拼接

  • 初始化一个点云pcd_all用来保存完成坐标变换后的点云
  • 为了与转换矩阵相匹配,为点云添加一列:
pcd_np = np.concatenate((pcd_np, np.expand_dims(np.ones(pcd_np.shape[0]), axis=1)), axis=1)
  • 点云左乘相机外参转换矩阵,再左乘机械臂转换矩阵,即得到点云在机械臂基座的坐标
  • 最终效果:
    在这里插入图片描述在这里插入图片描述

5.完整代码

import numpy as np
import math
import open3d as o3d
from Transformations import xyzrpw_to_H'''
旋转矩阵相关
'''
def Rx(theta):'''绕X轴旋转矩阵'''RX = np.array([[1, 0, 0],[0, math.cos(theta), -1*math.sin(theta)],[0, math.sin(theta), math.cos(theta)]])return RX
def Ry(theta):'''绕Y轴旋转矩阵'''RY = np.array([[math.cos(theta), 0, math.sin(theta)],[0, 1, 0],[-1*math.sin(theta), 0, math.cos(theta)]])return RY
def Rz(theta):'''绕Z轴旋转矩阵'''RZ = np.array([[math.cos(theta), -1*math.sin(theta), 0],[math.sin(theta), math.cos(theta), 0],[0, 0, 1]])return RZ'''
机械臂转换矩阵相关
'''
def WPR2R(w,p,r):'''定角旋转WPR转为旋转矩阵(角度)'''R = Rz(r/180*math.pi)@Ry(p/180*math.pi)@Rx(w/180*math.pi)return R
def FANUC2trans(x,y,z,w,p,r):'''FANUC转换矩阵(mm,角度,wpr)'''t = np.zeros((4, 4))t[0:3, 0:3] = WPR2R(w,p,r)t[:,3] = x,y,z,1t[3,0:3] = 0,0,0return t'''
相机外参
'''
def get_waican(x,y,z,rx,ry,rz):'''获取外参转换矩阵,mm,角度,欧拉角xyz'''R = Rx(rx/180*math.pi)@Ry(ry/180*math.pi)@Rz(rz/180*math.pi)t = np.zeros((4, 4))t[0:3, 0:3] = Rt[:, 3] = x, y, z, 1t[3, 0:3] = 0, 0, 0return tif __name__ == '__main__':root = 'datasFANUC'#外参转换矩阵# t_waican = get_waican(70.609, 264.977, -33.942, -0.80, 0.73, 147.95+10)t_waican = FANUC2trans(70.5, 269.927, -33.947, -0.85, 0.78, 147.95)print(t_waican)#t_waican = xyzrpw_to_H(np.array([70.5, 269.927, -33.947, -0.85, 0.78, 147.95]))print('外参转换矩阵:')print(t_waican)'''文本文件读取机械臂姿态索引,文件名(无后缀),X,Y,Z(mm),W,P,R(角度)'''flag = 1robot_data = root + '/datas.txt'f = open(robot_data)for line in f.readlines():line = line.strip('\n').split(',')print('索引:', line[0])file_data = line[1]print('处理文件:', file_data)# 转换矩阵line = line[2:]line = [float(i) for i in line]x,y,z,w,p,r = linet_robot = FANUC2trans(x,y,z,w,p,r)#print('机器人转换矩阵:', t_robot)#t_robot = xyzrpw_to_H(np.array([x,y,z,w,p,r]))t = t_robot@t_waicanprint(t)# 读取点云pcd = o3d.io.read_point_cloud(root + '/' + file_data + '.ply')pcd.paint_uniform_color([1.0, 0, 0])# o3d.visualization.draw_geometries([pcd])pcd_np = np.array(pcd.points) * 1000pcd_np = np.concatenate((pcd_np, np.expand_dims(np.ones(pcd_np.shape[0]), axis=1)), axis=1)#print(pcd_np.shape)pcd_np = pcd_np.Tpcd_np = t@pcd_nppcd_np = pcd_np.T# 使用第一个点云初始化最终点云if flag:pcd_all = pcd_npflag = 0else:pcd_all = np.concatenate((pcd_all, pcd_np))#print(pcd_all.shape)#print(pcd_all)#breakpcd_show = o3d.geometry.PointCloud()pcd_show.points = o3d.utility.Vector3dVector(pcd_all[:, :3])pcd_show.paint_uniform_color([1.0, 0, 0])# zero = o3d.geometry.PointCloud()# zero.points = o3d.utility.Vector3dVector(np.zeros((1, 3)))# zero.paint_uniform_color([0, 1.0, 0])#pcd = o3d.io.read_point_cloud('datasFANUC/' + 'point_cloud_00000' + '.ply')#pcd_np = np.array(pcd.points) * 1000#pcd.points = o3d.utility.Vector3dVector(pcd_np)#pcd.paint_uniform_color([0, 1.0, 0])o3d.visualization.draw_geometries([pcd_show])# zero,

6.调包获得转换矩阵

  • Transformations下载地址
from Transformations import xyzrpw_to_H
t_waican = xyzrpw_to_H(np.array([70.5, 269.927, -33.947, -0.85, 0.78, 147.95]))
  • 注意:包里使用的是欧拉角旋转,计算顺序和FANUC的定角旋转是相反的,所以使用的是xyzrpw_to_H函数而不是xyzwpr_to_H

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何将NetCore Web程序独立发布部署到Linux服务器

简介 在将 .NET Core 应用程序部署到 Linux 服务器上时,可以采用独立发布的方式,以便在目标服务器上运行应用程序而无需安装 .NET Core 运行时。本文介绍如果将NetCore Web程序独立发布部署到Linux服务器。 1、准备一台服务器 服务器配置:2核2G 系统环境:Alibaba Cloud…

小程序发成绩

在这个数字化快速发展的时代,让学生能够方便快捷地获取自己的成绩已经成为一项基本的需求。那么,如何实现这一目标呢?对于许多老师来说,可能首先想到的是使用各种代码或者Excel来发布成绩查询。今天,我们就来探讨一下这…

软件工程一些图的画法

软件工程一些图的画法 【一】数据库设计:ER图【1】ER图简介【2】实体之间的关系【3】ER图绘制常见问题【4】ER图转关系模式 【二】流程图【1】流程图的作用【2】流程图中使用的符号【3】三种循环的流程图画法【4】流程图的基本结构【5】流程图常用的形式 【一】数据…

ZZ308 物联网应用与服务赛题第F套

2023年全国职业院校技能大赛 中职组 物联网应用与服务 任 务 书 (F卷) 赛位号:______________ 竞赛须知 一、注意事项 1.检查硬件设备、电脑设备是否正常。检查竞赛所需的各项设备、软件和竞赛材料等; 2.竞赛任务中所使用…

尚硅谷大数据项目《在线教育之实时数仓》笔记007

视频地址:尚硅谷大数据项目《在线教育之实时数仓》_哔哩哔哩_bilibili 目录 第9章 数仓开发之DWD层 P053 P054 P055 P056 P057 P058 P059 P060 P061 P062 P063 P064 P065 第9章 数仓开发之DWD层 P053 9.6 用户域用户注册事务事实表 9.6.1 主要任务 读…

lv11 嵌入式开发 ARM指令集上 5

1 导学 1.1 指令集 指令 能够指示处理器执行某种运算的命令称为指令(如加、减、乘 ...) 指令在内存中以机器码(二进制)的方式存在 每一条指令都对应一条汇编 程序是指令的有序集合 指令集 处理器能识别的指令…

红黑树的模拟实现

一、介绍 1. 概念 红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍&#xff0c…

【Redis】list常用命令内部编码使用场景

文章目录 前置知识列表类型的特点 命令LPUSHLPUSHXRPUSHRPUSHXLRANGELPOPRPOPLINDEXLREMLINSERTLTRIMLSETLLEN 阻塞版本命令BLPOPBRPOP 命令总结内部编码测试内部编码 使用场景消息队列分频道的消息队列 模拟栈和队列 前置知识 列表类型是⽤来存储多个有序的字符串&#xff0c…

吴恩达《机器学习》7-1->7-4:过拟合问题、代价函数、线性回归的正则化、正则化的逻辑回归模型

一、过拟合的本质 过拟合是指模型在训练集上表现良好,但在新数据上的泛化能力较差。考虑到多项式回归的例子,我们可以通过几个模型的比较来理解过拟合的本质。 线性模型(欠拟合): 第一个模型是一个线性模型&#xff0…

量子计算和量子通信技术:引领潜力无限的未来

近年来,随着量子计算和量子通信技术的迅速发展,它们在各个领域的广泛应用前景引起了人们的极大兴趣。本文将深入探讨量子计算和量子通信技术的普遍应用,以及它们预示的未来,同时提出业内人士需要注意的事项。 介绍:量子…

OushuDB 专家认证第四期报名开始啦!

OushuDB 专家认证培训第四期今日正式启动!本次培训为偶数科技面向生态合作伙伴与客户公开举办的线上培训,旨在共同发展 OushuDB 生态。 报名时间:2023年11月9日9:00—11月30日12:00 报名方式:偶数科技官网(点击下方阅…

C/C++数据结构之链表题目答案与解析

个人主页:点我进入主页 专栏分类:C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 C语言刷题 数据结构初阶 欢迎大家点赞,评论,收藏。 一起努力,一起奔赴大厂。 目录 1.前言 2.题目…

灵活运用Vue指令:探究v-if和v-for的使用技巧和注意事项

🎬 江城开朗的豌豆:个人主页 🔥 个人专栏 :《 VUE 》 《 javaScript 》 📝 个人网站 :《 江城开朗的豌豆🫛 》 ⛺️ 生活的理想,就是为了理想的生活 ! 目录 ⭐ 专栏简介 📘 文章引言 一、作…

2023年Q3乳品行业数据分析(乳品市场未来发展趋势)

随着人们生活水平的不断提高以及对健康生活的追求不断增强,牛奶作为优质蛋白和钙的补充品,市场需求逐年增加。 今年Q3,牛奶乳品市场仍呈增长趋势。根据鲸参谋电商数据分析平台的相关数据显示,2023年7月-9月,牛奶乳品市…

计算机毕设 大数据工作岗位数据分析与可视化 - python flask

文章目录 0 前言1 课题背景2 实现效果3 项目实现3.1 概括 3.2 Flask实现3.3 HTML页面交互及Jinja2 4 **完整代码**5 最后 0 前言 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要…

【Excel】补全单元格值变成固定长度

我们知道股票代码都为6位数字,但深圳中小板代码前面以0开头,数字格式时前面的0会自动省略,现在需要在Excel表格补全它。如下图: 这时我们需要用到特殊的函数:TEXT或者RIGHT TEXT函数是Excel中一个非常有用的函数。TEX…

c: struct sort descending and ascending in windows and Ubuntu

/*** file StudentStructSort.h* author geovindu,Geovin Du,涂聚文 (geovindu163.com)* ide: vscode c11,c17 Ubuntu 22.4* brief 结构体排序示例* date 2023-11-05* version 0.1* copyright geovindu 站在巨人的肩膀上 Standing on the Shoulders of Giants**/#ifnd…

海康工业相机如何提高相机帧率

影响帧率的因素 相机参数 帧率限制使能 像素格式 曝光时间 数据包大小(网口) 相机默认参数 ADC位深 系统环境设置

opencv创建图片,绘制图片,画框,划线,改变像素点颜色

文章目录 创建空白图片创建一张渐变色彩色绘制多边形绘制多线改变像素点颜色 创建空白图片 bool tool_class::creatEmpty(int width, int height, std::string image_p) {// 创建一个空白图像cv::Mat blankImage(height, width, CV_8UC3, cv::Scalar(255, 255, 255));// 保存图…

CSS3 分页、框大小、弹性盒子

一、CSS3分页&#xff1a; 网站有很多个页面&#xff0c;需要使用分页来为每个页面做导航。示例&#xff1a; <style> ul.pagination { display: inline-block; padding: 0; margin: 0; } ul.pagination li {display: inline;} ul.pagination li a { color: black; f…