3、校正坐标系建立:振镜坐标系、场镜坐标系、工件坐标系的转换关系

做振镜校正,说白了就是跟三个坐标系打交道。我刚开始接触这行的时候,总觉得坐标系转换是个纯数学问题,套公式就行了。后来在产线上被现实狠狠教育了一回——你算得再漂亮,装调一偏,全白搭。

今天咱们就把这三个坐标系的关系彻底捋清楚。你想想看,激光束从振镜出来,经过场镜聚焦,最后打到工件上。每一步都涉及坐标变换。搞不懂这个,校正就是空中楼阁。

3.1 三个坐标系,各管各的事

先给它们一个明确的定义:

  • 振镜坐标系 (G):以振镜转轴中心为原点。X、Y轴对应两个镜片的偏转角度。说白了,这就是你给振镜发的指令坐标。
  • 场镜坐标系 (F):以场镜的光轴为基准。原点在场镜的入射光瞳中心。这个坐标系描述的是光束经过场镜后的理想位置。
  • 工件坐标系 (W):以工件台面为参考。原点通常设在工件的一个角上或中心。这是你最终要加工的位置。

核心认知: 振镜控制的是角度,场镜负责把角度映射成位置,工件坐标系才是你真正关心的加工坐标。三者之间是串联转换关系。

3.2 振镜坐标系 → 场镜坐标系

这一步转换,我习惯叫它「角度到位置的映射」。为什么这么说?因为振镜输出的本质是两个角度值 (θx, θy),而场镜的输入是光束的入射位置和角度。

对于理想场镜(f-θ 透镜),转换关系很简单:

X_f = f * θx
Y_f = f * θy

其中 f 是场镜的焦距。嗯,这里要注意——这个公式只在理想情况下成立。我在项目中遇到过一批场镜,实际焦距跟标称值差了0.3%。你说大不大?对于微米级加工,这误差能让你直接报废一批产品。

我的经验: 别迷信场镜的标称焦距。每次换新场镜,我都会用标准网格板实测一遍,反算出实际焦距。这个习惯帮我避免了好几次批量报废。

3.3 场镜坐标系 → 工件坐标系

这一步转换,说白了就是「理想位置到实际位置的映射」。场镜坐标系里的点 (X_f, Y_f) 是理论上的理想位置,但到了工件上,因为装调误差、工件倾斜、场镜畸变等因素,实际落点会偏移。

转换关系一般用一个仿射变换来描述:

X_w = a11 * X_f + a12 * Y_f + tx
Y_w = a21 * X_f + a22 * Y_f + ty

这里的 a11, a12, a21, a22 是旋转和缩放参数,tx, ty 是平移参数。你可能会问:这不就是个2D仿射变换吗?对,但实际应用中,我还会加入高阶项来补偿场镜的桶形畸变。

避坑指南: 我曾经遇到过一台设备,振镜和场镜的装调角度差了0.5度。仿射变换的参数怎么算都对不上。后来发现是机械装配时场镜绕Z轴转了个小角度。所以,做校正前,先确认机械装调没问题,否则你就是在用算法弥补机械的锅。

3.4 完整的转换链路

把上面两步串起来,完整的转换链路就是:

振镜角度 (θx, θy) 
    → 场镜理想位置 (X_f, Y_f) 
    → 工件实际位置 (X_w, Y_w)

反过来,校正的时候我们做的是逆向映射:

工件目标位置 (X_w, Y_w) 
    → 场镜理想位置 (X_f, Y_f) 
    → 振镜角度 (θx, θy)

这个逆向映射,就是校正算法的核心。说白了,你测出一堆网格点的实际位置,然后反算出振镜该给什么角度。

3.5 坐标系转换的SVG框架图

下面这张图,把三个坐标系的关系和转换路径画清楚了。我建议你把它存下来,调试的时候对照着看。

