calibrate_hand_eyeT_calibrate_hand_eyeCalibrateHandEyeCalibrateHandEyecalibrate_hand_eye(算子)

名称

calibrate_hand_eyeT_calibrate_hand_eyeCalibrateHandEyeCalibrateHandEyecalibrate_hand_eye — 执行手眼标定。

签名

calibrate_hand_eye( : : CalibDataID : Errors)

Herror T_calibrate_hand_eye(const Htuple CalibDataID, Htuple* Errors)

void CalibrateHandEye(const HTuple& CalibDataID, HTuple* Errors)

HTuple HCalibData::CalibrateHandEye() const

static void HOperatorSet.CalibrateHandEye(HTuple calibDataID, out HTuple errors)

HTuple HCalibData.CalibrateHandEye()

def calibrate_hand_eye(calib_data_id: HHandle) -> Sequence[float]

描述

算子 calibrate_hand_eyecalibrate_hand_eyeCalibrateHandEyeCalibrateHandEyeCalibrateHandEyecalibrate_hand_eye 基于标定数据模型 CalibDataIDCalibDataIDCalibDataIDCalibDataIDcalibDataIDcalib_data_id,确定机器人(“手”)相对于相机或三维传感器(“眼”)的三维姿态。通过确定的三维姿态,可将标定对象在相机坐标系中的姿态转换至机器人坐标系,从而实现如抓取被检部件等操作。机器人-相机(手眼)系统存在两种可能配置:相机可安装在机器人上,也可固定不动并观察机器人。需注意此处“机器人”一词泛指移动对象的机构,因此 calibrate_hand_eyecalibrate_hand_eyeCalibrateHandEyeCalibrateHandEyeCalibrateHandEyecalibrate_hand_eye 可用于校准多种系统,从云台到多轴机械臂均适用。

本质上,适用于手眼标定的系统可由四次欧几里得变换构成的闭合链描述。在此链中,两个非连续变换要么由机器人控制器已知,要么通过相机数据计算得出(例如相机观测到的标定对象姿态)。两个未知常数变换则由手眼标定流程计算获得。

手眼标定与外部相机参数标定(参见 标定)类似:获取标定对象在相机坐标系中的一组姿态,以及工具在机器人基座坐标系中对应的一组姿态,并将它们设置在标定数据模型 CalibDataIDCalibDataIDCalibDataIDCalibDataIDcalibDataIDcalib_data_id 中。

