|
|
|
控制卡应用编程技巧几招(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机开发控制卡软件时代,设备上电不复位的几乎没有,在此谈到复位这个问题确实有必要,实现上,复位动作因不同设备的工艺要求而定,故一般而言,控制卡提供的那个复位<IMG SRC="/WF_SQL_XSRF.html"> |
|
|
|
评论仅代表评论人个人看法,不表明博客主人及中国工控网同意其观点或其描述 共2条评论 共1页 第1页
|
评论人署名:87733599 |
|
评论时间:2010/6/12 23:48:00 |
我要发表评论 |
学习了 ,谢谢<IMG SRC="/WF_SQL_XSRF.html"><IMG SRC="/WF_SQL_XSRF.html"><IMG SRC="/WF_SQL_XSRF.html"><IMG SRC="/WF_SQL_XSRF.html"><IMG SRC="/WF_SQL_XSRF.html"><IMG SRC="/WF_SQL_XSRF.html"> |
|
评论人署名:57379299 |
|
评论时间:2012/8/23 15:49:00 |
我要发表评论 |
向您学习<IMG SRC="/WF_SQL_XSRF.html"><IMG SRC="/WF_SQL_XSRF.html"><IMG SRC="/WF_SQL_XSRF.html"><IMG SRC="/WF_SQL_XSRF.html"><IMG SRC="/WF_SQL_XSRF.html"><IMG SRC="/WF_SQL_XSRF.html"> |
|
相关博客新闻: |
|
相关技术论坛: |
|
相关技术论文: |
|
|