逐点比较法第一象限直线圆弧插补
- 格式:doc
- 大小:407.50 KB
- 文档页数:22
逐点比较法第一象限直线,圆弧插补编程逐点比较法是以折线来逼近给定的轨迹,就是每走一步控制系统都要将加工点与给定的图形轨迹相比较,以决定下一步进给的方向,使之逼近加工轨迹。
逐点比较法以折线来逼近直线或圆弧,其最大的偏差不超过一个最小设定单位。
只要将脉冲当量取得足够小,就可以达到精度要求。
逐点比较插补法在脉冲当量为0.01mm,系统进给速度小于3000mm/min时,能很好的满足要求。
一、逐点比较法直线插补如下图所示设直线 oA 为第一象限的直线,起点为坐标原点o (0 , 0) ,终点坐标为, A( ) , P() 为加工点。
若 P 点正好处在直线 oA 上,由相似三角形关系则有即点在直线 oA 上方 ( 严格为直线 oA 与 y 轴正向所包围的区域 ) ,则有即若 P 点在直线 oA 下方 ( 严格为直线 oA 与 x 轴正向所包围的区域 ) ,则有图 3 — 1 逐点比较法第一象限直线插补即令则有:①如,则点 P 在直线 oA 上,既可向 +x 方向进给一步,也可向 +y 方向进给一步;②如,则点 P 在直线 oA 上方,应向 +x 方向进给一步,以逼近oA 直线;③如,则点 P 在直线 oA 下方,应向 +y 方向进给一步,以逼近 oA 直线一般将及视为一类情况,即时,都向 +x 方向进给一步。
当两方向所走的步数与终点坐标相等时,停止插补。
这即逐点比较法直线插补的原理。
对第一象限直线 oA 从起点 ( 即坐标原点 ) 出发,当 F 时, +x 向走一步;当 F<0 时,y 向走一步。
特点:每一步都需计算偏差,这样的计算比较麻烦。
递推的方法计算偏差:每走一步后新的加工点的偏差用前一点的加工偏差递推出来。
采用递推方法,必须知道开始加工点的偏差,而开始加工点正是直线的起点,故。
下面推导其递推公式。
设在加工点 P( ) 处,,则应沿 +x 方向进给一步,此时新加工点的坐标值为新加工点的偏差为即若在加工点 P( ) 处,,则应沿 +y 方向进给一步,此时新加工点的坐标值为,新加工点的偏差为即综上所述,逐点比较法直线插补每走一步都要完成四个步骤 ( 节拍 ) ,即:(1) 位置判别根据偏差值大于零、等于零、小于零确定当前加工点的位置。
(2) 坐标进给根据偏差值大于零、等于零、小于零确定沿哪个方向进给一步。
(3) 偏差计算根据递推公式算出新加工点的偏差值。
(4) 终点判别用来确定加工点是否到达终点。
若已到达,则应发出停机或转换新程序段信号。
一般用 x 和 y 坐标所要走的总步数 J来判别。
令 J= ,每走一步则 J 减 1 ,直至 J=0 。
上图为第一象限直线插补程序框图二、逐点比较法插补程序#include "conio.h"#include "graphics.h"#include "process.h"#define Ni_circle 0#define Shun_circle 1void 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;elseYm=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<y0)Ym=Ym+sstep;if(Xm<=x0&&Ym<=y0)Xm=Xm+sstep;if(Xm<x0&&Ym>y0) {flag=1; Ym=Ym-sstep;}if(Xm>=x0&&Ym>=y0) {if(flag) break;Xm=Xm-sstep;}}}else{ /*it is Fm's else*/if(!Directory) {if(Xm>x0&&Ym<y0){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<y0)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();}三、逐点比较法圆弧插补圆弧插补加工:是将加工点到圆心的距离与被加工圆弧的名义半径相比较,并根据偏差大小确定坐标进给方向,以逼近被加工圆弧。