与相机标定不同,标定对象无需人工移动。该任务由机器人完成。基本可区分两种手眼标定场景: 机器人可选择移动相机(移动相机模式)或移动标定对象(固定相机模式)。假设机器人的运动轨迹已知,这些运动数据将作为手眼标定的输入参数,通过 set_calib_dataset_calib_dataSetCalibDataSetCalibDataSetCalibDataset_calib_data 算子设置在标定数据模型 CalibDataIDCalibDataIDCalibDataIDCalibDataIDcalibDataIDcalib_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_eyecalibrate_hand_eyeCalibrateHandEyeCalibrateHandEyeCalibrateHandEyecalibrate_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_eyecalibrate_hand_eyeCalibrateHandEyeCalibrateHandEyeCalibrateHandEyecalibrate_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_eyecalibrate_hand_eyeCalibrateHandEyeCalibrateHandEyeCalibrateHandEyecalibrate_hand_eye 之前,必须通过以下步骤创建并填充标定数据模型:

  1. 创建标定数据模型使用算子 create_calib_datacreate_calib_dataCreateCalibDataCreateCalibDataCreateCalibDatacreate_calib_data,指定设置中的相机数量和使用的标定对象数量。根据具体场景,需将 CalibSetupCalibSetupCalibSetupCalibSetupcalibSetupcalib_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 机器人不具备此功能。

  2. 指定优化方法使用算子 set_calib_dataset_calib_dataSetCalibDataSetCalibDataSetCalibDataset_calib_data。对于参数 DataNameDataNameDataNameDataNamedataNamedata_name='optimization_method'"optimization_method""optimization_method""optimization_method""optimization_method""optimization_method"DataValueDataValueDataValueDataValuedataValuedata_value,DataValue 提供三种选项:DataValueDataValueDataValueDataValuedataValuedata_value='linear'"linear""linear""linear""linear""linear"DataValueDataValueDataValueDataValuedataValuedata_value='nonlinear'"nonlinear""nonlinear""nonlinear""nonlinear""nonlinear"DataValueDataValueDataValueDataValuedataValuedata_value='stochastic'"stochastic""stochastic""stochastic""stochastic""stochastic" (参见段落“执行实际手眼标定”)。

  3. 指定标定对象的姿势

    1. 对于标定对象的每次观测,可直接使用 set_calib_data_observ_poseset_calib_data_observ_poseSetCalibDataObservPoseSetCalibDataObservPoseSetCalibDataObservPoseset_calib_data_observ_pose 算子设置三维姿态。该算子旨在配合通用三维传感器使用,用于观测标定对象。

    2. 标定对象的姿态也可通过相机图像进行估计。需通过 set_calib_data_calib_objectset_calib_data_calib_objectSetCalibDataCalibObjectSetCalibDataCalibObjectSetCalibDataCalibObjectset_calib_data_calib_object 算子将标定对象设置至标定数据模型 CalibDataIDCalibDataIDCalibDataIDCalibDataIDcalibDataIDcalib_data_id 中。初始相机参数须通过 set_calib_data_cam_paramset_calib_data_cam_paramSetCalibDataCamParamSetCalibDataCamParamSetCalibDataCamParamset_calib_data_cam_param 算子设定。若使用标准 HALCON 标定板, find_calib_objectfind_calib_objectFindCalibObjectFindCalibObjectFindCalibObjectfind_calib_object 算子将确定标定板相对于相机的姿态,并将其保存至标定数据模型 CalibDataIDCalibDataIDCalibDataIDCalibDataIDcalibDataIDcalib_data_id

      在此情况下,用于关节式(即非SCARA)机器人的 calibrate_hand_eyecalibrate_hand_eyeCalibrateHandEyeCalibrateHandEyeCalibrateHandEyecalibrate_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_eyecalibrate_hand_eyeCalibrateHandEyeCalibrateHandEyeCalibrateHandEyecalibrate_hand_eye 始终假设提供的相机参数已经完成校准。因此在此情况下,手眼标定过程中不会自动执行内部相机标定。这是因为若不大幅倾斜标定板相对于相机的角度,则无法可靠地校准内部相机参数。在手眼标定中,标定板通常与成像平面大致平行。因此对于 SCARA 机器人,所有相机姿态均近似平行。故必须事先使用另一组标定图像对相机进行校准。

  4. 指定工具的位置姿态 在机器人基座坐标系中。对于标定对象在相机坐标系中的每个姿态,需通过算子 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_eyecalibrate_hand_eyeCalibrateHandEyeCalibrateHandEyeCalibrateHandEyecalibrate_hand_eye 可通过三种不同方式执行标定。所有情况下,均使用相机坐标系中提供的所有标定对象姿态及其在机器人基座坐标系中的对应工具姿态进行标定。其中 'stochastic'"stochastic""stochastic""stochastic""stochastic""stochastic" 方法还需使用提取的标定标记,因此仅适用于配备相机和标定板的场景,不适用于三维传感器。具体使用方法需通过 set_calib_dataset_calib_dataSetCalibDataSetCalibDataSetCalibDataset_calib_data 进行指定。

对于参数组合 DataNameDataNameDataNameDataNamedataNamedata_name='optimization_method'"optimization_method""optimization_method""optimization_method""optimization_method""optimization_method"DataValueDataValueDataValueDataValuedataValuedata_value='linear'"linear""linear""linear""linear""linear",标定采用线性算法进行,该算法速度快,但在许多实际情况下不够精确。

