3. 逐点比较法圆弧插补的误差补偿策略

任务目标

逐点比较法圆弧插补的偏差计算基于当前点与圆心的比较,其固有缺陷是:偏差函数只反映当前点相对圆弧的方位,不包含累积误差信息。当插补点持续位于圆弧外侧时,每一步的径向误差会叠加,导致实际轨迹偏离理想圆弧越来越远。本案例设计一种误差累积修正策略:在每步插补后计算径向误差的累积值,当累积误差超过设定阈值时,强制插入一个修正步,使实际轨迹被拉回理想圆弧附近。

补偿策略原理

设理想圆弧圆心为原点,半径为R,当前插补点为P(x, y)。定义径向误差:

e = sqrt(x² + y²) - R

逐点比较法每步进给后,将e累加到累积误差变量acc中。当|acc| ≥ ε(ε为补偿阈值,通常取0.5~1个脉冲当量)时,触发修正:沿径向方向(向圆心或远离圆心)插入一个修正步,然后将acc清零。修正步的方向由e的符号决定:e > 0(点在圆外)时向圆心修正,e < 0(点在圆内)时远离圆心修正。

关键完整代码

import math

def arc_interp_with_compensation(R, steps_per_quadrant=20, threshold=0.5):
    """
    逐点比较法圆弧插补(第一象限逆圆)+ 误差累积修正
    返回插补点列表(含修正步)
    """
    x, y = R, 0          # 起点 (R, 0)
    F = 0                # 逐点比较偏差
    acc = 0.0            # 累积径向误差
    points = [(x, y)]
    step = R / steps_per_quadrant  # 脉冲当量(每步进给量)
    total_steps = steps_per_quadrant * 2  # 第一象限逆圆约需2倍步数
    
    for _ in range(total_steps):
        # --- 逐点比较法偏差判别与进给 ---
        if F < 0:
            # 偏差为负,向+y方向进给(逆圆内侧)
            y += step
            F += 2*y - step
        else:
            # 偏差≥0,向-x方向进给(逆圆外侧)
            x -= step
            F -= 2*x + step
        
        # --- 误差累积与修正 ---
        e = math.sqrt(x*x + y*y) - R
        acc += e
        
        if abs(acc) >= threshold:
            # 修正步:沿径向方向移动一个脉冲当量
            if e > 0:   # 在圆外,向圆心修正
                norm = math.sqrt(x*x + y*y)
                x -= step * (x / norm)
                y -= step * (y / norm)
            else:       # 在圆内,远离圆心修正
                norm = math.sqrt(x*x + y*y)
                x += step * (x / norm)
                y += step * (y / norm)
            acc = 0.0   # 修正后清零累积误差
        
        points.append((x, y))
        
        # 到达终点 (0, R) 附近则停止
        if x <= step/2 and y >= R - step/2:
            break
    
    return points

# 运行示例:半径10,每象限20步,阈值0.5
pts = arc_interp_with_compensation(R=10, steps_per_quadrant=20, threshold=0.5)

# 计算最大径向误差(验证指标)
max_err = 0.0
for (px, py) in pts:
    err = abs(math.sqrt(px*px + py*py) - 10)
    max_err = max(max_err, err)

print(f"插补点数: {len(pts)}")
print(f"最大径向误差: {max_err:.4f}")

# 对比:无补偿时同样参数的最大径向误差
def arc_interp_no_compensation(R, steps_per_quadrant=20):
    x, y = R, 0
    F = 0
    points = [(x, y)]
    step = R / steps_per_quadrant
    total_steps = steps_per_quadrant * 2
    for _ in range(total_steps):
        if F < 0:
            y += step
            F += 2*y - step
        else:
            x -= step
            F -= 2*x + step
        points.append((x, y))
        if x <= step/2 and y >= R - step/2:
            break
    return points

pts_nc = arc_interp_no_compensation(R=10, steps_per_quadrant=20)
max_err_nc = max(abs(math.sqrt(px*px + py*py) - 10) for px, py in pts_nc)
print(f"无补偿最大径向误差: {max_err_nc:.4f}")

运行与验证

  1. 环境依赖:仅需Python 3.6+,无第三方库。
  2. 运行方式:将代码保存为arc_compensation.py,执行python arc_compensation.py。
  3. 通过条件:程序输出补偿后的最大径向误差应明显小于无补偿时的误差(例如R=10、20步/象限时,无补偿误差约0.12~0.15,补偿后应降至0.05以下)。同时插补点数会因修正步而略有增加,这是正常现象。

关键说明

  • 修正步沿径向方向移动,需要计算单位方向向量,因此引入了math.sqrt运算。在实际数控系统中可用查表法近似,此处为清晰展示原理保留浮点计算。
  • 阈值threshold的选取影响补偿频率:阈值越小修正越频繁,轨迹更接近理想圆弧但步数增多;阈值过大则补偿效果减弱。建议取0.5~1.0倍脉冲当量。
  • 本实现针对第一象限逆圆,其他象限可通过坐标变换映射到第一象限处理。
误差累积修正效果示意(第一象限逆圆) 理想圆弧 R=10 无补偿:逐步外偏 补偿后:贴近理想圆弧 ● 修正触发点 修正步细节 径向修正 累积误差≥阈值时 X Y O 理想圆弧 无补偿轨迹 补偿后轨迹

上图示意了补偿策略的效果:蓝色轨迹在橙色标记点处触发径向修正,使插补路径被拉回理想圆弧附近,而红色无补偿轨迹则持续向外偏离。实际运行代码可得到精确的误差数值对比。