陳 偉 王士軍 張臨松 周永鑫
(山東理工大學機械工程學院,山東淄博255000)
SLM是一種金屬粉末在高能束激光的作用下快 速融化并快速冷卻凝固成型的技術[1],計算機控制系統根據二維切片信息控制激光掃描路徑,通過層層掃描和層層累積形成三維實體。與數控機床一樣[2],SLM 3D打印機(增材制造)也是靠編制數控加工程序來驅動激光掃描振鏡中的擺動伺服電動機進行加工的。那么如何正確、高效地對3D打印切片軟件(CAM軟件)產生的控制代碼進行譯碼就成為SLM 3D打印機控制系統開發過程中的關鍵性技術問題。
以往譯碼模塊設計方法[3-4],一般使用定義關鍵字符集的方式進行指令的識別及加工參數的提取,程序編制過程繁瑣,容易出錯且譯碼效率不高,通用性差。文獻[2]中,將GRETA正則表達式應用于車銑復合數控機床編譯器的研究。文獻[5]中,將GRETA正則表達式應用于機器人解釋器的研究。以上均在程序設計上不夠完善,程序結構不夠清晰,沒有充分發揮GRETA正則表達式的強大功能,只是簡單使用了GRETA正則表達式的rpattern::match函數。
針對上述情況,本文以Visual C++6.0作為程序開發平臺,在充分利用了GRETA正則庫中rpattern類的對象及其成員函數rpattern::substitute與放置替換結果的容器subst_results的基礎上,并結合MFC相關函數,將GRETA正則表達式應用于SLM 3D打印機開發了控制系統譯碼模塊,準確、高效地實現了對3D打印切片軟件生成的控制代碼的譯碼工作,為后續SLM 3D打印機控制系統的開發打下了堅實的基礎。
正則表達式是一種用于模式匹配和替換的強有力工具,即通過使用一系列的特殊字符建立匹配模式,然后將匹配模式與待比較字符串等目標對象進行對比,根據比較對象中是否包含匹配模式,再執行相應的程序[6]。在字符串處理方面,正則表達式表現出非常強大的功能。GRETA正則庫是微軟研究院推出的一個快速、靈活、完全兼容Perl 5正則語法的C++正則表達式模板類庫。關于匹配速度,GRETA的開發者Eric Niebler測試使用正則表達式“^([0-9]+)(\\-||$)(.?)$”去匹配字符串“100-this is a line of ftp response which contains a message string”,結果表明GRETA的匹配速度比Boost正則表達式快大約7倍,比ATL7正則表達式類快大約10倍。匹配速度之快,正好適應我們對高譯碼效率的要求。關于GRETA正則表達式的詳細信息和使用方法[7]本文省略。
GRETA正則庫是一個完全開源的庫,當前最新版本是GRETA-2.6.4,可到微軟官網搜索下載獲取GRETA源文件。在Visual C++6.0程序開發平臺下,GRETA的使用方法有兩種:一種是直接把GRETA源文件加入工程中,一般不推薦使用此法,原因是源文件的加入會使工程里有過多的類而使程序顯得不清晰,容易出錯;另外一種是將GRETA源文件編譯生成geeta.lib靜態庫,再鏈接到工程當中,使用時只需包含regexpr2.h頭文件即可。
本譯碼模塊采用層次化的編程方法[3],在譯碼過程的每個階段只設置一個處理函數,各函數彼此之間相互獨立,調用函數完成相應階段的代碼處理工作。通過層次化的編程方法設計的譯碼模塊,易于擴展和移植。面對不同3D打印切片軟件產生的控制代碼時,只需在各階段函數中對用于匹配替換的正則表達式做相應更改即可,并且用戶還可以很容易擴展一些個性化功能。
譯碼模塊的譯碼流程如下:
(1)從???.txt文件中讀取一行程序段。
(2)對讀取的每一行程序段,調用預處理函數BOOL PreProcess(string&strLine)進行預處理,去除非幾何信息和工藝信息(包括空格、注釋等),獲得有效程序段。
(3)對預處理無異常的程序段,調用詞法檢查函數BOOL LexCheck(string&strLine)進行詞法檢查,主要任務是識別出程序段中出現的不合法或者未定義功能的字符。若檢查出錯誤,提示錯誤的存在并將詳細錯誤信息記錄到錯誤報告中。
(4)對詞法檢查無異常的程序段,調用語法檢查函數BOOL GramCheck(string&strLine)進行語法檢查及加工信息的提取,并將編程值轉化為運動控制器可以識別的電動機脈沖數存儲到定制的鏈表中。如果語法檢查出現錯誤,提示錯誤的存在并將詳細錯誤信息記錄到錯誤報告中。譯碼模塊的總工作流程,如圖1所示。
本文設計的譯碼模塊是參考專業級切片軟件Simplify 3D后處理生成的控制代碼進行譯碼模塊設計,定義程序段書寫格式為:
[Gnn](0或多個)[X[-]nnn.nnn][Y[-]nnn.nnn][Z[-]nnn.nnn][I[-]nnn.nnn][J[-]nnn.nnn][K[-]nnn.nnn][R[-]nnn.nnn][E[-]nnn.nnn][Fnnn.nnn][Mnn]。其中,中括號的意思是其中的內容可以不出現。本模塊定義的功能字(GXYZIJKREFM),其次序不可以隨便顛倒,否則將提示錯誤。3D打印指令代碼遵循NIST RS274NGC標準,詳細的指令含義可參考國外開源網站RepRap.org。
本文設計的譯碼模塊,根據上述定義的程序段書寫格式,在譯碼過程每個階段利用GRETA正則表達式,通過匹配替換、提取替換結果的操作方法,自頂向下逐行掃描。首先進行預處理,然后進行詞法檢查、語法檢查以及加工信息的提取[8]。
程序開始,首先將 NC文件打開,調用 MFC中CStdioFile類的成員函數BOOL ReadString(CString&strLine)讀取一行程序段,然后調用預處理函數 BOOL PreProcess(string&strLine),去除控制代碼中的非幾何信息和工藝信息(包括空格、注釋等),以獲得有效程序段。