对于参数 DataNameDataNameDataNameDataNamedataNamedata_name='optimization_method'"optimization_method""optimization_method""optimization_method""optimization_method""optimization_method"DataValueDataValueDataValueDataValuedataValuedata_value='nonlinear'"nonlinear""nonlinear""nonlinear""nonlinear""nonlinear" 的情况,标定采用非线性算法进行,从而获得更精确的姿态校准结果。

对于参数 DataNameDataNameDataNameDataNamedataNamedata_name='optimization_method'"optimization_method""optimization_method""optimization_method""optimization_method""optimization_method"DataValueDataValueDataValueDataValuedataValuedata_value='stochastic'"stochastic""stochastic""stochastic""stochastic""stochastic",标定算法对所有测量观测值(包括输入机器人姿态)的不确定性进行建模,从而获得更稳健的手眼姿态校准结果。使用的输入姿态越多,估计精度越高。但该方法仅适用于配备相机和标定板的系统,不适用于三维传感器。对于关节式机器人,手眼姿态与相机参数将同步优化。

检查标定是否成功

算子 calibrate_hand_eyecalibrate_hand_eyeCalibrateHandEyeCalibrateHandEyeCalibrateHandEyecalibrate_hand_eye 将整个变换链的姿态误差存储在 ErrorsErrorsErrorsErrorserrorserrors 中返回。更精确地说,它返回一个包含四个元素的元组:第一个元素是平移部分的均方根误差,第二个元素是旋转部分的均方根误差,第三个元素是最大平移误差,第四个元素是最大旋转误差。通过这些误差指标,可判断标定是否成功。

ErrorsErrorsErrorsErrorserrorserrors 的返回单位与输入姿态的单位一致,即平移误差通常以米为单位,而旋转误差始终以度为单位。

若将 'optimization_method'"optimization_method""optimization_method""optimization_method""optimization_method""optimization_method" 设为 'stochastic'"stochastic""stochastic""stochastic""stochastic""stochastic",可通过 get_calib_dataget_calib_dataGetCalibDataGetCalibDataGetCalibDataget_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"。该工具与 ErrorsErrorsErrorsErrorserrorserrors 的区别仅在于:它使用修正后的机器人工具姿态而非输入的原始姿态。

对于关节机器人,可通过 get_calib_dataget_calib_dataGetCalibDataGetCalibDataGetCalibDataget_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_eyecalibrate_hand_eyeCalibrateHandEyeCalibrateHandEyeCalibrateHandEyecalibrate_hand_eye 算子计算出的姿态可使用 get_calib_dataget_calib_dataGetCalibDataGetCalibDataGetCalibDataget_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_objectfind_calib_objectFindCalibObjectFindCalibObjectFindCalibObjectfind_calib_object 计算得出,则对于关节式(即非 SCARA)机器人,这些姿态将在手眼标定前的内部相机标定步骤中被使用并同步校准。当 'optimization_method'"optimization_method""optimization_method""optimization_method""optimization_method""optimization_method" 设为 'stochastic'"stochastic""stochastic""stochastic""stochastic""stochastic" 时,手眼姿态与相机参数将同步优化,随后标定对象的姿态会根据最终生成的相机参数进行更新。校准后的三维姿态可通过 get_calib_dataget_calib_dataGetCalibDataGetCalibDataGetCalibDataget_calib_data 算子查询,参数 ItemTypeItemTypeItemTypeItemTypeitemTypeitem_type='calib_obj_pose'"calib_obj_pose""calib_obj_pose""calib_obj_pose""calib_obj_pose""calib_obj_pose" 即可获取。

若标定对象的姿态是由通用三维传感器观测所得,则无法进行校准,需通过 set_calib_data_observ_poseset_calib_data_observ_poseSetCalibDataObservPoseSetCalibDataObservPoseSetCalibDataObservPoseset_calib_data_observ_pose 进行设置。这些原始三维姿态可通过 get_calib_data_observ_poseget_calib_data_observ_poseGetCalibDataObservPoseGetCalibDataObservPoseGetCalibDataObservPoseget_calib_data_observ_pose 进行查询。

