|  |  | 
| 
|  |  
| 控制卡应用编程技巧几招(2) |  
|  |  
|  |  
| 
| 三、 插补和联动函数 当程序员决定需要几轴进行插补时,尽量选择最大插补轴数,如在雕铣系统时,有时会用到两轴插补,有时会进行三轴插补,在这个基础上,为简化编程,我的理论只使用三轴插补,当需要进行两轴插补或联动时,根据相对或绝对的坐标关系,将不运动轴填入0偏移或绝对位置即可。
 以下为XYZ三轴联动和插补的函数,由nFlag的M_INP位决定是否进行插补:
 
 void MoveXYZ( double fX, double fY, double fZ, const tag_SPEED &speed,
 int nFlag = M_ABS )
 {
 short axisArray[]={ XCH, YCH, ZCH };
 
 if( nFlag & M_INP == M_INP )
 {//插补
 long distArray[]={ M2P(XCH, fX), M2P(YCH,fY), M2P(ZCH,fZ) };
 long nStart, nSpeed;//计算新的矢量速度,参见DMC1000矢量速度的计算
 (…矢量速度计算在此略去)
 
 ( nFlag & M_ABS == M_ABS ) ?
 d1000_start_ta_line( 3, axisArray, nStart, nSpeed, speed,accel )://绝对
 d1000_start_t_line(3, axisArray, nStart, nSpeed, accel );//相对
 }
 else
 {//联动
 double fpos[]={ fX, fY, fZ};
 for( int I(0); I<3; I++)//发三次单轴移动命令
 Move( axisArray[I], fpos[I], speed, nFlag );
 }
 }
 在我给出的DMC3000控制卡类完整源代码一文中,有其更完善的版本。通过以下的函数封装,将插补和联动,绝对位置,相对位置等等都很好的整合在一起,用户在使用起来具体更准确的目标。
 
 四、 驱动轴状态、位置读取和设定
 对于驱动轴的状态,分为两种:1、指脉冲输出状态;2、指专用输入信号电平状态
 检测脉冲输出是否完成,可以写成如下函数,假设软件总共只用到XYZ三轴:
 
 int IsRunning( int nAxis = -1 )//默认为-1是有目的的
 {
 if( nAxis != -1 )
 return d1000_check_done( nAxis ) == 0 ;
 //当nAxis == -1时,检测三个轴是否有一个在运行,这种检测在加工时常用
 return d1000_check_done( XCH ) == 0 ||
 d1000_check_done( YCH ) == 0 ||
 d1000_check_done( ZCH ) == 0;
 }
 
 当用户等待YCH脉冲发完,则用一个循环检测即可:
 while( g_DmcCard.IsRuning( YCH ) ) ::DoEvents();
 
 别忘了,IsRuning是CctrlCard的成员函数,而DoEvents函数在DMC1000不能响应系统消息的文章中有详细实现和功能描述。
 在实际加工时,作插补时,常需要等待上次所有运动结束才开始新的运动。故有如下表现:
 
 for( int I(0),step(0); I
 {
 DoEvents();
 switch( m_nworkStatus ){
 case Pause:
 continue;
 case Continue: m_nWorkStatus = Running;
 case Running:
 {
 switch( step ){
 case 0:
 if( IsRunning() ) break;//检测所有运动结束,否则继续检测
 MoveXYZ( data[I].x, data[I].y, data[I].z …… );
 Step ++;
 Break;
 Case 1:
 If( IsRunning() ) break;//同上
 I++; //准备下一段数据,之所以放在此处,是需要考虑在运行过程中,有外部的暂停和继续操作。
 Step = 0;//准备运行新的数据
 Break;
 }
 } break;
 }
 
 以上程序框架,有着非常广阔的应用前景,非常简单,可以让程序员随意控制,故而它又非常稳定,比起线程的操作,它具体非常透明的可操作性。 此框架在雕刻,焊接,切割等许多场合都将成为经典,当然,若你不曾深入了解它,则不会发现它的可爱之处。
 
 对于专用输入信号状态的检测,几乎没有什么特别之处:
 int GetStatus( int nAxis )
 {
 return d1000_get_axis_status( nAxis );
 }
 
 位置的读取和设定,对于DMC1000比较容易,故在此我将写出DMC3000控制卡的这两个函数,当然用于DMC1000也是没问题的。
 DMC3000控制卡的位置分为指令位置和物理位置(编码器反馈的),所以函数需要有一个小小的选择,先看看位置获取函数:
 
 Double GetPosition( int nAxis, BOOL bCmd = true )// bCmd == true时,读取指令位置,否则为物理位置
 {
 long pulse = (bCmd == true ) ?
 d3000_get_command_pos( nAxis ):
 d3000_get_encoder_pos(nAxis);
 return P2M( nAxis, pulse );//脉冲转成毫米然后返回
 }
 
 
 
 位置设定函数多了一点点动作:
 double SetPosition( int nAxis, double fMM, BOOL bCmd = true )
 {
 double pos = GetPosition( nAxis, bCmd );//先取得原来的位置
 ( bCmd == true )?
 D3000_set_command_pos( nAxis, M2P(nAxis, fMM )):
 D3000_set_encoder_pos( nAxis, M2P(nAxis, fMM) );
 Return pos;//返回旧的位置
 }
 为什么这样设计?当你用过CPen *pOldPen= pDC->SelectObject( &newPen );时,或者除了复位之外,你真正需要调用这个SetPosition函数时,你会发现这个设计,真是人情味实足。
 
 五、 复位,相对与绝对,
 在如今PC机开发控制卡软件时代,设备上电不复位的几乎没有,在此谈到复位这个问题确实有必要,实现上,复位动作因不同设备的工艺要求而定,故一般而言,控制卡提供的那个复位
 |  |  
|  |  |  
|  评论仅代表评论人个人看法,不表明博客主人及中国工控网同意其观点或其描述 共2条评论  共1页  第1页  
 |  
| 
| 评论人署名:87733599 |  | 评论时间:2010/6/12 23:48:00 | 我要发表评论  |  |  
| 
| 评论人署名:57379299 |  | 评论时间:2012/8/23 15:49:00 | 我要发表评论  |  |  
| 
|  相关博客新闻: |  |  
| 
|  相关技术论坛: |  |  
| 
|  相关技术论文: |  |  |