插补模块是整个数控系统中一个极其重要的功能模块之一,插补算法的选择将直接影响到系统的精度、速度和加工能力范围。为此,本章将对各种插补原理进行剖析和实验。
插补算法很多,可以归纳为两大类:脉冲增量插补算法和数据采样插补算法。
脉冲增量插补算法比较简单,比较容易用硬件实现,所以,硬件数控系统较多采用该法,但随着计算机速度的大大提高,也可用软件模拟硬件来实现这类插补。这类插补算法的输出是脉冲形式,并且每次仅产生一个单位的行程增量(即脉冲当量)。脉冲当量一般为0.01mm,较精密的一般取为0.005mm、0.0025mm或0.001mm。显然,脉冲当量愈小,加工精度愈高。
脉冲增量插补算法的种类很多,如:数字脉冲乘法器、逐点比较法(最初称为区域判别法)、数据积分法(又称微分分析器DDA),比较积分法(包括:单步追踪法、目标点跟踪法即伸雄函数发生器SFG等)、矢量判别法、最小偏差法等。
数据采样插补算法,又称为时间分割法,它根据程编进给速度将零件轮廓曲线按插补周期分割为一系列微小直线段,然后,将这些微小直线段对应的位置增量数据进行输出,用以控制伺服系统实现坐标轴的进给。显然,这类插补的输出不是单个脉冲,而是一个数字量。这类插补适用于以交、直流伺服电动机作为执行元件的闭环或半闭环数控系统。
为了获得良好的插补精度和插补速度,数控研究人员又研制开发了下列插补方案:
(1)采用软硬结合的两级插补方案。先由计算机插补软件将加工零件的轮廓段按10-20ms的插补周期分割成若干直线段(称为粗插补过程),然后利用附加的硬件插补器进一步对粗插补送来的直线段进行插补,并输出脉冲(称为精插补过程)。这样,就大大缓和了实时插补和多任务控制之间的矛盾。FANUC公司生产的SYSTEM-5数控系统就采用了本方案。
(2)采用多CPU的分布式处理方案。这类系统中,先将数控系统的全部功能划分为几个子功能模块,并分别分配一个独立的CPU来完成该子功能,然后由系统软件来协调各个CPU之间的工作。如,美国的麦克唐纳.道格拉斯公司的ACTRIONⅢ型数控系统就采用了本方案,它用4台微处理器分别实现输入/输出、轮廓插补和进给速度控制功能、坐标轴伺服功能、数控加工程序编辑和CRT显示。
这是数控技术发展的一个方向,它具有较高的性价比。
(3)采用单台高性能微机方案。现在的微机性能甚至超过了以前的小型机的性能,德国西门子公司的SYSTEM-7系统和810系统就采用了本方案。本方案正在蓬勃发展之中。
限于篇幅,我们从前面所列插补方法中选择几种加以讨论并实验。
第一节 逐点比较法插补原理实验
一、实验目的
1.掌握逐点比较法直线与圆弧插补的基本原理
2.掌握逐点比较法直线插补与圆弧插补的程序编制方法
3.加深对逐点比较法插补的理解
二、实验原理
逐点比较法的基本原理是,在刀具按要求轨迹运动加工零件轮廓的过程中,不断比较刀具与被加工零件轮廓之间的相对位置,并根据比较结果决定下一步的进给方向,使刀具向减小偏差的方向进给(始终只有一个方向)。
一般地,逐点比较法插补过程有四个处理节拍,如图4-1:
(1)偏差判别。判别刀具当前位置相对于给定轮廓的偏差状况;
(2)坐标进给。根据偏差状况,控制相应坐标轴进给一步,使加工点向被加工轮廓靠拢;
(3)重新计算偏差。刀具进给一步后,坐标点位置发生了变化,应按偏差计算公式计算新位置的偏差值;
(4)终点判别。若已经插补到终点,则返回监控,否则重复以上过程。
图4-1 处理节拍 图4-2 第一象限直线插补规律
1.直线插补
图4-2为第一象限直线,其终点坐标为(Xe,Ye),现分析其插补规律。
刀尖点位置不外乎3种情况:轮廓线上方(点A),轮廓线上(B点),轮廓线下方(点C)。显然,在点A处,为使刀尖点向轮廓直线靠拢,应+X向走一步;C点处,应+Y向走一步;至于B点,看来两个方向均可以,但考虑汇编编程时的方便,现规定往+X向走一步。
A(X,Y)点处有:Y/X>Xe/Ye XeY-XYe > 0
B(X,Y)点处有:Y/X=Xe/Ye XeY-XYe = 0
C(X,Y)点处有:Y/X<Xe/Ye XeY-XYe < 0
F=XeY-XYe为原始的偏差计算公式(X,Y为当前插补点动态坐标),F称为偏差,每走一步到达新位置点,就要计算相应这个F值。
显然,F≥0时,须+X向走一步;F<0时,须+Y向走一步。为方便汇编编程和提高计算速度,现对偏差F的计算公式加以简化:
插补点位于A、B点时,走完下一步(+X):动态坐标变为(X=X+1,Y=Y),新偏差变为F=XeY-(X+1)Ye=XeY-XYe-Ye=F-Ye。这个公式比F=XeY-XYe计算要方便。
图4-3 逐点比较法第一象限直线插补软件框图
插补点位于C点时,走完下一步(+Y):动态坐标变为(X=X,Y=Y+1),新偏差变为F=Xe(Y+1)-XYe=XeY-XYe+Xe=F+Xe。
因此,
走完+X后:偏差计算公式为F=F-Ye;
走完+Y后:偏差计算公式为F=F+Xe。
图4-3为逐点比较法第一象限直线插补软件框图。
根据该插补软件框图,可编制逐点比较法第一象限直线插补汇编语言源程序(本程序指令系统采用MCS8031,仅供参考):
LP:MOV SP,#60H 定义堆栈指针
MOV 4AH,#00H 偏差单元清零
MOV 49H,#00H
MOV 48H,#01H 初始化XY电动机
MOV 47H,#02H
MOV A,4EH 计算终点判别,Xe+Ye之低位
ADD A,4CH
MOV 50H,A
MOV A,4DH Xe+Ye之高位
ADDC A,4BH 低位相加,可能产生进位
MOV 4FH,A
MOV A,#03H XY电动机上电
MOV DPTR,#0030H
MOVX @DPTR,A
LP2:ACALL DL0 延时子程序
MOV A,49H 取偏差F的高8位
JB ACC.7,LP4 偏差F< 0,去LP4
ACALL XMP F>=0,调X电动机正转子程序
CLR C 计算新偏差F值,F=F-Ye
MOV A,4AH
SUBB A,4CH 可向高位字节借位
MOV 4AH,A
MOV A,49H
SUBB A,4BH
MOV 49H,A
LP3:CLR C 终判值减1
MOV A,50H
SUBB A,#01H 可向高位字节借位
MOV 50H,A
MOV A,4FH
SUBB A,#00H 考虑低位字节借位
MOV 4FH,A 终判值判零
ORL A,50H
JNZ LP2 终判值不为零,去LP2,否则插补结束
LJMP 0000H
LP4:ACALL YMP 调Y电动机正转子程序
MOV A,4AH计算新偏差F值,F=F+Xe
ADD A,4EH
MOV 4AH,A
MOV A,49H
ADDC A,4DH
MOV 49H,A
SJMP LP3
XMP:MOV A,48H 取X电动机当前状态字
CLR C 移位法
RRC A
RRC A
RRC A
XMP2:CPL A
ANL A,#49H 屏蔽无关位
MOV 48H,A 保存X电动机状态字,作为下次转动的基准
ORL A,47H 保存Y电动机原状态不变
XMP4:MOV DPTR,#0030H
MOVX @DPTR,A
RET
XMM:MOV A,48H
CLR
RLC A
RLC A
RLC A
SJMP XMP2
YMP:MOV A,47H
CLR C
RRC A
RRC A
RRC A
YMP2:CPL A
ANL A,#92H
MOV 47H,A
ORL A,48H
SJMP XMP4
YMM:MOV A,47H
CLR C
RLC A
RLC A
RLC A
SJMP YMP2
说明:1)黑体字模块为软件环形分配器;
2)各变量地址分配如下:4FH50H-终判值,4DH4EH-Xe,4BH4CH-Ye,49H4AH-偏差值F,47H-Y电动机状态字,48H-X电动机状态字;以大地址格式(最低字节地址单元存放最高位数据)存放各种数据;
3)口地址0030H与XY三相步进电动机相线关系如下:
1.1. 圆弧插补
图4-4为第一象限逆圆,现分析其插补规律。
刀尖点位置不外乎3种情况:轮廓线外面(点A),轮廓线上(B点),轮廓线里面(点C)。显然,在点A处,为使刀尖点向轮廓圆弧靠拢,应-X向走一步;C点处,应+Y向走一步;至于B点,看来两个方向均可以,但考虑汇编编程时的方便,现规定往-X向走一步。
A(X,Y)点处有:X2+Y2>R2 X2+Y2-R2>0
B(X,Y)点处有:X2+Y2=R2 X2+Y2-R2=0
C(X,Y)点处有:X2+Y2<R2 X2+Y2-R2<0
原始的偏差计算公式为:F=X2+Y2-R2(X,Y为当前插补点动态坐标)。
图4-4 第一象限逆圆插补规律 图4-5 逐点比较法第一象限逆圆插补软件框图
显然,F<0时,须+Y向走一步;F≥0时,须-X向走一步。为方便汇编编程和提高计算速度,对偏差F的计算公式加以简化:
插补点位于A、B点时,走完下一步(-X):动态坐标变为(X=X-1,Y=Y),新偏差变为F=(X-1)2+Y2-R2=F-2X+1。
它比公式F=X2+Y2-R2计算要方便很多。
插补点位于C点时,走完下一步(+Y):动态坐标变为(X=X,Y=Y+1),新偏差变为F=X2+(Y+1)2-R2=F+2Y+1。
因此,
走完-X后:偏差计算公式为F=F-2X+1,动态坐标修正为X=X-1;
走完+Y后:偏差计算公式为F=F+2Y+1,动态坐标修正为Y=Y+1。
图4-5为逐点比较法第一象限逆圆插补软件框图。
根据该插补软件框图,编制出逐点比较法第一象限逆圆插补汇编语言源程序(本程序指令系统采用MCS8031,仅供参考):
RP:MOV SP,#60H
MOV 4AH,#00H F单元清零
MOV 49H,#00H
MOV 48H,#01H X电动机初始化
MOV 47H,#02H Y电动机初始化
MOV DPTR,#0030H
MOV A,#03H XY电动机上电
MOVX @DPTR,A
CLR C 计算终判值
MOV A,52H 低位X、Xe相减,得a
SUBB A,4EH
MOV 54H,A 保存结果于终判值单元低位字节
MOV A,51H 高位X、Xe相减,得b
SUBB A,4DH
MOV 53H,A 保存结果于终判值单元高位字节
CLR C 低位Ye、Y相减,得c
MOV A,4CH
SUBB A,50H
MOV 20H,C 暂存Ye、Y低位相减产生的借位位
ADD A,54H 计算d=a+c,d为低位终判值
MOV 54H,A 保存d于终判值单元低位字节
MOV 21H,C 暂存d=a+c产生的进位位
MOV A,4BH
MOV C,20H 恢复Ye、Y低位相减产生的借位位
SUBB A,4FH 高位Ye、Y相减,得e
MOV C,21H 恢复d=a+c产生的进位位
ADDC A,53H 计算f=b+e,f为高位终判值
MOV 53H,A 保存f于终判值单元高位字节
RP2:ACALL DL0 延时子程序
MOV A,49H 取F高位字节
JB ACC.7,RP6 高位=1,F<0,去RP6
ACALL XMM 高位=0,F>0,X反转一步
CLR C 计算新偏差F=F-2X+1
MOV A,4AH 计算g=F-X低位
SUBB A,52H
XCH A,B g存入B寄存器
MOV A,49H 计算h=F-X高位
SUBB A,51H
XCH A,B 低位存A,高位存B。BA内容为F-X
CLR C 计算i=g-X=F-2X低位
SUBB A,52H
XCH A,B B内容为F-2X低位,A内容为F-X高位
SUBB A,51H A内容为F-2X高位
XCH A,B BA内容为F-2X
ADD A,#01H 计算F-2X+1
MOV 4AH,A 4A内容为F-2X+1低位
XCH A,B B内容为F-2X+1低位,A内容为F-2X高位
ADDC A,#00H 考虑F-2X+1的进位
MOV 49H,A 49H的内容为F-2X+1高位
CLR C 计算X=X-1
MOV A,52H 低位
SUBB A,#01H
MOV 52H,A
MOV A,51H 高位
SUBB A,#00H
MOV 51H,A
RP4:CLR C 终判值减1
MOV A,54H
SUBB A,#01H
MOV 54H,A
MOV A,53H
SUBB A,#00H
MOV 53H,A
ORL A,54H
JNZ RP2 插补没结束,转至RP2
LJMP 0000H
RP6:ACALL YMP Y电动机正转
MOV R6,#02H 此处“2”,为“F+2Y+1”的“2”
RP7:MOV A,4AH F+2Y+1
ADD A,50H
MOV 4AH,A
MOV A,49H
ADDC A,4FH
MOV 49H,A
DJNZ R6,RP7
MOV A,4AH
ADD A,#01H
MOV 4AH,A
MOV A,49H
ADDC A,#00H
MOV A,50H
ADD A,#01H
MOV 50H,A
MOV A,4FH
ADDC A,#00H
MOV 4FH,A
AJMP RP4
说明:1)数据存放格式同前;
2)各变量地址分配如下:47H-4EH,存放数据方式同直线,4FH50H-Y,51H52H-X,53H54H-终判值
从逐点比较法的插补原理可知:本法不易实现三轴以上的联动。因此,一般用于数控车床等两轴联动的系统。
为了让没有条件的教学单位也能做实验,此处用VB和C语言改写上述程序,改写后可在计算机屏幕上模拟仿真插补过程。
2.2. 参考程序
VB程序:
直线:
Sub 偏差计算()
偏差 = Abs(x终点) × z动点 - x动点 × Abs(z终点)
End Sub
Sub 插补()
Dim c As Integer
Select Case 象限标志
Case 1: ''第一象限插补
Do Until x动点 + z动点 >= 总步数
If 偏差 >= 0 Then
x动点 = x动点 + 1:
Line -Step(0, x步长), vbRed
Else
z动点 = z动点 + 1:
Line -Step(z步长, 0), vbRed
End If
偏差计算
Loop
Case 2: ''第二象限插补
c = x终点: x终点= z终点: z终点= -c
c = x步长: x步长 = z步长: z步长 = -c
Do Until x动点 + z动点 >= 总步数
If 偏差 >= 0 Then
x动点 = x动点 + 1:
Line -Step(x步长, 0), vbRed
Else
z动点 = z动点 + 1:
Line -Step(0, z步长), vbRed
End If
偏差计算
Loop
Case 3: ''第三象限插补
x步长 = -x步长: z步长 = -z步长
Do Until x动点 + z动点 >= 总步数
If 偏差 >= 0 Then
x动点 = x动点 + 1:
Line -Step(0, x步长), vbRed
Else
z动点 = z动点 + 1:
Line -Step(z步长, 0), vbRed
End If
偏差计算
Loop
Case 4: ''第四象限插补
c = x终点: x终点= -z终点: z终点 = c
c = x步长: x步长 = -z步长: z步长 = c
Do Until x动点 + z动点 >= 总步数
If 偏差 >= 0 Then
x动点 = x动点 + 1: Line -Step(x步长, 0), vbRed
Else
z动点 = z动点 + 1: Line -Step(0, z步长), vbRed
End If
偏差计算
Loop
End Select
End Sub
圆弧:
Sub 偏差计算()
偏差 = Sqr((x动点 - x圆心) 2 + (z动点 - z圆心) 2) - R
End Sub
Sub 插补()
x动点 = x起点: z动点 = z起点:
动点象限判别
xx: Select Case 象限标志
Case 1: 单步连续判断
If 顺逆标志 = "顺" Then ''第一象限插补
Do Until (x动点 - x终点) = 0 And (z动点 - z终点) = 0
If 偏差 >= 0 Then
x动点 = x动点 - 1:
Line -Step(0, -x步长), vbRed
Else
z动点 = z动点 + 1:
Line -Step(z步长, 0), vbRed
End If
偏差计算
动点象限判别
If 象限标志 <> 1 Then
GoTo xx
End If
单步连续判断
Loop
ElseIf 顺逆标志 = "逆" Then
Do Until (x动点 - x终点) = 0 And (z动点 - z终点) = 0
If 偏差 >= 0 Then
z动点 = z动点 - 1:
Line -Step(-z步长, 0), vbRed
Else
x动点 = x动点 + 1:
Line -Step(0, x步长), vbRed
End If
DoEvents
偏差计算
动点象限判别
If 象限标志 <> 1 Then
GoTo xx
End If
Loop
End If
Case 2:单步连续判断
If 顺逆标志 = "顺" Then ''第二象限插补
Do Until (x动点 - x终点) = 0 And (z动点 - z终点) = 0
If 偏差 >= 0 Then
z动点 = z动点 - 1:
Line -Step(-z步长, 0), vbRed
Else
x动点 = x动点 - 1:
Line -Step(0, -x步长), vbRed
End If
偏差计算
动点象限判别
If 象限标志 <> 2 Then
GoTo xx
End If
Loop
ElseIf 顺逆标志 = "逆" Then
Do Until (x动点 - x终点) = 0 And (z动点 - z终点) = 0
If 偏差 >= 0 Then
x动点 = x动点 + 1:
Line -Step(0, x步长), vbRed
Else
z动点 = z动点 + 1:
Line -Step(z步长, 0), vbRed
End If
偏差计算
动点象限判别
If 象限标志 <> 2 Then
GoTo xx
End If
Loop
End If
Case 3: 单步连续判断
If 顺逆标志 = "顺" Then ''第三象限插补
Do Until (x动点 - x终点) = 0 And (z动点 - z终点) = 0
If 偏差 >= 0 Then
x动点 = x动点 + 1:
Line -Step(0, x步长), vbRed
Else
z动点 = z动点 - 1:
Line -Step(-z步长, 0), vbRed
End If
DoEvents
偏差计算
动点象限判别
If 象限标志 <> 3 Then
GoTo xx
End If
Loop
ElseIf 顺逆标志 = "逆" Then
Do Until (x动点 - x终点) = 0 And (z动点 - z终点) = 0
If 偏差 >= 0 Then
z动点 = z动点 + 1:
Line -Step(z步长, 0), vbRed
Else
x动点 = x动点 - 1:
Line -Step(0, -x步长), vbRed
End If
偏差计算
动点象限判别
If 象限标志 <> 3 Then
GoTo xx
End If
Loop
End If
Case 4: 单步连续判断
If 顺逆标志 = "顺" Then ''第三象限插补
Do Until (x动点 - x终点) = 0 And (z动点 - z终点) = 0
If 偏差 >= 0 Then
z动点 = z动点 + 1:
Line -Step(z步长, 0), vbRed
Else
x动点 = x动点 + 1:
Line -Step(0, x步长), vbRed
End If
偏差计算
动点象限判别
If 象限标志 <> 4 Then
GoTo xx
End If
Loop
ElseIf 顺逆标志 = "逆" Then
Do Until (x动点 - x终点) = 0 And (z动点 - z终点) = 0
If 偏差 >= 0 Then
x动点 = x动点 - 1:
Line -Step(0, -x步长), vbRed
Else
z动点 = z动点 - 1:
Line -Step(-z步长, 0), vbRed
End If
偏差计算
动点象限判别
If 象限标志 <> 4 Then
GoTo xx
End If
Loop
End If
End Select
End Sub
C程序:
#include "conio.h"
#include "graphics.h"
#include "process.h"
#define Ni_circle 0
#define Shun_circle 1
void init_graph();
void draw_Base_circle();
void draw_cabu_circle();
void close_graph();
void acrroods();
static float x0,y0;
void line_cabu(), draw_line(),draw_line_cabu();
void line_cabu() /*此函数控制直线插步两次*/
{
int i;
init_graph();
sleep(1);
for(i=0;i<2;i++)
{
line(0,120,300,120); outtextxy(310,120,"Z");
line(100,10,100,300); outtextxy(110,300,"X");
outtextxy(90,130,"O");
draw_line();
if(i==0)
draw_line_cabu(6);
else draw_line_cabu(2);
gotoxy(50,5);
getch();
cleardevice();
setcolor(WHITE);
}
}
void draw_line()/*画直线*/
{
line(100,120,600,450);
textcolor(YELLOW);
directvideo=0;
gotoxy(45,5); cprintf("Line from:X0 Y0 Z0 ");
gotoxy(45,6); cprintf("Line to :X500 Y0 Z330");
gotoxy(45,7); cprintf("Units :Pixel");
gotoxy(45,8); cprintf("Line now:");
}
void draw_line_cabu(int step)/*关键的直线插补函数*/
{
int Xe=600,Ye=450;
float Fm,Xm=100,Ym=120;
setcolor(RED);
moveto(Xm,Ym);
while(Xm<=Xe&&Ym<=Ye)
{
Fm=(Ym-120)*(Xe-100)-(Xm-100)*(Ye-120);
if(Fm>=0)
Xm=Xm+step;
else
Ym=Ym+step;
lineto(Xm,Ym);
gotoxy(55,8); printf("X%3.0f Y0 Z%3.0f",Xm-100,Ym-120);
delay(1100);
}
}
/* 圆插补部分的函数区*/
void init_graph() /*图形系统初始化*/
{
int gdrive=DETECT,gmode;
initgraph(&gdrive,&gmode,"");
cleardevice();
}
void acrroods() /*屏幕中心坐标*/
{
x0=getmaxx()/2;
y0=getmaxy()/2;
}
void draw_Base_circle() /*画圆及写参数*/
{
line(x0-200,y0,x0+200,y0); outtextxy(x0+220,y0,"Z");
line(x0,y0-180,x0,y0+180); outtextxy(x0+10,y0+180,"X");
outtextxy(x0-10,y0+10,"O");
circle(x0,y0,150);
textcolor(YELLOW);
directvideo=0;
gotoxy(46,2);cprintf("Circle start:X0 Y0 Z150");
gotoxy(46,3);cprintf("Circle end :X0 Y0 Z150");
gotoxy(46,4);cprintf("Units :Pixel");
gotoxy(46,5);cprintf("Circle now:");
}
void close_graph() /*关图形系统*/
{
closegraph();
}
void draw_cabu_circle(int sstep,int Directory)/*关键的圆插补函数*/
{
int flag=0;
float Fm,Xm,Ym;
Xm=x0+150; Ym=y0;
moveto(Xm,Ym);
setcolor(RED);
while(1) /*分象限,顺圆和逆圆讨论*/
{
Fm=(Xm-x0)*(Xm-x0)+(Ym-y0)*(Ym-y0)-150*150;/*圆判断公式*/
if(Fm>=0){
if(!Directory){ /*逆圆判断*/
if(Xm>=x0&&Ym<=y0)
{
if(flag) break; /*if语句判断象限,以下一样*/
else Xm=Xm-sstep;
}
if(Xm<=x0&&Ym<=y0)
{
flag=1; Ym=Ym+sstep;
}
if(Xm<=x0&&Ym>=y0)
Xm=Xm+sstep;
if(Xm>=x0&&Ym>=y0)
Ym=Ym-sstep;
}
else { /*it is Directory''s else*/
if(Xm>x0&&Ym
Ym=Ym+sstep;
if(Xm<=x0&&Ym<=y0)
Xm=Xm+sstep;
if(Xm
if(Xm>=x0&&Ym>=y0) {
if(flag) break;
Xm=Xm-sstep;}
}
}
else{ /*it is Fm''s else*/
if(!Directory) {
if(Xm>x0&&Ym
{
if(flag) break;
else Ym=Ym-sstep;
}
if(Xm<=x0&&Ym<=y0)
{
flag=1; Xm=Xm-sstep;
}
if(Xm<=x0&&Ym>=y0)
Ym=Ym+sstep;
if(Xm>=x0&&Ym>=y0)
Xm=Xm+sstep;
}
else{
if(Xm>x0&&Ym
Xm=Xm+sstep;
if(Xm<=x0&&Ym<=y0)
Ym=Ym-sstep;
if(Xm<=x0&&Ym>=y0){
flag=1; Xm=Xm-sstep;}
if(Xm>=x0&&Ym>=y0) {
if(flag) break;
else Ym=Ym+sstep;}
}
}
lineto(Xm,Ym);
gotoxy(58,5); printf("X%3.0f Y0 Z%3.0f ",Ym-y0,Xm-x0);
delay(800);
}
}
void circle_demo(int Directory) /*控制圆插补两次*/
{
int i=0,sstep;
init_graph();
sleep(2);
acrroods(&x0,&y0);
for(i=0;i<2;i++)
{
draw_Base_circle(150);
if(i==0){
sstep=6;
draw_cabu_circle(sstep,Directory);}
else{
sstep=1;
draw_cabu_circle(sstep,Directory);}
getch();
cleardevice();
setcolor(WHITE);
}
}
/* 圆插补部分的函数区结束*/
main()/*主函数负责写封面和函数调用*/
{
int choice=0;
init_graph();
while(choice!=4)
{
setfillstyle(1,RED);
bar(200,30,400,80);
setcolor(GREEN);
settextstyle(3,0,10);
outtextxy(220,50,"DEMO PROGRAM BY P.Y.F");
setcolor(WHITE);
settextstyle(0,0,1);
outtextxy(200,120,"1. Line demo.");
outtextxy(200,140,"2. Shun_Circle demo.");
outtextxy(200,160,"3. Ni_Circle demo.");
outtextxy(200,180,"4. Quit the program.");
outtextxy(160,200,"Please enter your choice:"); gotoxy(46,13);
scanf("%d",&choice);
switch(choice)
{
case 1: line_cabu();break;
case 2: circle_demo(Ni_circle);break;
case 3: circle_demo(Shun_circle);break;
case 4: break;
default: printf("\nChoice wrong,try again!");
}
}
close_graph();
}
三、实验步骤
为了方便教学工作,作者承担了“数控技术远程教育网”网站的部分建设工作,URL为http://dali.3322.net/。可以在雅虎、搜狐和中国教育科研网中找到该站,常年联系电子信箱:zqrong@pub.cz.jsinfo.net。
1.下载文件:CNC-V2.0,这是一个自解压文件(网站可能经常变动),建议你的计算机在运行前安装VB6.0或其运行库。
2.启动CNC-V2.0后,进入插补界面(图4-6):
3.根据界面,选择直线插补或圆弧插补。现以圆弧插补为例:
在主界面上选择圆弧插补后,进入圆弧插补界面。单击开始,就可清楚显示圆弧插补轨迹,修改左边的数据,可得到不同圆弧的插补轨迹。还可单步执行,让学员可以对照右上方坐标进行分析。如果圆弧半径相对于脉冲当量很大,那么,根本就看不到插补折线了,对于直线插补,操作与圆弧插补基本相似,参见(图4-7、4-8、4-9、4-10)。
图4-6 逐点比较法插补主页面
图4-7 逐点比较法圆弧插补界面
图4-8 逐点比较法圆弧插补演示(一)
图4-9 逐点比较法圆弧插补演示(二)
图4-10 逐点比较法直线插补演示
第二节 数字积分法插补原理实验
一、实验目的
1.掌握数字积分法直线与圆弧插补的基本原理
2.掌握数字积分法直线插补与圆弧插补的程序编制方法
3.加深对数字积分法插补的理解
二、实验原理
数字积分法的基本原理是,使用一系列的小矩形面积之和来近似轮廓曲线函数积分的整个面积。此处为方便理解,从物理上来进行DDA插补的分析。
1.直线插补
设直线的终点坐标为(Xe,Ye),现取容器两个:Qx和Qy,其容量相等,均为Q≥MAX(Xe,Ye)。按一定的节拍不断将Xe值加入Qx,同时将Ye值加入Qy;若Qx中的值超过Q,则在X方向发一个脉冲,若Qy中的值超过Q,则在Y方向发一个脉冲,注意,两个方向发脉冲的过程是相互独立的事件。显然,若Xe>Ye,则X方向脉冲发得较快;若Xe=Ye,则两个方向脉冲发得一样快;若Ye>Xe,则Y方向脉冲发得较快。
可得软件框图如下(图4-11)。
实际上,数字积分直线插补的物理意义是使插补点沿着速度矢量的方向上进给,对于圆弧插补,这同样适用。
2.圆弧插补
圆弧DDA插补与直线DDA插补有以下不同:
(1)直线插补时为常量(终点坐标)累加,圆弧插补时为变量(动点坐标)累加。
(2)直线插补时,Qx中放的是终点X坐标,Qy中放的是终点Y坐标;而圆弧插补时,Qx中放的是动点Y坐标,Qy中放的是动点X坐标。
可得圆弧DDA插补的软件框图(图4-12)。
图4-12 数字积分法圆弧插补软件框图
3.参考程序
直线:
Sub 插补X()
标志X = 0
If 余数X >= Q Then
余数X = 余数X Mod Q
x动点 = x动点 + 1: 标志X = 1
End If
End Sub
Sub 插补Y()
标志Y = 0
If 余数Y >= Q Then
余数Y = 余数Y Mod Q
y动点 = y动点 + 1: 标志Y = 1
End If
End Sub
Sub 插补Z()
标志Z = 0
If 余数Z >= Q Then
余数Z = 余数Z Mod Q
z动点 = z动点 + 1: 标志Z = 1
End If
End Sub
Sub 插补公共()
余数X = 余数X + x终点
余数Y = 余数Y + y终点
余数Z = 余数Z + z终点
插补X
插补Y
插补Z
插补记录 = 插补记录 + 1
End Sub
Sub 插补()
Dim c As Integer
插补记录 = 0: 余数X = 0: 余数Y = 0: 余数Z = 0: 划轮廓线
PSet (z原点, x原点), vbRed
Select Case 象限标志
Case 1: ''第一象限插补
Do Until 插补记录 = Q
插补公共
Line -Step(z步长 × 标志Z, x步长 × 标志X), vbRed
Loop
Case 2: ''第二象限插补
c = x终点: x终点 = z终点: z终点 = -c
c = x步长: x步长 = z步长: z步长 = -c
Do Until 插补记录 = Q
插补公共
Line -Step(x步长 × 标志X, z步长 × 标志Z), vbRed
Loop
Case 3: ''第三象限插补
x终点 = -x终点: z终点 = -z终点
x步长 = -x步长: z步长 = -z步长
Do Until 插补记录 = Q
插补公共
Line -Step(z步长 × 标志Z, x步长 × 标志X), vbRed
Loop
Case 4: ''第四象限插补
c = x终点: x终点 = -z终点: z终点 = c
c = x步长: x步长 = -z步长: z步长 = c
Do Until 插补记录 = Q
插补公共
Line -Step(x步长 × 标志X, z步长 × 标志Z), vbRed
Loop
End Select
End Sub
圆弧:
Sub 插补()
PSet (z原点, x原点), vbRed
余数X = 0: 余数Y = 0: 余数Z = 0: 插补记录 = 0:
过象限标志 = 0: 跨象限数量 = 0
If Opt逆圆 = False Then
xx: 跨象限数量 = 跨象限数量 + 1
Select Case 象限标志
Case 1: ''第一象限插补
过象限预处理
Do Until (x动点对圆心 - x终点对圆心) ^ 2 + (z动点对圆心 - z终点对圆心) ^ 2 <= 跨象限数量 ^ 2
If x动点对圆心 = 0 Then
象限标志 = 2:
过象限标志 = 1
GoTo xx
End If
插补公共
Line -Step(z步长 × 标志Z, -x步长 × 标志X), vbRed
Loop
过象限标志 = 0
Case 2: ''第二象限插补
过象限预处理
Do Until (x动点对圆心 - x终点对圆心) ^ 2 + (z动点对圆心 - z终点对圆心) ^ 2 <= 跨象限数量 ^ 2
If x动点对圆心 = 0 Then
象限标志 = 3:
过象限标志 = 1
GoTo xx
End If
插补公共
Line -Step(-x步长 × 标志X, z步长 × 标志Z), vbRed
Loop
过象限标志 = 0
Case 3: ''第三象限插补
过象限预处理
Do Until (x动点对圆心 - x终点对圆心) ^ 2 + (z动点对圆心 - z终点对圆心) ^ 2 <= 跨象限数量 ^ 2
If x动点对圆心 = 0 Then
象限标志 = 4:
过象限标志 = 1
GoTo xx
End If
插补公共
Line -Step(z步长 × 标志Z, -x步长 × 标志X), vbRed
Loop
过象限标志 = 0
Case 4: ''第四象限插补
过象限预处理
Do Until (x动点对圆心 - x终点对圆心) ^ 2 + (z动点对圆心 - z终点对圆心) ^ 2 <= 跨象限数量 ^ 2
If x动点对圆心 = 0 Then
象限标志 = 1:
过象限标志 = 1
GoTo xx
End If
插补公共
Line -Step(-x步长 × 标志X, z步长 ×标志Z), vbRed
Loop
过象限标志 = 0
End Select
Else
xy: 跨象限数量 = 跨象限数量 + 1
Select Case 象限标志
Case 1: ''第一象限插补
过象限预处理
Do Until (x动点对圆心 - x终点对圆心) ^ 2 + (z动点对圆心 - z终点对圆心) ^ 2 <= 跨象限数量 ^ 2
单步连续判断
If z动点对圆心 = 0 Then
象限标志 = 4:
过象限标志 = 1
GoTo xy
End If
插补公共
Line -Step(-z步长 × 标志Z, x步长 × 标志X), vbRed
Loop
过象限标志 = 0
Case 2: ''第二象限插补
过象限预处理
Do Until (x动点对圆心 - x终点对圆心) ^ 2 + (z动点对圆心 - z终点对圆心) ^ 2 <= 跨象限数量 ^ 2
单步连续判断
If z动点对圆心 = 0 Then
象限标志 = 1:
过象限标志 = 1
GoTo xy
End If
插补公共
Line -Step(x步长 × 标志X, -z步长 × 标志Z), vbRed
Loop
过象限标志 = 0
Case 3: ''第三象限插补
过象限预处理
Do Until (x动点对圆心 - x终点对圆心) ^ 2 + (z动点对圆心 - z终点对圆心) ^ 2 <= 跨象限数量 ^ 2
If z动点对圆心 = 0 Then
象限标志 = 2:
过象限标志 = 1
GoTo xy
End If
插补公共
Line -Step(-z步长 × 标志Z, x步长 × 标志X), vbRed
Loop
过象限标志 = 0
Case 4: ''第四象限插补
过象限预处理
Do Until (x动点对圆心 - x终点对圆心) ^ 2 + (z动点对圆心 - z终点对圆心) ^ 2 <= 跨象限数量 ^ 2
If z动点对圆心 = 0 Then
象限标志 = 3:
过象限标志 = 1
GoTo xy
End If
插补公共
Line -Step(x步长 × 标志X, -z步长 × 标志Z), vbRed
Loop
过象限标志 = 0
End Select
cc: End If
End Sub
三、实验步骤
1.启动CNC-V2.0后,进入如图界面(图4-13):
2.根据界面,选择直线插补或圆弧插补。现以圆弧插补为例:
在主界面上选择圆弧插补后,进入圆弧插补界面。单击开始,就可清楚显示圆弧插补轨迹,修改左边的数据,可得到不同圆弧的插补轨迹。还可单步执行,让学员可以对照右上方坐标进行分析。如果圆弧半径相对于脉冲当量很大,那么,根本就看不到插补折线了,对于直线插补,操作与圆弧插补基本相似。参见图4-14、4-15、4-16、4-17。
注意:当标尺值小于圆弧的半径时,数字积分法插补出带圆角的正方形,若标尺值是零,则该正方形的圆角不存在,见图4-16。
图4-13 数字积分法插补主页面
图4-14 数字积分法圆弧插补演示(一)
图4-15 数字积分法圆弧插补演示(二)
图4-16 数字积分法圆弧插补演示(三)
图4-17 数字积分法直线插补演示
第三节 数据采样法插补原理实验
一、实验目的
1.掌握数据采样法直线与圆弧插补的基本原理
2.了解数据采样法直线插补与圆弧插补的程序编制方法
3.加深对数据采样法插补的理解
二、实验原理
随着数控系统中计算机的引入,插补实时性和计算复杂性之间的矛盾已不再那么突出了。因此,现代数控系统中就采用了结合计算机采样思想的数据采样插补法。
数据采样法实际上是一种粗插补过程,它所产生的微小线段仍然比较大,必须进一步对其密化(即精插补)。粗插补算法较复杂,大多用高级语言编制;精插补算法较简单,多用汇编语言或硬件插补器实现。
粗插补产生微小线段的周期称为插补周期Ts,精插补的周期称为位置控制周期Tc,它是伺服位置环的采样控制周期。对于特定的系统,Ts、Tc是两个固定不变的时间参数,且Ts=nTc,n为自然数。
Ts对系统稳定性没有影响,但对被加工轮廓的轨迹精度有影响,Ts愈大,则产生的微小线段愈长(△L=FTs,F为程编速度),插补计算误差就愈大。而Tc对系统稳定性和被加工轮廓的轨迹精度都有影响。
可见,为减小插补误差,应尽量减小Ts,但Ts若太小,则CPU可能来不及进行位置计算、显示、监控、I/O处理等CNC任务,Ts必须大于插补运行时间和完成其他相关
图4-18 第一象限直线 图4-19 第一象限数据采样直线插补软件流程图
任务所需时间之和。目前,Ts一般在10ms左右,如美国AB公司的7360CNC系统,Ts=10.24ms;德国SIEMENS公司的System-7CNC系统,Ts=8ms。随着计算机速度的提高,Ts有减小的趋势。
Tc选择一般有两种情况:Tc=Ts(7360CNC系统),Tc=0.5Ts(System-7CNC系统)。
以上是数据采样法的基本原理,下面讨论插补具体轮廓线时的情形。
1.1. 直线插补
图4-18为第一象限直线,现分析其插补规律。
刀尖从点Ni-1移动到点Ni,沿轮廓直线方向的增量为DL=F×Ts,沿X向的增量为DX,沿Y向的增量为DY,它们之间的关系是:
DX=DL×Xe/L,DY=DL×Ye/L
其中,L为轮廓直线的长度,它满足等式:L2=Xe2+Ye2
Ni点的动态坐标可以用前一个点的坐标动态表示:X=X+DX,Y=Y+DY
由此,可设计第一象限数据采样直线插补软件流程图,见图4-19。
2.2. 圆弧插补
数据采样法圆弧插补的基本思路是在满足加工精度的前提下,用切线、弦线或割线来代替圆弧实现进给,即用直线逼近圆弧。
(1)切线法(一阶DDA算法)
图4-20为第一象限逆圆,现分析其切线法插补规律。
设当前点在Ni-1,按切线方向前进一个粗插补周期后到达Ni点,走过的粗插补
单位长度为 L=F×Ts,其中:F为进给速度,粗插补周期为Ts。
图4-20 切线法逆圆插补示意图 图4-21切线法圆弧插补流程图
显然,Xi-1=Rcosψi-1 (R为圆弧半径)
Yi-1=Rsinψi-1
Xi=Rcos(ψi-1+θ)
Yi=Rsin(ψi-1+θ)
从而
Xi=Xi-1cosθ-Yi-1 sinθ
Yi=Yi-1cosθ+Xi-1 sinθ
因θ很小,所以
sinθ=θ-θ3/3!+θ5/5!-……
cosθ=1-θ2/2!+θ4/4!-……
取一阶近似(一阶DDA名称的由来),得
sinθ=θ=F×Ts/R=K
cosθ=1
因此
Xi=Xi-1-KYi-1
Yi=Yi-1+KXi-1
Xi=Xi-Xi-1=-KYi-1
Yi=Yi-Yi-1=KXi-1
由此,可设计第一象限切线法数据采样圆弧插补软件流程图,见图4-21。
本法与脉冲增量方式DDA插补在本质上是相同的,前者是后者的推广。由于误差太大(可以在随后的实验中验证),在实际的CNC系统中并不使用。
(2)弦线法(直接函数算法)
图4-22为第一象限顺圆,弦线法插补规律(请参考有关书籍自行分析)如下:
Ⅰ区:
∆Xi=(Yi-1+∆Yi-1×0.5)×FTs/R
∆Yi=-Yi-1+(R2-(Xi-1+∆Xi)2)1/2
Xi=Xi-1+∆Xi
Yi=Yi-1+∆Yi
Ⅱ区:
∆Yi=(Xi-1+∆Xi-1×0.5)×FTs/R
∆Xi=-Xi-1+(R2-(Yi-1+∆Yi)2)1/2
Xi=Xi-1+∆Xi
Yi=Yi-1+∆Yi
Ⅲ区:
∆Xi=(Yi-1+∆Yi-1×0.5)×FTs/R#8710;Yi=-Yi-1—(R2-(Xi-1+∆Xi)2)1/2
Xi=Xi-1+∆Xi
Yi=Yi-1+∆Yi
Ⅳ区:
∆Yi=(Xi-1+∆Xi-1×0.5)×FTs/R
∆Xi=-Xi-1-(R2-(Yi-1+∆Yi)2)1/2
Xi=Xi-1+∆Xi
Yi=Yi-1+∆Yi
图4-22 弦线法顺圆插补示意图 图4-23 分区图
分区情况见图4-23。由此,不难得到其流程图4-24。
弦线法的精度比切线法高。
(3)割线法(二阶DDA算法)
一阶算法时曾得到:sinθ=θ-θ3/3!+θ5/5!-……
cosθ=1-θ2/2!+θ4/4!-……
我们现在取两阶近似,即为二阶DDA算法:
sinθ=θ-θ3/3!≈θ
cosθ=1-θ2/2!≈1-0.5×θ2
图4-25逆圆第一象限插补时,可计算得到:
∆Xi=K×Yi-1-0.5×Xi-1K2
∆Yi=-K×Xi-1-0.5×Yi-1K2
Xi=Xi-1+∆Xi
Yi=Yi-1+∆Yi
按此编制程序流程图4-26。割线法的精度比弦线法高。
图4-24 弦线法圆弧插补流程图
图4-25 割线法逆圆插补示意图 图4-26 割线法圆弧插补流程图
3.参考程序:
直线:
Sub 插补()
Dim l, K, a, B, f1, t
x动点对起
1;所有标注为智造资料网zl.fbzzw.cn的内容均为本站所有,版权均属本站所有,若您需要引用、转载,必须注明来源及原文链接即可,如涉及大面积转载,请来信告知,获取《授权协议》。
2;本网站图片,文字之类版权申明,因为网站可以由注册用户自行上传图片或文字,本网站无法鉴别所上传图片或文字的知识版权,如果侵犯,请及时通知我们,本网站将在第一时间及时删除,相关侵权责任均由相应上传用户自行承担。
内容投诉
智造资料网打造智能制造3D图纸下载,在线视频,软件下载,在线问答综合平台 » 数控机床操作教程-(4)轮廓控制原理实验(图文教程)