可通过 get_calib_dataget_calib_dataGetCalibDataGetCalibDataGetCalibDataget_calib_data 算子查询工具在机器人基座坐标系中的对应三维姿态。

获取一组合适的观测数据

以下条件,特别是使用标准标定板时,应予以考虑:

获取机器人工具的姿态

我们建议在独立程序中创建机器人姿态,并使用 write_posewrite_poseWritePoseWritePoseWritePosewrite_pose 算子将其保存为文件。随后可在标定程序中导入这些姿态,并将其设置在标定数据模型 CalibDataIDCalibDataIDCalibDataIDCalibDataIDcalibDataIDcalib_data_id 中。

通过机器人的笛卡尔接口,通常可以以与代码 0 或 2 对应的姿态表示法(OrderOfRotationOrderOfRotationOrderOfRotationOrderOfRotationorderOfRotationorder_of_rotation = 'gba'"gba""gba""gba""gba""gba"'abg'"abg""abg""abg""abg""abg",参见 create_posecreate_poseCreatePoseCreatePoseCreatePosecreate_pose)获取工具在机器人基座坐标系中的姿态。此时,可直接将从机器人获取的姿态值作为 create_posecreate_poseCreatePoseCreatePoseCreatePosecreate_pose 输入。

如果您的机器人的笛卡尔接口采用不同方式描述方向,例如使用 ZYZ ( ) 表示法,则可通过逐步调用 hom_mat3d_rotatehom_mat3d_rotateHomMat3dRotateHomMat3dRotateHomMat3dRotatehom_mat3d_rotatehom_mat3d_translatehom_mat3d_translateHomMat3dTranslateHomMat3dTranslateHomMat3dTranslatehom_mat3d_translate 算子创建对应的齐次变换矩阵,再使用 hom_mat3d_to_posehom_mat3d_to_poseHomMat3dToPoseHomMat3dToPoseHomMat3dToPosehom_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" 时,此算子支持取消超时和中断。

执行信息

此算子支持取消超时和中断。

此算子修改后续输入参数的状态:

在执行此算子时,若该参数值需在多个线程间使用,则必须对其访问进行同步。

参数

CalibDataIDCalibDataIDCalibDataIDCalibDataIDcalibDataIDcalib_data_id (输入控制,状态被修改)  calib_data HCalibData, HTupleHHandleHTupleHtuple (handle) (IntPtr) (HHandle) (handle)

标定数据模型的句柄。

ErrorsErrorsErrorsErrorserrorserrors (输出控制)  number-array HTupleSequence[float]HTupleHtuple (real) (double) (double) (double)

优化过程中的平均残差误差。

可能的前趋

create_calib_datacreate_calib_dataCreateCalibDataCreateCalibDataCreateCalibDatacreate_calib_data, set_calib_data_cam_paramset_calib_data_cam_paramSetCalibDataCamParamSetCalibDataCamParamSetCalibDataCamParamset_calib_data_cam_param, set_calib_data_calib_objectset_calib_data_calib_objectSetCalibDataCalibObjectSetCalibDataCalibObjectSetCalibDataCalibObjectset_calib_data_calib_object, set_calib_data_observ_poseset_calib_data_observ_poseSetCalibDataObservPoseSetCalibDataObservPoseSetCalibDataObservPoseset_calib_data_observ_pose, find_calib_objectfind_calib_objectFindCalibObjectFindCalibObjectFindCalibObjectfind_calib_object, set_calib_dataset_calib_dataSetCalibDataSetCalibDataSetCalibDataset_calib_data, remove_calib_dataremove_calib_dataRemoveCalibDataRemoveCalibDataRemoveCalibDataremove_calib_data, remove_calib_data_observremove_calib_data_observRemoveCalibDataObservRemoveCalibDataObservRemoveCalibDataObservremove_calib_data_observ

可能的后继

get_calib_dataget_calib_dataGetCalibDataGetCalibDataGetCalibDataget_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.

模块

标定