- 操作系統:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 編程語言:C++11
算法描述
計算機器人世界/手眼標定: w T b _{}^{w}\textrm{T}_b w?Tb? 和 c T g _{}^{c}\textrm{T}_g c?Tg?。
cv::calibrateRobotWorldHandEye 是 OpenCV 中用于機器人世界手眼標定的函數。該函數通過已知的世界坐標系(world)、相機坐標系(cam)、基座坐標系(base)和平板坐標系(gripper)的姿態來計算基座相對于世界的姿態以及末端執行器相對于相機的姿態。
函數原型
void cv::calibrateRobotWorldHandEye
(InputArrayOfArrays R_world2cam,InputArrayOfArrays t_world2cam,InputArrayOfArrays R_base2gripper,InputArrayOfArrays t_base2gripper,OutputArray R_base2world,OutputArray t_base2world,OutputArray R_gripper2cam,OutputArray t_gripper2cam,RobotWorldHandEyeCalibrationMethod method = CALIB_ROBOT_WORLD_HAND_EYE_SHAH
)
參數
- 參數R_world2cam: 從世界坐標系(world)到相機坐標系(camera)的齊次矩陣中提取的旋轉部分 (cTw)。這是一個包含所有從世界坐標系到相機坐標系變換的旋轉矩陣 (3x3) 或旋轉向量 (3x1) 的向量 (vector)。
- 參數t_world2cam: 從世界坐標系(world)到相機坐標系(camera)的齊次矩陣中提取的平移部分 (cTw)。這是一個包含所有從世界坐標系到相機坐標系變換的平移向量 (3x1) 的向量 (vector)。
- 參數R_base2gripper: 從機器人基座坐標系(base)到末端執行器坐標系(gripper)的齊次矩陣中提取的旋轉部分 (gTb)。這是一個包含所有從機器人基座坐標系到末端執行器坐標系變換的旋轉矩陣 (3x3) 或旋轉向量 (3x1) 的向量 (vector)。
- 參數t_base2gripper: 從機器人基座坐標系(base)到末端執行器坐標系(gripper)的齊次矩陣中提取的平移部分 (gTb)。這是一個包含所有從機器人基座坐標系到末端執行器坐標系變換的平移向量 (3x1) 的向量 (vector)。
- 參數R_base2world: 估計的從機器人基座坐標系(base)到世界坐標系(world)的齊次矩陣中提取的旋轉部分 (wTb),即 (3x3) 旋轉矩陣。
- 參數t_base2world: 估計的從機器人基座坐標系(base)到世界坐標系(world)的齊次矩陣中提取的平移部分 (wTb),即 (3x1) 平移向量。
- 參數R_gripper2cam: 估計的從末端執行器坐標系(gripper)到相機坐標系(camera)的齊次矩陣中提取的旋轉部分 (cTg),即 (3x3) 旋轉矩陣。
- 參數t_gripper2cam: 估計的從末端執行器坐標系(gripper)到相機坐標系(camera)的齊次矩陣中提取的平移部分 (cTg),即 (3x1) 平移向量。
- 參數method: 實現的機器人世界/手眼標定方法之一,參見 cv::RobotWorldHandEyeCalibrationMethod。
代碼示例
#include <iostream>
#include <opencv2/opencv.hpp>
#include <vector>using namespace cv;
using namespace std;int main()
{// 假設我們有四組數據,分別對應不同的抓取位置int num_poses = 4;// 從 world 到 cam 的旋轉矩陣和位移向量vector< Mat > R_world2cam( num_poses );vector< Mat > t_world2cam( num_poses );// 從 base 到 gripper 的旋轉矩陣和位移向量vector< Mat > R_base2gripper( num_poses );vector< Mat > t_base2gripper( num_poses );// 初始化示例數據R_world2cam[ 0 ] = ( Mat_< double >( 3, 3 ) << 1, 0, 0, 0, 1, 0, 0, 0, 1 );t_world2cam[ 0 ] = ( Mat_< double >( 3, 1 ) << 0.1, 0.2, 0.3 );R_world2cam[ 1 ] = ( Mat_< double >( 3, 3 ) << 0, -1, 0, 1, 0, 0, 0, 0, 1 );t_world2cam[ 1 ] = ( Mat_< double >( 3, 1 ) << 0.4, 0.5, 0.6 );R_world2cam[ 2 ] = ( Mat_< double >( 3, 3 ) << 0, 0, -1, 0, 1, 0, 1, 0, 0 );t_world2cam[ 2 ] = ( Mat_< double >( 3, 1 ) << 0.7, 0.8, 0.9 );R_world2cam[ 3 ] = ( Mat_< double >( 3, 3 ) << 0, 0, 1, 0, 1, 0, -1, 0, 0 );t_world2cam[ 3 ] = ( Mat_< double >( 3, 1 ) << 1.0, 1.1, 1.2 );R_base2gripper[ 0 ] = ( Mat_< double >( 3, 3 ) << 1, 0, 0, 0, 1, 0, 0, 0, 1 );t_base2gripper[ 0 ] = ( Mat_< double >( 3, 1 ) << 0.3, 0.4, 0.5 );R_base2gripper[ 1 ] = ( Mat_< double >( 3, 3 ) << 0, -1, 0, 1, 0, 0, 0, 0, 1 );t_base2gripper[ 1 ] = ( Mat_< double >( 3, 1 ) << 0.6, 0.7, 0.8 );R_base2gripper[ 2 ] = ( Mat_< double >( 3, 3 ) << 0, 0, -1, 0, 1, 0, 1, 0, 0 );t_base2gripper[ 2 ] = ( Mat_< double >( 3, 1 ) << 0.9, 1.0, 1.1 );R_base2gripper[ 3 ] = ( Mat_< double >( 3, 3 ) << 0, 0, 1, 0, 1, 0, -1, 0, 0 );t_base2gripper[ 3 ] = ( Mat_< double >( 3, 1 ) << 1.2, 1.3, 1.4 );// 輸出變量Mat R_base2world, t_base2world;Mat R_gripper2cam, t_gripper2cam;// 執行機器人世界手眼標定calibrateRobotWorldHandEye( R_world2cam, t_world2cam, R_base2gripper, t_base2gripper, R_base2world, t_base2world, R_gripper2cam, t_gripper2cam, CALIB_ROBOT_WORLD_HAND_EYE_SHAH );// 輸出結果cout << "Rotation matrix from base to world:\n" << R_base2world << endl;cout << "Translation vector from base to world:\n" << t_base2world << endl;cout << "Rotation matrix from gripper to camera:\n" << R_gripper2cam << endl;cout << "Translation vector from gripper to camera:\n" << t_gripper2cam << endl;return 0;
}
運行結果
Rotation matrix from base to world:
[1, 0, 0;0, 1, 0;0, 0, 1]
Translation vector from base to world:
[4.163336342344337e-17;9.71445146547012e-17;1.387778780781446e-17]
Rotation matrix from gripper to camera:
[1, 0, 0;0, 1, 0;0, 0, 1]
Translation vector from gripper to camera:
[-0.2;-0.1999999999999999;-0.2000000000000001]