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