|
|
三、插補(bǔ)和聯(lián)動(dòng)函數(shù) 當(dāng)程序員決定需要幾軸進(jìn)行插補(bǔ)時(shí),盡量選擇最大插補(bǔ)軸數(shù),如在雕銑系統(tǒng)時(shí),有時(shí)會(huì)用到兩軸插補(bǔ),有時(shí)會(huì)進(jìn)行三軸插補(bǔ),在這個(gè)基礎(chǔ)上,為簡(jiǎn)化編程,我的理論只使用三軸插補(bǔ),當(dāng)需要進(jìn)行兩軸插補(bǔ)或聯(lián)動(dòng)時(shí),根據(jù)相對(duì)或絕對(duì)的坐標(biāo)關(guān)系,將不運(yùn)動(dòng)軸填入0偏移或絕對(duì)位置即可。 以下為XYZ三軸聯(lián)動(dòng)和插補(bǔ)的函數(shù),由nFlag的M_INP位決定是否進(jìn)行插補(bǔ):
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 ) {//插補(bǔ) long distArray[]={ M2P(XCH, fX), M2P(YCH,fY), M2P(ZCH,fZ) }; long nStart, nSpeed;//計(jì)算新的矢量速度,參見(jiàn)DMC1000矢量速度的計(jì)算 (…矢量速度計(jì)算在此略去)
( nFlag & M_ABS == M_ABS ) ? d1000_start_ta_line( 3, axisArray, nStart, nSpeed, speed,accel )://絕對(duì) d1000_start_t_line(3, axisArray, nStart, nSpeed, accel );//相對(duì) } else {//聯(lián)動(dòng) double fpos[]={ fX, fY, fZ}; for( int I(0); I<3; I++)//發(fā)三次單軸移動(dòng)命令 Move( axisArray[I], fpos[I], speed, nFlag ); } } 在我給出的DMC3000控制卡類完整源代碼一文中,有其更完善的版本。通過(guò)以下的函數(shù)封裝,將插補(bǔ)和聯(lián)動(dòng),絕對(duì)位置,相對(duì)位置等等都很好的整合在一起,用戶在使用起來(lái)具體更準(zhǔn)確的目標(biāo)。
四、 驅(qū)動(dòng)軸狀態(tài)、位置讀取和設(shè)定 對(duì)于驅(qū)動(dòng)軸的狀態(tài),分為兩種:1、指脈沖輸出狀態(tài);2、指專用輸入信號(hào)電平狀態(tài) 檢測(cè)脈沖輸出是否完成,可以寫成如下函數(shù),假設(shè)軟件總共只用到XYZ三軸:
int IsRunning( int nAxis = -1 )//默認(rèn)為-1是有目的的 { if( nAxis != -1 ) return d1000_check_done( nAxis ) == 0 ; //當(dāng)nAxis == -1時(shí),檢測(cè)三個(gè)軸是否有一個(gè)在運(yùn)行,這種檢測(cè)在加工時(shí)常用 return d1000_check_done( XCH ) == 0 || d1000_check_done( YCH ) == 0 || d1000_check_done( ZCH ) == 0; }
當(dāng)用戶等待YCH脈沖發(fā)完,則用一個(gè)循環(huán)檢測(cè)即可: while( g_DmcCard.IsRuning( YCH ) ) ::DoEvents();
別忘了,IsRuning是CctrlCard的成員函數(shù),而DoEvents函數(shù)在DMC1000不能響應(yīng)系統(tǒng)消息的文章中有詳細(xì)實(shí)現(xiàn)和功能描述。 在實(shí)際加工時(shí),作插補(bǔ)時(shí),常需要等待上次所有運(yùn)動(dòng)結(jié)束才開始新的運(yùn)動(dòng)。故有如下表現(xiàn):
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;//檢測(cè)所有運(yùn)動(dòng)結(jié)束,否則繼續(xù)檢測(cè) MoveXYZ( data[I].x, data[I].y, data[I].z …… ); Step ++; Break; Case 1: If( IsRunning() ) break;//同上 I++; //準(zhǔn)備下一段數(shù)據(jù),之所以放在此處,是需要考慮在運(yùn)行過(guò)程中,有外部的暫停和繼續(xù)操作。 Step = 0;//準(zhǔn)備運(yùn)行新的數(shù)據(jù) Break; } } break; }
以上程序框架,有著非常廣闊的應(yīng)用前景,非常簡(jiǎn)單,可以讓程序員隨意控制,故而它又非常穩(wěn)定,比起線程的操作,它具體非常透明的可操作性。 此框架在雕刻,焊接,切割等許多場(chǎng)合都將成為經(jīng)典,當(dāng)然,若你不曾深入了解它,則不會(huì)發(fā)現(xiàn)它的可愛(ài)之處。
對(duì)于專用輸入信號(hào)狀態(tài)的檢測(cè),幾乎沒(méi)有什么特別之處: int GetStatus( int nAxis ) { return d1000_get_axis_status( nAxis ); }
位置的讀取和設(shè)定,對(duì)于DMC1000比較容易,故在此我將寫出DMC3000控制卡的這兩個(gè)函數(shù),當(dāng)然用于DMC1000也是沒(méi)問(wèn)題的。 DMC3000控制卡的位置分為指令位置和物理位置(編碼器反饋的),所以函數(shù)需要有一個(gè)小小的選擇,先看看位置獲取函數(shù):
Double GetPosition( int nAxis, BOOL bCmd = true )// bCmd == true時(shí),讀取指令位置,否則為物理位置 { long pulse = (bCmd == true ) ? d3000_get_command_pos( nAxis ): d3000_get_encoder_pos(nAxis); return P2M( nAxis, pulse );//脈沖轉(zhuǎn)成毫米然后返回 }
位置設(shè)定函數(shù)多了一點(diǎn)點(diǎn)動(dòng)作: double SetPosition( int nAxis, double fMM, BOOL bCmd = true ) { double pos = GetPosition( nAxis, bCmd );//先取得原來(lái)的位置 ( bCmd == true )? D3000_set_command_pos( nAxis, M2P(nAxis, fMM )): D3000_set_encoder_pos( nAxis, M2P(nAxis, fMM) ); Return pos;//返回舊的位置 } 為什么這樣設(shè)計(jì)?當(dāng)你用過(guò)CPen *pOldPen= pDC->SelectObject( &newPen );時(shí),或者除了復(fù)位之外,你真正需要調(diào)用這個(gè)SetPosition函數(shù)時(shí),你會(huì)發(fā)現(xiàn)這個(gè)設(shè)計(jì),真是人情味實(shí)足。
五、 復(fù)位,相對(duì)與絕對(duì), 在如今PC機(jī)開發(fā)控制卡軟件時(shí)代,設(shè)備上電不復(fù)位的幾乎沒(méi)有,在此談到復(fù)位這個(gè)問(wèn)題確實(shí)有必要,實(shí)現(xiàn)上,復(fù)位動(dòng)作因不同設(shè)備的工藝要求而定,故一般而言,控制卡提供的那個(gè)復(fù)位函數(shù)太過(guò)簡(jiǎn)單,有點(diǎn)力不從心,所以,本人自己寫了個(gè)復(fù)位函數(shù),但是代碼寫起來(lái)將會(huì)占用很大的面版,故有此需要者,可以來(lái)電或E_mail索取。 其基本思路是采用兩次找原點(diǎn),第一次高速找,停止后退出,再次以較低的速度找原點(diǎn)。并且在執(zhí)行第二次復(fù)位時(shí),會(huì)在離原點(diǎn)5毫米處減速(第一次執(zhí)行做不到)。
提供相對(duì)和絕對(duì)位置的概念是很有必要的,眾所周知,現(xiàn)在控制卡能作到最小單位為1個(gè)脈沖,當(dāng)然,作為數(shù)字脈沖,到此已不能再小了,故為了提高精度,通常情況下要提高計(jì)算當(dāng)量,即增加每轉(zhuǎn)脈沖數(shù),或減少每轉(zhuǎn)毫米數(shù)。 不論怎么,我們將問(wèn)題放大并明朗化,可以看看以下片段:
for( int I(0); I<10000; I++)// 走10000次 move( 0.5 );//走相對(duì)0.5個(gè)脈沖的距離
結(jié)果是:1個(gè)脈沖也發(fā)不出,造成很大的累積誤差。 若換成絕對(duì)方式: for( int I(0); I<10000; I++) goto( I*0.5 );
最后的誤差,最大也就是1個(gè)脈沖以內(nèi)。雖然還是有誤差,但總算達(dá)到可容忍的程序,再加上適當(dāng)?shù)膹?fù)位操作,讓客戶至少不必再擔(dān)心這個(gè)巨大的累積誤差了。
實(shí)質(zhì)上,在整個(gè)軟件設(shè)計(jì)時(shí)最好采用絕對(duì)坐標(biāo)系,即使要處理加工原點(diǎn)或工面起點(diǎn)等這些參數(shù),也要把它換算成絕對(duì)位置,唯手動(dòng)移動(dòng)設(shè)備可以例外。另外,在CNC系統(tǒng)中,除了有循環(huán)用到相對(duì)坐標(biāo)系,其余都是用絕對(duì)坐標(biāo)系為上策,實(shí)際上,在實(shí)現(xiàn)編程算法上,為統(tǒng)一起見(jiàn),最好將相對(duì)的坐標(biāo)關(guān)系全部轉(zhuǎn)成絕對(duì)的坐標(biāo)關(guān)系,這樣也便于外部進(jìn)行暫停或繼續(xù)的處理。
相信,到此為止,若你的設(shè)備在加工時(shí)有一定的誤差漂移,你會(huì)意識(shí)到自己應(yīng)該是不是要檢查一下采用了什么坐標(biāo)系了吧。
六、 輸出輸入及軟限位 對(duì)于通用的I/O操作,沒(méi)有什么特別要說(shuō)明的,只有兩點(diǎn)需要注意的,先給出兩個(gè)小函數(shù),以作參考:
int ReadBit( int nIO ); //讀指定通用輸入口的電平狀態(tài),返回1 或 0 int WriteBit( int nIO, int nStatus ); // 輸出電平到指定輸出端口
兩點(diǎn)注意: No.1 對(duì)于ReadBit若需要加入抗干擾處理,則寫一個(gè)函數(shù):
Int RealInput( int nIO, int nStatus, int di=50 ) { if( ReadBit( nIO ) != nStatus ) return 0; while( di -- );//耗上幾個(gè)CPU的周期時(shí)間,再讀一次 return ReadBit( nIO ) == nStatus; }
No.2 增加一個(gè)變量及函數(shù)擴(kuò)展一下輸出功能: Long m_nOutStatus= 0x00000000; 再次改造一下WirteBit void WriteBit( int nIO, int nStatus ) { if( nStatus ){ m_nOutStatus |= (1< } else{ m_nOutStatus &= (~(1< } d1000_out_bit( nIO, nStatus ); } 添加的訪問(wèn)輸出狀態(tài)函數(shù): int ReadOutbit( int nIO ) { static int a; a = 1<<(nIO-1); a &= m_nOutStatus; return a!=0; }
軟限位的思想原本是用于為客戶節(jié)省正負(fù)限位的光電開關(guān)成本而產(chǎn)生的,致使使用軟件限位正常的話,設(shè)備每個(gè)驅(qū)動(dòng)軸只需要一個(gè)原點(diǎn)開關(guān)即可。當(dāng)然,軟限位能正確運(yùn)作是非常重要的,否則很容易撞壞設(shè)備。而其正確運(yùn)行,就必須依賴正確的復(fù)位動(dòng)作,以找到可靠的機(jī)械原點(diǎn)位置。 軟件限位的基本算法非常簡(jiǎn)單,特別是在一個(gè)絕對(duì)坐標(biāo)系當(dāng)中。其原理如下:
if( pos < minPos ) pos = minPos; if( pos > maxPos ) pos = maxPos;
實(shí)在沒(méi)有必要再詳說(shuō)下去了。
編程技巧介紹至此算是一個(gè)了斷,若在未來(lái)的日子里,有更好的想法,我會(huì)拿出來(lái)給大家參考,請(qǐng)大家一起來(lái)支持這件事情,拿出自己的寶貴經(jīng)驗(yàn),算是給數(shù)控行業(yè)添加強(qiáng)有力的潤(rùn)滑劑吧。
謝謝。
|
|
|