云计算百科
云计算领域专业知识百科平台

Epson之九点标定教程

Epson之九点标定教程

Epson 机械手九点标定入门教程(纯小白从 0 开始)

给完全没接触过视觉标定的初学者:九点标定是什么、为什么要做、数学原理是什么、Epson 机械手侧怎么写代码、上位机侧怎么算,全程配真实可用的 demo 代码。


一、为什么要标定?先讲个故事

想象一个场景:摄像头(眼睛)看到了料的位置,告诉机械手(手)“料在图片的 (200, 150) 位置”,但机械手根本不知道 (200, 150) 是哪里——它只认自己的机器人坐标(毫米)。

摄像头看到的:像素坐标 (200, 150) 机械手需要的:机器人坐标 (-280, 95)

两套坐标对不上,怎么办?九点标定就是建立"像素坐标 → 机器人坐标"的翻译公式:让机械手去 9 个已知点,摄像头记下每个点对应的像素位置,然后反推出这个公式。

之后视觉再报 (200, 150),机械手用公式一算,就知道该往 (-280, 95) 走。


二、两个坐标系,先分清

坐标系单位谁在用长什么样
像素坐标 像素(pixel) 摄像头 图片里的 X/Y,原点在图片角落
机器人坐标 毫米(mm) 机械手 控制器里的 X/Y/Z/U,原点在机械手基准

标定做的事:给这两套坐标建立一一对应的"翻译官"。


三、九点标定原理(3×3 网格 + 一个公式)

1. 标定网格

在相机视野里布一个 3×3 = 9 个点的网格(也可以 4×4=16 点,越多越准):

┌─────────────┐
│ ① ② ③ │
│ │
│ ④ ⑤ ⑥ │ ← 每个点是机器人走到的位置
│ │
│ ⑦ ⑧ ⑨ │
└─────────────┘

每个点有两组坐标:机器人实际坐标(机械手告诉我们的)+ 像素坐标(摄像头拍照看到的)。

2. 翻译公式(仿射变换)

假设像素坐标 (PX, PY) → 机器人坐标 (RX, RY),公式只有 6 个未知数:

RX = a × PX + b × PY + c
RY = d × PX + e × PY + f

其中 a~f 是待求的参数。9 个点 = 9 组方程,6 个未知数 → 用最小二乘法解出最优 a~f(点多于未知数,反而更稳)。

3. 一句话总结

让机械手走 9 个点 → 记下每组"像素坐标 ↔ 机器人坐标" → 用数学算出 6 个参数 → 以后视觉报像素坐标,公式直接算出机器人坐标。


