起因

插补实战的时候发现一个缺口:那篇默认读者已经知道插补是什么,一上来就是偏差函数和递推。可"插补"恰恰是数控黑话里对开发者最不友好的一类词——两个字都认识,连起来不知道在说什么;教科书讲它之前先铺了一百页机床结构,厂商手册更干脆,一句"支持直线/圆弧插补"就翻篇。系列的规矩是不留知识黑洞,而插补是整个数控最中央的概念——解析器交出的段表、电机篇备好的脉冲、放电篇留的变频入口,最后全部汇到它身上。所以实战篇之前单开这篇,把概念从零垫平:插补是什么、为什么非有它不可、它站在系统哪一环。只假设两件事:你写过代码,并且知道步进电机来一个脉冲走一步。

这个词的来历就是答案的一半。interpolation 在数学里是"插值":已知两个点,把中间的点补出来。1952 年 MIT 改造的那台首台数控铣床面对的正是这道题——纸带上打的只有端点,起点到终点之间无穷多个中间位置,纸带打不起也存不下,必须由机床自己补出来。“插补"由此成了数控的专有动词,干的就是字面意思的事:在程序给的点之间,把中间的路一步步补出来。补路的角色叫插补器(interpolator),最早是控制柜里一抽屉门电路,后来是软件里的一个状态机——补路的家伙换了四代,题目没换过。

一、问题的模样:程序给的是几何,电机吃的是脉冲

拿一条最短的程序段开工:

1
G01 X10.0 Y5.0      ; 从当前点 (0,0) 直线走到 (10,5),单位 mm

在程序语言的世界里,这是一条连续线段,上面有无穷多个点。再看电机那头的世界:X、Y 是两台各听各脉冲的步进电机(电机篇)——X 来一个脉冲,工作台沿 X 挪 1µm;Y 来一个脉冲,沿 Y 挪 1µm。注意一个物理事实:没有任何电机能"斜着走”。工作台从不斜着滑,它只会横着挪一步、竖着挪一步,或者两边同时各挪一步。

所以"机床走出一条斜线"的真相是:把 X 方向的 10000 步和 Y 方向的 5000 步(1µm 当量)排成一个先后顺序,让工作台踩出的阶梯尽量贴住那条看不见的斜线。**插补,就是排这个顺序的算法。**把当量放大到 1mm 画出来(真实系统是 1µm,阶梯小一千倍,肉眼看就是一条光洁的直线):

1
2
3
4
5
6
7
8
Y(mm)
 4 ┤           ┌──╴
 3 ┤        ┌──╶┘       阶梯轨迹:X 的水平段 + Y 的竖直段,
 2 ┤     ┌──╶┘             每级高 1 当量、宽 2 当量
 1 ┤  ┌──╶┘             理想直线:(0,0)→(10,5) 连成的对角线,
 0 ┼──╶┘                   阶梯对它的偏差全程不超过 1 当量
   └─┬─┬─┬─┬─┬─┬─┬─┬─┬→ X(mm)
     1 2 3 4 5 6 7 8

一个容易转不过来的弯:插补不是"算出轨迹上每个点的坐标、再命令电机去那里",而是反着来——在"这一步只有 X+、X−、Y+、Y− 几个选项"的硬约束下,把几何一步一步兑现出来。约束不是数学给的,是硬件给的:接口只认脉冲沿,电机只走整步。下一节把"为什么不能顺着直觉来"的账算完。

二、为什么不直接"算坐标、发命令"——三笔账

写软件的人第一直觉都一样:来个循环,for i in 0..N { 命令电机去 (x0+i·dx, y0+i·dy) },坐标线性递增,多自然。这条路在三处同时碰壁:

接口账(最根本)。开环步进的世界里不存在"去坐标 X"这条命令,PUL/DIR 两根线只认脉冲沿——你只能喂步,不能指路。“指路"的世界(总线伺服那一族)是另一份合同(电机篇第八节),我们的目标机是步进开环,合同里没这一条。

