由数控系统状态信息生成XML 文件的方法研究*
2013-12-23刘荫忠杨东升尹震宇
张 帆,刘荫忠,杨东升,尹震宇
(1.中国科学院 研究生院,北京 100049;2.中国科学院 沈阳计算技术研究所,沈阳 110168)
0 引言
随着信息技术和计算机网络技术的迅猛发展和应用,制造业的生产方式发生了深刻的变革,极大地拓展了企业信息化的深度和广度,促进了制造业快速地向网络化方向发展,产生了以互联网络为背景的数控系统,就是网络化数控系统[1-3]。
Extensible Markup Language(XML)数据是以纯文本格式存储的,这使得XML 提供了一种与软件和硬件无关的共享数据方法。通过XML 可以在不兼容的系统之间轻松地交换数据,即使升级操作系统、升级服务器、升级应用程序、更新浏览器也不会受到兼容性的影响,所以可以用XML 来格式化数控系统的状态、控制、工艺等信息[4-6]。
状态监视系统就是网络化数控系统中的网络节点,为了使状态监视系统得到的数据格式化,我们采用XML 技术来存储数控系统的状态信息。数控系统自带的RCS 库的生成XML 文件的xmlMsgSaveAs(NMLmsg* nml_msg,const char * filename)函数[7-8]是有缺陷的:①生成的每个XML 文件仅仅是一种NMLmsg 的信息且包含该类型消息的全部信息,这样当需要有关n 种状态消息的信息时就会生成n 个不同的XML 文件,会不利于文件的传输;②当再次利用xmlMsgSaveAs(NMLmsg* nml_msg,const char *filename)函数生成XML 文件时,上次为了生成XML文件而生成的xmlNode 已经释放,不会被再次利用,需要重新生成新的xmlNode。
本文提出根据相应的conf 配置文件并利用libxml2 程序库生成XML 文件的方法。如果该方法生成的XML 文件含有的NMLmsg 消息的个数为n,那么该XML 文件的长度不会大于由数控系统自带的函数xmlMsgSaveAs(NMLmsg* nml_msg,const char * filename)生成的相应n 个XMLmsg 消息的XML 文件长度之和,并且比利用数控系统自带的能生成XML 文件的RCS 库函数的时间性能更佳。
1 数控系统网络架构
结合数控系统、RTAI(the Real Time Application Interface for Linux)及实时以太网RTnet 技术设计数控系统与状态监视器的实时通信,本篇论文重点解决利用XML 即可扩展的标记语言格式化数据信息,便于远程监控、数据存储与分析等。
如图1 所示,利用XML 即可扩展的标记语言来格式化数据信息。数控系统的一些信息,如轴数、轴速、增益等,都需要发给状态监视器。状态监视器可以将这些数控信息存放在一个单独的数据库中,也可以对其信息进行分析来了解数控系统的运转情况。为了使状态监视器得到的数据格式化,我们采用XML 技术存储数控信息[9-10],然后发给状态监视器。
图1 数控系统网络架构图
2 数控系统状态信息生成XML 文件
2.1 关键技术
Libxml2 是一个C 语言版的XML 解析器,本来是为Gnome 项目开发的工具,是一个基于MITLicense 的免费开源软件。它除了支持C 语言版以外,还支持C++、PHP、Pascal、Ruby、Tcl 等语言的绑定,能在Windows、Linux、Solaris、MacOsX 等平台上运行[5]。Libxml2 支持DOM 和SAX 两种解析方式。Libxm2 特有的一些数据类型,它们用来隐藏那些除非有特别需要否则就不用去理会的复杂细节,这些数据类型总是会一次一次的遇到。
xmlChar:对char 的基本代替,是一个UTF-8 编码字符串中的一个字节。如果用户数据使用了其他编码,在使用libxml2 函数前就必须转换为UTF-8。
xmlDoc 和xmlDocPtr:是一个包含了从解析文档后创建出的树的结构,xmlDocPtr 是指向该结构的指针。
xmlNode 和xmlNodePtr:包含单个节点的结构,xml-NodePtr 是指向该结构的指针,它用来遍历文档树。
RCS(Real-time Control System)是美国NIST(National Institute of Standards and Technology)的ISD(Intelligent Systems Division)一套完整的实时控制系统的设计思想、方法及相关支撑工具[6]。它从模块化、层次化的角度来构建一个复杂的控制系统,并提供了具有跨平台、跨网络通信能力的信息传送通道机制-NML,同时NML 能很好的支持可扩展标记语言XML。
通信规则由配置文件“. nml”定义,其中保存应用程序的进程参数和缓冲区参数。RCS 通信原理如图2 所示。计算机1 上的进程P1、P2、P3 可以直接访问本地共享内存缓冲区1、2,计算机2、3 上的进程P4,P5,P6 远程访问缓冲区。计算机1 上设置NML服务器进程1、2,代表远程进程对缓冲区中的消息进行编码与解码。所有进程均需根据配置文件“.nml”的规定执行通信动作。
图2 RCS 网络通信结构图
2.2 数控系统状态信息生成XML 文件的设计方法
针对数控系统的状态信息,设计一种能利用相应的conf 配置文件生成XML 文件的方法。根据数控系统状态信息设计conf 配置文件;检测conf 配置文件的更新时间;如果时间没有改变,则通过NML 通道读内存获取数据,利用libxml2 程序库函数更新XML 文件数据;如果时间已经改变,则根据conf 配置文件生成数据结构,通过NML 通道读内存获取数据,利用libxml2 程序库生成XML 文件,同时保存libxml2 程序库函数生成的XML 文件的结构。如图3 所示。
2.2.1 设计方法
(1)数据结构
①首先定义多叉树节点的类:该类包括的成员变量有节点名字name(name 的类型是string),指向父节点的指针,指向孩子节点的指针构成的vector。
②定义多叉树的类:多叉树类的成员变量包括指向根节点的指针root,以及类iterator。可以利用指向树节点的指针来初始化iterator。例如,假设树节点为node_type 多叉树为tree_type 则
node_type * one=new node_type(“one”);
tree_type::iterator iter(one);
多叉树类有一个成员函数为
iterator insert(iterator &position,const T &x);
在这里T 为string,该函数将以x 为name 的树节点作为position 对应节点的孩子,并返回以x 为name的树节点对应的iterator。
③定义一个map,map 的元素为
pair <int,tree_type::iterator >
int 类型的数据表示conf 配置文件中的数据层级level。
图3 方法设计流程图
(2)初始化
声明所有状态消息类型的指针;初始化各种状态消息类型名对应的字符串;定义一个大小为256 的字符数组;定义类型为<int,tree_type::iterator >的map。
(3)函数体
①获取配置文件“. conf”的最后一次改写的时间,并与最新读取的conf 配置文件的改写时间比较。如果改变了则记下最新时间转入步骤(2),否则转入步骤⑩。
②获取配置文件“.conf”的第一行(该行是没有实际意义的一行,只是为生成一个根节点,并设定该行的数据名为”time”)并存入char line[256],获取level,获取数据名,生成以该数据名为多叉树节点名字的节点,并生成相应的iterator。如果该节点是叶子节点转入步骤④。否则转入步骤③。
③将相应的元素<int,tree_type::iterator >插入map。
④生成以该节点为根的树。
⑤读配置文件的下一行并存入char line[256]。如果该行为空,说明到了文件尾,则转入步骤⑧,否则转入步骤⑥。
⑥获取该行的level,获取该行的数据名,生成以该数据名为多叉树节点名字的节点,并生成相应的iterator,放入到父节点的vector 中(父节点是map 中键level-1 对应的节点)。如果该节点是叶子节点转入步骤⑤。否则转入步骤⑦。
⑦通过函数map.count(level)判断map 中键level 是否存在。如果存在则直接将该iterator 赋值给mp[level],否则利用函数map. insert()插入到map中。转入步骤⑤。
⑧通过通道的read()函数来判断通道中是否有消息存在。如果没有消息存在则循环执行read()函数,直到通道中有消息存在。
⑨通过nml 通道获取获取叶子结点的值,利用生成的多叉树结构以及libxml2 程序库的函数xml-NewDoc 创建文档并在内存中保存文档,通过xml-SaveFile 将xml 文档存入文件,结束。
⑩通过nml 通道获取获取叶子结点的值,利用libxml2 的函数修改保存的xml 文档,通过xmlSave-File 将xml 文档存入文件,结束。
2.2.2 例子
配置文件的例子:数据层级,数据名:数据类型
读该conf 配置文件会生成一棵多叉树如图4 所示。
图4 根据配置文件生成的多叉树
生成XML 文件,见图5。
图5 生成的XML 文件
3 实验结果及分析
本文的实验是在具有800MHz CPU、512MB 内存的装有数控系统及Red Hat Linux 9.0 操作系统的Pentinum3 上实施操作的。
在用户空间使用数控系统提供的etime()函数记录时间戳,返回微秒级的时间计数。因为执行一遍程序的时间太短,所以采取while 循环执行一次main()函数就是执行原来的程序1000 遍。针对配置文件不同的n(0 <n <2000)执行三次main()函数,得到表1、表2、图6 的时间。
实验方案一:在原有的数控系统上进行实验,仅仅利用数控系统自带的RCS 库的函数生成XML 文件。
实验方案二:利用本文提出的方法生成XML 文件。
下面是实验结果:
表1 conf 配置文件没有改变时两个方案的时间表
表2 conf 配置文件改变时两个方案的时间表
在本实验中选取conf 配置文件时,配置文件包含了数控系统所有的状态消息类型。从表一可以看出当配置文件包含数控系统所有的状态消息类型时,n 越小方案二的时间性能越佳,但是无论n 如何取值,方案二在时间性能上总是优于方案一。从表二可以看出当conf 配置文件改变时,方案二的时间性能还是优于方案一,只是比conf 配置文件没有改变时的时间性能略有降低。
函数readfile_maketree()包括设计方法步骤的(2)-(7),函数readtree_makexml()包括设计方法的步骤(8)-(9)。由图6 可以看出利用conf 配置文件生成XML 文件时,读配置文件花费的时间占用整个方法时间的比例很小,这样就会突显出方案二的优势:①利用conf 配置文件仅仅会生成包含配置文件中对应的n 个节点的XML 文件,而方案一会生成不小于n 个节点的若干个XML 文件,这样方案二在生成XML 文档节点的时间上优于方案一。②在conf配置文件没有改变的情况下,方案二会利用上次保存在内存中的XML 文档,而方案二必须重新生成所有的XML 文档的节点,从这方面看方案二在生成XML 文档节点的时间上优于方案一。
图6 函数执行时间坐标图
4 结束语
采用根据conf 配置文件读取数控系统的状态信息并利用libxml2 程序库生成XML 文件的方法会比利用数控系统自带的RCS 库的函数生成XML 文件更有针对性,同时比利用数控系统自带的能生成XML 文件的RCS 库函数的时间性能更佳。采用根据conf 配置文件读取数控系统的状态信息并利用libxml2 程序库生成XML 文件的方法,可以更好的避免数控系统升级导致整个网络化监控平台信息失效,保证车间级对网络级的信息透明。
[1]毕留刚,王隆太. 网络化数控系统的研究和开发[J]. 智能控制技术,2006,35(1):57-61.
[2]宋桃桃. 基于实时网络数控系统通信平台的设计与实现[D]. 沈阳:中国科学院沈阳计算技术研究所,2008.
[3]张柏军,杜鹏. 网络化数控系统的研究与开发[J]. 数字技术与应用,2010(3):41-42.
[4]T. Bray,J. Paoli,C. M. Sperberg-McQueen,E. Maler,F. Yergeau,“Extensible Markup Language (XML)1.0(Fifth Edition),” W3CRecommendation 26 November 2008,http://www.w3.org/TR/xml/.
[5]陈红梅,陈静. XML 文档解析技术[J]. 信息技术,2009(10):174-177.
[6]Zefu Dai,Nick Ni,Jianwen Zhu.A 1 Cycle-Per-Byte XML Parsing Accelerator.FPGA,2010(10):199-208.
[7]V. Gazi,M. L. Moore,K. M. Passino,et al. The RCS Handbook:Tools for Real Time Control Systems Software Development.John Wiley and Sons,NY,2001.
[8]吴孜越,仲志丹,张洛平. XML 在数控机床远程监控与故障诊断系统中的应用[J]. 机械设计与制造,2008(8):131-133.
[9]于东,李筱颿,黄艳,等. 基于XML 的STEP-NC 程序解释器的设计与实现[J]. 小型微型计算机系统,2009(10):38-41.
[10]刘文远,章伟刚,王亚东,等. XML 环的定义、分类、判定和消除[J]. 小型微型计算机系统,2008(3):91-94.