calibrate_hand_eye T_calibrate_hand_eye CalibrateHandEye CalibrateHandEye calibrate_hand_eye (算子)
名称
calibrate_hand_eye T_calibrate_hand_eye CalibrateHandEye CalibrateHandEye calibrate_hand_eye — 执行手眼标定。
签名
def calibrate_hand_eye (calib_data_id : HHandle) -> Sequence[float]
描述
算子 calibrate_hand_eye calibrate_hand_eye CalibrateHandEye CalibrateHandEye CalibrateHandEye calibrate_hand_eye 基于标定数据模型 CalibDataID CalibDataID CalibDataID CalibDataID calibDataID calib_data_id ,确定机器人(“手”)相对于相机或三维传感器(“眼”)的三维姿态。通过确定的三维姿态,可将标定对象在相机坐标系中的姿态转换至机器人坐标系,从而实现如抓取被检部件等操作。机器人-相机(手眼)系统存在两种可能配置:相机可安装在机器人上,也可固定不动并观察机器人。需注意此处“机器人”一词泛指移动对象的机构,因此 calibrate_hand_eye calibrate_hand_eye CalibrateHandEye CalibrateHandEye CalibrateHandEye calibrate_hand_eye 可用于校准多种系统,从云台到多轴机械臂均适用。
本质上,适用于手眼标定的系统可由四次欧几里得变换构成的闭合链描述。在此链中,两个非连续变换要么由机器人控制器已知,要么通过相机数据计算得出(例如相机观测到的标定对象姿态)。两个未知常数变换则由手眼标定流程计算获得。
手眼标定与外部相机参数标定(参见 标定 )类似:获取标定对象在相机坐标系中的一组姿态,以及工具在机器人基座坐标系中对应的一组姿态,并将它们设置在标定数据模型 CalibDataID CalibDataID CalibDataID CalibDataID calibDataID calib_data_id 中。
与相机标定不同,标定对象无需人工移动。该任务由机器人完成。基本可区分两种手眼标定场景: 机器人可选择移动相机(移动相机模式)或移动标定对象(固定相机模式)。假设机器人的运动轨迹已知,这些运动数据将作为手眼标定的输入参数,通过 set_calib_data set_calib_data SetCalibData SetCalibData SetCalibData set_calib_data 算子设置在标定数据模型 CalibDataID CalibDataID CalibDataID CalibDataID calibDataID calib_data_id 中。
手眼标定的结果包含两个姿态:对于移动相机场景,计算出工具在相机坐标系中的三维姿态('tool_in_cam_pose' "tool_in_cam_pose" "tool_in_cam_pose" "tool_in_cam_pose" "tool_in_cam_pose" "tool_in_cam_pose" )以及标定对象在机器人基座坐标系中的三维姿态('obj_in_base_pose' "obj_in_base_pose" "obj_in_base_pose" "obj_in_base_pose" "obj_in_base_pose" "obj_in_base_pose" )。对于静止相机场景,计算相机坐标系中机器人基座的三维姿态('base_in_cam_pose' "base_in_cam_pose" "base_in_cam_pose" "base_in_cam_pose" "base_in_cam_pose" "base_in_cam_pose" )以及工具坐标系中标定对象的三维姿态('obj_in_tool_pose' "obj_in_tool_pose" "obj_in_tool_pose" "obj_in_tool_pose" "obj_in_tool_pose" "obj_in_tool_pose" )。其姿态类型与输入姿态的类型一致。若输入姿态类型不同,则返回类型为 0 的姿态。
下面将详细讨论两种手眼标定场景,随后介绍标定数据模型所需数据的通用信息及其准备工作。
移动相机(安装在机器人上)
在此配置中,标定对象保持静止。相机安装在机器人上,由机器人移动至不同位置。手眼标定的核心思想在于:通过观察标定对象所获取的信息(即标定对象相对于相机的姿态),可视为从标定对象经机器人底座至其工具(末端执行器),最终传递至相机的姿态链或齐次变换矩阵序列:
Moving camera: camera_H_cal = camera_H_tool * (base_H_tool)^(-1) * base_H_cal
| | | |
'obj_in_cam_pose' 'tool_in_cam_pose' 'tool_in_base_pose' 'obj_in_base_pose'
从标定对象姿态集合('obj_in_cam_pose' "obj_in_cam_pose" "obj_in_cam_pose" "obj_in_cam_pose" "obj_in_cam_pose" "obj_in_cam_pose" )和工具在机器人基座坐标系中的姿态('tool_in_base_pose' "tool_in_base_pose" "tool_in_base_pose" "tool_in_base_pose" "tool_in_base_pose" "tool_in_base_pose" )出发, 算子 calibrate_hand_eye calibrate_hand_eye CalibrateHandEye CalibrateHandEye CalibrateHandEye calibrate_hand_eye
可确定链末端两个缺失的变换:即机器人工具在相机坐标系中的姿态(
,
'tool_in_cam_pose' "tool_in_cam_pose" "tool_in_cam_pose" "tool_in_cam_pose" "tool_in_cam_pose" "tool_in_cam_pose" )以及标定对象在机器人基座坐标系中的姿态(
, 'obj_in_base_pose' "obj_in_base_pose" "obj_in_base_pose" "obj_in_base_pose" "obj_in_base_pose" "obj_in_base_pose" )。这两个姿态是恒定的。
相比之下,链中间的变换,
,虽已知但会随标定对象的每次观测而变化,因为它描述了工具相对于机器人基座坐标系的姿态。方程中使用的是逆变换矩阵,该逆变换在内部完成。
请注意,在校准 SCARA(Selective Compliance Assembly Robot Arm,选择性合规装配机器人手臂)机器人时,无法确定 'obj_in_base_pose' "obj_in_base_pose" "obj_in_base_pose" "obj_in_base_pose" "obj_in_base_pose" "obj_in_base_pose" 的 Z 向平移量。为消除此模糊性,系统内部将 'obj_in_base_pose' "obj_in_base_pose" "obj_in_base_pose" "obj_in_base_pose" "obj_in_base_pose" "obj_in_base_pose" 的 Z 向平移值设为 0.0,并据此计算 'tool_in_cam_pose' "tool_in_cam_pose" "tool_in_cam_pose" "tool_in_cam_pose" "tool_in_cam_pose" "tool_in_cam_pose" 。标定后需通过将机器人移动至相机坐标系中已知高度的位置来确定真实的 Z 轴平移量。为此可采用以下方法:将标定板放置于任意位置,随后移动机器人使相机能够观察到标定板. 此时采集标定板图像并查询当前机器人姿态(ToolInBasePose1 )。通过图像可确定标定板在相机坐标系中的姿态(ObjInCamPose1 )。随后手动将机器人工具移至标定板原点,再次查询机器人姿态(ToolInBasePose2 )。通过以下代码行,可利用这三个姿态与标定结果(ToolInCamPose )消除 Z 轴模糊性:
pose_invert(ToolInCamPose, CamInToolPose) pose_invert(ToolInCamPose, CamInToolPose) PoseInvert(ToolInCamPose, CamInToolPose) PoseInvert(ToolInCamPose, CamInToolPose) PoseInvert(ToolInCamPose, CamInToolPose) pose_invert(ToolInCamPose, CamInToolPose)
pose_compose(CamInToolPose, ObjInCamPose1, ObjInToolPose1) pose_compose(CamInToolPose, ObjInCamPose1, ObjInToolPose1) PoseCompose(CamInToolPose, ObjInCamPose1, ObjInToolPose1) PoseCompose(CamInToolPose, ObjInCamPose1, ObjInToolPose1) PoseCompose(CamInToolPose, ObjInCamPose1, ObjInToolPose1) pose_compose(CamInToolPose, ObjInCamPose1, ObjInToolPose1)
pose_invert(ToolInBasePose1, BaseInToolPose1) pose_invert(ToolInBasePose1, BaseInToolPose1) PoseInvert(ToolInBasePose1, BaseInToolPose1) PoseInvert(ToolInBasePose1, BaseInToolPose1) PoseInvert(ToolInBasePose1, BaseInToolPose1) pose_invert(ToolInBasePose1, BaseInToolPose1)
pose_compose(BaseInToolPose1, ToolInBasePose2, Tool2InTool1Pose) pose_compose(BaseInToolPose1, ToolInBasePose2, Tool2InTool1Pose) PoseCompose(BaseInToolPose1, ToolInBasePose2, Tool2InTool1Pose) PoseCompose(BaseInToolPose1, ToolInBasePose2, Tool2InTool1Pose) PoseCompose(BaseInToolPose1, ToolInBasePose2, Tool2InTool1Pose) pose_compose(BaseInToolPose1, ToolInBasePose2, Tool2InTool1Pose)
ZCorrection := ObjInToolPose1[2]-Tool2InTool1Pose[2]
set_origin_pose(ToolInCamPose, 0, 0, ZCorrection, ToolInCamPoseFinal) set_origin_pose(ToolInCamPose, 0, 0, ZCorrection, ToolInCamPoseFinal) SetOriginPose(ToolInCamPose, 0, 0, ZCorrection, ToolInCamPoseFinal) SetOriginPose(ToolInCamPose, 0, 0, ZCorrection, ToolInCamPoseFinal) SetOriginPose(ToolInCamPose, 0, 0, ZCorrection, ToolInCamPoseFinal) set_origin_pose(ToolInCamPose, 0, 0, ZCorrection, ToolInCamPoseFinal)
'optimization_method' "optimization_method" "optimization_method" "optimization_method" "optimization_method" "optimization_method" 'stochastic' "stochastic" "stochastic" "stochastic" "stochastic" "stochastic" 还估算观测值的不确定性。除上述输入姿态外,该方法还利用提取的标定标记,因此仅适用于配备相机和标定板的系统,不适用于三维传感器。对于关节式机器人,其手眼姿态与相机参数将同步优化。
固定摄像机
在此配置中,机器人抓取标定对象并将其移至相机前方。同样地,从标定对象观测中提取的信息——即标定对象在相机坐标系中的姿态(例如外部相机参数)——等同于姿态链或齐次变换矩阵,这次是从标定对象经由机器人工具传递至其基座,最终到达相机:
Stationary camera: camera_H_cal = camera_H_base * base_H_tool * tool_H_cal
| | | |
'obj_in_cam_pose' 'base_in_cam_pose' 'tool_in_base_pose' 'obj_in_tool_pose'
类似于移动相机的配置,算子通过
calibrate_hand_eye calibrate_hand_eye CalibrateHandEye CalibrateHandEye CalibrateHandEye calibrate_hand_eye 确定链两端的两个变换:即机器人底座坐标系在相机坐标系中的姿态(
,
'base_in_cam_pose' "base_in_cam_pose" "base_in_cam_pose" "base_in_cam_pose" "base_in_cam_pose" "base_in_cam_pose" ),以及标定对象相对于机器人工具的姿态(
,
'obj_in_tool_pose' "obj_in_tool_pose" "obj_in_tool_pose" "obj_in_tool_pose" "obj_in_tool_pose" "obj_in_tool_pose" )。
链中间的变换,
,描述了工具相对于机器人基座坐标系的姿态。
变换描述了标定对象相对于相机坐标系的姿态。
请注意,在校准 SCARA 机器人时,无法确定 'obj_in_tool_pose' "obj_in_tool_pose" "obj_in_tool_pose" "obj_in_tool_pose" "obj_in_tool_pose" "obj_in_tool_pose" 的 Z 向平移量。为消除此歧义,系统内部将 'obj_in_tool_pose' "obj_in_tool_pose" "obj_in_tool_pose" "obj_in_tool_pose" "obj_in_tool_pose" "obj_in_tool_pose" 的 Z 向平移量设为 0.0,并据此计算 'base_in_cam_pose' "base_in_cam_pose" "base_in_cam_pose" "base_in_cam_pose" "base_in_cam_pose" "base_in_cam_pose" 。标定后需通过将机器人移动至相机坐标系中已知高度的位置来确定真实的 Z 向平移量。为此可采用以下方法:将标定板(未安装在机器人上)放置于任意位置,确保相机可观察到该标定板。随后需确定标定板在相机坐标系中的姿态(ObjInCamPose )。随后手动将机器人工具移至标定板原点并获取机器人姿态(ToolInBasePose )。结合这两个姿态与标定结果(BaseInCamPose ),可通过以下代码行消除 Z 轴模糊性:
pose_invert(BaseInCamPose, CamInBasePose) pose_invert(BaseInCamPose, CamInBasePose) PoseInvert(BaseInCamPose, CamInBasePose) PoseInvert(BaseInCamPose, CamInBasePose) PoseInvert(BaseInCamPose, CamInBasePose) pose_invert(BaseInCamPose, CamInBasePose)
pose_compose(CamInBasePose, ObjInCamPose, ObjInBasePose) pose_compose(CamInBasePose, ObjInCamPose, ObjInBasePose) PoseCompose(CamInBasePose, ObjInCamPose, ObjInBasePose) PoseCompose(CamInBasePose, ObjInCamPose, ObjInBasePose) PoseCompose(CamInBasePose, ObjInCamPose, ObjInBasePose) pose_compose(CamInBasePose, ObjInCamPose, ObjInBasePose)
ZCorrection := ObjInBasePose[2]-ToolInBasePose[2]
set_origin_pose(BaseInCamPose, 0, 0, ZCorrection, BaseInCamPoseFinal) set_origin_pose(BaseInCamPose, 0, 0, ZCorrection, BaseInCamPoseFinal) SetOriginPose(BaseInCamPose, 0, 0, ZCorrection, BaseInCamPoseFinal) SetOriginPose(BaseInCamPose, 0, 0, ZCorrection, BaseInCamPoseFinal) SetOriginPose(BaseInCamPose, 0, 0, ZCorrection, BaseInCamPoseFinal) set_origin_pose(BaseInCamPose, 0, 0, ZCorrection, BaseInCamPoseFinal)
'optimization_method' "optimization_method" "optimization_method" "optimization_method" "optimization_method" "optimization_method" 'stochastic' "stochastic" "stochastic" "stochastic" "stochastic" "stochastic" 还估算观测值的不确定性。除上述输入姿态外,该方法还利用提取的标定标记,因此仅适用于配备相机和标定板的系统,不适用于三维传感器。对于关节式机器人,其手眼姿态与相机参数将同步优化。
准备标定输入数据
在调用 calibrate_hand_eye calibrate_hand_eye CalibrateHandEye CalibrateHandEye CalibrateHandEye calibrate_hand_eye 之前,必须通过以下步骤创建并填充标定数据模型:
创建标定数据模型 使用算子
create_calib_data create_calib_data CreateCalibData CreateCalibData CreateCalibData create_calib_data ,指定设置中的相机数量和使用的标定对象数量。根据具体场景,需将
CalibSetup CalibSetup CalibSetup CalibSetup calibSetup calib_setup 设置为 'hand_eye_moving_camera' "hand_eye_moving_camera" "hand_eye_moving_camera" "hand_eye_moving_camera" "hand_eye_moving_camera" "hand_eye_moving_camera" 、'hand_eye_stationary_camera' "hand_eye_stationary_camera" "hand_eye_stationary_camera" "hand_eye_stationary_camera" "hand_eye_stationary_camera" "hand_eye_stationary_camera" 、'hand_eye_scara_moving_camera' "hand_eye_scara_moving_camera" "hand_eye_scara_moving_camera" "hand_eye_scara_moving_camera" "hand_eye_scara_moving_camera" "hand_eye_scara_moving_camera" 或 'hand_eye_scara_stationary_camera' "hand_eye_scara_stationary_camera" "hand_eye_scara_stationary_camera" "hand_eye_scara_stationary_camera" "hand_eye_scara_stationary_camera" "hand_eye_scara_stationary_camera" 。这四种场景一方面区分机器人移动相机还是标定对象,另一方面区分标准的是关节式机器人还是 SCARA 机器人。关节式机器人的机械臂通常具有三个旋转关节,覆盖 6 个自由度(3 个平移和 3 个旋转)。SCARA 机器人则由两个平行旋转关节和一个平行平移关节构成,仅具备 4 自由度(3 个平移和 1 旋转)。简言之,关节式机器人可实现末端执行器的俯仰动作,而 SCARA 机器人不具备此功能。
指定优化方法 使用算子
set_calib_data set_calib_data SetCalibData SetCalibData SetCalibData set_calib_data 。对于参数
DataName DataName DataName DataName dataName data_name ='optimization_method' "optimization_method" "optimization_method" "optimization_method" "optimization_method" "optimization_method" ,
DataValue DataValue DataValue DataValue dataValue data_value ,DataValue 提供三种选项:DataValue DataValue DataValue DataValue dataValue data_value ='linear' "linear" "linear" "linear" "linear" "linear" 、DataValue DataValue DataValue DataValue dataValue data_value ='nonlinear' "nonlinear" "nonlinear" "nonlinear" "nonlinear" "nonlinear"
和 DataValue DataValue DataValue DataValue dataValue data_value ='stochastic' "stochastic" "stochastic" "stochastic" "stochastic" "stochastic"
(参见段落“执行实际手眼标定”)。
指定标定对象的姿势
对于标定对象的每次观测,可直接使用
set_calib_data_observ_pose set_calib_data_observ_pose SetCalibDataObservPose SetCalibDataObservPose SetCalibDataObservPose set_calib_data_observ_pose 算子设置三维姿态。该算子旨在配合通用三维传感器使用,用于观测标定对象。
标定对象的姿态也可通过相机图像进行估计。需通过 set_calib_data_calib_object set_calib_data_calib_object SetCalibDataCalibObject SetCalibDataCalibObject SetCalibDataCalibObject set_calib_data_calib_object 算子将标定对象设置至标定数据模型 CalibDataID CalibDataID CalibDataID CalibDataID calibDataID calib_data_id 中。初始相机参数须通过 set_calib_data_cam_param set_calib_data_cam_param SetCalibDataCamParam SetCalibDataCamParam SetCalibDataCamParam set_calib_data_cam_param 算子设定。若使用标准 HALCON 标定板,
find_calib_object find_calib_object FindCalibObject FindCalibObject FindCalibObject find_calib_object 算子将确定标定板相对于相机的姿态,并将其保存至标定数据模型 CalibDataID CalibDataID CalibDataID CalibDataID calibDataID calib_data_id 。
在此情况下,用于关节式(即非SCARA)机器人的 calibrate_hand_eye calibrate_hand_eye CalibrateHandEye CalibrateHandEye CalibrateHandEye calibrate_hand_eye 算子会在执行手眼标定前先校准相机。若将 'optimization_method' "optimization_method" "optimization_method" "optimization_method" "optimization_method" "optimization_method" 设为 'stochastic' "stochastic" "stochastic" "stochastic" "stochastic" "stochastic" ,则会同时优化手眼姿态与相机参数。若提供的相机参数已完成校准,可通过调用
set_calib_data(CalibDataID,'camera','general','excluded_settings','params') set_calib_data(CalibDataID,"camera","general","excluded_settings","params") SetCalibData(CalibDataID,"camera","general","excluded_settings","params") SetCalibData(CalibDataID,"camera","general","excluded_settings","params") SetCalibData(CalibDataID,"camera","general","excluded_settings","params") set_calib_data(CalibDataID,"camera","general","excluded_settings","params") 关闭相机标定功能。
相比之下,对于SCARA机器人,calibrate_hand_eye calibrate_hand_eye CalibrateHandEye CalibrateHandEye CalibrateHandEye calibrate_hand_eye 始终假设提供的相机参数已经完成校准。因此在此情况下,手眼标定过程中不会自动执行内部相机标定。这是因为若不大幅倾斜标定板相对于相机的角度,则无法可靠地校准内部相机参数。在手眼标定中,标定板通常与成像平面大致平行。因此对于 SCARA 机器人,所有相机姿态均近似平行。故必须事先使用另一组标定图像对相机进行校准。
指定工具的位置姿态 在机器人基座坐标系中。对于标定对象在相机坐标系中的每个姿态,需通过算子
set_calib_data(CalibDataID,'tool', PoseNumber, 'tool_in_base_pose', ToolInBasePose) set_calib_data(CalibDataID,"tool", PoseNumber, "tool_in_base_pose", ToolInBasePose) SetCalibData(CalibDataID,"tool", PoseNumber, "tool_in_base_pose", ToolInBasePose) SetCalibData(CalibDataID,"tool", PoseNumber, "tool_in_base_pose", ToolInBasePose) SetCalibData(CalibDataID,"tool", PoseNumber, "tool_in_base_pose", ToolInBasePose) set_calib_data(CalibDataID,"tool", PoseNumber, "tool_in_base_pose", ToolInBasePose) 在机器人基座坐标系中设置对应的工具姿态。
执行实际的手眼标定
算子 calibrate_hand_eye calibrate_hand_eye CalibrateHandEye CalibrateHandEye CalibrateHandEye calibrate_hand_eye 可通过三种不同方式执行标定。所有情况下,均使用相机坐标系中提供的所有标定对象姿态及其在机器人基座坐标系中的对应工具姿态进行标定。其中 'stochastic' "stochastic" "stochastic" "stochastic" "stochastic" "stochastic"
方法还需使用提取的标定标记,因此仅适用于配备相机和标定板的场景,不适用于三维传感器。具体使用方法需通过 set_calib_data set_calib_data SetCalibData SetCalibData SetCalibData set_calib_data 进行指定。
对于参数组合
DataName DataName DataName DataName dataName data_name ='optimization_method' "optimization_method" "optimization_method" "optimization_method" "optimization_method" "optimization_method" 和
DataValue DataValue DataValue DataValue dataValue data_value ='linear' "linear" "linear" "linear" "linear" "linear" ,标定采用线性算法进行,该算法速度快,但在许多实际情况下不够精确。
对于参数
DataName DataName DataName DataName dataName data_name ='optimization_method' "optimization_method" "optimization_method" "optimization_method" "optimization_method" "optimization_method" 和
DataValue DataValue DataValue DataValue dataValue data_value ='nonlinear' "nonlinear" "nonlinear" "nonlinear" "nonlinear" "nonlinear" 的情况,标定采用非线性算法进行,从而获得更精确的姿态校准结果。
对于参数
DataName DataName DataName DataName dataName data_name ='optimization_method' "optimization_method" "optimization_method" "optimization_method" "optimization_method" "optimization_method" 和
DataValue DataValue DataValue DataValue dataValue data_value ='stochastic' "stochastic" "stochastic" "stochastic" "stochastic" "stochastic" ,标定算法对所有测量观测值(包括输入机器人姿态)的不确定性进行建模,从而获得更稳健的手眼姿态校准结果。使用的输入姿态越多,估计精度越高。但该方法仅适用于配备相机和标定板的系统,不适用于三维传感器。对于关节式机器人,手眼姿态与相机参数将同步优化。
检查标定是否成功
算子 calibrate_hand_eye calibrate_hand_eye CalibrateHandEye CalibrateHandEye CalibrateHandEye calibrate_hand_eye 将整个变换链的姿态误差存储在 Errors Errors Errors Errors errors errors 中返回。更精确地说,它返回一个包含四个元素的元组:第一个元素是平移部分的均方根误差,第二个元素是旋转部分的均方根误差,第三个元素是最大平移误差,第四个元素是最大旋转误差。通过这些误差指标,可判断标定是否成功。
Errors Errors Errors Errors errors errors 的返回单位与输入姿态的单位一致,即平移误差通常以米为单位,而旋转误差始终以度为单位。
若将 'optimization_method' "optimization_method" "optimization_method" "optimization_method" "optimization_method" "optimization_method" 设为 'stochastic' "stochastic" "stochastic" "stochastic" "stochastic" "stochastic" ,可通过
get_calib_data get_calib_data GetCalibData GetCalibData GetCalibData get_calib_data 获取
'hand_eye_calib_error_corrected_tool' "hand_eye_calib_error_corrected_tool" "hand_eye_calib_error_corrected_tool" "hand_eye_calib_error_corrected_tool" "hand_eye_calib_error_corrected_tool" "hand_eye_calib_error_corrected_tool" 。该工具与
Errors Errors Errors Errors errors errors 的区别仅在于:它使用修正后的机器人工具姿态而非输入的原始姿态。
对于关节机器人,可通过 get_calib_data get_calib_data GetCalibData GetCalibData GetCalibData get_calib_data 获取相机标定的 'camera_calib_error' "camera_calib_error" "camera_calib_error" "camera_calib_error" "camera_calib_error" "camera_calib_error" 参数,该值表示标定标记中心点直接反向投影至相机图像时的均方根误差(RMSE)。若 'optimization_method' "optimization_method" "optimization_method" "optimization_method" "optimization_method" "optimization_method" 参数设置为 'stochastic' "stochastic" "stochastic" "stochastic" "stochastic" "stochastic" ,则
'camera_calib_error_corrected_tool' "camera_calib_error_corrected_tool" "camera_calib_error_corrected_tool" "camera_calib_error_corrected_tool" "camera_calib_error_corrected_tool" "camera_calib_error_corrected_tool" 将通过姿态链利用修正后的工具姿态返回反向投影误差。
获取标定结果
通过 calibrate_hand_eye calibrate_hand_eye CalibrateHandEye CalibrateHandEye CalibrateHandEye calibrate_hand_eye
算子计算出的姿态可使用 get_calib_data get_calib_data GetCalibData GetCalibData GetCalibData get_calib_data 进行查询。在移动相机场景中,可获取工具在相机坐标系中的三维姿态('tool_in_cam_pose' "tool_in_cam_pose" "tool_in_cam_pose" "tool_in_cam_pose" "tool_in_cam_pose" "tool_in_cam_pose" )以及标定对象在机器人基座坐标系中的三维姿态('obj_in_base_pose' "obj_in_base_pose" "obj_in_base_pose" "obj_in_base_pose" "obj_in_base_pose" "obj_in_base_pose" )。对于静止相机场景,可获取机器人基座在相机坐标系中的三维姿态('base_in_cam_pose' "base_in_cam_pose" "base_in_cam_pose" "base_in_cam_pose" "base_in_cam_pose" "base_in_cam_pose" )以及标定对象在工具坐标系中的三维姿态('obj_in_tool_pose' "obj_in_tool_pose" "obj_in_tool_pose" "obj_in_tool_pose" "obj_in_tool_pose" "obj_in_tool_pose" )。
查询输入数据
若标定对象相对于相机的姿态是通过 find_calib_object find_calib_object FindCalibObject FindCalibObject FindCalibObject find_calib_object 计算得出,则对于关节式(即非 SCARA)机器人,这些姿态将在手眼标定前的内部相机标定步骤中被使用并同步校准。当 'optimization_method' "optimization_method" "optimization_method" "optimization_method" "optimization_method" "optimization_method" 设为 'stochastic' "stochastic" "stochastic" "stochastic" "stochastic" "stochastic" 时,手眼姿态与相机参数将同步优化,随后标定对象的姿态会根据最终生成的相机参数进行更新。校准后的三维姿态可通过 get_calib_data get_calib_data GetCalibData GetCalibData GetCalibData get_calib_data
算子查询,参数 ItemType ItemType ItemType ItemType itemType item_type ='calib_obj_pose' "calib_obj_pose" "calib_obj_pose" "calib_obj_pose" "calib_obj_pose" "calib_obj_pose" 即可获取。
若标定对象的姿态是由通用三维传感器观测所得,则无法进行校准,需通过 set_calib_data_observ_pose set_calib_data_observ_pose SetCalibDataObservPose SetCalibDataObservPose SetCalibDataObservPose set_calib_data_observ_pose 进行设置。这些原始三维姿态可通过 get_calib_data_observ_pose get_calib_data_observ_pose GetCalibDataObservPose GetCalibDataObservPose GetCalibDataObservPose get_calib_data_observ_pose 进行查询。
可通过 get_calib_data get_calib_data GetCalibData GetCalibData GetCalibData get_calib_data 算子查询工具在机器人基座坐标系中的对应三维姿态。
获取一组合适的观测数据
以下条件,特别是使用标准标定板时,应予以考虑:
在不同标定姿态之间,标定对象的位置(移动相机:相对于机器人的基座;固定相机:相对于机器人的工具)和相机的位置(移动相机:相对于机器人的工具;固定相机:相对于机器人的基座)均不得改变。
尽管理论上最低可使用三个标定对象姿态,但建议采集 10 个或更多姿态,其中相机或机械臂的姿态应存在显著差异。若将 'optimization_method' "optimization_method" "optimization_method" "optimization_method" "optimization_method" "optimization_method"
设为 'stochastic' "stochastic" "stochastic" "stochastic" "stochastic" "stochastic" ,则至少需要 25 个姿态。使用的姿态越多,估计精度越高。
对于关节式(即非 SCARA)机器人,标定对象姿态之间的旋转幅度至关重要,应至少达到 30 度,更佳为 60 度。姿态间的旋转必须涉及至少两个不同的旋转轴。姿态方向差异越大,手眼标定的结果就越精确。SCARA 机器人仅需一个旋转轴。图像间的旋转幅度也应足够大。
对于相机而言,在标定过程中及标定之后,相机内部参数必须保持恒定。请注意,图像尺寸、焦距、光圈或焦点的改变都会导致相机内部参数发生变化。
如前所述,在采集单张图像期间不得对相机进行任何调整。请确保对焦能力足以应对相机与标定板之间距离的预期变化。因此,标定板需置于明亮的照明环境中,这样便可使用更小的光圈,从而获得更大的景深。
获取机器人工具的姿态
我们建议在独立程序中创建机器人姿态,并使用 write_pose write_pose WritePose WritePose WritePose write_pose 算子将其保存为文件。随后可在标定程序中导入这些姿态,并将其设置在标定数据模型 CalibDataID CalibDataID CalibDataID CalibDataID calibDataID calib_data_id 中。
通过机器人的笛卡尔接口,通常可以以与代码 0 或 2 对应的姿态表示法(OrderOfRotation OrderOfRotation OrderOfRotation OrderOfRotation orderOfRotation order_of_rotation =
'gba' "gba" "gba" "gba" "gba" "gba" 或 'abg' "abg" "abg" "abg" "abg" "abg" ,参见 create_pose create_pose CreatePose CreatePose CreatePose create_pose )获取工具在机器人基座坐标系中的姿态。此时,可直接将从机器人获取的姿态值作为
create_pose create_pose CreatePose CreatePose CreatePose create_pose 输入。
如果您的机器人的笛卡尔接口采用不同方式描述方向,例如使用 ZYZ (
) 表示法,则可通过逐步调用 hom_mat3d_rotate hom_mat3d_rotate HomMat3dRotate HomMat3dRotate HomMat3dRotate hom_mat3d_rotate 和 hom_mat3d_translate hom_mat3d_translate HomMat3dTranslate HomMat3dTranslate HomMat3dTranslate hom_mat3d_translate 算子创建对应的齐次变换矩阵,再使用 hom_mat3d_to_pose hom_mat3d_to_pose HomMat3dToPose HomMat3dToPose HomMat3dToPose hom_mat3d_to_pose 将结果矩阵转换为姿态。以下示例代码演示如何从上述 ZYZ 表示法生成姿态:
hom_mat3d_identity(HomMat3DIdent) hom_mat3d_identity(HomMat3DIdent) HomMat3dIdentity(HomMat3DIdent) HomMat3dIdentity(HomMat3DIdent) HomMat3dIdentity(HomMat3DIdent) hom_mat3d_identity(HomMat3DIdent)
hom_mat3d_rotate(HomMat3DIdent, phi3, 'z', 0, 0, 0, HomMat3DRotZ) hom_mat3d_rotate(HomMat3DIdent, phi3, "z", 0, 0, 0, HomMat3DRotZ) HomMat3dRotate(HomMat3DIdent, phi3, "z", 0, 0, 0, HomMat3DRotZ) HomMat3dRotate(HomMat3DIdent, phi3, "z", 0, 0, 0, HomMat3DRotZ) HomMat3dRotate(HomMat3DIdent, phi3, "z", 0, 0, 0, HomMat3DRotZ) hom_mat3d_rotate(HomMat3DIdent, phi3, "z", 0, 0, 0, HomMat3DRotZ)
hom_mat3d_rotate(HomMat3DRotZ, phi2, 'y', 0, 0, 0, HomMat3DRotZY) hom_mat3d_rotate(HomMat3DRotZ, phi2, "y", 0, 0, 0, HomMat3DRotZY) HomMat3dRotate(HomMat3DRotZ, phi2, "y", 0, 0, 0, HomMat3DRotZY) HomMat3dRotate(HomMat3DRotZ, phi2, "y", 0, 0, 0, HomMat3DRotZY) HomMat3dRotate(HomMat3DRotZ, phi2, "y", 0, 0, 0, HomMat3DRotZY) hom_mat3d_rotate(HomMat3DRotZ, phi2, "y", 0, 0, 0, HomMat3DRotZY)
hom_mat3d_rotate(HomMat3DRotZY, phi1, 'z', 0, 0, 0, HomMat3DRotZYZ) hom_mat3d_rotate(HomMat3DRotZY, phi1, "z", 0, 0, 0, HomMat3DRotZYZ) HomMat3dRotate(HomMat3DRotZY, phi1, "z", 0, 0, 0, HomMat3DRotZYZ) HomMat3dRotate(HomMat3DRotZY, phi1, "z", 0, 0, 0, HomMat3DRotZYZ) HomMat3dRotate(HomMat3DRotZY, phi1, "z", 0, 0, 0, HomMat3DRotZYZ) hom_mat3d_rotate(HomMat3DRotZY, phi1, "z", 0, 0, 0, HomMat3DRotZYZ)
hom_mat3d_translate(HomMat3DRotZYZ, Tx, Ty, Tz, base_H_tool) hom_mat3d_translate(HomMat3DRotZYZ, Tx, Ty, Tz, base_H_tool) HomMat3dTranslate(HomMat3DRotZYZ, Tx, Ty, Tz, base_H_tool) HomMat3dTranslate(HomMat3DRotZYZ, Tx, Ty, Tz, base_H_tool) HomMat3dTranslate(HomMat3DRotZYZ, Tx, Ty, Tz, base_H_tool) hom_mat3d_translate(HomMat3DRotZYZ, Tx, Ty, Tz, base_H_tool)
hom_mat3d_to_pose(base_H_tool, RobPose) hom_mat3d_to_pose(base_H_tool, RobPose) HomMat3dToPose(base_H_tool, RobPose) HomMat3dToPose(base_H_tool, RobPose) HomMat3dToPose(base_H_tool, RobPose) hom_mat3d_to_pose(base_H_tool, RobPose)
请注意,手眼标定仅在工具在机器人基座坐标系中的姿态以高精度指定时才有效。在提供的各种方法中,将 'optimization_method' "optimization_method" "optimization_method" "optimization_method" "optimization_method" "optimization_method" 设置为 'stochastic' "stochastic" "stochastic" "stochastic" "stochastic" "stochastic"
将针对工具在机器人基座坐标系中姿态的噪声产生最稳健的结果。使用的输入姿态越多,估计结果就越准确。
请注意,当 'optimization_method' "optimization_method" "optimization_method" "optimization_method" "optimization_method" "optimization_method" 设置为 'stochastic' "stochastic" "stochastic" "stochastic" "stochastic" "stochastic" 时,此算子支持取消超时和中断。
执行信息
多线程类型:可重入(与非独占算子并行运行)。
多线程作用域:全局(可从任何线程调用)。
在内部数据级别上自动并行化。
此算子支持取消超时和中断。
此算子修改后续输入参数的状态:
在执行此算子时,若该参数值需在多个线程间使用,则必须对其访问进行同步。
参数
CalibDataID CalibDataID CalibDataID CalibDataID calibDataID calib_data_id (输入控制,状态被修改) calib_data → HCalibData , HTuple HHandle HTuple Htuple (handle) (IntPtr ) (HHandle ) (handle )
标定数据模型的句柄。
Errors Errors Errors Errors errors errors (输出控制) number-array → HTuple Sequence[float] HTuple Htuple (real) (double ) (double ) (double )
优化过程中的平均残差误差。
可能的前趋
create_calib_data create_calib_data CreateCalibData CreateCalibData CreateCalibData create_calib_data ,
set_calib_data_cam_param set_calib_data_cam_param SetCalibDataCamParam SetCalibDataCamParam SetCalibDataCamParam set_calib_data_cam_param ,
set_calib_data_calib_object set_calib_data_calib_object SetCalibDataCalibObject SetCalibDataCalibObject SetCalibDataCalibObject set_calib_data_calib_object ,
set_calib_data_observ_pose set_calib_data_observ_pose SetCalibDataObservPose SetCalibDataObservPose SetCalibDataObservPose set_calib_data_observ_pose ,
find_calib_object find_calib_object FindCalibObject FindCalibObject FindCalibObject find_calib_object ,
set_calib_data set_calib_data SetCalibData SetCalibData SetCalibData set_calib_data ,
remove_calib_data remove_calib_data RemoveCalibData RemoveCalibData RemoveCalibData remove_calib_data ,
remove_calib_data_observ remove_calib_data_observ RemoveCalibDataObserv RemoveCalibDataObserv RemoveCalibDataObserv remove_calib_data_observ
可能的后继
get_calib_data get_calib_data GetCalibData GetCalibData GetCalibData get_calib_data
参考文献
K. Daniilidis: “Hand-Eye Calibration Using Dual Quaternions”;
International Journal of Robotics Research, Vol. 18, No. 3,
pp. 286-298; 1999.
M. Ulrich, C. Steger: “Hand-Eye Calibration of SCARA Robots Using Dual
Quaternions”; Pattern Recognition and Image Analysis, Vol. 26, No. 1,
pp. 231-239; January 2016.
M. Ulrich, M. Hillemann: “Generic Hand–Eye Calibration of Uncertain
Robots”; 2021 IEEE International Conference on Robotics and
Automation (ICRA), pp. 11060-11066; 2021.
模块
标定