节拍账。就算退一步只要求"按时喂步”:空走 5m/min、1µm 当量,节拍是 83kHz(电机篇第五节的账),每拍 12µs。83kHz 的中断每秒打断 CPU 八万次,每次进出栈加分发一两微秒,CPU 吃掉一成还带微秒级抖动——抖动直接变成低速爬行。结论:喂步的钟必须由硬件敲(FPGA),软件只决定"哪一步"。这正是实战篇"模式与节拍分离"的来由。

量化账。再退一步,换能指路的伺服:坐标是连续量,物理落点仍然量化到分辨率,阶梯并没有被消灭,只是从插补器搬进驱动器里排。轨迹离散是物理事实,不是算法将就——先接受它,后面的数学才立得住。

三笔账算完,问题定型成它真正的样子:**每一拍做一个极小的决定——这一拍 X 出不出步、Y 出不出步。**上面那条 10mm 斜线要做一万五千次,每次决定的预算只有几次加减和比较。插补这门学问的全部内容,就是怎么用加减比较去逼近本该乘除开方才能描述的几何。

顺带钉一个词:资料里的"插补周期"。数据采样式 CNC(伺服那一族)里插补器每隔 1ms 算一次各轴的位置设定值,这个 1ms 叫插补周期;脉冲增量式的世界里对应的是单个脉冲的节拍,12µs 量级,密近百倍。两个门派的分野和我们的选型(接口决定算法),实战篇第一节展开。

三、最笨的办法最聪明:走一步、看一眼、再走一步

人在这个问题上先给出了答案。手动车锥度的老师傅两只手各摇一个手轮,大拖板进一点、小拖板进一点,节奏有轻有重,刀尖走出来的就是斜线——他脑子里的判据并不复杂:看一眼刀偏到哪边了,下一步往回找。五十年代的硬接线数控柜把这套手感原样搬进逻辑电路:每走一个当量判一次方向,逐点比较法由此得名——走一步、比一次、再走一步。

判什么?得有个记分牌告诉机器"当前点偏在哪边"。直线 (0,0)→(10,5) 的记分牌取 F = Xe·Y − Ye·X(Xe、Ye 是全段增量,这里 =10、=5;X、Y 是当前点,教学尺度当量 1mm):理想的线是 Y = X/2,点落在线上方 Y 偏大、F > 0;落在线下方 F < 0;压线 F = 0。

每步的规则只有一条:X 走一步、Y 走一步,两个候选各算一下走完之后的 F,哪个让 |F| 更小就走哪个——永远朝"更贴线"的那边迈。前 10 步手算出来:

当前点 F 走 X 后 F′=F−5 走 Y 后 F′=F+10 走哪 走完位置
1 (0,0) 0 −5 +10 X(|−5| 小) (1,0)
2 (1,0) −5 −10 +5 Y (1,1)
3 (1,1) +5 0 +15 X (2,1)
4 (2,1) 0 −5 +10 X (3,1)
5 (3,1) −5 −10 +5 Y (3,2)
6 (3,2) +5 0 +15 X (4,2)
7 (4,2) 0 −5 +10 X (5,2)
8 (5,2) −5 −10 +5 Y (5,3)
9 (5,3) +5 0 +15 X (6,3)
10 (6,3) 0 −5 +10 X (7,3)

三个看点。第一,节奏:X 多 Y 少、平均二比一——斜率 1/2 长这个样子,没有人把比例教给算法,它从"挑 |F| 小"里自己长出来;第 3、6、9 步走完 F 正好归零,踩在线上,是这套节奏的锚点。第二,F 不用重算:X 走一步 F 就减 5、Y 走一步 F 就加 10,两个增量整段不变——这就是实战篇里"偏差递推"的全部内容,加减法伺候,一个乘法都没有。第三,终点不用算距离:X 剩余量、Y 剩余量各自数到零就到,总步数 15 = |10| + |5|,一笔明账,多一步少一步都是有 bug。

