【仿真】UR机器人相机标定、立体标定、手眼标定、视觉追踪(双目)

实现在CoppeliaSim环境中进行手眼标定和目标追踪的一个例子。它主要涉及到机器人、机器视觉和控制算法的编程,使用了Python语言。接下来对该代码的主要类和方法进行解析:
1. 导入相关库
用于与CoppeliaSim模拟器通过ZeroMQ接口通信。
包含
Rotation类,用于执行各种旋转和方向变换操作。OpenCV库,用于执行各种图像处理和计算机视觉任务。
用于执行各种数学和矩阵运算。
用于进行图像和数据的可视化。
用于创建和操作迭代对象的库。
用于实现与时间相关的功能。
2. 定义全局变量
分别用于定义场景路径、等待间隔、超时时间、接受的旋转误差、接受的平移误差、接受的停止速度阈值。
3. 定义主要的方法和步骤
连接到CoppeliaSim模拟器。
获取模拟器中对象的句柄。
从摄像头获取图像,并将其转换为OpenCV的BGR格式。
设置从一个坐标帧到另一个坐标帧的变换矩阵。
获取从一个坐标帧到另一个坐标帧的变换矩阵。
计算实际位姿与目标位姿之间的误差。
等待机器人移动到目标位姿,直到误差足够小或超时。
设置目标位姿并等待机器人移动完成。
4. 实施手眼标定和目标追踪
使用二维码检测来定位目标,然后进行相机标定和手眼标定计算。
计算机器人末端和摄像头之间的相对位姿。
实现了一系列的图像获取和处理,利用OpenCV库进行棋盘角点的提取。
通过实验获取数据,计算相机内部参数和两个相机之间的位姿。
实现了基于不同位姿下的图像集合进行手眼标定。
完成了在模拟器中交互式地跟踪目标的过程。
5. 保存与加载数据
使用方法来压缩和保存相关数据,以便后续的分析和使用。
本代码的特点在于它结合了机器人控制、图像处理、手眼标定和交互式目标追踪等多个领域的技术,是一套完整的解决方案。
视频演示
源码解析
函数
1. 通过ZeroMQ远程API连接到CoppeliaSim:创建客户端实例,获取CoppeliaSim API的实例,停止当前模拟,加载模拟场景,开始模拟,返回客户端和sim实例
2. 获取对象句柄: 获取机器人基座的句柄,获取机器人末端执行器的句柄,获取第一个相机的句柄,获取第二个相机的句柄,获取目标球的句柄
3. 定义从CoppeliaSim视觉传感器获取图像并转换为OpenCV格式的BGR图像的函数:从指定相机获取图像数据,将获取的图像数据转换为NumPy数组并重塑为正确的形状,将图像在垂直方向上翻转,以符合OpenCV的图像显示方式
4. 定义设置给定对象在某个参考框架下的位姿(位置和姿态)的函数:设置对象的变换矩阵,以定义其位置和方向
5. 定义获取给定对象在某个参考框架下的位姿的函数:初始化为4x4的单位矩阵,获取对象的变换矩阵并重塑,组成位姿矩阵
6. 定义计算两个位姿之间误差的函数:计算平移误差,计算旋转误差,将旋转误差转换为角度
7.定义等待机器人移动到目标位姿的函数:记录开始时间,初始化误差值为无穷大,计算已经经过的时间,如果超时则返回失败,等待一定时间,获取当前位姿,获取当前速度,计算线速度均值,计算角速度均值,计算误差,如果误差小于阈值且速度接近零,则返回成功
8. 定义设置目标位姿并等待机器人移动完成的函数:设置目标位姿,等待机器人移动到目标位姿并返回结果
主程序
########## 定义场景路径、等待间隔、超时时间以及接受的误差
设置NumPy打印选项
定义场景路径
定义等待时间间隔,单位秒
定义超时时间,单位秒
接受的旋转误差阈值
接受的平移误差阈值
接受的停止速度阈值
连接到CoppeliaSim并开始模拟
获取必要的句柄
########### 设置图像的检测、摄像机标定参数,并检测棋盘格角点
初始化棋盘格检测所需的终止条件:设置寻找亚像素角点的精确度和最大迭代次数,设置相机标定时需要固定的参数
设置棋盘格的尺寸和单位长度:棋盘格的行和列,示例尺寸,根据实际需要调整,单位长度,以米为单位,初始化棋盘格的三维坐标,设置棋盘格上每个点的x,y坐标,z坐标默认为0
从第一个相机获取BGR图像
获取图像的高度和宽度
将图像从BGR转换为灰度图
寻找棋盘格角点
对角点坐标进行精确化
在图像上绘制并显示棋盘格角点
获取机器人末端执行器的原始位姿
定义平移和旋转参数
构建平移和旋转矩阵
设置末端执行器到目标位姿并等待动作完成
显示相机1获取的图像
将末端执行器复位到原始位姿
显示相机1获取的图像
显示相机2获取的图像
########### 构建多个位姿变换矩阵,以便在手眼标定实验中使用
定义平移和旋转的范围
根据定义的范围生成一系列变换矩阵
计算生成的变换矩阵数量
########### 使用生成的位姿变换矩阵收集用于手眼标定的数据
初始化相机1、2图像点和对象点的列表,用于相机标定
定义机器人末端执行器的位姿列表、相机1拍摄的图像列表、相机2拍摄的图像列表
遍历所有预设的变换矩阵:{计算目标位姿,移动机器人末端执行器到目标位姿,如果移动失败,则跳过此次循环。获取当前机器人末端执行器的位姿,从相机1获取图像,并找到棋盘格角点,显示找到的角点,从相机2获取图像,并找到棋盘格角点,显示找到的角点,将找到的角点和对应的对象点分别存入列表,将图像存入相应列表}
计算成功捕获棋盘格角点的图像数量
########### 对两个相机分别进行标定获取内参和畸变系数
分别对两个相机进行标定,获取相机内参矩阵和畸变系数
输出相机内参矩阵和畸变系数
########### 进行立体标定获取两相机之间的旋转和平移矩阵
进行立体标定,获取两个相机间的相对位姿关系()

