我自己看了斑竹的NCHOLE程序,确实构思巧妙,特别是它可以在多个坐标平面内进行测量的功能.其中"dist_approach 1.,100."指令我也是第一次看到,相信对我以后的编程有很大的帮助.
根据我们车间经常测量夹具体底板的实际情况,我也曾编过一个类似的小程序,发出来给大家斧正,不完善的地方有兴趣的朋友给修一下.夹具底板为平面非固定孔系,要求高,位置度多0.03以下,已经到了三坐标精度的极限,因此去除手动误差成了我的首要选择,但是又因为每个夹具体又不一样,所以也要考虑程序的通用性.
程序开始要输入所测量孔的个数,并且所有孔都要先手动量一下,我也曾试过"傻瓜"方式,当遇到大直径小厚度的(例:R=100,H=3)孔时,发现不容易将测头放到适当的高度.
优点:无手动测量误差,在XY平面内测量通用性强,当2个建坐标基准孔与图纸基准不重合时,能自动将实际与理论的长度误差按各基准孔到原点的距离成比例分配,不会将误差积累到一个基准孔上.
缺点:要先输入待测孔的个数,按比例分配部分程序没找到合适的方程来解决,只好用穷举法了,所以这部分程序多,造成程序可读性差.
program PMZB[WM1,WM2]
  element_array MEMORY[100]
  coord ce,cx,cp,c1,c2
  element ex,e1,e2
  integer e,n,lx,st
  real xske,yske,xpre,ypre
  real dmx,xcor,ycor
  real xs1,xs2,ys1,ys2,xs,ys,czx,czy
  real ccx,ccy
  metric_mode 
  dms_angle 
  set_dim (dm=whole,a=full,arel=acute,amode=a360)
  dy 
! 
  DATI
  out_format (10,4)
  refsys 0
  selpl x
  noprn 
  manmove 
  probe (1,1)
  format (plane,f)
  dy (" 请输入待测孔的个数 ")
  read (N)
  dy (" 请测量基准面 ")
  mpl (MEMORY[1],4)
  skew1 (MEMORY[1],1,0)
  format (circle,x,y,dm,f)
  E=1
  loop 
    E=E+1
    if (E eq 2) then
      dy (" 请测量第一基准圆 !!! ")
    elsif (E eq 3) then
      dy (" 请测量第二基准圆 !!! ")
    else 
      dy (" 请测量其它圆 !!! ")
    end_if 
    mcir (MEMORY[E],4)
    exif (E eq (N+1))
  end_loop 
! 用手动测量的圆建立坐标系
  REF
! 
  loop 
    dy (" 请选择基准圆分布类型 ")
    dy (" 第一基准圆在坐标原点,第二基准圆在轴线上.   请输入 [1] ")
    dy (" 第一基准圆在坐标原点,第二基准圆随机分布.   请输入 [2] ")
    dy (" 第一基准圆和第二基准圆都随机分布.          请输入 [3] ")
    read (LX)
    exif (LX eq 1) or (LX eq 2) or (LX eq 3)
  end_loop 
  if (LX eq 2) then
    dy (" 请输入 (X) 旋转座标值 ")
    read (XSKE)
    dy (" 请输入 (Y) 旋转座标值 ")
    read (YSKE)
    iskew (ofs,XSKE,YSKE,z,2,1)
  elsif (LX eq 3) then
    dy (" 请输入 (X) 旋转座标矢量和 ")
    read (XSKE)
    dy (" 请输入 (Y) 旋转座标矢量和 ")
    read (YSKE)
    iskew (ofs,XSKE,YSKE,z,2,1)
    dy (" 请输入第一基准圆 (X) 座标值 ")
    read (XPRE)
    dy (" 请输入第一基准圆 (Y) 座标值 ")
    read (YPRE)
    preset (MEMORY[n+2],X=XPRE,Y=YPRE,2,2)
  end_if 
!   
  ncmove 
  fly (on)
  mspeed 70
  get_position (CE)
  move (X=0,Y=0,Z=CE|z)
  E=1
  loop 
    exif (E eq (N+1))
    E=E+1
    EX=MEMORY[E]
    CX=EX
    ST=E
    KONG
    if (E eq 3) then
! 用自动测量的圆建立坐标系
      REF
      if (LX eq 2) then
        iskew (ofs,XSKE,YSKE,z,2,1)
      elsif (LX eq 3) then
        iskew (ofs,XSKE,YSKE,z,2,1)
          e1=memory[n+3]
          c1=e1
          xs1=c1|x
          ys1=c1|y
        preset (MEMORY[n+2],X=XPRE,Y=YPRE,2,2)