再补一刀精度:全程 |F| ≤ 5,折成几何偏差 |F|/√(Xe²+Ye²) ≤ 5/√125 ≈ 0.45 当量——阶梯的贴线误差不到半个台阶,这就是阶梯轨迹"宏观上就是直线"的定量版本。

这套数学还有段值得记的身世:1962 年 IBM 的 Bresenham 在绘图仪上独立推导出同一个 F、同一种递推(往像素网格里画直线该点亮哪格),后来成了所有光栅显示器和打印机画线的底层算法——机床和绘图仪两个世界互不知晓,殊途同归到同一条递推。3B 纸带的 J/G/Z 三个字段,就是这套逻辑硬件时代的寄存器投影(详解篇讲过来历)。

四、插补器站在链条的哪一环

把全链画出来,看"单位"怎么一路变形:

1
2
3
4
 *.nc/*.3b     段表            步进位图          PUL/DIR 沿     相电流        工作台
 ───────────解析器──→──────────插补器──→────FPGA/模式环──→────驱动器──→──电机/丝杠──→ 位移
   字符         绝对 µm 几何      每拍四轴谁出步     电平沿          斩波脉冲      (µm 级)
              [解析篇]         [本篇→实战篇]      [实战篇§四]     [电机篇]      机械本体

链条上每一环只认自己的输入输出,插补器是其中唯一"既懂数学、又懂硬件脾气"的一环:上游交给它的是纯几何(µm 整数的段表),它交出去的是纯决策(这一拍谁动)。中间还藏着一个分工:几何它自己批量算,节拍交给 FPGA 按变频频率播放——模式与节拍分离,实战篇第四节的主角,这里先立桩。

五、这个词的边界:圆弧、四轴和样条

圆弧插补是同一道题换了"贴"的对象:记分牌从"离直线偏多少"换成"离圆周偏多少"(F = x²+y²−R²,圆外为正、圆内为负),规则不变——走一步、比一次,点在圆外就往圆心那侧迈,圆内就往外迈,宏观上就是贴着圆周走。四轴联动是给四个电机各配一个放行闸门,同一节拍下按几何比例放步:XY 走轮廓、UV 摆锥度(锥形切割)。

日常语境里"插补"已经泛化成"把离散程序点之间的轨迹补出来"这一整类问题:高档铣削系统有样条插补(NURBS)、螺旋插补、渐开线插补——记分牌换得更复杂,套路没变。线切割的日常是二维轮廓,直线加圆弧全覆盖,3B 时代六十年就这两样,够用是被历史验过的;上下异形那种真三维活,本质是直线插补在四轴上的推广,不是新记分牌。我们的系统先把两样做扎实——每多一种记分牌,验证面就大一圈,这是自己写系统才体会到的账。

顺手拆一对常被混的词:驱动器手册里的"细分“和插补的”“不在一层。细分是电机内部的电气粒度——绕组电流按正弦切了多少微步(电机篇第三节,它买的是平稳不是精度);插补是轨迹上的几何粒度——工作台一拍走几个脉冲当量。一个在电机里,一个在轨迹上,互不替代。

总结

这篇就干一件事:把"插补"从一个黑话变成一个能讲清的问题。三句话版本——程序给的是几何(段表里一段段 µm 整数的线段和圆弧),电机吃的是脉冲(每拍只有 X/Y 出不出步几个选项),插补是中间排步序的算法(每一拍用加减和比较,朝更贴轨迹的方向迈一步)。三笔账解释了为什么不能"算坐标、发命令”(接口只认喂步不认指路、83kHz 节拍必须硬件敲、量化躲不掉);逐点比较的记分牌 F 和"挑 |F| 小"给了这个问题最省的解,上面那张 15 步手算表就是实战篇 LineGen 的前传。

验收三条:能把插补讲给一个没碰过机床的程序员听懂;能算出 G01 X10 Y5 在 1µm 当量下的总步数(15000)并说出为什么是两轴步数之和;能在全链图上指出插补器吞什么吐什么。过了这三条,插补实战剩下的就只是把这套直觉写成带符号的 Rust 递推、塞进 12µs 的节拍里。

参考链接