首先,我们要了解一下常规的手眼标定流程是怎么样的。
(一)如果吸嘴中心就是法兰盘的中心则
是下面这样的:
按九宫格走九个点,取得九组吸嘴的像素坐标与法兰盘的坐标
(图1)
进行标定
(二)如果吸嘴位置不在法兰盘中心
则标定流程要复杂些:
人工创建工具坐标Tool 1,把工具坐标中心创建到标定片的Mark点上去
按九宫格走九个点,取得九组特征点的像素坐标与对应的机械坐标
进行标定
这里的难点是创建工具坐标的方法。
人工创建工具坐标,一般按工具向导来创建,需要第二个点同第一个点U轴差180度。对于结构紧凑的机器来说,你是不可能做到的。
即使能做到,这个过程是相当磨人的。
如果想不转180度创建工具坐标,则需要自己写,而不是使用工具向导来创建。
这里勇哥介绍一下同事用到的一种利用旋转中心进行标定的方法,它可以用以实现自动标定的需求。
注意:如果你得人工去创建工具坐标的话,就做不到自动标定了。
另外,自动标定是需要里面写程序,IPC上写一段自动标定的程序与之配合才可以做到的。
第一步:
机器人吸嘴上放上标定片,走矩形四个位置。取得4组特征点B的像素坐标。
同时取得4组机械坐标,这个机械坐标是机器人U轴中心A的机械坐标。(这个过程简化了九点标定,只取4个点)
我们同时有了四组像素与机械坐标,用halcon算子vector_to_hom_mat2d进行标定。
此时标定的结果不是我们想要的,它只是把机器人法兰盘中心(U轴中心)的A点和特征点B标定在了一起。
因为机器人默认使用tool 0工具坐标系工作的,我们这样标定也就是把特征点和Tool 0工具坐标的中心(这个中心就是法兰盘的中心)标定在了一起。
这是我们的第一次标定,它标定出来的结果是存在一个固定偏差的,这个偏差就是法兰盘中心(u轴中心)到特征的固定的距离偏差。
标定成功后,我们获得一个标定关系的矩阵homMat2D
(图2)
第二步:
接下来进行三点定圆心的操作。如下图所示,我们通过旋转机器人法兰盘(u轴中心)的中心旋转出三个位置。
通过三个特征点B,我们可以求出通过它们的一个圆,其圆心是法兰盘中心(u轴中心)在相机坐标系中的像素坐标。
现在我们求出的圆心只是像素坐标,通过第一步的标定关系矩阵homMat2D,利用halcon算子affine_trans_point_2d可以计算出这个圆心的机械坐标。
重要的地方来了!这个圆心的机械坐标并不是法兰盘的中心坐标,而是拥有固定偏差值的一个坐标!
注:如果只看图3,你可能很疑惑,这3个角度明明是绕着U轴中心转动的呀,为什么说这个中心不是法兰盘U轴的中心呢?
注意,这个三点的中心只是在像素坐标系里面是U轴的中心!
但是,当你把这个像素转为机械坐标时,因为你原来第一次标定时的矩阵homMat2D,里面的信息就是法兰盘中心到特征点的关系,所以此时你把圆心像素坐标转为机器坐标时,你还是用的这个矩阵homMat2D在转换。因此你转化后的机械坐标不是U轴中心,而是法兰盘到特征点机械坐标的距离。
(图3)
第三步
接下来进行第二次标定的过程。
有了第3步的Tool 0工具坐标中心的机械坐标,我们可以计算工具1和工具0的毫米偏差,并把最初标定时的Tool0下的四个特征点的机械坐标加上这个毫米偏差,使其变为Tool1下的坐标,Tool1的工具中心就是我们选取的特征点那个地方。
说人话:法兰盘中心(u轴中心)机械坐标减去 用3点定圆那个圆心的机械坐标,求出固定偏差值。
这个固定偏差就是法兰盘到特征点机械坐标的距离!
然后我们用这个偏差值更新一下第一次标定时的四组像素与机械坐标数据,重新标定即可。
这次更新的过程其实就是把Tool0下的四组机械坐标转化为Tool1下的四组机械坐标。
可能你会说,我们目前为止根本没有Tool1呀,这个没关系,本步骤不需要Tool1,第四步才会创建Tool1坐标。那个时候用得上三点圆心的机械坐标了。
第四步
最后利用三点定圆的圆心机械坐标,我们来创建Tool 1坐标系。要实现求出工具坐标x,y的过程可以在机器人端写程序,也可以用代码来实现,但是创建Tool 1坐标系这一步仍然还是需要在机器人端来执行。
最后我们就达到最终的目的:
创建工具坐标Tool 1,把工具坐标中心创建到标定片的Mark点上去,然后生成四组特征点的像素坐标与机械坐标。
大功告成!
(图1: 4个标定点,3个旋转点,1个)
(图2:第一次标定)
(图3:第二次标定)
下面是标定的输出信息,请参考:
C#
CT1机械坐标: mechanalPosX=-22.585 mechanicalPosY=170.856 p1 {X = 1102.115 Y = 1110.051} IsEmpty: false X: 1102.115 Y: 1110.051 p2 {X = 289.26 Y = 1175.885} IsEmpty: false X: 289.26 Y: 1175.885 p3 {X = 1814.609 Y = 1332.285} IsEmpty: false X: 1814.609 Y: 1332.285 圆心位置: {X = 857.9301 Y = 3146.18433} 圆心转机械坐标: row1AfrTrans={-14.4875695091889} col1AfterTrans={88.6095108466213} 第一次标定后的矩阵: homMat2D: {[-0.040066467819754, -0.000775766400971161, 22.3672349752005, 0.000818720706487857, -0.0402510697036496, 214.656297497753]} 偏差:CT1机械坐标-圆心机械坐标 //double spanX = Convert.ToDouble(mechanicalPosX) - row1AfterTrans.D; //double spanY = Convert.ToDouble(mechanicalPosY) - col1AfterTrans.D; spanX=-8.0974304908110746 spanY=82.246489153378647 第二次标定后的矩阵: homMat2D: {[-0.040066467819754, -0.000775766400971159, 14.2299334255784, 0.000818720706487857, -0.0402510697036496, 296.790879463611]} 1713 等待机器人前往标定点1...... 1728 模板位置:0, X:438.338, Y:560.191, U:0 1729 机器人到达标定点1,当前像素坐标为:457.791;445.217机械坐标为:3.703;197.128 1729 等待机器人前往标定点2..... 1654 模板位置:0, X:414.878, Y:1742.642, U:-0.001 1655 机器人到达2号点,当前像素坐标为:434.001;1627.619机械坐标为:3.704;149.502 1655 等待机器人前往标定点3...... 1601 模板位置:0, X:1679.666, Y:1718.163, U:0.001 1602 机器人到达标定点3,当前像素坐标为:1699.957;1602.742机械坐标为:-46.975;151.532 1602 等待机器人前往标定点4...... 1605 模板位置:0, X:1700.915, Y:601.786, U:0 1606 机器人到达标定点4,当前像素坐标为:1720.958;486.131机械坐标为:-46.975;196.502 1606 开始Tool0下的标定...... 1606 Tool0下标定完成,开始创建工具坐标 1606 等待机器人前往创建工具2号点...... 1609 模板位置:0, X:315.584, Y:1289.472, U:-0.397 1610 机器人到达创建工具2号点,当前像素坐标为:289.26;1175.885 1610 等待机器人前往创建工具3号点...... 1613 模板位置:0, X:1754.706, Y:1432.779, U:0.366 1614 机器人到达创建工具3号点,当前像素坐标为:1814.609;1332.285 1614 等待机器人前往创建工具1号点...... 1615 模板位置:0, X:1081.994, Y:1225.572, U:0.001 1616 机器人到达标创建工具1号点,当前像素坐标为:1102.115;1110.051机械坐标为:-22.585;170.856 1612 Tool0工具中心经标定关系转化后的坐标为:-14.4477;88.7214 1710 机器人工具1创建完成 1714 模板位置:0, X:1112.962, Y:916.192, U:-0.398 1715 标定精度测试结果:X偏差:0.104mm,Y偏差:0.041mm 1715 标定精度较差 1715 自动标定完成
本次标定成功后,tool1结果为:
x,y,z,u
82.008, 9.569, 0, 0
这里勇哥想知道的是,怎么把tool1结果转换为tool0呢?
tool0
3.703,197.128
tool1:
-4.377,279.296
显然并不是简单的把Tool0加上工具坐标这么简单。
审核编辑:刘清