4. 逐点比较法圆弧插补:偏差判别、进给方向与终点判别
各位同学,今天我们来聊聊圆弧插补。说实话,直线插补搞明白了,圆弧插补的思路其实是一脉相承的。但圆弧有个麻烦——它的轨迹是弯的,偏差怎么算?往哪个方向走?什么时候停?这三个问题,就是逐点比较法圆弧插补的核心。
我记得刚入行那会儿,带我的老师傅跟我说过一句话:「直线插补是走直线,圆弧插补是画圆圈,但本质上都是在『猜』下一步该往哪走。」当时觉得这话挺玄乎,后来自己写代码调机床才明白,还真是这么回事。
4.1 圆弧插补的偏差判别函数
先说说偏差怎么算。对于直线插补,我们用的是点到直线的距离。对于圆弧,道理类似——看当前点是在圆内、圆上,还是圆外。
假设我们要加工一段圆弧,起点是 A,终点是 B,圆心在原点 O(0,0),半径为 R。那么对于任意一个点 P(x, y),它到圆心的距离平方是:
F = x² + y² - R²
这个 F 就是偏差判别函数。它的含义很直观:
- F = 0:点在圆弧上,完美
- F > 0:点在圆外,离圆心远了
- F < 0:点在圆内,离圆心近了
你想想看,这个公式是不是比直线插补还简单?直线插补好歹要算个叉积,圆弧插补直接平方和减半径平方就完事了。
核心要点:偏差判别函数 F = x² + y² - R²,决定了刀具当前位置与理想圆弧的位置关系。
4.2 进给方向与终点判别
偏差算出来了,下一步就是决定往哪走。这里有个关键问题:圆弧有四个象限,每个象限的进给方向都不一样。
我给大家画个图,这样更清楚:
上面这张图展示了四个象限的圆弧走向。注意看,我这里画的是逆时针圆弧。顺时针的情况正好相反,这个后面会细说。
进给方向的规则是这样的:
| 象限 | 偏差 F | 进给方向 | 说明 |
|---|---|---|---|
| 第一象限 | F ≥ 0 | -X | 向圆内走 |
| F < 0 | +Y | 向圆外走 | |
| 第二象限 | F ≥ 0 | -Y | 向圆内走 |
| F < 0 | -X | 向圆外走 | |
| 第三象限 | F ≥ 0 | +X | 向圆内走 |
| F < 0 | -Y | 向圆外走 | |
| 第四象限 | F ≥ 0 | +Y | 向圆内走 |
| F < 0 | +X | 向圆外走 |
这个表格看着复杂,其实有个规律:F ≥ 0 时往圆内走,F < 0 时往圆外走。至于具体是哪个轴、正方向还是负方向,取决于当前在哪个象限。
我的小技巧:记不住的时候,就想想「F ≥ 0 往圆心方向走,F < 0 远离圆心方向走」。然后根据当前象限的坐标轴方向,自然就能推出进给方向了。
再说终点判别。这个和直线插补一样,用总步数来判断。假设起点到终点的 X 方向步数为 Nx,Y 方向步数为 Ny,那么总步数就是:
N = |Nx| + |Ny|
每走一步,N 减 1。当 N = 0 时,说明到达终点。
4.3 四象限圆弧插补实现
好了,理论讲完了,咱们上代码。我习惯用 Python 来验证算法,因为调试方便,逻辑看得清楚。
def arc_interpolation(start, end, center, clockwise=False):
"""
逐点比较法圆弧插补
start: 起点坐标 (xs, ys)
end: 终点坐标 (xe, ye)
center: 圆心坐标 (xc, yc)
clockwise: True为顺时针,False为逆时针
"""
# 计算半径
R = ((start[0] - center[0])**2 + (start[1] - center[1])**2)**0.5
# 当前点
x, y = start[0], start[1]
# 计算总步数
dx = abs(end[0] - start[0])
dy = abs(end[1] - start[1])
total_steps = int(dx + dy)
# 记录路径
path = [(x, y)]
for step in range(total_steps):
# 计算偏差
F = (x - center[0])**2 + (y - center[1])**2 - R**2
# 判断象限
if x >= center[0] and y >= center[1]:
quadrant = 1
elif x < center[0] and y >= center[1]:
quadrant = 2
elif x < center[0] and y < center[1]:
quadrant = 3
else:
quadrant = 4
# 根据象限和偏差决定进给方向
if clockwise:
# 顺时针
if quadrant == 1:
if F >= 0:
y -= 1 # -Y
else:
x += 1 # +X
elif quadrant == 2:
if F >= 0:
x -= 1 # -X
else:
y -= 1 # -Y
elif quadrant == 3:
if F >= 0:
y += 1 # +Y
else:
x -= 1 # -X
else: # quadrant == 4
if F >= 0:
x += 1 # +X
else:
y += 1 # +Y
else:
# 逆时针
if quadrant == 1:
if F >= 0:
x -= 1 # -X
else:
y += 1 # +Y
elif quadrant == 2:
if F >= 0:
y -= 1 # -Y
else:
x -= 1 # -X
elif quadrant == 3:
if F >= 0:
x += 1 # +X
else:
y -= 1 # -Y
else: # quadrant == 4
if F >= 0:
y += 1 # +Y
else:
x += 1 # +X
path.append((x, y))
return path
这段代码我实际跑过,效果还不错。不过要注意,这里用的是整数坐标,实际数控系统中也是用整数脉冲当量来计算的。
曾经踩过的坑:有一次我在调试四象限圆弧插补时,发现刀具在象限交界处会「抖」一下。查了半天,原来是象限判断的边界条件没处理好。比如在 X 轴上,x == center[0] 时应该归到哪个象限?我的建议是:统一归到上一个象限,或者单独处理边界情况。
4.4 实际应用中的注意事项
最后聊几个实际项目中容易遇到的问题:
- 过象限问题:圆弧从一个象限跨越到另一个象限时,进给方向会突变。这时候要特别注意,别让刀具「愣」在那里。
- 圆弧半径太小:如果半径小于一个脉冲当量,那圆弧就变成了一团「毛线」。我建议最小半径至少是 5 个脉冲当量。
- 终点误差:逐点比较法走出来的圆弧,终点不一定正好落在目标点上。一般允许半个脉冲当量的误差。
嗯,关于逐点比较法圆弧插补,核心内容就这些。偏差判别函数、进给方向、终点判别,这三个东西搞明白了,圆弧插补也就拿下了。下次咱们聊聊更高效的插补方法——数字积分法。
公众号:蓝海资料掘金营,微信deep3321