只要你按照我的步骤走应该做出来不是问题!!!
完整的python源代码!!!!!!!!!!!!!!!!!!!全部开源讲解步骤详细!!!!!
一、标定原理
机器人手眼标定分为eye in hand与eye to hand两种。
介绍之前进行变量定义说明:对于 Eye-in-hand 手眼标定方式,需要求解工业机器人的末端坐标系与相机坐标系之间的坐标转换关系。 Eye-in-hand 手眼标定的原理示意图如图 1所示。这其中有几个坐标系, 基础坐标系(用 base 表示) 是机器臂的基底坐标系,末端坐标系(用 end 表示) 是机器臂的末端坐标系, 相机坐标系(用 cam 表示) 是固定在机器臂上面的相机自身坐标系,标定物坐标系(用 cal 表示)是标定板所在的坐标系。任意移动两次机器臂,由于标定板和机器臂的基底是不动的,因此对于某个世界点,其在 base 坐标系和 cal 坐标系下的坐标值不变,在 end 坐标系和 cam 坐标系下的坐标值随着机器臂的运动而改变。根据这一关系,可以求解出end坐标系和 cam 坐标系之间的转换矩阵。具体求解过程如下:
{b}: base基坐标系
{g}: end夹具坐标系
{t}: cal标定板坐标系
{c}: camera相机坐标系
本文主要只讲解眼在手上,以及眼在手上的代码实现
眼在手上(eye in hand)
眼在手上,相机固定在机器人上。
重点讲代码实现
calibrateHandeye()
参数描述如下:R_gripper2base,t_gripper2base是机械臂抓手相对于机器人基坐标系的旋转矩阵与平移向量,需要通过机器人运动控制器或示教器读取相关参数转换计算得到;R_target2cam, t_target2cam 是标定板相对于相机的齐次矩阵,在进行相机标定时可以求取得到(calibrateCamera()得到),也可以通过solvePnP()单独求取相机外参数获得 ; R_cam2gripper ,t_cam2gripper是求解的手眼矩阵分解得到的旋转矩阵与平移矩阵;OpenCV实现了5种方法求取手眼矩阵 , Tsai两步法速度最快。
以上的参数无所就四个前面两个分别是基于机械臂base到爪子的end的旋转与平移矩阵。然后就是每次拍照的相机的每次外惨P的旋转与平移矩阵。
获取这四个参数 前面两个参数可以每次记录机械臂的移动的位姿就可以算出,后面的两个参数是计算每次拍照的外惨P。
实际开始操作
一准备标定纸
免费的棋盘格标定板生成网址: https://calib.io/pages/camera-calibration-pattern-generator
行列分别是8,11 则此标定纸规格为8*11并且其中每个小格子里面大小为10mm,使用a4白纸打印出来就可。
拍照准备
由于是相机开启是以视频流的形式所以需要写一个拍照的功能包
cd ~
mkdir paizhao/src
cd paizhao/src
运行:
ros2 pkg create python_img --build-type ament_python --dependencies rclpy cv_bridge sensor_msgs vision_msgs cv2 --license Apache-2.0 --node-name img_huoqu
会出现以上的功能包python_img
cd ~/paizhao/src/python_img/python_img
将以下代码复制到img_huoqu.py即可
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
import cv2
class ImageListener(Node):
def __init__(self):
super().__init__('image_listener')
self.subscription = self.create_subscription(
Image,
'camera/color/image_raw',
self.listener_callback,
10)
self.subscription # prevent unused variable warning
self.bridge = CvBridge()
self.count = 0
def listener_callback(self, data):
self.get_logger().info('Receiving video frame')
cv_image = self.bridge.imgmsg_to_cv2(data, desired_encoding='bgr8')
# 显示图像
cv2.imshow("Image Window", cv_image)
# 按下“t”键保存图像
if cv2.waitKey(1) & 0xFF == ord('t'):
self.count += 1
filename = f'image_{
self.count}.bmp'
cv2.imwrite(filename, cv_image)
self.get_logger().info(f'Image saved: {
filename}')
def main(args=None):
rclpy.init(args=args)
image_listener = ImageListener()
rclpy.spin(image_listener)
# 销毁窗口
cv2.destroyAllWindows()
# 关闭节点
image_listener.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
编译
cd ~/paizhao
colcon build
运行
cd ~/paizhao
. ./install/setup.bash
ros2 run python_img img_huoqu