> 技术文档 > 【3D手眼标定案例】--SCARA机器人手眼标定系统详解

【3D手眼标定案例】--SCARA机器人手眼标定系统详解

* This example explains how to perform the hand-eye calibration for* a SCARA robot. In this case, the camera is attached to the robot tool* and the calibration object is stationary with respect to the robot.* * Provide the description file of the calibration plate and the* camera parameters of the previously calibrated cameraCalibObjDescr := \'calibrate_hand_eye_scara_setup_01_calplate.cpd\'gen_cam_par_area_scan_division (0.004938, -10379.136, 4.65138e-006, 4.65e-006, 617.294, 534.687, 1280, 1024, CameraParam)* 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. Acquire calibration images and corresponding robot poses* * Create a new calibration modelcreate_calib_data (\'hand_eye_scara_moving_cam\', 1, 1, CalibDataID)* Set the camera parameters in the calibration modelset_calib_data_cam_param (CalibDataID, 0, [], CameraParam)* Set the calibration plate in the calibration modelset_calib_data_calib_object (CalibDataID, 0, CalibObjDescr)for Index := 1 to 10 by 1 * Read the calibration image read_image (CalibImage, \'3d_machine_vision/hand_eye/scara_moving_cam_setup_01_calib_\' + Index$\'02\') * Read the corresponding robot pose (pose of the tool in the * robot base coordinate system) read_pose (\'scara_moving_cam_setup_01_tool_in_base_pose_\' + Index$\'02\' + \'.dat\', ToolInBasePose) * Set the robot pose in the calibration model set_calib_data (CalibDataID, \'tool\', Index, \'tool_in_base_pose\', ToolInBasePose) * Determine the pose of the calibration plate in the camera * coordinate system and set the pose in the calibration model find_calib_object (CalibImage, CalibDataID, 0, 0, Index, [], []) * Visualize 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)endfordisp_continue_message (WindowHandle, \'black\', \'true\')stop ()* * 2. Check the input poses for consistency* check_hand_eye_calibration_input_poses (CalibDataID, 0.05, 0.005, Warnings)if (|Warnings| != 0) * There were problem detected in the input poses. Inspect Warnings and * remove erroneous poses with remove_calib_data and remove_calib_data_observ. dev_inspect_ctrl (Warnings) stop ()endif* * 3. Perform the hand-eye calibration* calibrate_hand_eye (CalibDataID, Errors)* Get the result of the calibration, i.e., the pose of* the robot base in the camera coordinate systemget_calib_data (CalibDataID, \'camera\', 0, \'tool_in_cam_pose\', ToolInCamPosePre)* Free the calibration modelclear_calib_data (CalibDataID)* Visualizedisp_preliminary_result (WindowHandle, ToolInCamPosePre, Errors)disp_continue_message (WindowHandle, \'black\', \'true\')stop ()* * 3. Fix the pose ambiguity* * When calibrating a SCARA robot, it is impossible to determine* all pose parameters unambiguously. In case of a moving* camera, the Z translation of ObjInBasePose cannot be determined.* Therefore, it is necessary to fix the unknown translation in* Z by moving the robot to a pose of known height in the camera* coordinate system. Because normally the camera does not see* the object if the tool is moved to the object, the robot is* moved to two poses. For this, the calibration plate is placed* at an arbitrary position. The robot is then manually moved such* that the camera can observe the calibration plate. Now, an image* of the calibration plate is acquired and the robot pose is* queried (-> ToolInBasePoseRef1). From the image, the pose of the* calibration plate in the camera coordinate system can be* determined (-> ObjInCamPoseRef1). Afterwards, the tool of the* robot is manually moved to the origin of the calibration plate* (-> ToolInBasePoseRef2). These three poses and the result of the* calibration (ToolInCamPosePre) can be used to fix the* Z ambiguity by using the procedure fix_scara_ambiguity_moving_cam:read_image (ImageRef1, \'3d_machine_vision/hand_eye/scara_moving_cam_setup_01_calib_ref_1\')get_calib_plate_pose (ImageRef1, CameraParam, CalibObjDescr, ObjInCamPoseRef1)read_pose (\'scara_moving_cam_setup_01_tool_in_base_pose_ref_1.dat\', ToolInBasePoseRef1)read_pose (\'scara_moving_cam_setup_01_tool_in_base_pose_ref_2.dat\', ToolInBasePoseRef2)fix_scara_ambiguity_moving_cam (ToolInCamPosePre, ObjInCamPoseRef1, ToolInBasePoseRef1, ToolInBasePoseRef2, ZCorrection)set_origin_pose (ToolInCamPosePre, 0, 0, ZCorrection, ToolInCamPose)* * Visualizedisp_final_results (WindowHandle, ToolInCamPosePre, ToolInCamPose)disp_end_of_program_message (WindowHandle, \'black\', \'true\')* * After the hand-eye calibration is performed, the resulting pose* ToolInCamPose can be used in robotic grasping applications:* Let us assume that the camera acquires an image of the object that* should be grasped. This image was taken at a certain robot pose* (-> ToolInBasePose). From the image, the pose of the object in the* camera coordinate system must be determined (-> ObjInCamPose) by* using image processing.* Based on these two poses and the result of the calibration* (ToolInCamPose), the robot pose can be computed that is necessary* to grasp the object (-> ObjInBasePose):pose_invert (ToolInCamPose, CamInToolPose)create_pose (-0.0043, 0.0085, 0.087, 0.445, 0.068, 355.9, \'Rp+T\', \'gba\', \'point\', ObjInCamPose)create_pose (0.2612, 0.084, 0.1731, 0, 0, 178.128, \'Rp+T\', \'gba\', \'point\', ToolInBasePose)pose_compose (CamInToolPose, ObjInCamPose, ObjInToolPose)pose_compose (ToolInBasePose, ObjInToolPose, ObjInBasePose)