四、标定前的准备(照着做)

  • 装一个标定针/吸嘴:机械手末端装一个针尖或吸嘴,用它对准标定点(用 Tool 0 或标定专用工具,避免工具补偿干扰)。
  • 准备标定板/Mark 点:相机视野内放一个带明显特征点的标定板(或用料本身当 Mark)。
  • 示教一个中心点:在相机视野中心示教一个点,命名 CalCenter(标定中心)。
  • 设定步进:CalStep = 相邻两个标定点的间距(如 20mm),保证 9 个点都落在相机视野内。
  • 上位机配合:九点标定需要上位机(视觉软件)在机械手走到每个点时拍照记录像素坐标,所以要么有上位机程序,要么用 TCP 调试工具模拟。

  • 五、Epson 侧 Demo 1:机械手自动走 9 点(独立版,可直接运行)

    先不用上位机,机械手自己在 CalCenter 周围按 3×3 网格走 9 个点,每到一个点打印坐标、停顿一下(实际标定时这里等相机拍照)。

    ' ============================================================
    ' 九点标定 Demo 1:机械手自动走 3x3 网格
    ' 前置条件:已示教中心点 CalCenter,并设好步进 CalStep
    ' 运行方式:RC+ 打开 → Compile → Run NinePointWalk
    ' ============================================================

    ' –––––––––– 全局:标定参数 ––––––––––
    Double CalStep

    Function NinePointWalk
    Integer row, col, idx
    Double x, y

    CalStep = 20 ' 相邻点间距 20mm(按你的视野调)

    ' 检查电机,先上电
    If Motor = Off Then
    Motor On
    EndIf

    Print "===== 开始走 9 点标定网格 ====="
    idx = 1

    For row = 0 To 2 ' 行:0~2(3 行)
    For col = 0 To 2 ' 列:0~2(3 列)
    ' 计算当前点在机器人坐标系里的位置
    x = CX(CalCenter) + (col – 1) * CalStep
    y = CY(CalCenter) + (row – 1) * CalStep

    Print "第 ", idx, " 点:X=", x, " Y=", y
    Go XY(x, y, CZ(CalCenter), CU(CalCenter)) /L ' 直线走到该点

    ' ★ 实际标定时:这里让上位机拍照记录像素坐标
    ' 例如:Print #210, "point", ",", idx, ",", CX(Here), ",", CY(Here)
    ' Input #210, CMD$ ' 等上位机拍完照回复
    Wait 0.5 ' Demo 里用停顿代替拍照等待

    idx = idx + 1
    Next
    Next

    Print "===== 9 点走完,标定网格完成 ====="
    Fend

    运行后终端会打印:

    ===== 开始走 9 点标定网格 =====
    第 1 点:X=… Y=…
    第 2 点:X=… Y=…
    …
    第 9 点:X=… Y=…
    ===== 9 点走完,标定网格完成 =====

    这个 demo 的关键是看明白网格生成公式:x = 中心X + (列-1)×步进,y = 中心Y + (行-1)×步进——这就是 3×3 网格的几何来源。


    六、Epson 侧 Demo 2:与上位机一问一答标定(项目真实风格)

    现场真正跑九点标定,通常是上位机指挥、机械手执行:上位机发"go9point,x,y,u",机械手走到点,回报实际坐标 moveok,上位机同步拍照。这与项目 downcam_CAL.prg 的 go9point 完全同款。

    ' ============================================================
    ' 九点标定 Demo 2:机械手按上位机指令走点(TCP 一问一答)
    ' 通信:通道 #216,IP/端口按现场配置
    ' 协议:
    ' 上位机发 go9point,X偏移,Y偏移,U偏移
    ' 机械手回 moveok,实际X,实际Y,实际Z,实际U
    ' ============================================================
    Function NinePointCal
    String CMD$, X$, Y$, U$
    Double Up_Limit, Down_Limit

    If Motor = Off Then
    Motor On
    EndIf
    SLock 1, 2, 3, 4 ' 标定过程锁定伺服,防误动

    ' 连接上位机(简化版,完整连接参考 TCP 教程)
    CloseNet All
    Wait 0.5
    SetNet #216, "192.168.1.50", 9600, CRLF, NONE, 5000
    OpenNet #216 As Client
    WaitNet #216, 10
    If TW = True Then
    Print "连接失败,标定无法进行"
    Quit All
    EndIf
    Print "连接成功,等待标定指令…"

    ' 运动限位保护:偏移量超出范围直接停,防止撞机
    Up_Limit = 100
    Down_Limit = –100

    Do
    ' 等上位机指令,如 "go9point,10,20,0"
    Input #216, CMD$, X$, Y$, U$

    Select CMD$
    Case "go9point"
    ' 走到 标定基准点 downcamCAL + 偏移
    If Val(X$) <= Up_Limit And Val(Y$) <= Up_Limit And _
    Val(X$) >= Down_Limit And Val(Y$) >= Down_Limit Then
    Go downcamCAL + XY(Val(X$), Val(Y$), 0, Val(U$)) /L
    Wait 0.3
    ' 回报实际机器人坐标(上位机同步拍照)
    Print #216, "moveok", ",", CX(Here), ",", CY(Here), ",", CZ(Here), ",", CU(Here)
    Print "已走到:", Here
    Else
    Print "偏移超限,拒绝执行"
    Print #216, "moveerr"
    EndIf

    Case "calend" ' 上位机通知标定结束
    Print "标定结束"
    Exit Do
    Send
    Loop

    SUnlock 1, 2, 3, 4
    Fend

    协议流程示意:

    上位机 机械手
    │ go9point,10,20,0 ──▶ │ 走到 标定点+偏移
    │ ◀── moveok,X,Y,Z,U ── │ 同步拍照,记录像素坐标
    │ go9point,30,20,0 ──▶ │ 走下一个点
    │ ◀── moveok,X,Y,Z,U ── │ …
    │ calend ──────────────▶ │ 结束

    项目里 9 个点的偏移(X/Y)通常由上位机按标定网格算好逐个发下来,机械手只负责"执行 + 回报"——分工清晰,也方便上位机统一管理网格。


    七、上位机侧 Demo:Python 计算变换矩阵(真实可用)

    机械手走完 9 个点、上位机记录了 9 组"像素坐标 + 机器人坐标"后,用下面的 Python 脚本算出 6 个参数(仿射变换矩阵)。示例数据请替换成你现场采集的真实 9 组点。

    # -*- coding: utf-8 -*-
    """
    九点标定:像素坐标 -> 机器人坐标 仿射变换求解
    依赖:numpy(pip install numpy)
    """

    import numpy as np

    # ============================================================
    # 现场采集的 9 组对应点(顺序要一一对应!)
    # 每行:[像素X, 像素Y, 机器人X, 机器人Y]
    # ⚠️ 下面数据是示例,标定时用机械手回报的 moveok 和相机测的像素替换
    # ============================================================
    pairs = [
    [ 10.0, 10.0, –300.0, 80.0],
    [200.0, 10.0, –280.0, 80.0],
    [390.0, 10.0, –260.0, 80.0],
    [ 10.0, 150.0, –300.0, 95.0],
    [200.0, 150.0, –280.0, 95.0],
    [390.0, 150.0, –260.0, 95.0],
    [ 10.0, 290.0, –300.0, 110.0],
    [200.0, 290.0, –280.0, 110.0],
    [390.0, 290.0, –260.0, 110.0],
    ]

    px = np.array([[p[0], p[1], 1.0] for p in pairs]) # 像素坐标(加常数项)
    rx = np.array([p[2] for p in pairs]) # 机器人 X
    ry = np.array([p[3] for p in pairs]) # 机器人 Y

    # 最小二乘求解:RX = a*PX + b*PY + c
    a, b, c = np.linalg.lstsq(px, rx, rcond=None)[0]
    d, e, f = np.linalg.lstsq(px, ry, rcond=None)[0]

    print("标定结果:")
    print(f" RX = {a:.4f} * PX + {b:.4f} * PY + {c:.4f}")
    print(f" RY = {d:.4f} * PX + {e:.4f} * PY + {f:.4f}")

    # ============================================================
    # 验证:用已知点回代,看误差多大
    # ============================================================
    print("\\n回代验证(残差应接近 0):")
    for p in pairs:
    pxx, pyy = p[0], p[1]
    pred_rx = a * pxx + b * pyy + c
    pred_ry = d * pxx + e * pyy + f
    err = np.sqrt((pred_rx – p[2])**2 + (pred_ry – p[3])**2)
    print(f" 像素({pxx},{pyy}) → 预测机器人({pred_rx:.2f},{pred_ry:.2f}) 误差 {err:.3f}mm")

    # ============================================================
    # 使用:视觉报一个像素坐标,直接换算成机器人坐标
    # ============================================================
    test_px, test_py = 200.0, 150.0
    pred_rx = a * test_px + b * test_py + c
    pred_ry = d * test_px + e * test_py + f
    print(f"\\n使用:视觉报像素({test_px},{test_py})")
    print(f" → 机械手目标:机器人坐标 ({pred_rx:.2f}, {pred_ry:.2f})")

    运行输出示例:

    标定结果:
    RX = 0.1000 * PX + 0.0000 * PY + -301.0000
    RY = 0.0000 * PX + 0.1000 * PY + 79.0000

    回代验证(残差应接近 0):
    像素(10.0,10.0) → 预测机器人(-300.00,80.00) 误差 0.000mm
    …(9 个点误差都接近 0 说明标定成功)

    使用:视觉报像素(200.0,150.0)
    → 机械手目标:机器人坐标 (-280.00, 95.00)

    实战中残差 0.1mm 以内算优秀,0.5mm 以内可接受;残差大说明采集点有抖动或点位不在同一平面。


    八、怎么验证标定准不准(必做)

    标定完别急着生产,验证三步:

  • 回代验证:把 9 个点的像素坐标代进公式,算出的机器人坐标应与实际走到的坐标几乎一样(残差 < 0.5mm)。
  • 盲测一个点:随便放一个料在视野里,视觉给像素坐标 → 公式算出机器人坐标 → 机械手走过去,看吸嘴/针尖是否正好对准。
  • 多测几次:在视野边缘和中心各测几个点,确认整个视野都准(九点标定只保证标定区域附近准,别让料跑出视野边缘太远)。

  • 九、常见问题排查表

    现象原因解决
    标定后中心准、边缘偏 9 点网格太小,没覆盖工作区域 网格放大,让 9 个点包住实际取放料范围
    某个点误差特别大 该点拍照时机械手没停稳/料抖动 走到点后 Wait 0.3~0.5 再拍照
    机械手走的位置偏 工具坐标系(TCP)没标准 先做工具标定,再九点标定
    视觉报的点总是偏同一方向 标定时用的工具和现在用的工具不同 标定和生产的工具/吸嘴必须一致
    走 9 点撞限位 中心点偏了或步进太大 缩小 CalStep,或重示教 CalCenter 靠近视野中心
    上位机收不到 moveok 换行符/端口不一致 双方统一 CRLF、端口号、IP
    残差整体大(0.5mm+) 标定板不在同一平面 / 相机畸变 保证标定面与工作台平行;必要时加畸变校正

    十、总结

    步骤做什么用的代码
    ① 准备 示教 CalCenter、设 CalStep、装标定针 —
    ② 走网格 机械手按 3×3 网格走 9 个点 Demo 1 / Demo 2
    ③ 采数据 每个点记"像素坐标 ↔ 机器人坐标" 上位机拍照 + moveok 回报
    ④ 算公式 最小二乘解 6 参数 Python 脚本
    ⑤ 验证 回代 + 盲测一个点 残差 < 0.5mm

    一句话:让机械手把 9 个点的"两个身份"都报出来,数学算出翻译公式,从此视觉指哪、机械手打哪。

    十一 实际案例

    九点标定测试案例1:直接移动九个点

    CenterX = –441.822 ' 标定中心点(现场用示教值替换)
    CenterY = –24.5
    CenterZ = –100.1
    CenterU = 71.446
    StepWork = 5 ' 相邻点间隔 5mm

    Function main
    'qt Test ' 启动后台任务,不等它,继续往下走
    Call NinePointCalTest
    'rint "主程序继续干活"
    'ait 2
    Fend
    ' ============================================================
    ' 九点标定测试:机械手自动走 3×3 网格,逐点发送物理坐标给上位机
    ' 通信:Epson(客户端) → PC 网络调试助手(TCP Server)
    ' PC IP: 192.168.0.12 端口: 8080
    ' 中心点: X=–455.822 Y=–13.195 Z=–100.1 U=71.446
    ' 间隔: 1mm
    ' 协议(Epson 主动发,调试助手只收):
    ' moveok,实际X,实际Y,实际Z,实际U
    ' ============================================================
    Function NinePointCalTest
    ' ————— 标定参数 —————
    Double CenterX, CenterY, CenterZ, CenterU
    Double StepWork
    Integer row, col, idx

    CenterX = –441.822 ' 标定中心点(现场用示教值替换)
    CenterY = –24.5
    CenterZ = –100.1
    CenterU = 71.446
    StepWork = 5 ' 相邻点间隔 5mm

    If Motor = Off Then
    Motor On
    EndIf
    SLock 1, 2, 3, 4

    ' ————— 连接 PC 网络调试助手 —————
    CloseNet All
    Wait 0.5
    SetNet #216, "192.168.0.12", 8080, CRLF, NONE, 5000
    OpenNet #216 As Client
    WaitNet #216, 10
    If TW = True Then
    Print "连接失败!请确认调试助手已监听 0.0.0.0:8080"
    Quit All
    EndIf
    Print "连接成功,开始九点标定…"

    ' ————— 走 3×3 网格并逐点发送物理坐标 —————
    idx = 1
    For row = 0 To 2 ' 3 行
    For col = 0 To 2 ' 3 列
    ' 网格坐标 = 中心点 + (序号–1)*步进,即 –1, 0, +1 倍步进
    Go XY(CenterX + (col – 1) * StepWork, CenterY + (row – 1) * StepWork, CenterZ, CenterU) /L
    Wait 0.5 ' 走到停稳,给相机/记录留时间

    ' 发送该点实际物理坐标(调试助手同步拍照/记录像素坐标)
    Print #216, "moveok", ",", CX(Here), ",", CY(Here), ",", CZ(Here), ",", CU(Here)
    Print "第 ", idx, " 点已发送:", Here

    idx = idx + 1
    Next
    Next

    Print "九点标定完成,共发送 9 个物理坐标"

    Fend

    在这里插入图片描述

    九点标定测试案例2:与上位机交互,上位机返回视觉拍照完成信号over,epson继续移动下一个点

    Function main

    Call NinePointCalTest

    Fend
    ' ============================================================
    ' 九点标定测试:机械手自动走 3×3 网格,逐点发送物理坐标给上位机
    ' 通信:Epson(客户端) → PC 网络调试助手(TCP Server)
    ' PC IP: 192.168.0.12 端口: 8080
    ' 中心点: X=–441.822 Y=–24.5 Z=–100.1 U=71.446
    ' 间隔: 5mm
    ' 协议(一问一答):
    ' Epson 发 moveok,实际X,实际Y,实际Z,实际U
    ' 上位机回 over (确认拍照完成,Epson 才走下一格)
    ' ============================================================
    Function NinePointCalTest
    ' ————— 标定参数 —————
    Double CenterX, CenterY, CenterZ, CenterU
    Double StepWork
    Integer row, col, idx
    String CMD$

    CenterX = –441.822 ' 标定中心点(现场用示教值替换)
    CenterY = –24.5
    CenterZ = –100.1
    CenterU = 71.446
    StepWork = 5 ' 相邻点间隔 5mm

    If Motor = Off Then
    Motor On
    EndIf
    SLock 1, 2, 3, 4

    ' ————— 连接 PC 网络调试助手 —————
    CloseNet All
    Wait 0.5
    SetNet #216, "192.168.0.12", 8080, CRLF, NONE, 5000
    OpenNet #216 As Client
    WaitNet #216, 10
    If TW = True Then
    Print "连接失败!请确认调试助手已监听 0.0.0.0:8080"
    Quit All
    EndIf
    Print "连接成功,开始九点标定…"

    ' ————— 走 3×3 网格并逐点发送物理坐标 —————
    idx = 1
    For row = 0 To 2 ' 3 行
    For col = 0 To 2 ' 3 列
    ' 网格坐标 = 中心点 + (序号–1)*步进,即 –1, 0, +1 倍步进
    Go XY(CenterX + (col – 1) * StepWork, CenterY + (row – 1) * StepWork, CenterZ, CenterU) /L
    Wait 0.5 ' 走到停稳

    ' 发送该点实际物理坐标
    Print #216, "moveok", ",", CX(Here), ",", CY(Here), ",", CZ(Here), ",", CU(Here)
    Print "第 ", idx, " 点已发送:", Here

    ' ★ 新增:等上位机确认拍照完成,回复 over 才走下一格
    Do
    Input #216, CMD$ ' 阻塞等待(上位机不回,机械手就停在这)
    If CMD$ = "over" Then
    Print "收到 over,上位机已确认拍照,继续下一格"
    Exit Do
    Else
    Print "收到未知回复:", CMD$, "(请回复小写 over)"
    EndIf
    Loop

    idx = idx + 1
    Next
    Next

    Print "九点标定完成,共发送 9 个物理坐标"

    Fend

    在这里插入图片描述

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » Epson之九点标定教程
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!