一、直线插补原理:逐点比较法与数字积分法(DDA)
大家好,我是老张。今天咱们聊聊直线插补。
插补这东西,说白了就是让机床走出我们想要的轨迹。你给个起点终点,插补算法负责算出中间那些点。我刚开始做运动控制时,总觉得这玩意儿很简单——不就是两点一线吗?后来踩了不少坑才明白,插补的精度和效率,直接决定了加工质量。
这一章,我重点讲两种最经典的直线插补方法:逐点比较法和数字积分法(DDA)。这两种方法,一个偏逻辑判断,一个偏数值累加,思路完全不同,但都能实现直线插补。
核心要点:
- 逐点比较法:每一步都判断当前位置与理想直线的偏差,决定下一步走向
- 数字积分法:用累加运算模拟积分过程,生成脉冲序列
- 两者都能实现直线插补,但适用场景不同
3.1 逐点比较法——一步一个脚印
逐点比较法,名字就说明了它的思路:每走一步,都拿当前位置跟理想直线比一比,看看偏了没有,然后决定下一步往哪走。
我记得刚入行时,带我的老师傅说:「插补就像走路,走歪了赶紧纠正,别等偏到沟里再回头。」这话糙理不糙,逐点比较法就是这个道理。
3.1.1 基本原理
假设我们要从原点(0,0)走到终点(Xe,Ye)。理想直线就是连接这两点的线段。每一步,我们计算一个偏差值F:
F = Xe * Yi - Ye * Xi
其中(Xi,Yi)是当前位置。你想想看:
- 如果F=0,说明正好在直线上
- 如果F>0,说明在直线上方
- 如果F<0,说明在直线下方
然后根据偏差决定进给方向:
- F≥0时,向+X方向走一步
- F<0时,向+Y方向走一步
我的经验:实际项目中,偏差计算可以用递推公式来优化,避免每次都做乘法。比如F≥0走+X后,新偏差F' = F - Ye;F<0走+Y后,新偏差F' = F + Xe。这样只用加减法,速度快很多。
3.1.2 实现步骤
逐点比较法的流程,说白了就是四步循环:
- 偏差判别:计算当前偏差F
- 坐标进给:根据F的正负决定走X还是Y
- 偏差计算:用递推公式更新F
- 终点判断:检查是否到达终点
代码实现也很直接:
// 逐点比较法直线插补
void line_interpolation_pc(int Xe, int Ye) {
int X = 0, Y = 0;
int F = 0;
int steps = Xe + Ye; // 总步数
while (steps > 0) {
if (F >= 0) {
X++; // 向+X走一步
F -= Ye; // 更新偏差
} else {
Y++; // 向+Y走一步
F += Xe; // 更新偏差
}
steps--;
// 输出脉冲到电机
output_pulse(X, Y);
}
}
注意:这段代码只处理了第一象限的情况。实际项目中要处理8个象限和坐标轴方向,需要根据终点坐标的符号做分支判断。我曾经在一个项目中忘了处理负坐标,结果机床直接往反方向跑...嗯,从那以后我写插补代码第一件事就是做象限判断。
3.2 数字积分法(DDA)——用累加逼近直线
数字积分法,英文叫Digital Differential Analyzer,简称DDA。这名字听着高大上,其实原理很简单——用累加器模拟积分过程。
为什么会想到用积分?你想想看,直线运动可以分解成X和Y两个方向的速度分量。如果速度是恒定的,那位移就是速度对时间的积分。DDA就是把这个积分过程用数字累加来实现。
3.2.1 基本原理
假设我们要从(0,0)走到(Xe,Ye),总步数为N。那么:
- X方向每步的增量:ΔX = Xe / N
- Y方向每步的增量:ΔY = Ye / N
但ΔX和ΔY通常不是整数,没法直接输出脉冲。DDA的做法是:用两个累加器,每次累加ΔX和ΔY,当累加值超过1时,就输出一个脉冲。
说白了,就是用累加器的溢出脉冲来模拟连续运动。
3.2.2 实现步骤
DDA的实现比逐点比较法更规整:
// DDA直线插补
void line_interpolation_dda(int Xe, int Ye, int N) {
int X_acc = 0, Y_acc = 0;
int i;
for (i = 0; i < N; i++) {
X_acc += Xe;
Y_acc += Ye;
if (X_acc >= N) {
X_acc -= N;
// X方向输出一个脉冲
pulse_x();
}
if (Y_acc >= N) {
Y_acc -= N;
// Y方向输出一个脉冲
pulse_y();
}
}
}
关键点:N的取值决定了插补精度。N越大,步长越小,轨迹越平滑。但N太大也会导致计算量增加。我一般取N为2的幂次,比如256或1024,这样可以用移位代替除法,效率高很多。
3.3 两种方法的对比
两种方法我都用过,各有千秋。这里做个对比:
| 对比项 | 逐点比较法 | 数字积分法(DDA) |
|---|---|---|
| 核心思想 | 偏差判别,逐步逼近 | 累加积分,溢出脉冲 |
| 运算复杂度 | 加减法,简单 | 加法+比较,稍复杂 |
| 插补精度 | 最大偏差不超过1个脉冲当量 | 与累加器位数有关,一般也控制在1个脉冲当量内 |
| 速度均匀性 | 较好,每步都有进给 | 可能存在脉冲不均匀的情况 |
| 多轴扩展 | 较复杂,需要重新设计偏差函数 | 容易,增加累加器即可 |
| 适用场景 | 两轴联动,精度要求高的场合 | 多轴联动,需要平滑运动的场合 |
我的建议:如果你做的是两轴雕刻机,对轨迹精度要求高,逐点比较法更合适。如果是多轴机器人或者需要平滑加减速的场合,DDA更好扩展。我个人习惯是:简单场景用逐点比较法,复杂场景用DDA。
3.4 实际项目中的避坑指南
做插补这么多年,我踩过的坑不少。分享几个常见的:
- 终点判断要谨慎:逐点比较法用总步数判断终点,DDA用累加次数判断。但实际中电机可能有丢步,单纯靠步数判断会出问题。我一般会加一个位置反馈做双重校验。
- 象限切换要平滑:跨象限时,进给方向会变,处理不好会有冲击。建议在象限边界做速度平滑过渡。
- 累加器溢出要正确处理:DDA的累加器溢出后要减去N,而不是清零。否则会丢失累加信息,导致轨迹偏移。
曾经踩过的坑:有一次我用DDA做四轴联动,发现轨迹总是有微小抖动。查了两天才发现,是累加器位数不够,导致溢出频率不稳定。后来把累加器从16位换成32位,问题就解决了。所以,累加器位数一定要留够余量。
3.5 小结
逐点比较法和数字积分法,是直线插补的两种经典方法。一个靠偏差判断,一个靠累加积分,思路不同但殊途同归。
理解这两种方法,是掌握插补技术的基础。后面的章节我们会讲圆弧插补、速度规划、平滑处理,这些都是在今天的基础上展开的。
嗯,今天就到这里。如果你在实际调试中遇到问题,欢迎交流。
公众号:蓝海资料掘金营,微信deep3321