刻字机尖角补偿

1 刻字机尖角补偿原理

刀具切割直线段过渡方法在文章旋转偏心裁切刀切向跟踪及半径补偿 已经有过说明。刻字机由于刀具半径的影响,切割直角时会不直会比较圆滑,而且在闭合曲线的下刀点会容易不闭合。使用尖角补偿可以克服这些问题。

刻字机尖角补偿_第1张图片

如上图所示,切割俩条相邻线段AB和BC时,刀心需要走的轨迹是从A' --> B' --> B'' -->C'。由于刻字机使用的刻刀刀尖半径都比较小,而且刀具也是固定没有转动轴控制转动,所以从B'过渡到B''时使用圆弧进行过渡。这里B2和B1都是圆弧上的过渡点。示意图中从B'B''采用小线段B'B2、B2B1、B1B''进行圆弧拟合过渡。

AB的矢量角α,则A'点坐标为(Xa+r*cosα,Ya+r*sinα)。BC的矢量角为β,则B''的坐标为(Xb+r*cosβ,Yb+r*sinβ)。C'的坐标为(Xc+r*cosβ,Yc+r*sinβ)。AB的转角为β-α。

2 尖角补偿python程序实现

import numpy
import cv2
import math

const_ratio = 10
WIDTH = 100
HEIGHT = 60
KNIFE_CIR = 40 #plt中40个单位=1mm
ANGLE_STEP = 30 #圆弧过渡时插补间隔30度

def show_img(window,img):
    cv2.namedWindow(window,0)
    cv2.resizeWindow(window,int(img.shape[1]),int(img.shape[0]))
    cv2.imshow(window,img)

def proc_line(line):
    i = 0
    signZ = 1
    if len(line) == 0:
        return None
    while line[i]<'0' or line[i]>'9':
        if line[i] == 'U':
            signZ = 0
        if line[i] == '-':
            break
        i = i+1
        if i == len(line):
            return None
        
    line = line[i:]
    if len(line) == 0:
        return None
    strs = line.split(',')
    if len(strs) != 2:
        return None
    axis_y = int(strs[0])
    axis_x = int(strs[1])
    
    if (axis_x is None) or (axis_y is None):
        return None
    return {'x':axis_x,'y':axis_y,'z':signZ}