!将差值按各基准孔距理论中心大小成比例分配
!采集两个基准孔数据
        e2=memory[n+3]
        c2=e2
        xs2=c2|x
        ys2=c2|y
!将数据进行分析并计算差值分配比例
        czx=abs(xs1)-abs(xske)
        czy=abs(ys1)-abs(yske)
        xs=xpre*xs2
        ys=ypre*ys2
        if xs gt 0 then
          if xpre gt 0 then
            if czx gt 0 then
              ccx=abs(xpre/(xske+xpre)*czx)
            elsif czx lt 0 then
              ccx=-abs(xpre/(xske+xpre)*czx)
            end_if            
          elsif xpre lt 0 then
            if czx gt 0 then
              ccx=-abs(xpre/(xske+xpre)*czx)
            elsif czx lt 0 then
              ccx=abs(xpre/(xske+xpre)*czx)
           end_if 
          end_if
        elsif xs lt 0 then
          if xpre gt 0 then
            if czx gt 0 then
              ccx=abs(xpre/xske*czx)
            elsif czx lt 0 then
              ccx=-abs(xpre/xske*czx)              
            end_if
          elsif xpre lt 0 then
            if czx gt 0 then
              ccx=-abs(xpre/xske*czx)
            elsif czx lt 0 then
              ccx=abs(xpre/xske*czx)              
            end_if         
          end_if 
        end_if
        if ys gt 0 then
          if ypre gt 0 then
            if czy gt 0 then
              ccy=abs(ypre/(yske+ypre)*czy)
            elsif czy lt 0 then
              ccy=-abs(ypre/(yske+ypre)*czy)
            end_if            
          elsif ypre lt 0 then
            if czy gt 0 then
              ccy=-abs(ypre/(yske+ypre)*czy)
            elsif czy lt 0 then
              ccy=abs(ypre/(yske+ypre)*czy)
           end_if 
          end_if
        elsif ys lt 0 then
          if ypre gt 0 then
            if czy gt 0 then
              ccy=abs(ypre/yske*czy)
            elsif czy lt 0 then
              ccy=-abs(ypre/yske*czy)              
            end_if
          elsif ypre lt 0 then
            if czy gt 0 then
              ccy=-abs(ypre/yske*czy)
            elsif czy lt 0 then
              ccy=abs(ypre/yske*czy)              
            end_if         
          end_if 
        end_if
      preset (MEMORY[n+2],x=xpre+ccx,y=ypre+ccy,2,2) 
      end_if
    end_if
    E=ST
  end_loop 
  for I=1 to N+1 by 1
    prn 
    output MEMORY[I]
  end_for 
  noprn 
  refsys 0
  move (Z=-50)
endstat 
  procedure REF
    proj (MEMORY[n+2],MEMORY[1],MEMORY[2])
    proj (MEMORY[n+3],MEMORY[1],MEMORY[3])
    iline (MEMORY[n+4],2,MEMORY[n+2])
    skew1 (MEMORY[1],1,0)
    skew2 (MEMORY[n+4],1,1,z)
    preset (MEMORY[1],z=0,1,1)
    preset (MEMORY[n+2],x=0,y=0,1,1)
  end_procedure 
! 
  procedure KONG
    move (X=CX|x,Y=CX|y)
    move (Z=CX|z)
    format (circle,x,y,dm,f)
    mcir (MEMORY[E],6)
    for I=1 to 6 by 1
      CP={CX|x+EX|dm/2*cos (60*I),CX|y+EX|dm/2*sin (60*I),CX|z}
      movetf (CP)
    end_for 
    move (Z=CE|z)
  end_procedure 
! 
  procedure DATI
    integer TIH
    real TI,DA,TIM1,TIM,TIS1,TIS,TIH1
    string ED[10],EM[10],ES[10]
    out_format (6,2)
    DA=date
    TI=time
!时 
    TIH1=trunc (TI/100)
    TIH=round (TIH1)
!分 
    TIM1=(TI/100)
    TIM=(TIM1-trunc (TIM1))
!秒 
    TIS1=trunc (TI)
    TIS=(TI-TIS1)
    out_format (4,2)
    if encode(ED,DA) and encode(EM,TIM) and encode(ES,TIS) then
      prn ("                      ***************  Measure: ZHOU  ********")
      prn ("Date = ","200",ED[1],"-",ED[2],ED[3],"-",ED[5],ED[6])
      prn ("Time = ",TIH,":",EM[3],EM[4],":",ES[3],ES[4])
      prn ("  ")
    end_if 
    noprn 
  end_procedure 
end_program 
何必呢  何苦呢...