在預處理函數中,首先定義兩個描述匹配空格和注釋的模板字符串(即正則表達式)CString Space_str(“\\\\s”)和 CString Note_str(“;.?”),模板字符串中“ \\s”、點號(.)和星號(?)都是元字符。 “ \\s”的意思是匹配任意的空白符,包括空格、回車、換行等。點號(.)的意思是匹配除換行符以外的任意字符。星號(?)的意思是指定星號(?)前面的內容可以連續出現N次。
然后用它們來初始化兩個rpattern類的對象Space_pat和Note_pat:
static constr pattern Space_pat((LPCTSTR)Space_str,””,NOBACKREFS|GLOBAL);
static const rpattern Note_pat((LPCTSTR)Note_str,””,NOBACKREFS);
其中,參數””是空字符串,默認省略,是執行替換操作時的替換字符串。參數GLOBAL表示執行替換操作時替換所有與模板字符串相匹配的字段。參數NOBACKREFS表示不記錄backref,執行替換操作時使用此參數,可大幅提高替換速度。
最后把讀入的一行程序段作為傳遞參數,調用rpattern類的替換函數Space_pat.substitute(strLine,results)和 Note_pat.substitute(strLine,results)將程序段中所有與模板字符串相匹配的字段替換為空串,已達到除去空格、注釋的目的,完成預處理工作。
若程序預處理完成的程序段為空字符串,則進入下一次輪回,讀取下一行程序段。若不為空字符串,調用詞法檢查函數BOOL LexCheck(string&strLine)進行詞法檢查。詞法檢查主要是找出程序段中出現的不合法或者未定義功能的字符,識別出控制代碼中的各個單詞。
根據本節開頭講到的程序段書寫格式,可定義用于詞法檢查的模板字符串static const CString Lex_str("(G\\d{1,2})?(X-? \\d+( \\.\\d+)?)?(Y-?\\d+( \\.\\d+)?)?(Z-? \\d+( \\. \\d+)?)?...…(E-? \\d+(\\.\\d+)?)?(F \\d{3,})?(M84)?"),該模板字符串中,\\d表示匹配任意一個阿拉伯數字。大括號表示指定它前面的字符或字符串出現的次數。?為元字符,表示指定它前面的字符或字符串可以出現0次或1次。+為元字符,表示指定它前面的字符或字符串可以出現一次或更多次。使用該模板字符串,可以檢索控制代碼中出現的指令字是否符合本控制系統的規定。
在詞法檢查函數中,使用模板字符串Lex_Reg初始化rapattern類對象Lex_pat:
static const rpattern Lex_pat((LPCTSTR)Lex_str,GLOBAL);
通過調用函數Lex_pat.substitute(strLine,results)完成匹配替換操作,將所有與模板字符串相匹配的字段替換為空串,最后余留的就是不合法字符或者未定義功能的字符。參數resullts是subst_results類的對象(即放置替換結果的容器),替換后的所有結果都放置在這個容器中,通過調用其成員函數subst_results::backref_str()可提取詞法檢查無異常的程序段。詞法檢查流程圖,如圖2所示。
在詞法檢查無異常的情況下,根據數控語言的語法規則,調用語法檢查函數BOOL GramCheck(string&strLine)對控制代碼進行語法檢查。語法檢查[9]的主要任務是檢查每行程序段是否存在同組模態G代碼錯誤、是否缺少相關指令參數。
G指令和M指令是一段加工程序中所占比重較大的指令代碼,搭起了整個加工程序的框架,對于其中功能相同或相近的指令,它們不能出現在同一程序段中。比如,在每一行程序段中,同組模態代碼出現的次數不可多于一次。依據這一特征把具有同屬性的代碼放在一組中,以指令參數區分本組不同代碼,在全局空間進行存放。當在一行程序段中提取到多個G指令時,循環匹配記錄同組模態代碼出現的次數。
GRETA正則表達式在執行完匹配替換操作后,與整個模板字符串相匹配的字段被存儲在backref 0中,與第一個圓括號內的模板字符串相匹配的字段被存儲在backref 1中,與第二個圓括號內的模板字符串相匹配的字段被存儲在backref 2中,以此類推。基于此特點,我們利用圓括號對指令字和其后的指令參數進行細化分割,設計模板字符串,完成加工信息的提取工作。例如,匹配G指令的模板字符串為 CString G_str(“(G)(\\d{1,2})”),使用括號將 G 指令分成兩組,后續可通過指定組號,利用替換容器類的成員函數subst_results::backref(size_t cbackref)對指令參數進行提取。出于提高譯碼效率的目的,在進行語法檢查的同時,對控制代碼加工指令和指令參數進行提取,保存到定制的鏈表中。語法檢查與加工信息提取流程圖,如圖3所示。
本文以Visual C++6.0作為程序開發平臺進行SLM 3D打印機控制系統譯碼模塊開發,其控制系統的用戶界面,如圖4、圖5所示。編寫以下具有典型錯誤的控制代碼程序進行仿真測試:




測試后的結果,如圖4所示。

將以上錯誤代碼修正后,重新加載到控制系統中,仿真程序得到了預期圖形,說明本文開發的譯碼模塊得到了正確的結果。其仿真測試界面如圖5所示。
本文利用GRETA正則表達式開發的SLM 3D打印控制系統譯碼模塊,能夠實現快速、準確地提取加工信息。GRETA正則表達式自由、靈活,易于理解。層次化的編程方法,使開發的譯碼模塊具有良好的可擴展性與可移植性,為后期基于運動控制卡的SLM 3D打印機控制系統開發奠定了堅實的基礎。