def plot_plt(cv_img,data,print_width,print_height):
    height_total = print_height
    width_total = print_width
    line = ""
    comma = 0
    points = []
    for i in range(len(data)):
        try:
            ch = chr(data[i])
        except:
            ch = data[i]
        if ch == ';':
            point = proc_line(line)
            if point is not None:
                points.append(point)
            line = ""
            comma = 0
        else:
            line = line+ch
            if ch==',' or ch==' ':
                comma = comma+1
            if comma == 2:
                point = proc_line(line)
                if point is not None:
                    points.append(point)
                line = ""
                comma = 0
    max_x = points[0]['x']
    max_y = points[0]['y']
    min_x = points[0]['x']
    min_y = points[0]['y']
   
    for point in points:
        if point['x']>max_x:
            max_x = point['x']
        if point['y']>max_y:
            max_y = point['y']
        if point['x']max_x:
            max_x = point['x']
        if point['y']>max_y:
            max_y = point['y']
        if point['x']= 180:
            angle_delta = angle_delta-360
        elif angle_delta <= -180:
            angle_delta = angle_delta+360
        if angle_delta>0:
            angle_step = ANGLE_STEP
        else:
            angle_step = -ANGLE_STEP
        print(angle_delta,length)
        if length == 0:
            continue
        elif point['z'] == 0: #抬刀时不处理
            pointsInterpArr.append(point)
        elif pre_point['z'] == 0:#由抬刀变为下刀保存下刀点坐标和角度,并进行起点和终点偏移
            downPoint = pre_point
            downAngle = angle
            x1=pre_point['x']+KNIFE_CIR*math.cos(angle)
            y1=pre_point['y']+KNIFE_CIR*math.sin(angle)
            pointsInterpArr.append({'x':int(x1),'y':int(y1),'z':0})
            x2 = point['x']+KNIFE_CIR*math.cos(angle)
            y2 = point['y']+KNIFE_CIR*math.sin(angle)
            pointsInterpArr.append({'x':int(x2),'y':int(y2),'z':1})
            off_x = KNIFE_CIR*math.cos(angle)
            off_y = KNIFE_CIR*math.sin(angle)
        elif abs(angle_delta)>30:#下刀切割时线段转角大于30度时进行圆弧过渡
            count = math.floor(angle_delta/angle_step)
            remain = angle_delta-count*angle_step
            for j in range(0,count):
                x = pre_point['x']+KNIFE_CIR*math.cos(pre_angle+angle_step*(j+1)*math.pi/180)
                y = pre_point['y']+KNIFE_CIR*math.sin(pre_angle+angle_step*(j+1)*math.pi/180)
                pointsInterpArr.append({'x':int(x),'y':int(y),'z':1})
            if abs(remain) > 0.1:
                x = pre_point['x']+KNIFE_CIR*math.cos(angle)
                y = pre_point['y']+KNIFE_CIR*math.sin(angle)
                pointsInterpArr.append({'x':int(x),'y':int(y),'z':1})
            
            delta_x = KNIFE_CIR*math.cos(angle)
            delta_y = KNIFE_CIR*math.sin(angle)
            pointsInterpArr.append({'x':int(point['x']+delta_x),'y':int(point['y']+delta_y),'z':point['z']})  

            off_x = KNIFE_CIR*math.cos(angle)
            off_y = KNIFE_CIR*math.sin(angle)
        else:#转角小于30度直接过渡
            delta_x = KNIFE_CIR*math.cos(angle)
            delta_y = KNIFE_CIR*math.sin(angle)
            pointsInterpArr.append({'x':int(point['x']+delta_x),'y':int(point['y']+delta_y),'z':point['z']}) 

        #发现是下刀点坐标时代表曲线段闭合,进行闭合圆弧过渡
        if downPoint != None and length > 0 and point['x'] == downPoint['x'] and point['y'] == downPoint['y']:
            angle_delta = (downAngle-angle)*180/math.pi
            if angle_delta >= 180:
                angle_delta = angle_delta-360
            elif angle_delta <= -180:
                angle_delta = angle_delta+360
            if angle_delta>0:
                angle_step = ANGLE_STEP
            else:
                angle_step = -ANGLE_STEP
            count = math.floor(angle_delta/angle_step)
            remain = angle_delta-count*angle_step
            for j in range(0,count):
                x = point['x']+KNIFE_CIR*math.cos(angle+angle_step*(j+1)*math.pi/180)
                y = point['y']+KNIFE_CIR*math.sin(angle+angle_step*(j+1)*math.pi/180)
                pointsInterpArr.append({'x':int(x),'y':int(y),'z':1})
            if abs(remain) > 0.1:
                x = point['x']+KNIFE_CIR*math.cos(downAngle)
                y = point['y']+KNIFE_CIR*math.sin(downAngle)
                pointsInterpArr.append({'x':int(x),'y':int(y),'z':1})
        pre_point = point
        pre_angle = angle

    pre_point = pointsInterpArr[0]
    black = (0,255,0)
    
    offset_x = 10*const_ratio
    offset_y = 10*const_ratio

    max_x = pointsInterpArr[0]['x']
    max_y = pointsInterpArr[0]['y']
    min_x = pointsInterpArr[0]['x']
    min_y = pointsInterpArr[0]['y']
    for point in pointsInterpArr:
        if point['x']>max_x:
            max_x = point['x']
        if point['y']>max_y:
            max_y = point['y']
        if point['x']

正方形尖角补偿轨迹:

刻字机尖角补偿_第2张图片

三角形尖角补偿轨迹:

刻字机尖角补偿_第3张图片

方圆尖角补偿轨迹:

刻字机尖角补偿_第4张图片

你可能感兴趣的:(运动控制,算法)