前言
手眼标定是将相机坐标系下的物体坐标转换到机械臂坐标系下(比如机器人基座base系,或者自定义的世界系,如人形机械臂参考的固定的世界系等)的常用技术。常见的安装方式主要有如下两种
• In-Hand Camera:相机安装在机械臂的末端,随机械臂一起运动,用于获取更接近操作的视觉信息。
• Fixed Camera:相机固定在某个位置,不随机械臂运动,适用于获取整个工作区域的视觉信息。
In-Hand Camera
In-Hand Camera的标定是为了求出相机与机械臂末端工具(TOOL)之间的变换关系,一般是一个大小为4x4的刚体变换矩阵, 在KDL可以用Frame中声明这个变量, 由于输入公式较为麻烦,这里我就用自己写代码的方式进行阐述,比如T_B_E表示机械臂末端(end-effector)或法兰在基座BASE下的表示, 这里假设工具参数已提前通过4点法或6点法标定得到,视作为一个精确的值。
标定时,将一个已知精确大小的标定板(比如棋盘格)固定放置, 然后让机械臂运动,以使相机可以从多个不同角度拍摄标定板图像,拍摄图像的时确保棋盘格图像不超出图像边界,并记录对应的机械臂末端位姿。假设相机内参已知,每一张标定板图像都可以算出相机(C)在标定板(P)下的位姿T_C_P, 这里定义 T_E_C为相机在末端工具坐标系下的表示,对于每一张图片有如下关系式成立(对消直接能看出来, 结果均为T_B_C, 即相机在BASE下的表示)
T_B_E * T_E_C = T_B_P * T_P_C |
做下一步变换,消除T_B_P, 由于标定版是相对BASE固定的,所以对应任一标定数据,有(下标为i为第i个数据,j类似)
Ti_B_E * T_E_C * Ti_C_P = Tj_B_E * T_E_C * Tj_C_P |
两边左乘Tj_B_E的逆有
T_j_E_B * Ti_B_E * T_E_C * Ti_C_P = T_E_C * Tj_C_P |
再右乘Ti_C_P的逆有
T_j_E_B * Ti_B_E * T_E_C = T_E_C * Tj_C_P * Ti_P_C |
对于T_j_E_B Ti_B_E, Tj_C_P Ti_P_C, 都是已知的,方程就变为典型的AX=XB
的形式, 这类方程有很多解法,比如Tsai方法,dual-quaternion方法以及Kronecker Product方法等, 将所需的参数输入到具体的算法中后即可标定出T_E_C的结果,也就是相机在工具系下的表示(这样物体在相机系下的表示就可以转到末端工具系下进行表示了)。比如相机识别了焊缝的点位信息后,转到工具系下就可以直接去做焊接相关的工作了。
Fixed Camera
对Fixed Camera进行手眼标定时,主要关注相机(C)到Base frame(B)之间的变换, 也可以是相机到World frame(W)之间的变换,在人形机器人中一般会转到世界系下去做表示,这里简单的对从C到B之间的转换做个说明, 标定的时候有一些区别,这时候相机是在固定的位置,比如人形机器人的头部位置,手上固定着标定版,然后运动机械臂,使相机能从不同视角拍摄到标定板,每拍摄图像时,同时记录当时机械臂末端的位姿(用工具或者法兰表示都可以)。
不难发现如下关系,
T_B_E * T_E_P = T_B_C * T_C_P |
用上述同样的方式,有(此时末端工具,比如手与标定版T_E_P之间是不变的)
Ti_E_B * T_B_C * Ti_C_P = Tj_E_B * T_B_C * Tj_C_P |
同样的操作,有
Tj_B_E * Ti_E_B * T_B_C = T_B_C * Tj_C_P * Ti_P_C |
又变成了AX=XB
的方式,同样求解即可得到T_B_C, 即相机在BASE下的表示,如果把BASE换成World, 可以得到相机在世界系下的表示。
求解可以直接调用成熟的库如open-cv
, 原理还是很简单的,这样对手眼标定这个常用的技术就有了更深入的认识了。若想知道更多的有关相机内外参的标定 可以看看张正友标定法, 就明白为啥要引入棋盘格进行标定了。