【3D手眼标定案例】--SCARA机器人手眼标定系统详解
【3D手眼标定案例】--SCARA机器人手眼标定系统详解
【3D手眼标定案例】--SCARA机器人手眼标定系统详解

SCARA机器人手眼校准系统深度解析

1. 代码功能详细解析
1.1 系统初始化
  • 初始化参数:设置标定板描述文件和相机参数
  • 创建显示窗口:适配图像尺寸且关闭自动更新
  • 关键操作
    • gen_cam_par_area_scan_division: 生成面阵相机参数(像素大小、焦距、畸变参数等)
    • create_calib_data: 创建SCARA专用移动相机手眼校准数据结构
1.2 数据采集
  • 循环采集10组校准数据:
    1. 读取校准图像
    2. 获取当前机器人工具在基座坐标系中的位姿 (ToolInBasePose)
    3. 在图像中定位标定板,计算标定板在相机坐标系中的位姿 (ObjInCameraPose)
    4. 可视化显示标定板位置
1.3 数据验证
  • check_hand_eye_calibration_input_poses: 验证输入的机器人位姿是否合理(旋转角度差异>0.05rad,平移>5mm)
  • 检查警告信息并移除异常位姿点
1.4 初步校准
  • calibrate_hand_eye: 执行手眼校准计算
  • get_calib_data: 获取初步校准结果 - 工具在相机坐标系中的位姿 (ToolInCamPosePre)
1.5 解决SCARA特殊歧义问题
  • 读取两个参考位姿:
    1. 机器人观察到标定板的位姿 (ToolInBasePoseRef1)
    2. 机器人末端精确对标定板原点的位姿 (ToolInBasePoseRef2)
  • get_calib_plate_pose: 从图像中提取标定板位姿 (ObjInCamPoseRef1)
  • fix_scara_ambiguity_moving_cam: 计算Z轴歧义修正值
  • set_origin_pose: 应用Z轴修正获取最终校准结果 (ToolInCamPose)
