插补算法基础:直线插补原理、圆弧插补原理、逐点比较法、数字积分法
各位工程师朋友,大家好。今天我们来聊聊运动控制里最基础、也最核心的一块——插补算法。
说实话,我刚入行那会儿,觉得插补就是“让电机走直线、画圆弧”。后来踩了不少坑才明白,插补的本质是用离散的脉冲序列,去逼近一条连续的运动轨迹。你想想看,电机只能走一步算一步,但我们要它走出平滑的直线或圆弧,这中间就需要一套“算法”来指挥。
这一章,我会把四种最经典的插补方法掰开揉碎了讲。分别是:直线插补、圆弧插补、逐点比较法、数字积分法。嗯,咱们一个一个来。
一、直线插补原理
直线插补,说白了就是让运动部件从起点A走到终点B,走出一条笔直的线。但问题是,电机只能走X轴或Y轴方向,不能走斜线。怎么办?
答案是:用X和Y方向的微小步进,交替或同时走,合成出斜线效果。
我习惯把直线插补分成两类:
- 逐点比较法直线插补:每一步都判断当前位置在直线的哪一侧,然后决定下一步往哪个方向走。
- 数字积分法直线插补:用积分的思想,把速度分量累加起来,决定何时走一步。
先看逐点比较法。它的核心逻辑就四个字:偏差判别。
假设我们要从(0,0)走到(4,3)。每一步,我们计算一个偏差值F:
- 如果F >= 0,说明点在直线上方或线上,下一步走+X方向。
- 如果F < 0,说明点在直线下方,下一步走+Y方向。
每次走完一步,更新偏差值。就这么简单。
核心公式(直线插补偏差递推):
设终点坐标为(Xe, Ye),当前偏差为F。
- 若F >= 0:走+X,新偏差 F' = F - Ye
- 若F < 0:走+Y,新偏差 F' = F + Xe
直到走到终点为止。
我在项目中遇到过一个问题:用逐点比较法走长直线时,如果终点坐标很大(比如上万脉冲),偏差值会变得很大,导致计算溢出。后来我改用相对偏差,每次只保留小范围的差值,才解决了这个问题。
二、圆弧插补原理
圆弧插补比直线复杂一些。它的目标是让刀具沿着圆弧轨迹运动。
你想想看,圆弧上每个点的切线方向都在变,电机怎么跟?
常用的方法还是逐点比较法,只不过偏差公式换成了圆的方程。
假设圆心在原点,半径为R,当前点坐标为(Xi, Yi)。偏差值F = Xi² + Yi² - R²。
- 如果F >= 0,点在圆外或圆上,下一步走 -X 方向(向圆内修正)。
- 如果F < 0,点在圆内,下一步走 +Y 方向(向圆外修正)。
当然,这只是第一象限逆圆的情况。实际工程中,还要考虑象限切换、顺圆逆圆等。
避坑指南:我曾经在四象限圆弧插补时,忘记处理象限边界处的方向切换,结果刀具在过象限时“卡”了一下,工件表面留下明显刀痕。后来我加了一个象限检测逻辑,每次过象限前预判下一步方向,才彻底解决。
三、逐点比较法详解
逐点比较法,名字很直白:每走一步,比较一下当前位置和目标轨迹的偏差。
它的工作流程是一个循环:
- 偏差判别:计算当前偏差F。
- 坐标进给:根据F的正负,决定走X还是Y。
- 偏差计算:更新F值。
- 终点判别:判断是否到达终点。
这个方法的优点是:算法简单,计算量小,适合硬件实现。早期很多数控系统都用它。
缺点也很明显:速度不均匀。因为每一步的进给方向不同,合成速度会有波动。我做过测试,在低速时影响不大,但高速时会导致振动。
注意:逐点比较法只适用于两轴联动。三轴以上要用更复杂的算法,比如数字积分法或样条插补。
四、数字积分法(DDA)
数字积分法,英文叫Digital Differential Analyzer,简称DDA。它的思路和逐点比较法完全不同。
DDA的核心思想是:把速度看成积分量,累加溢出时走一步。
举个例子。假设X轴速度是Vx,Y轴速度是Vy。我们设置两个累加器,每个时钟周期累加一次。当累加器溢出时,对应的轴就走一步。
这样,走步的频率就和速度成正比了。
DDA直线插补公式:
设累加器位数为N,终点坐标为(Xe, Ye)。
- 每个周期:X累加器 += Xe,Y累加器 += Ye
- 若X累加器溢出,则X轴走一步,累加器减去2^N
- 若Y累加器溢出,则Y轴走一步,累加器减去2^N
直到总步数达到2^N次为止。
DDA的优点很明显:速度均匀,适合多轴联动。而且它天然支持直线和圆弧,只要改变累加值就行。
但DDA也有个坑:累加器位数有限,会导致轨迹误差。我记得有一次做高精度雕刻机,用8位累加器,结果走出来的直线有肉眼可见的锯齿。后来换成16位累加器,问题才解决。
五、两种方法的对比
| 对比项 | 逐点比较法 | 数字积分法(DDA) |
|---|---|---|
| 核心思想 | 偏差判别,逐点逼近 | 速度积分,累加溢出 |
| 计算量 | 小(加减法为主) | 中等(累加+比较) |
| 速度均匀性 | 较差(有波动) | 较好(均匀) |
| 多轴扩展 | 困难(两轴为主) | 容易(任意轴数) |
| 精度控制 | 取决于步长 | 取决于累加器位数 |
| 典型应用 | 早期数控系统 | 现代运动控制卡 |
我个人习惯:低速、两轴场景用逐点比较法;高速、多轴场景用DDA。当然,现在很多高端控制器直接用样条插补了,但理解这两种基础方法,是理解更复杂算法的基础。
六、知识体系总览
下面这张图,是我自己整理的插补算法知识框架。你可以看到,直线和圆弧是基础,逐点比较法和DDA是两种实现路径。
从这张图你可以看到,直线和圆弧是“做什么”,逐点比较法和DDA是“怎么做”。理解了这两层,你就掌握了插补算法的核心。
七、代码示例:逐点比较法直线插补
最后,我贴一段我自己常用的逐点比较法直线插补代码。用C语言写的,简单易懂。
// 逐点比较法直线插补
// 起点(0,0),终点(Xe, Ye)
void line_interp(int Xe, int Ye) {
int F = 0; // 当前偏差
int step = 0; // 已走步数
int total = Xe + Ye; // 总步数
while (step < total) {
if (F >= 0) {
// 走+X方向
move_x(1);
F -= Ye;
} else {
// 走+Y方向
move_y(1);
F += Xe;
}
step++;
}
}
这段代码虽然简单,但包含了逐点比较法的全部精髓。你可以在单片机上直接跑,效果立竿见影。
小技巧:实际工程中,终点坐标Xe和Ye可能很大,导致F值溢出。我建议用长整型(32位或64位),或者像前面说的,用相对偏差法。
好了,这一章的内容就到这里。插补算法是运动控制的基石,理解了它,后面学速度规划、加减速控制就会轻松很多。
公众号:蓝海资料掘金营,微信deep3321