振镜坐标系 (G) 输入:角度 (θx, θy) 原点:振镜转轴中心 场镜坐标系 (F) 输入:理想位置 (X_f, Y_f) 原点:场镜入射光瞳 工件坐标系 (W) 输出:实际位置 (X_w, Y_w) 原点:工件台面参考点 f-θ 映射 X_f = f·θx Y_f = f·θy 仿射变换 含畸变补偿 校正逆向映射链路 工件目标 (X_w, Y_w) → 场镜理想 (X_f, Y_f) → 振镜角度 (θx, θy) 校正算法本质:求解逆向映射的参数矩阵 实测网格点 → 最小二乘拟合 → 得到校正系数

3.6 实战中的坐标系对齐

理论说完了,聊点实际的。坐标系对齐这件事,我踩过的坑比走过的路还多。

第一个坑:原点定义不一致。 振镜的原点在转轴中心,场镜的原点在光瞳,工件的原点在台面。这三个原点在物理空间里根本不重合。怎么办?我的做法是:先找一个公共参考点,比如用一个十字标记,让三个坐标系都认这个点。

第二个坑:旋转方向。 振镜的X轴正方向跟工件的X轴正方向可能相反。我记得有一次,校正完发现图形是镜像的,找了半天才发现是振镜驱动器的接线反了。嗯,这种低级错误,犯过一次就记住了。

第三个坑:单位统一。 振镜输出的是角度(度或弧度),场镜输出的是长度(毫米),工件也是长度(毫米)。转换的时候别忘了单位换算。我习惯把所有中间量都转成毫米,最后再转回角度。

我的小技巧: 在代码里用一个结构体把三个坐标系的原点、方向、单位都存起来。每次转换前先检查一遍。这个习惯帮我省了不少调试时间。

3.7 代码示例:坐标系转换类

下面是一个简单的Python类,实现了三个坐标系之间的转换。实际项目中我会加上畸变模型,这里先给个基础版本:

class CoordinateTransformer:
    def __init__(self, focal_length):
        self.f = focal_length  # 场镜焦距 (mm)
        # 仿射变换参数 (从场镜到工件)
        self.a11 = 1.0
        self.a12 = 0.0
        self.a21 = 0.0
        self.a22 = 1.0
        self.tx = 0.0
        self.ty = 0.0
    
    def g_to_f(self, theta_x, theta_y):
        """振镜角度 → 场镜理想位置"""
        x_f = self.f * theta_x  # theta 单位:弧度
        y_f = self.f * theta_y
        return x_f, y_f
    
    def f_to_w(self, x_f, y_f):
        """场镜理想位置 → 工件实际位置"""
        x_w = self.a11 * x_f + self.a12 * y_f + self.tx
        y_w = self.a21 * x_f + self.a22 * y_f + self.ty
        return x_w, y_w
    
    def g_to_w(self, theta_x, theta_y):
        """振镜角度 → 工件位置(完整链路)"""
        x_f, y_f = self.g_to_f(theta_x, theta_y)
        return self.f_to_w(x_f, y_f)
    
    def set_affine(self, a11, a12, a21, a22, tx, ty):
        """设置仿射变换参数(由校正算法计算得出)"""
        self.a11 = a11
        self.a12 = a12
        self.a21 = a21
        self.a22 = a22
        self.tx = tx
        self.ty = ty

这个类看着简单,但它是整个校正系统的基础。你想想看,所有的校正算法最终都要落到这个转换关系上。参数怎么来?靠实测网格点,用最小二乘法拟合出来。

3.8 小结

三个坐标系的关系,说白了就是:振镜给角度,场镜做映射,工件看结果。校正的本质,就是把这个映射关系反过来算清楚。

我个人习惯在每次校正前,先手动验证一下坐标系的对齐。拿一个已知位置的标记点,让振镜打一下,看看实际落点跟预期差多少。这一步花不了几分钟,但能避免后面白忙活半天。

下一节咱们会深入讲校正数据的采集方法。到时候你会看到,坐标系转换的精度直接决定了校正效果的好坏。


专注资料整理