1.6 应用示例
  • 位姿转换计算抓取位置:
    1. 计算相机在工具坐标系中的位姿 (CamInToolPose)
    2. 组合位姿计算物体在工具坐标系中的位置 (ObjInToolPose)
    3. 组合位姿计算物体在基座坐标系中的位置 (ObjInBasePose)
2. 功能应用场景

该代码适用于以下SCARA机器人典型应用:

  1. 精密电子装配

    • PCB板元件插装
    • 芯片贴装校准
    • SMT设备拾取系统
  2. 小型零件分拣

    • 手表零件装配
    • 医疗器械组装
    • 微型机械组装
  3. 快速抓取系统

    • 传送链零件拾取
    • 高速分拣系统
    • 自动插装设备
  4. 实验室自动化

    • 微孔板操作
    • 样本分选系统
    • 细胞培养设备
3. 完整步骤流程及流程图

在这里插入图片描述

4. 关键函数算子解析
find_calib_object (CalibImage, CalibDataID, 0, 0, Index, [], [])
  • 功能:在图像中识别标定板并计算位姿
  • 参数
    • CalibImage:输入图像
    • CalibDataID:校准数据结构ID
    • 0, 0:相机和标定对象索引
    • Index:当前位姿索引
    • [], []:保留参数
  • 内部算法:基于边缘检测和特征匹配
fix_scara_ambiguity_moving_cam (ToolInCamPosePre, ObjInCamPoseRef1, ToolInBasePoseRef1, ToolInBasePoseRef2, ZCorrection)
  • 功能:解决SCARA机器人Z轴方向位姿歧义
  • 参数
    • ToolInCamPosePre:初步校准结果
    • ObjInCamPoseRef1:参考位姿1中标定板在相机坐标系的位姿
    • ToolInBasePoseRef1:参考位姿1的机器人位姿
    • ToolInBasePoseRef2:参考位姿2的机器人位姿
    • ZCorrection:返回的Z轴校正值
  • 数学原理
    ΔZ = [T2(z) - T1(z)] - (R1-1 * R2 * O1)(z) + O1(z)

    其中T是平移向量,R是旋转矩阵,O是标定板位置

set_origin_pose (ToolInCamPosePre, 0, 0, ZCorrection, ToolInCamPose)
  • 功能:应用Z轴校正
  • 参数
    • ToolInCamPosePre:原始位姿
    • 0, 0:X/Y轴校正值(保持为0)
    • ZCorrection:Z轴校正值
    • ToolInCamPose:输出校正后位姿
get_calib_plate_pose (Image, CameraParam, CalibObjDescr, ObjInCamPose)
  • 功能:从单张图像计算标定板位姿
  • 参数
    • Image:输入图像
    • CameraParam:相机内部参数
    • CalibObjDescr:标定板描述文件
    • ObjInCamPose:输出的标定板位姿
  • 算法:点特征匹配和PnP算法
