圆弧插补C语言程序
- 格式:doc
- 大小:24.00 KB
- 文档页数:3
圆弧插补指令G02/G03指令格式:G02R__X (U )__ Z (W )__ F__ ;G03 I__ K__指令意义:刀具沿X 、Z 两轴同时从起点位置(当前程序段运行前的位置)以R 指定的值为半径或以I 、K 值确定的圆心顺时针(G02)/逆时针(G03)圆弧插补至X(U )、Z (W )指定的终点位置。
指令地址:G02:顺时针圆弧插补,见图3-15A ; G03:逆时针圆弧插补,见图3-15B ;X :终点位置在X 轴方向的绝对坐标值,其取值范围是:-9999.999mm ~+9999.999mm;Z :终点位置在Z 轴方向的绝对坐标值,其取值范围是:-9999.999mm ~+9999.999mm;U :终点位置相对起点位置在X 轴方向的坐标值,其取值范围是:-9999.999mm ~+9999.999mm;W :终点位置相对起点位置在Z 轴方向的坐标值,其取值范围是:-9999.999mm ~+9999.999mm;I :圆心相对圆弧起点在X 轴上的坐标值,其取值范围是:-9999.999mm ~+9999.999mm;K :圆心相对圆弧起点在Z 轴上的坐标值,其取值范围是:-9999.999mm ~+9999.999mm;R :圆弧半径;F :沿圆周运动的切线速度,其取值范围是:1~15000mm/min,其速度合成图见本手册3.6节进给功能F 代码。
图3-15A G02轨迹图图3-15B G03轨迹图指令说明:● 顺时针或逆时针是从垂直于圆弧所在平面的坐标轴的正方向看到的回转方向,它是与采用前刀座坐标系还是后刀座坐标系有关的,如图3-16;图3-16 圆弧方向的确定● 圆弧中心用地址I 、K 指定时,其分别对应于X ,Z 轴。
I 、K 表示从圆弧起点到圆心的矢量分量,是增量值:I =圆心坐标X -圆弧起始点的X 坐标; K =圆心坐标Z -圆弧起始点的Z 坐标;OKI图3-17 圆弧I 、K 值I 、K 根据方向带有符号,I 、K 方向与X 、Z 轴方向相同,则取正值;否则,取负值。
#include<stdio.h>#include<math.h>#include<stdlib.h>/********************************************************************/ /* 函数名: InsertPoint *//* 功能:控制机床各轴进给并将进给结果写入文件中 *//* 参数:double x, double y 插补点单位:毫米 *//* 说明:与机床硬件关联,每产生一个点调用一次 *//********************************************************************/ void InsertPoint(double xCur,double yCur){extern FILE *fp;char ch=10;printf("xCur=%f,yCur=%f\n",xCur,yCur);fprintf(fp,"%f,%f",xCur,yCur);fputc(ch,fp);}/********************************************************************/ /* 函数名: Judge_Quadrant *//* 功能:判断参数坐标的所在象限并返回相应象限值 *//* 参数:double x mm *//* double y mm *//********************************************************************/ unsigned short Judge_Quadrant(double x, double y){unsigned short nDir;if (x>=0){ //象限判断if (y>=0){nDir=1;return 1;}else{nDir=4;return 4;}}else{if (y>=0){nDir=2;return 2;}else{nDir=3;return 3;}}}/********************************************************************/ /* 函数名: DDA_Line */ /* 功能:数字积分法直线插补 *//* 参数:double XEnd, double YEnd 插补终点 mm *//* int step 步长 mm *//* unsigned short n 寄存器位数 *//********************************************************************/ void DDA_Line(unsigned short n, int step, double XEnd, double YEnd){long XRes,YRes; //寄存器溢出后余数long xEnd,yEnd; //插补终点值long XCur=0,YCur=0; //当前位置int IPCount=0;//累加值int nQuadrant;//象限int Q; //累加器容量int bInterpXEnable,bInterpYEnable;XRes=YRes=0;bInterpXEnable=bInterpYEnable=0;xEnd=labs(XEnd);yEnd=labs(YEnd);Q=(fabs(YEnd)+fabs(XEnd))/step;nQuadrant=Judge_Quadrant(XEnd,YEnd);//计算插补象限switch(nQuadrant){case 1:while (IPCount<Q){XRes+=xEnd/step;YRes+=yEnd/step;if (XRes>=Q){XRes=XRes%Q;XCur+=step;bInterpXEnable=1;}if (YRes>=Q){YRes=YRes%Q;YCur+=step;bInterpYEnable=1;}if (bInterpXEnable==1||bInterpYEnable==1) {InsertPoint(XCur,YCur);bInterpXEnable=bInterpYEnable=0;}IPCount++;}break;case 2:while (IPCount<Q){XRes+=xEnd/step;YRes+=yEnd/step;if (XRes>=Q){XRes=XRes%Q;XCur-=step;bInterpXEnable=1;}if (YRes>=Q){YRes=YRes%Q;YCur+=step;bInterpYEnable=1;}if (bInterpXEnable==1||bInterpYEnable==1) { InsertPoint(XCur,YCur); bInterpXEnable=bInterpYEnable=0;}IPCount++;}break;case 3:while (IPCount<Q){XRes+=xEnd/step;YRes+=yEnd/step;if (XRes>=Q){XRes=XRes%Q;XCur-=step;bInterpXEnable=1;}if (YRes>=Q){YRes=YRes%Q;YCur-=step;bInterpYEnable=1;}if (bInterpXEnable==1||bInterpYEnable==1) {InsertPoint(XCur,YCur); bInterpXEnable=bInterpYEnable=0;}IPCount++;}break;case 4:while (IPCount<Q){XRes+=xEnd/step;YRes+=yEnd/step;if (XRes>=Q){XRes=XRes%Q;XCur+=step;bInterpXEnable=1;}if (YRes>=Q){YRes=YRes%Q;YCur-=step;bInterpYEnable=1;}if (bInterpXEnable==1||bInterpYEnable==1) {InsertPoint(XCur,YCur); bInterpXEnable=bInterpYEnable=0;}IPCount++;}break;}}/********************************************************************//* 函数名: DDA_Line *//* 功能:数字积分法圆弧插补 *//* 参数:double XEnd, double YEnd 插补终点 mm *//* int step 步长 mm *//* unsigned short n 寄存器位数 *//********************************************************************/void DDA_Circle(unsigned short n, int step, double XStart, double YStart, double XEnd, double Y End, double radius, int bIsCW){double xCur=XStart,yCur=YStart;long xRes=0,yRes=0;int ndir,Q;int judge=1;int full_circle=0;int xEnable,yEnable;xEnable=yEnable=0;Q=radius;//溢出基值,也可取为pow(2,n)InsertPoint(xCur,yCur);if(XStart==XEnd&YStart==YEnd)full_circle=1;//判断是否要画整圆while(judge==1||full_circle==1)//检测终点{xRes+=fabs(xCur);yRes+=fabs(yCur);if(xRes>=Q&fabs(yCur)<=radius){xRes=xRes%Q;yEnable=1;}if(yRes>=Q&fabs(xCur)<=radius){yRes=yRes%Q;xEnable=1;}if(bIsCW==0)//逆圆插补{ndir=Judge_Quadrant(xCur,yCur);if(yEnable==1)//xRes溢出,y轴进给{switch(ndir){case 1:if(fabs(yCur)<radius) yCur+=step;break;//防止y轴超出半径范围case 2:yCur-=step;break;case 3:if(fabs(yCur)<radius) yCur-=step;break;//防止y轴超出半径范围case 4:yCur+=step;break;}}if(xEnable==1)//yRes溢出,x轴进给{switch(ndir){ case 1:xCur-=step;break;case 2:if(fabs(xCur)<radius) xCur-=step;break;//防止x轴超出半径范围case 3:xCur+=step;break;case 4:if(fabs(xCur)<radius) xCur+=step;break;//防止x轴超出半径范围}}}else//顺圆插补{ndir=Judge_Quadrant(xCur,yCur);if(yEnable==1)//xRes溢出,y轴进给{switch(ndir){case 1:yCur-=step;break;case 2:if(fabs(yCur)<radius) yCur+=step;break;//防止y轴超出半径范围case 3:yCur+=step;break;case 4:if(fabs(yCur)<radius) yCur-=step;break;//防止y轴超出半径范围}}if(xEnable==1)//yRes溢出,x轴进给{switch(ndir){case 1:if(fabs(xCur)<radius) xCur+=step;break;//防止x轴超出半径范围case 2:xCur+=step;break;case 3:if(fabs(xCur)<radius) xCur-=step;break;//防止x轴超出半径范围case 4:xCur-=step;break;}}}judge=(fabs(xCur-XEnd)>=step||fabs(yCur-YEnd)>=step);if(xEnable||yEnable)//判断并进行进给运动{InsertPoint(xCur,yCur);xEnable=yEnable=0;full_circle=0;}}}FILE *fp;int main(){char fn[10];printf("please input filename:\n");scanf("%s",fn);if((fp=fopen(fn,"w"))==NULL) { printf("can't open file\n"); exit(0);}DDA_Circle(4,1,50,0,40,-30,50,1);//输入要插补的圆弧的参数// DDA_Line(4,1,50,-20);//输入要插补的圆弧的参数fclose(fp);return 0;}。
3、G2/G3 :圆弧插补指令刀具从现处位置沿圆弧轨迹移动至圆弧终点。
移动的速度由进给速度F指令指定。
编程格式:XY平面圆弧: G2或G3 X — Y — R — F—X — Y—:为圆弧的终点位置坐标。
R—:圆弧的半径。
F—:为刀具移动的速度,即切削进给速度。
G2 —:顺时针圆弧插补。
G3 —:逆时针圆弧插补。
G2/G3 :圆弧插补指令应用将执行动作:刀具从现处位置C点沿CD之间的圆弧轨迹移移动至圆弧终点D。
CD段圆弧是一段顺时针圆弧轨迹,所以用G2指令。
加工程序:绝对坐标编程:N80 G90 G2 X63.0 Y20.0 R23.0相对坐标编程:N80 G91 G2 X23.0 Y-23.0 R23.0 F100平面的选择:数控系统一般可以加工XY、XZ、YZ平面的圆弧。
G17:该指令表示选择XY平面,在此平面中进行圆弧插补和刀具补偿。
此代码为系统初始代码。
电源一接通G17 就作为平面选择的起始代码而自动生效。
G18:该指令表示选择XZ平面,在此平面中进行圆弧插补和刀具补偿。
G19:该指令表示选择YZ平面,在此平面中进行圆弧插补和刀具补偿。
G17、G18、G19平面顺逆圆弧判断示意图:G17、G18、G19平面顺逆圆弧判断用IJK代替R编程I:表示圆心点相对起点在X轴上的增量坐标。
J:表示圆心点相对起点在Y轴上的增量坐标。
K:表示圆心点相对起点在Z轴上的增量坐标。
用IJK代替R编程应用加工程序:。
N50 G1 G90 X15 Y0N60 G2 I-15 。
#include "math.h"#include "stdio.h"main(){int type;while(1){printf("请输入线型:\n");printf("1表示直线\n2表示圆弧\n3表示退出\n");scanf("%d",&type);if(type==1)Line();elseif(type==2)Arc();elsebreak;}}void Line(){int m=0,x,y,x0,y0,xe,ye,JX,JY,JS,F1=0,F2;printf("请输入直线的起点坐标和终点坐标(数据之间用逗号分隔):\n");scanf("%d,%d,%d,%d",&x0,&y0,&xe,&ye);x=x0;y=y0;JX=xe-x0;JS=abs(JX)+abs(JY);printf("偏差判别坐标进给终点判断偏差运算\n");while(JS!=0){if(F1>=0){if(JX>0)x++;elsex--;F2=F1-abs(JY);JS-=1;if(F1>0)if(JX>0)printf(" F%d>0 +X %d F%d=F%d-|Ye-Y0|=%d\n",m,JS,m+1,m,F2);elseprintf(" F%d>0 -X %d F%d=F%d-|Ye-Y0|=%d\n",m,JS,m+1,m,F2);elseif(JX<0)printf(" F%d=0 +X %d F%d=F%d-|Ye-Y0|=%d\n",m,JS,m+1,m,F2);elseprintf(" F%d=0 -X %d F%d=F%d-|Ye-Y0|=%d\n",m,JS,m+1,m,F2);F1=F2;}else{if(JY>0)y++;elsey--;F2=F1+abs(JX);if(JY<0)printf(" F%d<0 +Y %d F%d=F%d+|Xe-X0|=%d\n",m,JS,m+1,m,F2);elseprintf(" F%d<0 -Y %d F%d=F%d+|Xe-X0|=%d\n",m,JS,m+1,m,F2);F1=F2;m++;}}}void Arc(){int m=0,x,y,x0,y0,xe,ye,dox,doy,JX,JY,Ie,Je,F1=0,F2,flag;int R1,R2,R3,R4,SR1,SR2,SR3,SR4,NR1,NR2,NR3,NR4;printf("请输入圆弧类型:\n1表示顺园\n2表示逆圆\n");scanf("%d",&flag);printf("请输入圆弧的起点,终点坐标以及圆心相对起点的坐标(数据之间用逗号分隔):\n");scanf("%d,%d,%d,%d,%d,%d",&x0,&y0,&xe,&ye,&dox,&doy);x=x0;y=y0;Ie=xe-(x0+dox);Je=ye-(y0+doy);printf("偏差判别坐标进给偏差运算终点判别\n");while((Ie-JX)!=0||(Je-JY)!=0)/*for(;i<=1;)*/{R1=(JX>0)&&(JY>=0);R3=(JX<0)&&(JY<=0);R4=(JX>=0)&&(JY<0);SR1=(flag==1)&&R1;SR2=(flag==1)&&R2;SR3=(flag==1)&&R3;SR4=(flag==1)&&R4;NR1=(flag==2)&&R1;NR2=(flag==2)&&R2;NR3=(flag==2)&&R3;NR4=(flag==2)&&R4;if(F1>=0)if(SR1||NR2||SR3||NR4)if(SR3||NR4){y++;F2=F1+2*JY+1;JY+=1;if(F1>0){printf(" F%d>0 +Y F%d=F%d+2*J%d+1=%d I%d-Ie=%d\n",m,m+1,m,m,F2,m+1,JX-Ie);printf(" (%d,%d) J%d-Je=%d\n",JX,JY,m+1,JY-Je);}else{printf(" F%d=0 +Y F%d=F%d+2*J%d+1=%d I%d-Ie=%d\n",m,m+1,m,m,F2,m+1,JX-Ie);printf(" (%d,%d) J%d-Je=%d\n",JX,JY,m+1,JY-Je);}F1=F2;m++;}else{y--;F2=F1-2*JY+1;JY-=1;if(F1>0){printf(" F%d>0 -Y F%d=F%d-2*J%d+1=%d I%d-Ie=%d\n",m,m+1,m,m,F2,m+1,JX-Ie);printf(" (%d,%d) J%d-Je=%d\n",JX,JY,m+1,JY-Je);}else{printf(" F%d=0 -Y F%d=F%d-2*J%d+1=%d I%d-Ie=%d\n",m,m+1,m,m,F2,m+1,JX-Ie);printf(" (%d,%d) J%d-Je=%d\n",JX,JY,m+1,JY-Je);}F1=F2;}elseif(SR2||NR3){x++;F2=F1+2*JX+1;JX+=1;if(F1>0){printf(" F%d>0 +X F%d=F%d+2*I%d+1=%d I%d-Ie=%d\n",m,m+1,m,m,F2,m+1,JX-Ie);printf(" (%d,%d) J%d-Je=%d\n",JX,JY,m+1,JY-Je);}else{printf(" F%d=0 +X F%d=F%d+2*I%d+1=%d I%d-Ie=%d\n",m,m+1,m,m,F2,m+1,JX-Ie);printf(" (%d,%d) J%d-Je=%d\n",JX,JY,m+1,JY-Je);}F1=F2;m++;}else{x--;F2=F1-2*JX+1;JX-=1;if(F1>0){printf(" F%d>0 -X F%d=F%d-2*I%d+1=%d I%d-Ie=%d\n",m,m+1,m,m,F2,m+1,JX-Ie);printf(" (%d,%d) J%d-Je=%d\n",JX,JY,m+1,JY-Je);}else{printf(" F%d=0 -X F%d=F%d-2*I%d+1=%d I%d-Ie=%d\n",m,m+1,m,m,F2,m+1,JX-Ie);printf(" (%d,%d) J%d-Je=%d\n",JX,JY,m+1,JY-Je);}F1=F2;m++;}elseif(SR2||NR1||SR4||NR3)if(NR1||SR2){y++;F2=F1+2*JY+1;JY+=1;printf(" F%d<0 +Y F%d=F%d+2*J%d+1=%d I%d-Ie=%d\n",m,m+1,m,m,F2,m+1,JX-Ie);printf(" (%d,%d) J%d-Je=%d\n",JX,JY,m+1,JY-Je);F1=F2;else{y--;F2=F1-2*JY+1;JY-=1;printf(" F%d<0 -Y F%d=F%d-2*J%d+1=%dI%d-Ie=%d\n",m,m+1,m,m,F2,m+1,JX-Ie);printf(" (%d,%d) J%d-Je=%d\n",JX,JY,m+1,JY-Je);F1=F2;m++;}elseif(SR1||NR4){F2=F1+2*JX+1;JX+=1;printf(" F%d<0 +X F%d=F%d+2*I%d+1=%d I%d-Ie=%d\n",m,m+1,m,m,F2,m+1,JX-Ie);printf(" (%d,%d) J%d-Je=%d\n",JX,JY,m+1,JY-Je);F1=F2;m++;}else{x--;F2=F1-2*JX+1;JX-=1;printf(" F%d<0 -X F%d=F%d-2*I%d+1=%d I%d-Ie=%d\n",m,m+1,m,m,F2,m+1,JX-Ie);printf(" (%d,%d) J%d-Je=%d\n",JX,JY,m+1,JY-Je);F1=F2;}}。
. ❖圆弧插补指令
1.G02顺时针圆弧插补:沿着刀具进给路径,圆弧段为顺时针。
2.G03逆时针圆弧插补:沿着刀具进给路径,圆弧段位逆时针。
❖圆弧半径编程
1.格式:G02/G03X_Y_Z_R_F;
2.移到圆弧初始点;
3.G02/G03+圆弧终点坐标+R圆弧半径。
(圆弧<或=半圆用+R;大于半圆
(180度)小于整圆(360度)用-R。
圆弧半径R编程不能用于整圆加工。
)
❖用I、J、K编程(整圆加工)
1.格式:G02\G03X_Y_Z_I_J_K_F_;
2.I、J、K分别表示X\Y\Z方向相对于圆心之间的距离,X方向用I表示,
Y方向用J表示,z方向用K表示(G17平面K为0)。
正负判断方法:刀具停留在轴的负方向,往正方向进给,也就是与坐标轴同向,那么就取正值,反之为负。
❖技巧
1.在加工整圆时,一般把刀具定位到中心点,下刀后移动到x轴或Y轴的
轴线上,这样就有一根轴是0,便于编程。
1 / 1'.。