2. 逐点比较法(一):直线插补原理,偏差计算公式推导,进给方向判定规则。
各位好,今天我们聊聊逐点比较法。这个方法在数控系统里很经典,说白了就是“走一步看一步”。
我记得刚入行那会儿,师傅让我调一台老式铣床的直线插补。我盯着屏幕上的轨迹,心想这玩意儿怎么就能走出直线呢?后来才明白,逐点比较法的核心思想其实很简单——每走一步,就判断一下当前位置偏离理想直线有多远,然后决定下一步往哪走。
你想想看,这就像蒙着眼睛走路,每迈一步就问自己:“我偏了没?偏了就纠正。” 虽然笨,但可靠。很多老系统到现在还在用这个方法,就因为它计算量小、实时性好。
2.1 基本原理:走一步,看一步
逐点比较法,顾名思义,就是逐点比较当前位置与目标轨迹的偏差。具体到直线插补,我们只关心一件事:当前点是在直线的上方、下方,还是正好在直线上。
整个流程可以概括为四个步骤,我习惯叫它“四步循环”:
- 偏差判别:计算当前点相对于理想直线的偏差值。
- 坐标进给:根据偏差值,决定向X方向还是Y方向走一步。
- 偏差计算:走到新位置后,重新计算偏差。
- 终点判别:检查是否到达终点。没到就继续循环。
嗯,这里要注意:每一步只能走一个脉冲当量,要么走X,要么走Y,不能同时走。这就是逐点比较法的“离散化”思想。
核心要点:逐点比较法用“折线”逼近“直线”。虽然每一步都是走直角,但只要步长足够小,宏观上看就是一条光滑的直线。
2.2 偏差计算公式推导
好,接下来是硬核部分。我们推导一下偏差公式。
假设我们要插补一条从原点O(0,0)到终点E(Xe, Ye)的直线。注意,这里Xe和Ye都是正数,我们先把第一象限的情况搞清楚。
设当前点为P(Xi, Yi)。那么,怎么判断P点在直线的哪一侧?
我教你一个方法:用向量叉积。直线OE的方向向量是(Xe, Ye),点P相对于O的位置向量是(Xi, Yi)。这两个向量的叉积,就是判断P点偏左还是偏右的依据。
叉积公式:
F = Xe × Yi - Ye × Xi
这个F就是我们说的偏差值。它的几何意义是什么?
- F = 0:P点在直线上。
- F > 0:P点在直线上方(严格来说,是直线的逆时针侧)。
- F < 0:P点在直线下方(顺时针侧)。
为什么会这样?你想想看,如果P点在直线上方,那么向量OP相对于OE是逆时针旋转的,叉积为正。反之亦然。
个人经验:我在调试一台激光切割机时,发现切出来的直线总是偏一个角度。查了半天,发现是偏差公式里的符号搞反了。所以,一定要确认你的坐标系方向和进给方向是否匹配。我建议你推导完公式后,手动算几个点验证一下。
2.3 进给方向判定规则
有了偏差值F,下一步就好办了。进给规则很简单:
- F ≥ 0:向X正方向走一步(+X)。
- F < 0:向Y正方向走一步(+Y)。
为什么这样定?因为当F≥0时,点在直线上方或线上,我们需要让它向X方向走,靠近直线;当F<0时,点在直线下方,需要向Y方向走。
你可能会问:那F=0的时候,为什么选+X而不是+Y?其实都可以,但习惯上选+X。这样能保证轨迹的单调性。
2.4 偏差计算的递推公式
每次走一步后,如果都用原始公式重新算一遍F,计算量有点大。我们能不能用递推的方式?
当然可以。假设当前点P(Xi, Yi)的偏差为Fi,我们走一步到新点P',然后计算新偏差Fi+1。
情况一:从P向+X方向走一步
新坐标:Xi+1 = Xi + 1, Yi+1 = Yi
新偏差:
Fi+1 = Xe × Yi+1 - Ye × Xi+1
= Xe × Yi - Ye × (Xi + 1)
= (Xe × Yi - Ye × Xi) - Ye
= Fi - Ye
情况二:从P向+Y方向走一步
新坐标:Xi+1 = Xi, Yi+1 = Yi + 1
新偏差:
Fi+1 = Xe × (Yi + 1) - Ye × Xi
= (Xe × Yi - Ye × Xi) + Xe
= Fi + Xe
你看,递推公式只需要加减法,没有乘法。这就是逐点比较法高效的原因。
递推公式总结:
- 向+X走:
F ← F - Ye - 向+Y走:
F ← F + Xe
2.5 终点判别
终点判别有两种常用方法:
| 方法 | 原理 | 特点 |
|---|---|---|
| 总步数法 | 总步数 N = Xe + Ye,每走一步减1,减到0为止 | 简单可靠,最常用 |
| 坐标比较法 | 判断当前坐标是否等于终点坐标 | 需要比较两个坐标,略复杂 |
我个人习惯用总步数法。为什么?因为只需要一个计数器,减法操作,效率高。我曾经在一个项目里用坐标比较法,结果因为坐标值比较大,每次比较都要花额外时间,后来改回总步数法,问题就解决了。
2.6 完整流程与SVG图
我们把整个流程串起来,看一张流程图就清楚了。
避坑指南:我曾经在一个项目中,终点判别用了坐标比较法,结果因为坐标值很大(Xe=50000, Ye=30000),每次比较都要做两次减法,导致插补周期不稳定。后来换成总步数法,用一个计数器搞定。所以,如果对实时性要求高,优先用总步数法。
2.7 手动算一个例子
光说不练假把式。我们手动算一个例子:从(0,0)到(4,3)。
初始化:F=0, N=4+3=7
| 步数 | 当前点 | F值 | F≥0? | 进给方向 | 新F值 | 剩余步数 |
|---|---|---|---|---|---|---|
| 0 | (0,0) | 0 | 是 | +X | 0-3=-3 | 6 |
| 1 | (1,0) | -3 | 否 | +Y | -3+4=1 | 5 |
| 2 | (1,1) | 1 | 是 | +X | 1-3=-2 | 4 |
| 3 | (2,1) | -2 | 否 | +Y | -2+4=2 | 3 |
| 4 | (2,2) | 2 | 是 | +X | 2-3=-1 | 2 |
| 5 | (3,2) | -1 | 否 | +Y | -1+4=3 | 1 |
| 6 | (3,3) | 3 | 是 | +X | 3-3=0 | 0 |
| 7 | (4,3) | 0 | — | 终点 | — | 0 |
你看,走了7步,正好到达终点(4,3)。每一步的进给方向都是根据F值实时决定的,这就是逐点比较法的精髓。
小技巧:调试的时候,我习惯把每一步的坐标和F值打印出来,画在纸上。这样能直观地看到轨迹是否合理。如果发现轨迹偏离太大,多半是递推公式写错了。
2.8 第一象限的局限性
我们刚才讲的都是第一象限的情况。实际加工中,直线可能出现在任何象限。怎么办?
其实很简单:根据象限调整进给方向。比如第二象限,X方向是负的,Y方向是正的。进给规则要相应调整。
不过别急,我们先把第一象限吃透。后面的章节会扩展到其他象限。你想想看,如果第一象限搞明白了,其他象限无非是符号变化,对吧?
嗯,今天就到这里。记住一句话:逐点比较法,走一步算一步,步步为营。这个方法虽然古老,但它的思想在很多现代算法中依然能看到影子。