在halcon手眼 标定中,主要分为相机固定和相机随机械手移动两种标定方式。
在固定 相机时,标定 板固定 在夹具上,机械手带着标定板进行一系列的移动,
在每个位置让相机对标定板拍照,同时记录下机械手的位置信息(信息由机械手系统提供)。
相机运动时,是标定板固定不动,机械手带着相机在不同位置拍照,同时记录拍照时机械手对应的位姿,
最后求得委屈什么坐标系与机械手基础坐标系关系。
当前帖子演示如何进行SCARA机器人的手眼标定。
相机相对机器人固定。
标定板固定于机器手工具末端上。
在代码最后,标定结果及数据会被保存到磁盘文件。
保存的数据可以在后续用于计算要抓取物体的位置。
保存的结果可以在halcon例程pick_and_place_scara_stationary_cam.hdev中使用。
文件位于C:/Users/Public/Documents/MVTec/HALCON-17.12-Progress/examples/hdevelop/Calibration/Hand-Eye
下图为标定结果
halcon手眼标定实现与应用
下面为具体代码与详细注释
- CalibObjDescr := 'calibrate_hand_eye_scara_setup_01_calplate.cpd'
- CalibrationPlateThickness := 0.003
- CameraParam := ['area_scan_division',0.0165251, -642.277, 4.65521e-006, 4.65e-006, 595.817, 521.75, 1280, 1024]
- *设置要抓取物体厚度,以实现确定抓取平面的位姿
- ObjectThickness := 0.001
- dev_close_window ()
- dev_open_window_fit_size (0, 0, 1280, 1024, 640, -1, WindowHandle)
- set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
- dev_update_off ()
- *
- * 步骤1 读取标定板图像及机械手位姿。
- *创建标定模型。模型类型为手眼相对固定形式。
- *'hand_eye_scara_stationary_cam'为标定类型, 1, 1为标定时相机及标定板个数, CalibDataID为输出句柄。
- create_calib_data ('hand_eye_scara_stationary_cam', 1, 1, CalibDataID)
- * Set the camera parameters in the calibration model
- *设置标定用相机的参数与类型。CalibDataID为模型句柄, 0为相机索引, []为相机类型,表示面扫,
- *CameraParam为相机内参。
- set_calib_data_cam_param (CalibDataID, 0, [], CameraParam)
- *设置标定板的描述文件
- set_calib_data_calib_object (CalibDataID, 0, CalibObjDescr)
- for Index := 1 to 10 by 1
- * 读取标定板图像
- read_image (CalibImage, '3d_machine_vision/hand_eye/scara_stationary_cam_setup_01_calib_' + Index
- 当前这个实现就是将相机固定在一个地方,机械手带动标定 板在不同的位置进行拍照,
- 再进行标定求出摄像机坐标系与机械手基础坐标系转换关系,其实就是平移矢量和放置矩阵。
- 核心就是要确定 摄像机和机械手基础 坐标系间的关系 ,机械手基础坐标系就是以机械手底座
- 为原点建立的坐标系,摄像 机坐标系是以摄像 机中心为原点 建立 的坐标系,知道 它们间的关系
- 后就可以计算出要抓取物体可基础 坐标系下的坐标,从而 可以进行准确抓取。
- 02')
- *读取图片对应的机械手位姿(机械手基础坐标系下夹具的位姿)
- *这里的对应意思是,标定板固定于机械手夹具,相机对标定板拍照,此时机械手夹具位姿。
- *文件在位于C:/Users/Public/Documents/MVTec/HALCON-17.12-Progress/examples/hdevelop/Calibration/Hand-Eye
- read_pose ('scara_stationary_cam_setup_01_tool_in_base_pose_' + Index
- 当前这个实现就是将相机固定在一个地方,机械手带动标定 板在不同的位置进行拍照,
- 再进行标定求出摄像机坐标系与机械手基础坐标系转换关系,其实就是平移矢量和放置矩阵。
- 核心就是要确定 摄像机和机械手基础 坐标系间的关系 ,机械手基础坐标系就是以机械手底座
- 为原点建立的坐标系,摄像 机坐标系是以摄像 机中心为原点 建立 的坐标系,知道 它们间的关系
- 后就可以计算出要抓取物体可基础 坐标系下的坐标,从而 可以进行准确抓取。
- 02' + '.dat', ToolInBasePose)
- *设置标定模型中机械手位姿,ToolInBasePose为上面从文件读取的数值。
- set_calib_data (CalibDataID, 'tool', Index, 'tool_in_base_pose', ToolInBasePose)
- *确定在相机坐标系下标定板的位姿,并设置到标定模型中。
- find_calib_object (CalibImage, CalibDataID, 0, 0, Index, [], [])
- * 显示结果
- dev_display (CalibImage)
- *从标定模型中获取标定板位姿信息。
- get_calib_data_observ_pose (CalibDataID, 0, 0, Index, ObjInCameraPose)
- *显示标定图像
- disp_caltab (WindowHandle, CalibObjDescr, CameraParam, ObjInCameraPose, 1)
- disp_message (WindowHandle, 'Calibration image ' + Index + ' of 10', 'window', 12, 12, 'black', 'true')
- wait_seconds (0.2)
- endfor
- disp_continue_message (WindowHandle, 'black', 'true')
- stop ()
- * 步骤2 执行手眼标定
- calibrate_hand_eye (CalibDataID, Errors)
- * Get the result of the calibration, i.e., the pose of
- * the robot base in the camera coordinate system
- *获取标定结果,当前获取在相机坐标系与机械手基础坐标系关系,也就是旋转矩阵和平移矢量。
- *这也是相机固定类型的手眼标定目的:求得这种关系。有了各个坐标系间的转换关系后
- *就可以换算出物体在机械手基础坐标系下的坐标,从而让机构手抓取物体。
- get_calib_data (CalibDataID, 'camera', 0, 'base_in_cam_pose', BaseInCamPosePre)
- * 释放模型
- clear_calib_data (CalibDataID)
- * 可视化显示
- disp_preliminary_result (WindowHandle, BaseInCamPosePre, Errors)
- disp_continue_message (WindowHandle, 'black', 'true')
- stop ()
- *步骤3 确定详细位姿。
- *在进行SCARA机械手标定时,无法确定全部位姿参数。在相机固定标定情况下,
- *ObjInToolPose的Z轴转换不能确定,所以必须移动机械手到已知高度,确定Z轴的转换。
- *首先解下标定板放在相机能拍全的任意位置,计算相机坐标系下标定板位姿(保存到ObjInCamPoseRef)
- *然后人为移动机械手夹具到标定板中心(数据保存到ToolInBasePoseRef)
- *前面两个变量传入函数fix_scara_ambiguity_stationary_cam就可确定Z轴的转换
- *得到ObjInCamPoseRef
- read_image (ImageRef, '3d_machine_vision/hand_eye/scara_stationary_cam_setup_01_calib_ref')
- *get_calib_plate_pose (ImageRef, CameraParam, CalibObjDescr, ObjInCamPoseRef)
- create_calib_data ('calibration_object', 1, 1, CalibDataID)
- set_calib_data_cam_param (CalibDataID, 0, [], CameraParam)
- set_calib_data_calib_object (CalibDataID, 0, CalibObjDescr)
- find_calib_object (ImageRef, CalibDataID, 0, 0, 0, [], [])
- get_calib_data_observ_pose (CalibDataID, 0, 0, 0, ObjInCamPoseRef)
- clear_calib_data (CalibDataID)
- *得到ToolInBasePoseRef
- read_pose ('scara_stationary_cam_setup_01_tool_in_base_pose_ref.dat', ToolInBasePoseRef)
- *fix_scara_ambiguity_stationary_cam (BaseInCamPosePre, ToolInBasePoseRef, ObjInCamPoseRef, ZCorrection)
- pose_invert (BaseInCamPosePre, CamInBasePose)
- pose_compose (CamInBasePose, ObjInCamPoseRef, ObjInBasePose)
- ZCorrection := ObjInBasePose[2] - ToolInBasePoseRef[2]
- *转换三维位姿的原点。
- set_origin_pose (BaseInCamPosePre, 0, 0, ZCorrection, BaseInCamPose)
- *
- *可视化显示。
- disp_final_results (WindowHandle, BaseInCamPosePre, BaseInCamPose)
- disp_end_of_program_message (WindowHandle, 'black', 'true')
- *
- *手眼标定后,计算所得的BaseInCamPose可用于机械手抓取工作:
- *我们假设相机对要抓取的物体拍摄一图像,计算得到其位姿保存到变量ObjInCamPose,
- *通过此变量ObjInCamPose及前面标定的结果BaseInCamPose,
- *机械手抓取物体的位姿ObjInBasePose就可以计算出来。
- pose_invert (BaseInCamPose, CamInBasePose)
- create_pose (0.0035, -0.0128, 0.7981, 1.345, 356.158, 180.194, 'Rp+T', 'gba', 'point', ObjInCamPose)
- pose_compose (CamInBasePose, ObjInCamPose, ObjInBasePose)
- *
- * 准备额外的数据来计算被抓取 物体位姿。
- *计算测量平面位姿
- set_origin_pose (ObjInCamPoseRef, 0, 0, CalibrationPlateThickness - ObjectThickness, MPInCamPose)
- * 保存数据用于后续机械手抓取项目
- * 保存标定结果
- write_pose (CamInBasePose, 'cam_in_base_pose.dat')
- *相机内参
- write_cam_par (CameraParam, 'camera_parameters.dat')
- *测量板位姿
- write_pose (MPInCamPose, 'measurement_plane_in_cam_pose.dat')
复制代码
当前这个实现就是将相机固定在一个地方,机械手带动标定 板在不同的位置进行拍照,
再进行标定求出摄像机坐标系与机械手基础坐标系转换关系,其实就是平移矢量和放置矩阵。
核心就是要确定 摄像机和机械手基础 坐标系间的关系 ,机械手基础坐标系就是以机械手底座
为原点建立的坐标系,摄像 机坐标系是以摄像 机中心为原点 建立 的坐标系,知道 它们间的关系
后就可以计算出要抓取物体可基础 坐标系下的坐标,从而 可以进行准确抓取。
|