|
发表于 2014-3-11 17:00:41
|
显示全部楼层
我用CopperCAM出刀路。底层出隔离刀路,x坐标都为负值。更改了下楼主的程序,发上来供大家参考。
Dim Lz(100) As Double '每行的Z值先记录在数组中
Dim Yk As Integer
Dim Xk As Integer
TotX=-105 'GetOEMDRO(1221) '用户从DRO输入需要测试区域X方向最大坐标mm
TotY=45 'GetOEMDRO(1222) '用户从DRO输入需要测试区域Y方向最大坐标mm
Testep=5 'GetOEMDRO(1223) '用户从DRO输入每个测试样本点步进mm
Open "CNCZ0fix.z0f" For Output As #1 '新建测试数据记录文件
Print #1, TotX & "," & TotY & "," & Testep ' 写TotX,TotY,Testep到文件
Message "检查开始,请准备..."
MsgBox("请务必确认对刀线路连接良好!!")
Code "G4 P1" '执行G4代码,程序停顿1秒,等候准备工作
CurrentFeed=GetOEMDRO(818) '获得当前进给率
Code "F100" '为探测设置进给速率为100 mm/min
GageH=0 'GetUserDRO(1001) '获取用户设置的测量块高度
Code "G0 Z10"
Code "G0 X0 Y0"
X0=0 'GetOEMDRO(800) '获得起始点X坐标值
Y0=0 'GetOEMDRO(801) '获得起始点Y坐标值
Message "TotalX=" & TotX & ",TotalY=" & TotY & ",Testep=" & Testep
Yk=0 '当前行号
Dim xTestep As Integer
Dim yTestep As Integer
If (TotX > X0) Then
xTestep = Testep
Else
xTestep = -Testep
End If
If (TotY > Y0) Then
yTestep = Testep
Else
yTestep = -Testep
End If
For Y=Y0 To TotY Step yTestep
Code "G0 Y" & Y '走刀到当前Y
Yk=CInt(Y/yTestep) '当前行号(从0开始)
If (YK Mod 2)=0 Then
Xbg=X0 '奇数行X轴起始位置
Xed=TotX '奇数行X轴终止位置
Xsp=xTestep '奇数行X轴步进
Else
Xbg=TotX '偶数行X轴起始位置
Xed=X0 '偶数行X轴终止位置
Xsp=-xTestep '偶数行X轴步进
End If
For X=Xbg To Xed Step Xsp
Code "G0 X" & X '走刀到当前X
CurrentZ=GetOEMDRO(802) '获得当前Z坐标值
ZNew=CurrentZ-10 'Z轴目标为当前高度向下移动10mm
Code "G31 Z" & ZNew '执行G31,向下进行探测
While IsMoving() '等待触碰,执行这个函数后,当所有轴停止则返回0
Wend 'end while
Znew=GetOEMDRO(802) '记录刀尖触碰时Z的位置
FinalMove=Znew+2 '对刀后Z轴上移至量块顶面上方2mm
Code "G0 Z" & FinalMove '执行Z轴移动到最终位置
Z0=Znew-GageH '减去量块高度,得到Z0平面误差
Xk=CInt(X/xTestep) '当前列号(从0开始)
Lz(Xk)=Z0 'Z0值暂存数组中
Message "TotalX=" & TotX & ",TotalY=" & TotY & "; X=" & X & ",Y=" & Y & ",Z0=" & Z0 '信息栏输出完成的测试点信息
Next
For X=X0 To TotX Step xTestep '完成一行后,统一写测试信息
Xk=CInt(X/xTestep) '当前列号(从0开始)
Print #1, X & "," & Y & "," & Lz(Xk) '写X,Y,Z0到文件
Next
Next
Close #1
Code "F" & CurrentFeed '回存保留的进给率
Code "G0 X" & X0 & "Y" & Y0 '返回起始点
Message "检测完毕,数据保存至CNCZ0fix.z0f"
对应matlab程序
clear all;
clc;
ztest=load('d:\CNCZ0fix.z0f'); %导入CNC Z轴零点测试数据
fnc=fopen('d:\test.CNC','rt'); %原nc文件
fncnew=fopen('d:\newline.nc','wt'); %带生成的新的nc文件
totx=ztest(1,1); %零点测试区域x轴最大值
toty=ztest(1,2); %零点测试区域y轴最大值
testep=ztest(1,3); %零点测试步长mm
x_testep = testep;
y_testep = testep;
if (totx < 0)
x_testep = -x_testep;
end
if (toty < 0)
y_testep = -y_testep;
end
xPointNum = round(totx./x_testep)+1;
yPointNum = round(toty./y_testep)+1;
zerr=zeros(xPointNum, yPointNum);
m=2;
for j=1:1:yPointNum
for i=1:1:xPointNum
zerr(i,j)=ztest(m,3); %生成Z轴零点误差矩阵
m=m+1;
end
end
ptsrd=zeros(1,7); %nc文件行号,点x值,点y值,点z值,本句中用于更新(插入)修正后的z值的首位、尾位、G语句值
m=0;
lncnt=0; %文件行号
Gval=1; %当前是否G语句值
xx0=0; %之前点x,y值
yy0=0;
xx=0; %当前点x,y,z值
yy=0;
zz=3;
wh_z=[0,0]; %x,y,z定义值所在当前语句中的字符首尾位置
fln=fgets(fnc);
while(fln~=-1)
lncnt=lncnt+1;
wh_z=[0,0];
flg=0;
for i=1:1:size(fln,2)
if((fln(i)=='G') | (fln(i)=='g')) %当前语句中包含G语句的定义
for j=i+1:1:size(fln,2)
if(~(fln(j)>='0' & fln(j)<='9')) %找到G语句定义的尾位
break;
end
end
Gval=str2num(fln(i+1:j-1)); %获取G语句值定义
end
if((fln(i)=='X') | (fln(i)=='x')) %当前语句中包含x值的定义
for j=i+1:1:size(fln,2)
if(~((fln(j)>='0' & fln(j)<='9') | (fln(j)=='.') | (fln(j)=='-') | (fln(j)=='+'))) %找到x值定义的尾位
break;
end
end
flg=1; %flg==1,本语句有坐标值定义
xx=str2num(fln(i+1:j-1)); %获取x值定义
wh_z=[j,j]; %本句中用于更新(插入)修正后的z值的首尾位(新语句的首位位置置'Z',旧语句尾位起为其他后续语句)
end
if((fln(i)=='Y') | (fln(i)=='y')) %当前语句中包含y值的定义
for j=i+1:1:size(fln,2)
if(~((fln(j)>='0' & fln(j)<='9') | (fln(j)=='.') | (fln(j)=='-') | (fln(j)=='+'))) %找到y值定义的尾位
break;
end
end
flg=1; %flg==1,本语句有坐标值定义
yy=str2num(fln(i+1:j-1)); %获取y值定义
wh_z=[j,j]; %本句中用于更新(插入)修正后的z值的首尾位(新语句的首位位置置'Z',旧语句尾位起为其他后续语句)
end
if((fln(i)=='Z') | (fln(i)=='z')) %当前语句中包含y值的定义
for j=i+1:1:size(fln,2)
if(~((fln(j)>='0' & fln(j)<='9') | (fln(j)=='.') | (fln(j)=='-') | (fln(j)=='+'))) %找到z值定义的尾位
break;
end
end
flg=1; %flg==1,本语句有坐标值定义
zz=str2num(fln(i+1:j-1)); %获取z值定义
wh_z=[i,j]; %本句中用于更新(插入)修正后的z值的首尾位(新语句的首位位置置'Z',旧语句尾位起为其他后续语句)
end
end
if(flg==1)
if(m>0)
xx0=ptsrd(m,2);
yy0=ptsrd(m,3);
else
xx0=0;
yy0=0;
end
dis=sqrt((xx-xx0).^2+(yy-yy0).^2);
if( (dis>testep/2) & (Gval==1) ) %当前走刀为G1,且当前点较之前点水平位移大于testep/2,则进行插值
zz0=ptsrd(m,4);
n=ceil(dis/(testep/2)); %将本条刀路内共分为n个子刀路,需插值n-1个
for k=1:1:n-1
m=m+1;
ptsrd(m,1:4)=[0,k/n*(xx-xx0)+xx0,k/n*(yy-yy0)+yy0,k/n*(zz-zz0)+zz0]; %插值的行号设为0
ptsrd(m,7)=Gval; %存放G值
end
end
m=m+1;
ptsrd(m,1:4)=[lncnt,xx,yy,zz]; %写入本语句行号,x,y,z值
ptsrd(m,5:6)=[wh_z(1),wh_z(2)]; %本句中用于更新(插入)修正后的z值的首尾位(新语句的首位位置置'Z',旧语句尾位起为其他后续语句)
ptsrd(m,7)=Gval; %存放G值
end
fln=fgets(fnc);
end
%以下通过Z轴零点误差矩阵修正各点z值
for i=1:1:size(ptsrd,1)
x0=ptsrd(i,2)/x_testep;
y0=ptsrd(i,3)/y_testep;
x1=floor(x0);
x2=ceil(x0);
y1=floor(y0);
y2=ceil(y0);
if(x2==x1 & y2==y1) %当前雕刻点与样本点重合
z0=zerr(x1+1,y1+1);
ptsrd(i,4)=ptsrd(i,4)+z0; %z0取重合的样本点的零点位置,修正当前点z轴的下刀量
else %当前雕刻点与样本点不重合
if(x2==x1)
if(x1>0)
x1=x1-1;
else
x2=x2+1;
end
end
if(y2==y1)
if(y1>0)
y1=y1-1;
else
y2=y2+1;
end
end
nbpts=[x1,y1,zerr(x1+1,y1+1);x1,y2,zerr(x1+1,y2+1);x2,y1,zerr(x2+1,y1+1);x2,y2,zerr(x2+1,y2+1)]; %四周的样本点
dis=sqrt((x0-nbpts(:,1)).^2+(y0-nbpts(:,2)).^2); %计算与四周样本点的水平距离
[Y,I]=sort(dis); %距离从小到大排序
plpts=nbpts(I(1:3),:); %选出距离最小的三个样本点
a1=x0-plpts(1,1); %将当前点的x,y值代入由三个样本点构建平面方程,得到z0
a2=plpts(2,1)-plpts(1,1);
a3=plpts(3,1)-plpts(1,1);
b1=y0-plpts(1,2);
b2=plpts(2,2)-plpts(1,2);
b3=plpts(3,2)-plpts(1,2);
c2=plpts(2,3)-plpts(1,3);
c3=plpts(3,3)-plpts(1,3);
c1=(a1*b3*c2+a2*b1*c3-a1*b2*c3-a3*b1*c2)./(a2*b3-a3*b2);
z0=c1+plpts(1,3);
ptsrd(i,4)=ptsrd(i,4)+z0; %通过估计的零点位置z0,修正当前点z轴的下刀量
end
end
fseek(fnc,0,'bof');
m=1;
lncnt=0;
wh_z=[0,0];
fln=fgets(fnc);
while((fln~=-1) & (m<=size(ptsrd,1)))
lncnt=lncnt+1;
if(lncnt==ptsrd(m,1)) %只修改有坐标值定义的语句
wh_z=ptsrd(m,5:6); %本句中用于更新(插入)修正后的z值的首尾位(新语句的首位位置置'Z',旧语句尾位起为其他后续语句)
flnnew=sprintf('%sZ%0.3f%s',fln(1:wh_z(1)-1),ptsrd(m,4),fln(wh_z(2):size(fln,2))); %生成新语句
fprintf(fncnew,'%s',flnnew);
while((m<size(ptsrd,1)) & (ptsrd(m+1,1)==0)) %本语句后面有插值,创建新语句输出
m=m+1;
flnnew=sprintf('G%dX%0.3fY%0.3fZ%0.3f\n',ptsrd(m,7),ptsrd(m,2),ptsrd(m,3),ptsrd(m,4)); %生成新语句
fprintf(fncnew,'%s',flnnew);
end
m=m+1;
else
fprintf(fncnew,'%s',fln); %没有坐标值定义的语句直接输出
end
fln=fgets(fnc);
end
fclose(fnc);
fclose(fncnew);
plot3(ptsrd(:,2),ptsrd(:,3),ptsrd(:,4)); |
|