5. 函数列表表格
函数名称 功能描述 常用参数 gen_cam_par_area_scan_division 生成面阵相机参数 像素尺寸、焦距、畸变参数、主点位置、分辨率 create_calib_data 创建校准数据结构 校准类型、相机数、标定对象数 set_calib_data_cam_param 设置相机参数 数据结构ID、相机索引、相机参数 set_calib_data_calib_object 设置标定对象 数据结构ID、标定对象索引、描述文件 find_calib_object 识别标定板 图像、数据结构ID、位姿索引 get_calib_data_observ_pose 获取观测位姿 数据结构ID、相机索引、标定对象索引、位姿索引 disp_caltab 显示标定板 窗口句柄、描述文件、相机参数、位姿 check_hand_eye_calibration_input_poses 验证位姿数据 数据结构ID、旋转阈值、平移阈值、警告列表 calibrate_hand_eye 执行手眼校准 数据结构ID、误差列表 get_calib_data 获取标定数据 数据结构ID、数据类型、特定参数 fix_scara_ambiguity_moving_cam 解决SCARA歧义 初步位姿、参考位姿1、参考位姿2、修正值 set_origin_pose 设置位姿原点 原始位姿、XYZ修正量、输出位姿 create_pose 创建位姿 平移XYZ、旋转欧拉角、表示形式、序列类型 pose_invert 位姿求逆 输入位姿、输出逆位姿 pose_compose 位姿组合 位姿A、位姿B、组合结果
6. 核心算法简化代码
* 1. 初始化CalibObjDescr := \'scara_calplate.cpd\'CameraParam := [参数列表...]create_calib_data (\'hand_eye_scara_moving_cam\', 1, 1, CalibDataID)set_calib_data_cam_param (CalibDataID, 0, [], CameraParam)set_calib_data_calib_object (CalibDataID, 0, CalibObjDescr)* 2. 数据采集for Index := 1 to 10 read_image (Image, \'calib_\' + Index$\'02\') read_pose (\'tool_pose_\' + Index$\'02\'.dat, ToolInBasePose) set_calib_data (CalibDataID, \'tool\', Index, \'tool_in_base_pose\', ToolInBasePose) find_calib_object (Image, CalibDataID, 0, 0, Index, [], [])endfor* 3. 数据验证check_hand_eye_calibration_input_poses (CalibDataID, 0.05, 0.005, Warnings)if (|Warnings| > 0) handle_warnings(Warnings)endif* 4. 校准计算calibrate_hand_eye (CalibDataID, Errors)get_calib_data (CalibDataID, \'camera\', 0, \'tool_in_cam_pose\', ToolInCamPosePre)clear_calib_data (CalibDataID)* 5. 解决Z轴歧义read_image (RefImage1, \'ref_image1\')get_calib_plate_pose (RefImage1, CameraParam, CalibObjDescr, ObjInCamPoseRef1)read_pose (\'ref_tool_pose1.dat\', ToolInBasePoseRef1)read_pose (\'ref_tool_pose2.dat\', ToolInBasePoseRef2)fix_scara_ambiguity_moving_cam (ToolInCamPosePre, ObjInCamPoseRef1, ToolInBasePoseRef1, ToolInBasePoseRef2, ZCorrection)set_origin_pose (ToolInCamPosePre, 0, 0, ZCorrection, ToolInCamPose)* 6. 应用位姿转换pose_invert (ToolInCamPose, CamInToolPose)ObjInCamPose := [从当前图像检测结果]ToolInBasePose := [机器人当前位姿]pose_compose (CamInToolPose, ObjInCamPose, ObjInToolPose)pose_compose (ToolInBasePose, ObjInToolPose, ObjInBasePose)
7. 场景案例代码(SCARA PCB贴装系统)
* SCARA机器人PCB元件贴装系统** 系统描述: * SCARA机器人携带相机对传送带上的PCB板进行元件贴装* 每个PCB板位置可能有所偏移,需要视觉引导精确定位* 1. 初始化init_hand_eye_calibration(\'scara_calibration.dat\', ToolInCamPose, CameraParam)* 主贴装循环while (pallets_available) * 1.1 移动到预备位置 move_robot_to_scan_position(ScaraHandle) * 1.2 获取当前PCB图像 capture_pcb_image(PcbImage, CameraHandle) * 1.3 创建PCB坐标系 create_pcb_coordinate(PcbImage, PcbPose, Fiducials) if (not validate_fiducials(Fiducials)) reject_pcb() continue endif * 2. 元件贴装循环 foreach Component in ComponentList * 2.1 定位元件拾取位置 component_data := find_component(Component, PcbPose) if (not component_data.success) log_error(\'元件定位失败: \' + Component.name) continue endif  * 2.2 转换到机器人坐标系 pose_invert (ToolInCamPose, CamInToolPose) pose_compose (CamInToolPose, component_data.pick_pose, PickInToolPose)  * 获取当前机器人位姿 get_current_tool_pose(ScaraHandle, ToolInBasePose)  * 2.3 计算拾取位置 pose_compose (ToolInBasePose, PickInToolPose, PickInBasePose)  * 2.4 计算放置位置 place_pose := compute_placement_pose(component_data, PcbPose) pose_compose (CamInToolPose, place_pose, PlaceInToolPose) pose_compose (ToolInBasePose, PlaceInToolPose, PlaceInBasePose)  * 2.5 拾取元件 success := pick_component(FeederSystem, component_data.feed_location) if (not success) log_error(\'拾取失败: \' + Component.name) continue endif  * 2.6 执行贴装 scara_pick_and_place(ScaraHandle, PickInBasePose, PlaceInBasePose)  * 2.7 视觉验证 verify_placement(component_data) endforeach * 3. 完成PCB处理 mark_pcb_completed()endwhile* ------------------- 核心函数 -------------------function create_pcb_coordinate(Image, PcbPose, Fiducials){ * 1. 识别定位焊盘 find_fiducial_marks(Image, Fiducials) * 2. 匹配焊盘位置 fiducial_positions := [] foreach Fiducial in Fiducials center := get_fiducial_center(Fiducial) fiducial_positions := [fiducial_positions, center] endfor * 3. 创建PCB坐标系 calculate_pcb_pose(fiducial_positions, PcbPose)}function compute_placement_pose(Component, PcbPose){ * 1. 获取元件在PCB坐标系中的理论位置 nominal_pose := get_nominal_placement(Component.id) * 2. 组合实际PCB位姿 pose_compose(PcbPose, nominal_pose, PlacePose) * 3. 应用工艺偏移 apply_pressure_offset(PlacePose, Component.height) apply_solder_paste_compensation(PlacePose) return PlacePose}function scara_pick_and_place(ScaraHandle, PickPose, PlacePose){ * 1. 计算中间过渡点 SafeHeight := 0.05 *米 ApproachHeight := 0.005 ** 拾取路径 MoveToPosition(PickPose.X, PickPose.Y, SafeHeight) MoveVerticalTo(PickPose.Z + ApproachHeight) OpenGripper() MoveVerticalTo(PickPose.Z) CloseGripper() MoveVerticalTo(SafeHeight) * 放置路径 MoveToPosition(PlacePose.X, PlacePose.Y, SafeHeight) MoveVerticalTo(PlacePose.Z + ApproachHeight) MoveVerticalTo(PlacePose.Z) OpenGripper() MoveVerticalTo(SafeHeight)}function verify_placement(Component){ * 1. 移动到检查位置 move_to_inspection_position() * 2. 获取检查图像 capture_inspection_image(InspectionImage) * 3. 分析贴装质量 analysis_results := [] analysis_results.placement_accuracy := measure_position(Component) analysis_results.solder_paste := check_solder_paste() analysis_results.skirting := check_component_skirting() * 4. 记录结果 log_component_result(Component, analysis_results) * 5. 不合格处理 if (analysis_results.defect_level > Threshold) mark_defective_component(Component) endif}

工业应用:SCARA PCB贴装系统解析

系统特点
  1. 高速高精度贴装

    • 贴装速度:0.5秒/元件
    • 定位精度:±25μm
    • 元件尺寸适应范围:0201 (0.25×0.125mm) 到 LGA(15×15mm)
  2. 智能校准技术

    • 自动标定误差补偿
    • 动态热变形补偿
    • 真空吸嘴磨损检测
  3. 自适应工艺系统

    • 焊膏厚度实时补偿
    • 元件压力自适应控制
    • 角度偏差自动修正
技术创新点
  1. 混合坐标系系统
    • PCB基准坐标系
    • 机器人基座坐标系
    • 相机与工具关系坐标系
    • 元件贴装坐标系

多坐标系动态转换确保高精度定位

  1. 三级视觉系统

    视觉系统 分辨率 精度 功能 全局相机 5MP 50μm PCB定位 元件相机 12MP 10μm 元件拾取 检测相机 20MP 5μm 贴装验证
  2. 实时质量控制环

    #mermaid-svg-EemiW4JdoSTvNA0H {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-EemiW4JdoSTvNA0H .error-icon{fill:#552222;}#mermaid-svg-EemiW4JdoSTvNA0H .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-EemiW4JdoSTvNA0H .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-EemiW4JdoSTvNA0H .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-EemiW4JdoSTvNA0H .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-EemiW4JdoSTvNA0H .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-EemiW4JdoSTvNA0H .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-EemiW4JdoSTvNA0H .marker{fill:#333333;stroke:#333333;}#mermaid-svg-EemiW4JdoSTvNA0H .marker.cross{stroke:#333333;}#mermaid-svg-EemiW4JdoSTvNA0H svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-EemiW4JdoSTvNA0H .label{font-family:\"trebuchet ms\",verdana,arial,sans-serif;color:#333;}#mermaid-svg-EemiW4JdoSTvNA0H .cluster-label text{fill:#333;}#mermaid-svg-EemiW4JdoSTvNA0H .cluster-label span{color:#333;}#mermaid-svg-EemiW4JdoSTvNA0H .label text,#mermaid-svg-EemiW4JdoSTvNA0H span{fill:#333;color:#333;}#mermaid-svg-EemiW4JdoSTvNA0H .node rect,#mermaid-svg-EemiW4JdoSTvNA0H .node circle,#mermaid-svg-EemiW4JdoSTvNA0H .node ellipse,#mermaid-svg-EemiW4JdoSTvNA0H .node polygon,#mermaid-svg-EemiW4JdoSTvNA0H .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-EemiW4JdoSTvNA0H .node .label{text-align:center;}#mermaid-svg-EemiW4JdoSTvNA0H .node.clickable{cursor:pointer;}#mermaid-svg-EemiW4JdoSTvNA0H .arrowheadPath{fill:#333333;}#mermaid-svg-EemiW4JdoSTvNA0H .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-EemiW4JdoSTvNA0H .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-EemiW4JdoSTvNA0H .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-EemiW4JdoSTvNA0H .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-EemiW4JdoSTvNA0H .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-EemiW4JdoSTvNA0H .cluster text{fill:#333;}#mermaid-svg-EemiW4JdoSTvNA0H .cluster span{color:#333;}#mermaid-svg-EemiW4JdoSTvNA0H div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-EemiW4JdoSTvNA0H :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;}贴装前元件检查拾取验证贴装动作3D检测数据反馈

性能指标
  1. 生产效率

    • 最高贴装速度:42,000件/小时
    • 板尺寸:50×50mm - 510×460mm
    • 换型时间:< 5分钟
  2. 定位精度

    指标 规格 重复定位精度 ±10μm 绝对定位精度 ±25μm 角度精度 ±0.05° Z轴压力精度 ±10g
  3. 质量指标

    • 首次通过率:> 99.5%
    • 缺陷率:< 50ppm
    • 过程能力指数:Cpk > 1.67
应用价值
  1. 制造效率提升

    • 贴装周期缩短40%
    • 人力减少70%
    • 场地占用减少35%
  2. 质量提升

    • 缺陷率降低85%
    • 返工率降低95%
    • 工艺参数一致性提升60%
  3. 柔性制造

    • 支持多种封装工艺
    • 最小批量:1片
    • 自动配方管理

该系统代表了SCARA机器人在精密电子制造领域的最高应用水平,通过先进的手眼校准技术和高精度视觉引导,实现微米级精度的元件贴装,全面提升电子制造的质量和效率。