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 个参数 → 以后视觉报像素坐标,公式直接算出机器人坐标。


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

  1. 装一个标定针/吸嘴:机械手末端装一个针尖或吸嘴,用它对准标定点(用 Tool 0 或标定专用工具,避免工具补偿干扰)。
  2. 准备标定板/Mark 点:相机视野内放一个带明显特征点的标定板(或用料本身当 Mark)。
  3. 示教一个中心点:在相机视野中心示教一个点,命名 CalCenter(标定中心)。
  4. 设定步进:CalStep = 相邻两个标定点的间距(如 20mm),保证 9 个点都落在相机视野内。
  5. 上位机配合:九点标定需要上位机(视觉软件)在机械手走到每个点时拍照记录像素坐标,所以要么有上位机程序,要么用 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 以内可接受;残差大说明采集点有抖动或点位不在同一平面。


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

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

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

九、常见问题排查表

现象原因解决
标定后中心准、边缘偏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
' ============================================================
' 九点标定测试:机械手自动走 3x3 网格,逐点发送物理坐标给上位机
' 通信: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 "连接成功,开始九点标定..."

    ' ---------- 走 3x3 网格并逐点发送物理坐标 ----------
    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
' ============================================================
' 九点标定测试:机械手自动走 3x3 网格,逐点发送物理坐标给上位机
' 通信: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 "连接成功,开始九点标定..."

    ' ---------- 走 3x3 网格并逐点发送物理坐标 ----------
    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

在这里插入图片描述

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