相机机械臂手眼标定-眼在手外(二)
眼在手外标定原理
公式推导如下:
可推出如下公式:
H
c
a
m
b
a
s
e
=
H
t
o
o
l
b
a
s
e
∗
H
c
a
l
t
o
o
l
∗
H
c
a
m
c
a
l
H ^{base}_{cam}= H^{base}_{tool} * H^{tool}_{cal} * H^{cal}_{cam}
Hcambase=Htoolbase∗Hcaltool∗Hcamcal
其中:
H
c
a
m
b
a
s
e
H^{base}_{cam}
Hcambase:从机械臂基座标系到相机坐标系的变换矩阵(个人习惯这么说),实际代表相机坐标系在机械臂基坐标系下的位姿。
H
t
o
o
l
b
a
s
e
H^{base}_{tool}
Htoolbase: 从机械臂基坐标系到机械臂末端坐标系的变换矩阵,代表末端工具坐标系在机械臂基坐标系下的位姿。
H
c
a
l
t
o
o
l
H^{tool}_{cal}
Hcaltool: 从机械臂末端坐标系到标定板坐标系的变换矩阵,代表标定板坐标系在末端坐标系下的位姿。
H
c
a
m
c
a
l
H^{cal}_{cam}
Hcamcal: 从标定板坐标系到相机坐标系的变换矩阵,代表相机坐标系在标定板坐标系下的位姿。
在进行眼在手外的标定过程中,需要保持 H c a l t o o l H^{tool}_{cal} Hcaltool 的变换相对不变,也就是说机械臂的末端坐标系和标定板保持不变,当然这是因为该值我们无法直接准确的测量,因此保持其每次相机采集时相对不变,用于方程式求解过程中将其消除。(在标定过程中,标定板固定在机械臂末端)
进一步公式推导:
H
c
a
l
t
o
o
l
=
H
b
a
s
e
t
o
o
l
∗
H
c
a
m
b
a
s
e
∗
H
c
a
l
c
a
m
H^{tool}_{cal} = H^{tool}_{base} * H^{base}_{cam} * H^{cam}_{cal}
Hcaltool=Hbasetool∗Hcambase∗Hcalcam
此时根据采集的多次机械臂位姿进行求解
其中
H
b
a
s
e
t
o
o
l
H^{tool}_{base}
Hbasetool 通过读取机械臂末端坐标系相对于基坐标系位姿,然后在进行矩阵求逆,得到基坐标系相对于机械臂末端坐标系的位姿。
H
c
a
m
b
a
s
e
H^{base}_{cam}
Hcambase 为手眼标定的待求解,相机坐标系相对于机械臂基坐标的位姿。
H
c
a
l
c
a
m
H^{cam}_{cal}
Hcalcam 为标定板坐标系相对于相机坐标系的位姿。通过PNP算法获取
采用相邻的两次数据采集的结果进行求解
其中
H
c
a
l
t
o
o
l
H^{tool}_{cal}
Hcaltool 保持不变不变:
0
H
b
a
s
e
t
o
o
l
∗
0
H
c
a
m
b
a
s
e
∗
0
H
c
a
l
c
a
m
=
1
H
b
a
s
e
t
o
o
l
∗
1
H
c
a
m
b
a
s
e
∗
1
H
c
a
l
c
a
m
^0H^{tool}_{base} * ^0H^{base}_{cam}* ^0H^{cam}_{cal} = ^1H^{tool}_{base} * ^1H^{base}_{cam} * ^1H^{cam}_{cal}
0Hbasetool∗0Hcambase∗0Hcalcam=1Hbasetool∗1Hcambase∗1Hcalcam
由于
H
c
a
m
b
a
s
e
H^{base}_{cam}
Hcambase保持不变,因此
0
H
b
a
s
e
t
o
o
l
∗
H
c
a
m
b
a
s
e
∗
0
H
c
a
l
c
a
m
=
1
H
b
a
s
e
t
o
o
l
∗
H
c
a
m
b
a
s
e
∗
1
H
c
a
l
c
a
m
^0H^{tool}_{base} * H^{base}_{cam} * ^0H^{cam}_{cal}=^1H^{tool}_{base} * H^{base}_{cam} * ^1H^{cam}_{cal}
0Hbasetool∗Hcambase∗0Hcalcam=1Hbasetool∗Hcambase∗1Hcalcam
进行化简:
(
1
H
b
a
s
e
t
o
o
l
)
−
1
∗
0
H
b
a
s
e
t
o
o
l
∗
H
c
a
m
b
a
s
e
=
H
c
a
m
b
a
s
e
∗
1
H
c
a
l
c
a
m
∗
(
0
H
c
a
l
c
a
m
)
−
1
(^1H_{base}^{tool})^{-1}*^0 H^{tool}_{base}* H^{base}_{cam} = H ^{base}_{cam}*^1H_{cal}^{cam} *(^0H^{cam}_{cal})^{-1}
(1Hbasetool)−1∗0Hbasetool∗Hcambase=Hcambase∗1Hcalcam∗(0Hcalcam)−1
转换为AX = XB的形式,求解出X即可。
在计算 H c a l c a m H_{cal}^{cam} Hcalcam 时,使用opencv自带的pnp算法
void solvePnP(InputArray objectPoints, InputArray imagePoints, InputArray cameraMatrix, InputArray distCoeffs, OutputArray rvec, OutputArray tvec, bool useExtrinsicGuess=false, int flags = CV_ITERATIVE)
objectPoints - 世界坐标系下的棋盘点的坐标(这里世界坐标系与棋盘坐标系的原点重合)
imagePoints - 在图像坐标系下对应的像素点的坐标
cameraMatrix - 相机的内参矩阵
distCoeffs - 相机的畸变系数
以上两个参数通过相机标定可以得到。相机的内参数的标定参见:
rvec - 输出的旋转向量。从相机坐标系到棋盘坐标系的旋转矩阵,代表棋盘格坐标系在相机坐标系下的旋转量。
tvec - 输出的平移向量。从相机坐标系到棋盘坐标系的平移向量,代表棋盘格坐标系在相机坐标系下的平移量。
flags - 默认使用CV_ITERATIV迭代法
通过将rvec和tvec转换为变换矩阵,便可以算出 H c a l c a m H_{cal}^{cam} Hcalcam
求解最终的X,也就是 H c a m t o o l H^{tool}_{cam} Hcamtool 时使用opencv中的手眼标定算子
void
cv::calibrateHandEye(InputArrayOfArrays R_gripper2base,
InputArrayOfArrays t_gripper2base,
InputArrayOfArrays R_cam2target,
InputArrayOfArrays t_cam2target,
OutputArray R_base2cam,
OutputArray t_base2cam,
HandEyeCalibrationMethod method = CALIB_HAND_EYE_TSAI)
其中:
R_gripper2base:从机械臂末端坐标系到机械臂基坐标系的旋转矩阵,代表机械臂基坐标系在机械臂末端坐标系下的旋转量。
t_gripper2base:从机械臂末端坐标系到机械臂基坐标系的平移向量,代表机械臂基坐标系在机械臂末端坐标系下的平移量。
R_cam2target: 从相机坐标系到标定板棋盘格坐标系的旋转矩阵,代表标定板坐标系在相机坐标系下的旋转量。
t_cam2target: 从相机坐标系到标定板棋盘格坐标系的平移向量,代表标定板坐标系在相机坐标系下的平移量。
R_base2cam:从机械臂基坐标系到相机坐标系的旋转矩阵,代表相机坐标系在机械臂机械臂基坐标系下的旋转量。
t_base2cam:从机械臂基坐标系到相机坐标系的平移向量,代表相机坐标系在机械臂基坐标系下的平移量。
注意:本文中的坐标系描述语言和其他描述存在出入,具体参照上述内容进行理解,如本人描述有误请提醒改正,共勉。