Halcon执行手眼标定, 发那科机器人三点法标定
固定相机
原理: ObjInCam = BaseInCam × ToolInBase × ObjInTool
其中 对标定板的多次拍照可以确定CalObjInCam
机器人内部参数可以读取到ToolInBase
然后生成手眼标定参数集合 CalibDataID , CalibDataID中存放了相机内部参数, 标定板描述文件等, 通过手眼标定确定等号右边第一和第三个参数 BaseInCam , ObjInTool
最终要求得ObjInBase
ObjInBase = CamInBase × ObjInCam
手眼标定确定了 BaseInCam, 求出逆矩阵即可
ObjInCam 为照相机拍标定板确定
二者相乘得到ObjInBase
注意:
如果没有夹具, 则直接
ToolInBase = ToolInBase
如果有夹具, 则ToolInBase × GripperInTool = GripperInBase
则ToolInBase = GripperInBase×Inv(GripperInTool)
固定相机:
*关闭程序计数器,变量更新,图像更新窗口
dev_update_off ()
* 校正图像路径
*ImageNameStart := '3d_machine_vision/handeye/stationarycam_calib3cm_'
ImageNameStart:= '3d_machine_vision/calib/'
ImgPath := '3d_machine_vision/calib/'
*read_image (Image, ImgPath + 'calib_')
*机器人工具坐标系的位姿
*stationarycam_start_campar.dat
DataNameStart := 'handeye/stationarycam_'*校正图像的数目
NumImages := 17*读取一张图像
read_image (Image, ImageNameStart+'calib_'+'02')*获取图像的大小
get_image_size (Image, Width, Height)
* 关闭已经打开的窗口
dev_close_window ()*打开新窗口
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)*设置线宽
dev_set_line_width (2)*设置区域填充方式为margin
dev_set_draw ('margin')*显示图像
dev_display (Image)* 设置字体
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')**************************************************************准备手眼标定的数据*************************************************************************************** 标定板描述文件
CalTabFile := 'caltab_30mm.descr'* 读取摄像机内部参数
read_cam_par (DataNameStart + 'start_campar.dat', StartCamParam)* 创建手眼标定模型create_calib_data ('hand_eye_stationary_cam', 1, 1, CalibDataID)* 重要, 将 摄像机内部参数 StartCamParam 写入手眼标定模型CalibDataID中
* 对手眼标定模型设置摄像机内部参数
set_calib_data_cam_param (CalibDataID, 0, 'area_scan_division', StartCamParam)* 对手眼标定模型设置标定板描述文件
set_calib_data_calib_object (CalibDataID, 0, CalTabFile)*采用非线性算法获取精确校准姿态 再次校准 CalibDataID
set_calib_data (CalibDataID, 'model', 'general', 'optimization_method', 'nonlinear')
disp_message (WindowHandle, 'The calibration data model was created', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()**************************************************************获取标定板MARK点坐标和标定板相对相机的位姿获取ObjInCam**************************************************************************************for I := 1 to NumImages by 1*读取含标定板的图像*read_image (Image, ImageNameStart + I$'02d')read_image (Image, ImgPath + 'calib_' + I$'02d')dev_display (Image)*寻找标定板对象find_calib_object (Image, CalibDataID, 0, 0, I, [], [])*获取标定板轮廓get_calib_data_observ_contours (Caltab, CalibDataID, 'caltab', 0, 0, I)*********非常重要 得到第一个已知参数*获取标定板MARK点坐标和标定板相对相机的位姿 Mark点: 标定板上的圆get_calib_data_observ_points (CalibDataID, 0, 0, I, RCoord, CCoord, Index, CalObjInCamPose)dev_set_color ('green')dev_display (Image)dev_display (Caltab)dev_set_color ('yellow')disp_cross (WindowHandle, RCoord, CCoord, 6, 0)dev_set_colored (3)disp_3d_coord_system (WindowHandle, StartCamParam, CalObjInCamPose, 0.01)* 读取机器人基座坐标系下机器人工具位姿read_pose (DataNameStart + 'robot_pose_' + I$'02d' + '.dat', ToolInBasePose)* 设置机器人基座坐标系下机器人工具位姿设置到手眼标定模型里 CalibDataIDset_calib_data (CalibDataID, 'tool', I, 'tool_in_base_pose', ToolInBasePose)* Uncomment to inspect visualizationdisp_message (WindowHandle, 'Extracting data from calibration image ' + (I + 1) + ' of ' + NumImages, 'window', -1, -1, 'black', 'true')disp_continue_message (WindowHandle, 'black', 'true')wait_seconds (1)
endfor
disp_message (WindowHandle, 'All relevant data has been set in the calibration data model', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()**************************************************************执行手眼标定**************************************************************************************
dev_display (Image)
disp_message (WindowHandle, 'Performing the hand-eye calibration', 'window', 12, 12, 'black', 'true')*执行手眼标定
calibrate_hand_eye (CalibDataID, Errors)* 查询手眼标定的错误情况
get_calib_data (CalibDataID, 'model', 'general', 'camera_calib_error', CamCalibError)* Query the camera parameters and the poses
* 获取校正后摄像机内部参数
get_calib_data (CalibDataID, 'camera', 0, 'params', CamParam)* 获取摄像机坐标系下机器人基座的位姿 : BaseInCamPose 未知 需要求出的 等号右边第一个参数
get_calib_data (CalibDataID, 'camera', 0, 'base_in_cam_pose', BaseInCamPose)* 获取机器人工具坐标系下校正对象的位姿 : ObjInToolPose 未知 需要求出的 等号右边第三个参数
get_calib_data (CalibDataID, 'calib_obj', 0, 'obj_in_tool_pose', ObjInToolPose)* 错误对话框是否被抑制
dev_get_preferences ('suppress_handled_exceptions_dlg', PreferenceValue)dev_set_preferences ('suppress_handled_exceptions_dlg', 'true')**************************************************************保存手眼标定的结果到本地硬盘**************************************************************************************
****************************
***********************
*********
***CalObjInCamPose = BaseInCamPose * ToolInBasePose * ObjInToolPose
***已知条件:CalObjInCamPose 通过标定板图像(校正对象), ToolInBasePose(系统)
***在有夹具下: ToolInBasePose(系统) = ObjInbase*Inv(GripperInTool)
***要求等号右边的1和3try* 保存相机内部参数参数到本地文件 : CamParamwrite_cam_par (CamParam, DataNameStart + 'final_campar.dat')* 将摄像机坐标系下的机器人底座位姿保存到本地 获得了未知参数 等号右边 参数1write_pose (BaseInCamPose, DataNameStart + 'final_pose_cam_base.dat')* 将机器人工具坐标系下的校正对象的位姿保存到本地 获得了未知参数 等号右边 参数3write_pose (ObjInToolPose, DataNameStart + 'final_pose_tool_calplate.dat')catch (Exception)* Do nothing
endtry
dev_set_preferences ('suppress_handled_exceptions_dlg', PreferenceValue)
* Display calibration errors of the hand-eye calibration
disp_results (WindowHandle, CamCalibError, Errors)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()**************************************************************计算摄像机坐标系下校正对象的位姿**************************************************************************************
* 查询摄像机,校正对象,校正对象位姿的相对关系
query_calib_data_observ_indices (CalibDataID, 'camera', 0, CalibObjIdx, PoseIds)for I := 0 to NumImages - 1 by 1read_image (Image, ImageNameStart + I$'02d')*获取机器人基准坐标中机器人工具的姿态 : 系统获得ToolInBasePoseget_calib_data (CalibDataID, 'tool', PoseIds[I], 'tool_in_base_pose', ToolInBasePose)dev_display (Image)*计算摄像机坐标系下校正对象的位姿calc_calplate_pose_stationarycam (ObjInToolPose, BaseInCamPose, ToolInBasePose, CalObjInCamPose)dev_set_colored (3)disp_3d_coord_system (WindowHandle, CamParam, CalObjInCamPose, 0.01)Message := 'Using the calibration results to display the'Message[1] := 'coordinate system in image ' + (I + 1) + ' of ' + NumImagesdisp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')if (I < NumImages - 1)disp_continue_message (WindowHandle, 'black', 'true')stop ()endif
endfor
* 释放手眼标定模板内存
clear_calib_data (CalibDataID)
*
**************************************************************获取机器人基座坐标系中校正对象的位姿**************************************************************************************ObjInCamPose := CalObjInCamPose***CalObjInCamPose = BaseInCamPose * ToolInBasePose * ObjInToolPosepose_invert (BaseInCamPose, CamInBasePose)*CalibDataID 有相机的内部参数, 标定板描述文件 标定板上Mark点坐标等
*最终结果之一 由 get_calib_data (CalibDataID, 'camera', 0, 'base_in_cam_pose', BaseInCamPose) 得到等号右边第一个未知参数 BaseInCamPose
*由 get_calib_data (CalibDataID, 'calib_obj', 0, 'obj_in_tool_pose', ObjInToolPose) 得到等号右边第三个未知参数 ObjInToolPose*最终结果之二,等号左边 需要看有没有Cal 由 get_calib_data_observ_points (CalibDataID, 0, 0, I, RCoord, CCoord, Index, CalObjInCamPose) 得到 等号左边已知参数 CalObjInCamPose
*由 set_calib_data (CalibDataID, 'tool', I, 'tool_in_base_pose', ToolInBasePose) 得到等号右边第二个已知参数 ToolInBasePose*获取机器人基座坐标系中校正对象的位姿ObjInBasePose
pose_compose (CamInBasePose, ObjInCamPose, ObjInBasePose)
移动相机
*关闭程序计数器,变量更新,图像窗口更新
dev_update_off ()* 校正图像路径
ImageNameStart := '3d_machine_vision/handeye/movingcam_calib3cm_'*机器人工具坐标系的位姿
DataNameStart := 'handeye/movingcam_'*校正图像的数目
NumImages := 14*读取一张图像
read_image (Image, ImageNameStart + '00')* 关闭已经打开的窗口
dev_close_window ()*获取图像的大小
get_image_size (Image, Width, Height)*打开新窗口
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)*设置线宽
dev_set_line_width (2)*设置区域填充方式为margin
dev_set_draw ('margin')*显示图像
dev_display (Image)*设置字体信息,字体大小为14,字体为mono,粗体
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')* 标定板描述文件
CalTabFile := 'caltab_30mm.descr'* 读取摄像机内部参数
read_cam_par (DataNameStart + 'start_campar.dat', StartCamParam)* 创建手眼标定模型
create_calib_data ('hand_eye_moving_cam', 1, 1, CalibDataID)* 对手眼标定模型设置摄像机内部参数
set_calib_data_cam_param (CalibDataID, 0, 'area_scan_division', StartCamParam)* 对手眼标定模型设置标定板描述文件
set_calib_data_calib_object (CalibDataID, 0, CalTabFile)*采用非线性算法获取精确校准姿态
set_calib_data (CalibDataID, 'model', 'general', 'optimization_method', 'nonlinear')
disp_message (WindowHandle, 'The calibration data model was created', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
**************************************************************获取标定板MARK点坐标和标定板相对相机的位姿**************************************************************************************
for I := 0 to NumImages - 1 by 1*读取含标定板的图像read_image (Image, ImageNameStart + I$'02d')*寻找标定板对象find_calib_object (Image, CalibDataID, 0, 0, I, [], [])*获取标定板轮廓get_calib_data_observ_contours (Caltab, CalibDataID, 'caltab', 0, 0, I)*获取标定板MARK点坐标和标定板相对相机的位姿get_calib_data_observ_points (CalibDataID, 0, 0, I, RCoord, CCoord, Index, PoseForCalibrationPlate)dev_set_color ('green')dev_display (Image)dev_display (Caltab)dev_set_color ('yellow')disp_cross (WindowHandle, RCoord, CCoord, 6, 0)dev_set_colored (3)disp_3d_coord_system (WindowHandle, StartCamParam, PoseForCalibrationPlate, 0.01)* 读取机器人基座坐标系下机器人工具位姿read_pose (DataNameStart + 'robot_pose_' + I$'02d' + '.dat', ToolInBasePose)* 设置机器人基座坐标系下机器人工具位姿设置到手眼标定模型里set_calib_data (CalibDataID, 'tool', I, 'tool_in_base_pose', ToolInBasePose)* Uncomment for inspection of visualization
* disp_message (WindowHandle, 'Extracting data from calibration image ' + (I + 1) + ' of ' + NumImages, 'window', 12, 12, 'black', 'true')
* disp_continue_message (WindowHandle, 'black', 'true')
* stop ()
endfor
disp_message (WindowHandle, 'All relevant data has been set in the calibration data model', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()**************************************************************执行手眼标定***************************************************************************************执行手眼标定
calibrate_hand_eye (CalibDataID, Errors)* 查询手眼标定的错误情况
get_calib_data (CalibDataID, 'model', 'general', 'camera_calib_error', CamCalibError)* 获取摄像机内部参数
get_calib_data (CalibDataID, 'camera', 0, 'params', CamParam)* 获取摄像机坐标系下机器人工具的位姿
get_calib_data (CalibDataID, 'camera', 0, 'tool_in_cam_pose', ToolInCamPose)* 获取机器人基础坐标系下校正对象的位姿
get_calib_data (CalibDataID, 'calib_obj', 0, 'obj_in_base_pose', CalObjInBasePose)* 错误对话框是否被抑制
dev_get_preferences ('suppress_handled_exceptions_dlg', PreferenceValue)
dev_set_preferences ('suppress_handled_exceptions_dlg', 'true')
try* 保存相机内部参数参数到本地文件write_cam_par (CamParam, DataNameStart + 'final_campar.dat')* 将摄像机坐标系下的机器人工具位姿保存到本地write_pose (ToolInCamPose, DataNameStart + 'final_pose_cam_tool.dat')* 将机器人基础坐标系下的校正对象的位姿保存到本地write_pose (CalObjInBasePose, DataNameStart + 'final_pose_base_calplate.dat')
catch (Exception)* do nothing
endtry
dev_set_preferences ('suppress_handled_exceptions_dlg', PreferenceValue)
dev_display (Image)
* Display calibration errors
disp_results (WindowHandle, CamCalibError, Errors)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()**************************************************************计算摄像机坐标系下校正对象的位姿**************************************************************************************
* 查询摄像机,校正对象,校正对象位姿的相对关系
query_calib_data_observ_indices (CalibDataID, 'camera', 0, CalibObjIdx, PoseIds)for I := 0 to NumImages - 1 by 1read_image (Image, ImageNameStart + I$'02d')dev_display (Image)*获取机器人基准坐标中机器人工具的姿态get_calib_data (CalibDataID, 'tool', PoseIds[I], 'tool_in_base_pose', ToolInBasePose)*计算摄像机坐标系下校正对象的位姿calc_calplate_pose_movingcam (CalObjInBasePose, ToolInCamPose, ToolInBasePose, CalObjInCamPose)*显示坐标系统dev_set_colored (3)disp_3d_coord_system (WindowHandle, CamParam, CalObjInCamPose, 0.01)Message := 'Using the calibration results to display 'Message[1] := 'the coordinate system in image ' + (I + 1) + ' of ' + NumImagesdisp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')if (I < NumImages - 1)disp_continue_message (WindowHandle, 'black', 'true')stop ()endif
endfor
* 释放手眼标定模板内存
clear_calib_data (CalibDataID)**************************************************************获取机器人基座坐标系中校正对象的位姿**************************************************************************************
ObjInCamPose := CalObjInCamPose*位姿反向,获取机器人工具坐标系下摄像机坐标系的位姿
pose_invert (ToolInCamPose, CamInToolPose)*机器人基础坐标系下机器人工具坐标系的位姿和机器人工具坐标系下摄像机坐标系的位姿进行乘积,从而获取机器人基础坐标系下摄像机坐标系的位姿。
pose_compose (ToolInBasePose, CamInToolPose, CamInBasePose)*机器人基础坐标系下摄像机坐标系的位姿和摄像机坐标系下校正对象坐标系的位姿进行乘积,从而获取机器人基础坐标系下校正对象坐标系的位姿。
pose_compose (CamInBasePose, ObjInCamPose, ObjInBasePose)
固定相机:
移动相机:
三点法操作步骤:
记录接近点1
a.移动光标到接近点1(Approachpoint1);
b.把示教坐标切换成全局坐标(WORLD)后移动机器人,使工具尖端接触到基准点;
c.按【SHIFT】+F5【RECORD】(位置记录)记录
记录接近点2
a.移动光标到接近点2(Approachpoint2);
b.把示教坐标切换成关节坐标(JOINT),旋转J6轴(法兰面)至少90度,不要超过360度
c.把示教坐标切换成全局坐标(WORLD)后移动机器人,使工具尖端接触到基准点;
d.按【SHIFT】+F5【RECORD】(位置记录)记录;
记录接近点3
a.移动光标到接近点3(Approachpoint3);
b.把示教坐标切换成关节坐标(JOINT),旋转J4轴和J5轴,不要超过90度;
c.把示教坐标切换成全局坐标(WORLD)后移动机器人,工具尖端接触到基准点;
d.按【SHIFT】+F5【RECORD】(位置记录)记录;
当三个点记录完成,新的工具坐标系被自动计算生成.Point1-3显示成USED,如下图所示:
Halcon执行手眼标定, 发那科机器人三点法标定相关推荐
- 西门子S7-1500PLC大项目案例 带14台发那科机器人 三个SEW变频器控制的4面转台 阀岛控制130多个气缸 2台西门子TP1200触摸屏
西门子S7-1500PLC大项目案例 带14台发那科机器人 三个SEW变频器控制的4面转台 阀岛控制130多个气缸 2台西门子TP1200触摸屏 11个ET200S模块 S7-1200与S7-1500 ...
- 西门子1200 1500 完整大型PLC程序 3台西门子触 摸屏 程序块无密码 结构清晰 程序带中文注解 共1多台发那科机器人
西门子1200 1500 完整大型PLC程序 3台西门子触 摸屏 程序块无密码 结构清晰 程序带中文注解 共1多台发那科机器人 三个SEW变频器控制的4面转台 130多个气缸 1200 1500 间使 ...
- 确保发那科机器人零点标定(零点复归)精度的3种方法
确保发那科机器人零点标定(零点复归)精度的3种方法 随便聊聊 先贴结论 一.测试项目 二.测试方法 三.不同零点复归方法精度测试 1.测试过程 2.测试数据 3.测试结论 四.重做用户及工具坐标系测试 ...
- 制动器作用停止 发那科机器人_FANUC机器人长期停机再运转时注意事项
[塑料机械网 技术学堂] FANUC机器人在长期切断电源后,初次开机再投入使用时,需充分确认现场条件后再投入运转,避免因操作不当而引起设备的故障.对此,建议您按以下操作指引进行操作. 1. 开机前确 ...
- 发那科机器人示教器电缆线_云和发那科机器人维修
广州友仪机电设备有限公司创立于2007年,成长在自动化行业高速发展的高铁上,现在已经成为华南地区具影响力的工控维修品牌,2015年我们再出发,组织公司精英力量设立机器人项目事业部,投入大量经费购入四大 ...
- cclink 和发那科机器人_发那科 iB系列 | 机器人地装行走轴三大升级介绍
1. 引言 FANUC机器人行走轴是一款供机器人使用的直线运动导轨平台,按其拖链形式可以分为标准型(边置型)与紧凑型(中置型)两种形式.行走轴使用FANUC伺服电机驱动,通过精密行星减速机.高精度齿轮 ...
- 法那科机器人初始化启动_发那科机器人的控制方式和控制柜的启动方式
工业机器人能得到广泛应用,得益于它拥有有多种控制方式,按作业任务的不同,可主要分为点位控制方式.连续轨迹控制方式.力(力矩)控制方式和智能控制方式四种控制方式. 1.点位控制方式(PTP) 这种控制方 ...
- cclink 和发那科机器人_FANUC机器人焊枪工具坐标系设定
FANUC.ROBOT ⇊ 点击进入 ⇊ 如何察看机器人当前的位置信息 | 操作面板的创建功能 FANUC | Motion Optimization功能 轨迹自动拾取和自动退臂功能 | Optimi ...
- 发那科机器人编程软件fanuc roboguide授权补丁_发那科Robot | Line Tracking功能
在物流搬运.喷涂等应用中,工件通常是通过传送带来传输的,传输过程中,考虑系统的节拍问题,传送带往往进行持续的运动,不会在机器人对工件搬运或者喷涂过程中停止运动.那么,机器人怎样在工件运动过程中精确地对 ...
最新文章
- Eclipse 代码自动提示的设置
- 【Flutter】Flutter 混合开发 ( Flutter 与 Native 通信 | 完整代码示例 )
- 计算机应用基础二00018,2019年10月自学考试00018《计算机应用基础》试题(二)
- IOS学习:常用第三方库(GDataXMLNode:xml解析库)
- 计算出你和另一个人的关系,准的邪门了!
- 2017.10.28 排序 思考记录
- QT最常用的字符串操作
- [机器学习、Spark]Spark机器学习库MLlib的概述与数据类型
- 第一次在csdn写博客!
- Rstudio代码自动格式化:styler
- 候选码、主码、外码、全码、超码
- C#练习题答案: 反恐精英系列【难度:1级】--景越C#经典编程题库,1000道C#基础练习题等你来挑战
- 公众号快速注册并认证小程序功能介绍
- 动手学习深度学习-跟李沐学AI-自学笔记(1)
- 红米5 Android 8.0,红米 5 获得 Android 8.0 稳定版更新:修复大量问题
- 快手程序员爆料:有大厂背书就是好,这就是光环效应
- 程序员不得不学的操作系统知识(一)
- C语言讲义——错误处理
- pg.Pool 的 query 用法
- 利用matlab将.mat格式文件转换成wav文件
热门文章
- 约瑟夫环数学递推公式及其证明
- 公安大数据平台建设项目
- pppoe linux 配置文件,arm-linux配置pppoe
- aliyun短信服务包含随机生成四位数字验证码工具类
- dnfdpl服务器维护了,DNF5月dpl奖励“暗改”:强化器、时空石没了,史派克逼退玩家...
- 搭建自己网站----内网穿透
- GTX2080的GPU版本caffe的环境
- @JsonFormat、@JSONField、@DateTimeFormat的使用以及其区别 ||||返回json的时候的时间转化
- MySQL联合索引(abc)命中规则
- 第三代宝马6系GT概念合成图