基于GRETA正则表达式的SLM 3D打印机控制系统译码模块设计∗∗
2019-03-06王士军张临松周永鑫
陈 伟 王士军 张临松 周永鑫
(山东理工大学机械工程学院,山东淄博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打印机控制系统的开发打下了坚实的基础。
1 GRETA正则表达式及其在VC++6.0环境下的使用
正则表达式是一种用于模式匹配和替换的强有力工具,即通过使用一系列的特殊字符建立匹配模式,然后将匹配模式与待比较字符串等目标对象进行对比,根据比较对象中是否包含匹配模式,再执行相应的程序[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头文件即可。
2 译码模块的译码流程
本译码模块采用层次化的编程方法[3],在译码过程的每个阶段只设置一个处理函数,各函数彼此之间相互独立,调用函数完成相应阶段的代码处理工作。通过层次化的编程方法设计的译码模块,易于扩展和移植。面对不同3D打印切片软件产生的控制代码时,只需在各阶段函数中对用于匹配替换的正则表达式做相应更改即可,并且用户还可以很容易扩展一些个性化功能。
译码模块的译码流程如下:
(1)从∗∗∗.txt文件中读取一行程序段。
(2)对读取的每一行程序段,调用预处理函数BOOL PreProcess(string&strLine)进行预处理,去除非几何信息和工艺信息(包括空格、注释等),获得有效程序段。
(3)对预处理无异常的程序段,调用词法检查函数BOOL LexCheck(string&strLine)进行词法检查,主要任务是识别出程序段中出现的不合法或者未定义功能的字符。若检查出错误,提示错误的存在并将详细错误信息记录到错误报告中。
(4)对词法检查无异常的程序段,调用语法检查函数BOOL GramCheck(string&strLine)进行语法检查及加工信息的提取,并将编程值转化为运动控制器可以识别的电动机脉冲数存储到定制的链表中。如果语法检查出现错误,提示错误的存在并将详细错误信息记录到错误报告中。译码模块的总工作流程,如图1所示。
3 译码模块的功能定义
本文设计的译码模块是参考专业级切片软件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]。
3.1 程序预处理
程序开始,首先将 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)将程序段中所有与模板字符串相匹配的字段替换为空串,已达到除去空格、注释的目的,完成预处理工作。
3.2 词法检查
若程序预处理完成的程序段为空字符串,则进入下一次轮回,读取下一行程序段。若不为空字符串,调用词法检查函数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所示。
3.3 语法检查与加工信息提取
在词法检查无异常的情况下,根据数控语言的语法规则,调用语法检查函数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所示。
4 译码模块程序仿真测试
本文以Visual C++6.0作为程序开发平台进行SLM 3D打印机控制系统译码模块开发,其控制系统的用户界面,如图4、图5所示。编写以下具有典型错误的控制代码程序进行仿真测试:
测试后的结果,如图4所示。
将以上错误代码修正后,重新加载到控制系统中,仿真程序得到了预期图形,说明本文开发的译码模块得到了正确的结果。其仿真测试界面如图5所示。
5 结语
本文利用GRETA正则表达式开发的SLM 3D打印控制系统译码模块,能够实现快速、准确地提取加工信息。GRETA正则表达式自由、灵活,易于理解。层次化的编程方法,使开发的译码模块具有良好的可扩展性与可移植性,为后期基于运动控制卡的SLM 3D打印机控制系统开发奠定了坚实的基础。