从仿真场景获取两个相机间的位姿关系
########### 初始化手眼标定所需的矩阵列表
初始化手眼标定所需的数据结构:{机器人夹持器到基座的旋转矩阵列表, 标定板到相机的旋转矩阵列表,机器人夹持器到基座的平移向量列表,标定板到相机的平移向量列表 }
############ 遍历采集的相机1每个图像点、对象点、末端执行器位姿以及图像
遍历每组图像点、对象点、末端执行器位姿以及图像:{ 使用solvePnP求解标定板相对于相机的位姿,在图像中绘制坐标轴并显示,构造标定板到相机的变换矩阵,将求解得到的旋转矩阵和平移向量添加到列表中 }
使用cv2.calibrateHandEye进行相机1手眼标定,求解夹持器到相机1的变换矩阵

输出夹持器到相机1的变换矩阵
定义OpenGL到OpenCV的坐标系统转换矩阵
从场景获取末端执行器到相机1的位姿,并进行坐标系统转换
根据立体标定结果计算夹持器到第二个相机的变换矩阵
从场景获取末端执行器到相机2的位姿,并进行opengl到opencv坐标系统转换
将所有标定数据保存到压缩文件中,以备后用
########### 为机器人对目标进行跟踪做准备
定义一系列位姿变换,用于测试不同的目标位姿
定于存储所有生成的变换矩阵列表
根据上述定义的范围生成一系列变换矩阵
向棋盘格中心的位姿变换
向后(z负向)的位姿变换
棋盘格基座的获取
获取并输出棋盘格的原始位姿
将机器人末端执行器和棋盘格复位到原始位姿
将棋盘格复位到原始位姿
########### 在相机1视角下,机器人对目标进行跟踪
初始化变换矩阵和图像列表,用于存储相机1当前位姿、下一位姿和各位姿对应的图像:存储当前机器人末端执行器的位姿、存储计算得到的下一步的机器人末端执行器位姿、存储相机1拍摄的图像列表
遍历所有预先定义的位姿变换矩阵【实现了在相机1视角下对棋盘格位姿跟踪和视觉处理的自动化实验,为机器人视觉系统的测试和校准提供了重要的数据支持】:{ 计算目标物体(棋盘格)的新位姿,移动棋盘格到新位姿、如果移动失败,则跳过此次循环,获取相机1图像并转换为灰度图像,寻找棋盘格角点,打印旋转和平移误差。精细化角点位置,使用solvePnP求解物体位姿,计算棋盘基座到相机的变换矩阵,应用向目标中心的位姿变换得到棋盘中心到相机的变换矩阵,可视化并显示旋转轴。获取机器人末端执行器当前位姿,计算新的末端执行器位姿,以便于下一次移动,添加当前末端执行器位姿到列表,添加计算得到的下一步位姿到列表,添加图像到列表,移动机器人末端执行器到新的位姿,拍摄并显示移动后的图像}
将机器人末端执行器和棋盘格复位到原始位姿
########### 在相机2视角下,机器人对目标进行跟踪
初始化变换矩阵和图像列表,用于存储相机2当前位姿、下一位姿和各位姿对应的图像:存储当前机器人末端执行器的位姿、存储计算得到的下一步的机器人末端执行器位姿、存储相机2拍摄的图像列表
遍历所有预先定义的位姿变换矩阵【实现了在相机2视角下对机器人位姿跟踪和视觉处理的自动化实验,为机器人视觉系统的测试和校准提供了重要的数据支持】:{计算目标物体(棋盘格)的新位姿、移动棋盘格到新位姿、如果移动失败,则跳过此次循环、获取相机2的图像、转换为灰度图像、寻找棋盘格角点、打印旋转和平移误差、精细化角点位置、使用solvePnP求解物体位姿、计算物体到相机的变换矩阵、应用向目标中心的位姿变换、可视化并显示旋转轴、获取机器人末端执行器当前位姿、计算新的末端执行器位姿,以便于下一次移动、添加当前末端执行器位姿到列表、添加计算得到的下一步位姿到列表、添加图像到列表、移动机器人末端执行器到新的位姿、拍摄并显示移动后的图像}
将收集的位姿和图像数据存储为压缩文件,方便后续使用
将机器人末端执行器和棋盘格复位到原始位姿
########### 在相机2视角下,机器人对目标进行交互式跟踪模拟
交互式跟踪模拟:{从相机2获取BGR图像、将图像转换为灰度图、
检测棋盘格角点、如果没有找到角点,继续下一次循环、通过子像素角点检测精细化角点位置、使用solvePnP算法求解物体位姿、如果solvePnP求解失败,继续下一次循环、初始化物体到相机的变换矩阵、根据旋转向量更新旋转矩阵、更新平移向量、应用向目标中心的位姿变换、获取当前机器人末端执行器的位姿、根据得到的相机位姿计算新的机器人末端执行器位姿、将机器人末端执行器移动到新的位姿}
作者陈晓永:智能装备专业高级工程师,软件工程师。机器人自动化产线仿真动画制作
The End
相关文章:
【仿真】UR机器人相机标定、立体标定、手眼标定、视觉追踪(双目)
实现在CoppeliaSim环境中进行手眼标定和目标追踪的一个例子。它主要涉及到机器人、机器视觉和控制算法的编程,使用了Python语言。接下来对该代码的主要类和方法进行解析: 1. 导入相关库 用于与CoppeliaSim模拟器通过ZeroMQ接口通信。包含Rotation类&…...
功能测试【测试用例模板、Bug模板、手机App测试★】
功能测试 Day01 web项目环境与测试流程、业务流程测试一、【了解】web项目环境说明1.1 环境的定义:项目运行所需要的所有的软件和硬件组合1.2 环境(服务器)的组成:操作系统数据库web应用程序项目代码1.3 面试题:你们公司有几套环境࿱…...
Android音频系统
最近在做UAC的项目,大概就是接收内核UAC的事件,也就是声音相关事件。然后就是pcm_read和AudioTrackr->write之间互传。感觉略微有点奇怪,所以简单总结一下。 1 UAC的简要流程 open_netlink_socket 打开内核窗口,类似于ioctl。…...
Android开发系列(九)Jetpack Compose之ConstraintLayout
ConstraintLayout是一个用于构建复杂布局的组件。它通过将子视图限制在给定的约束条件下来定位和排列视图。 使用ConstraintLayout,您可以通过定义视图之间的约束关系来指定它们的位置。这些约束可以是水平和垂直的对齐、边距、宽度和高度等。这允许您创建灵活而响…...
SpringMVC系列三: Postman(接口测试工具)
接口测试工具 💞Postman(接口测试工具)Postman介绍Postman是什么Postman相关资源Postman安装Postman快速入门Postman完成Controller层测试其它说明 💞课后作业 上一讲, 我们学习的是SpringMVC系列二: 请求方式介绍 现在打开springmvc项目 💞…...
项目实训-vue(十二)
项目实训-vue(十二) 文章目录 项目实训-vue(十二)1.概述2.处理进度可视化 1.概述 本篇博客将记录我在图片上传页面中的工作。 2.处理进度可视化 除了导航栏之外,我们还需要对上传图片以及图片处理的过程以及流程进行…...
达梦数据库的系统视图v$lock
达梦数据库的系统视图v$lock 在达梦数据库(DM)中,V$LOCK 系统视图用于查看当前数据库中的锁定状态。该视图提供了关于所有锁定详细信息,例如锁的内存地址、所属事务 ID,锁类型和锁模式等。这对于数据库管理员进行锁定…...
【无人机三维路径规划】基于树木生长算法TGA实现复杂城市地形下无人机避障三维航迹规划附Matlab代码
% 定义无人机起始位置和目标位置 start_point [0, 0, 0]; % 起始位置 [x, y, z] target_point [100, 100, 100]; % 目标位置 [x, y, z] % 定义城市地形和障碍物信息 city_map imread(‘city_map.png’); % 城市地形图像 obstacles [ 20, 30, 10; % 障碍物1位置 [x, y, z] …...
制造业工厂的管理到底有多难
一、引言 随着全球经济的不断发展,制造业作为实体经济的核心,对国家的经济增长起着至关重要的作用。然而,制造业工厂的管理却是一项复杂而艰巨的任务。本文将深入探讨制造业工厂管理所面临的挑战,并提出相应的应对策略。 二、制造…...
QTday5 2024-06-19
作业要求: 1.思维导图 2.整理代码:TCP服务器 作业1:思维导图 作业2:整理代码 运行代码: widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> #include <QList>…...
Node官网下载各个版本
node官网下载各个版本地址 例如 14.16.0 Index of /download/release/v14.16.0/...
备战秋招day4
算法 242. 有效的字母异位词 class Solution {public boolean isAnagram(String s, String t) {int[] count new int[26];for(int i 0;i<s.length();i){count[s.charAt(i)-a];}for(int i 0;i<t.length();i){count[t.charAt(i)-a]--;if(count[t.charAt(i)-a]<0){r…...
【华为OD机试B卷】服务器广播、需要广播的服务器数量(C++/Java/Python)
题目 题目描述 服务器连接方式包括直接相连,间接连接。 A和B直接连接,B和C直接连接,则A和C间接连接。 直接连接和间接连接都可以发送广播。 给出一个N*N数组,代表N个服务器, matrix[i][j] 1, 则代表i和j直…...
目标检测数据集 - 手机屏幕表面表面缺陷检测数据集下载「包含VOC、COCO、YOLO三种格式」
数据集介绍:手机屏幕表面缺陷检测数据集,真实采集高质量手机屏幕表面含缺陷图片数据,数据集含多款不同型号和品牌的手机屏幕表面图片数据,包括苹果手机屏、三星手机屏、华为手机屏等数据。数据标注标签包括 Bubble 气泡/水滴、Scr…...
语音相关算法学习整理
最近看了一下百度paddlespeech的一些公开课,把课程里的视频内容大体听了一下,现在整理一下笔记。教程链接见:飞桨AI Studio星河社区-人工智能学习与实训社区 语音识别的过程可以这样简单概括: 将声音信号经过预加重、加窗、fft等…...
[C#] opencvsharp对Mat数据进行序列化或者反序列化以及格式化输出
【简要介绍】 在OpenCVSharp中,FileStorage类用于将数据(包括OpenCV的Mat类型数据)序列化为XML或YAML格式的文件,以及从这些文件中反序列化数据。以下是关于FileStorage类用法的详细说明: 写入数据(序列化…...
Linux中的TCP与UDP:理解两者的差异
在计算机网络的世界中,TCP(传输控制协议)和UDP(用户数据报协议)是两种至关重要的传输层协议。它们就像是我们日常生活中的通信方式,有着不同的使用场景和优缺点。通过一个简单的比喻,我们可以更…...
通信系统网络架构_1.局域网网络架构
当今,通信网络从大的方面主要包括局域网、广域网、移动通信网等网络形式。不同的网络会采用不同的技术进行网络构建。以下针对不同的网络给出各自的网络架构以及所采用的技术。 1.概述 局域网,即计算机局部区域网络,是一种为单一机构所拥有的…...
Pycharm 启动 Django项目 —— python篇
1、打开你的工程,在菜单栏里找到Run-->Edit Configurations 2、在打开的对话框里边选择Python,点击号 3.选择Python 4.出现了一个新的项Unnamed,你可以把它改名叫debug,好听一点 5.脚本选择你网站的manage.py,脚本参…...
6-47选择整数计算
整数计算: 用swing组件来实现整数计算,需要对整数计算的值进行校验。 import javax.swing.*; import java.awt.*; import java.awt.event.*;public class IntegerCalculator extends JFrame implements ActionListener {private JCheckBox[] checkBoxe…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...
基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...
深入理解Optional:处理空指针异常
1. 使用Optional处理可能为空的集合 在Java开发中,集合判空是一个常见但容易出错的场景。传统方式虽然可行,但存在一些潜在问题: // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...
