3. 手眼标定系统搭建

任务目标

搭建一套可用于后续手眼标定算法验证的物理实验平台:完成工业机器人、相机与标定板的安装布局,确定手眼关系模式(眼在手上或眼在手外),并打通机器人控制柜与上位机之间的通信链路,使上位机能够读取机器人当前位姿。

平台组成与安装要求

  • 工业机器人:任意支持外部通信的六轴工业机器人(如UR、ABB、KUKA、汇川等),需开启TCP/IP或Modbus TCP服务端,用于响应位姿查询请求。
  • 相机:固定焦距工业相机(如海康MV-CA系列、Basler acA系列),通过GigE或USB3.0接口连接上位机,能够输出未畸变或带畸变系数的灰度/彩色图像。
  • 标定板:棋盘格或圆点阵标定板,推荐7×10棋盘格(内角点6×9),方格边长20mm或30mm,打印后粘贴于刚性平面。
  • 安装模式:二选一,本案例以眼在手外(固定相机)为例——相机固定安装于机器人工作空间上方或侧方,标定板安装在机器人末端法兰上。若采用眼在手上模式,则相机刚性连接于末端法兰,标定板固定于工作空间内。

通信配置

上位机与机器人之间采用TCP/IP通信,机器人作为服务端监听固定端口(如30001),上位机作为客户端发送位姿查询指令。以下以UR机器人(端口30001,数据格式为URScript)为例,给出最小通信实现。其他品牌机器人请参照其官方通信协议替换数据解析部分。

关键完整代码

import socket
import struct
import time

# ========== 机器人通信(UR机器人,端口30001) ==========
ROBOT_IP = "192.168.1.10"
ROBOT_PORT = 30001

def get_robot_pose():
    """连接UR机器人,读取当前TCP位姿(x,y,z,rx,ry,rz)"""
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.settimeout(3)
        s.connect((ROBOT_IP, ROBOT_PORT))
        # 等待UR发送数据包(每10ms发送一次,共110字节)
        data = b""
        while len(data) < 110:
            chunk = s.recv(110 - len(data))
            if not chunk:
                break
            data += chunk
        s.close()
        if len(data) < 110:
            raise ValueError("数据包不完整")
        # 解析TCP位姿:偏移28字节处为x,y,z,偏移52字节处为rx,ry,rz(均为float64)
        pose = struct.unpack("!6d", data[28:76])
        return pose  # (x, y, z, rx, ry, rz)
    except Exception as e:
        print(f"通信失败: {e}")
        return None

# ========== 相机连接(以海康GigE相机为例,需安装MVS SDK) ==========
# 实际使用时请替换为对应相机SDK的调用方式
def grab_image():
    """采集一帧图像(示意代码,需按相机SDK实际接口调整)"""
    # from pymvsc import MvCamera  # 示例导入
    # cam = MvCamera()
    # cam.open_device_by_ip("192.168.1.20")
    # cam.start_grabbing()
    # frame = cam.get_frame()
    # cam.stop_grabbing()
    # cam.close()
    # return frame.image_array
    pass  # 替换为实际相机采集代码

# ========== 验证主流程 ==========
if __name__ == "__main__":
    # 1. 验证机器人通信
    pose = get_robot_pose()
    if pose is not None:
        print(f"机器人位姿: x={pose[0]:.3f}, y={pose[1]:.3f}, z={pose[2]:.3f}, "
              f"rx={pose[3]:.3f}, ry={pose[4]:.3f}, rz={pose[5]:.3f}")
    else:
        print("机器人通信失败,请检查IP和端口")
    
    # 2. 验证相机采集(需安装对应SDK后取消注释)
    # img = grab_image()
    # if img is not None:
    #     print(f"图像采集成功,尺寸: {img.shape}")
    # else:
    #     print("相机采集失败")

运行与验证

  1. 机器人通信验证:将机器人控制柜IP设为192.168.1.10,确保上位机与机器人处于同一网段。运行上述代码,若终端打印出6个浮点数位姿,说明通信链路正常。
  2. 相机采集验证:安装相机厂商SDK(如海康MVS),将相机IP设为192.168.1.20,取消代码中grab_image()的注释并替换为实际SDK调用。运行后若打印图像尺寸,说明相机连接正常。
  3. 平台就绪判定:机器人通信正常且相机能采集到包含标定板的清晰图像,即视为平台搭建完成。此时可手动移动机器人至不同位姿,每次移动后记录机器人位姿并拍摄一张标定板图像,为后续标定采集数据。

常见问题

  • 机器人连接超时:检查控制柜网络端口是否开启、IP是否可达(ping 192.168.1.10)、UR机器人需在设置中启用“Dashboard Server”和“Primary Client Interface”。
  • 图像模糊:调整相机曝光时间和光圈,确保标定板在视野内清晰成像;若标定板反光,可调整光源角度。
  • 位姿数据异常:确认机器人当前处于非奇异位形,且TCP坐标系定义正确(UR默认使用工具坐标系)。