殷冰磊,董伯麟
(合肥工业大学 机械工程学院,安徽 合肥 230009)
工业机器人控制系统的设计包括硬件设计和软件系统设计。目前对工业机器人软件系统的设计主要研究有:(1)依托第三方内核实现可拓展的工业机器人控制软件系统。高美原[1]等结合ROS和Linux CNC构建了一个可配置的软件架构;毕鲁雁[2]等采用强实时能力的RTX和具备丰富资源的工业计算机为平台搭建了一个开放的可拓展的控制系统平台。(2)以总线及以太网技术为基础建立易扩展的机器人控制软件系统。王力宇[3]等采用EtherCAT总线技术简化机器人软件系统结构,提高了系统的稳定性。(3)通过采用组件与模块化技术建立工业机器人软件系统的开放性结构;曹波[4]等基于模块化的思想将整个控制系统按功能进行了子系统化;周伟花[5]研究了面向制造者和面向用户的可重构模块化设计在机器人系统上的应用。(4)采用分层理论对机器人软件系统进行层次划分。陆伟[6]构建的三层软件架构系统有效地避免了机器人在数据处理过程中的信息冗余问题;Fang Jian[7]等将机器人软件系统分为交互层、决策层和物理层以提高软件的稳定性和执行效率。
以上的软件研究设计均是面向系统的设计。当系统功能增加、系统行为变得复杂时,上层应用对象数目急剧增加,对象之间和与底层组件之间的交互就会变得交错复杂,导致系统的运行及维护繁琐和低效。
针对上述问题,基于面向对象设计范式,提出主动对象计算模型来构建工业机器人系统的方法。主动对象具有低耦合高聚合的特性,能够降低应用对象交互的复杂度,有效提高系统软件的灵活性、可移植性和开放性。
主动对象(Active Object,AO)来自建模统一语言(Unified Modeling Language,UML),在UML规范里,一个主动对象是“一个对象,它有自己的控制的线程”,以一种运行到完成的方式来处理事件,和其他事件通过异步交换事件来通信[8]。简单来说,主动对象=状态机+控制的线程+事件队列。
继承在软件构建过程中是基础性的。在面向对象设计里,类继承描述了对象类之间的关系,并对软件的组织及代码的重用极为重要。主动对象计算模型则采用了一种行为重用的方法,被称为行为继承,如同Ultimate Hook模式[9]里所采用的差异化编程方式,应用程序仅需实现与系统标准行为不同的部分。行为继承使得主动对象即使在建模系统复杂度增加的情况下,行为重用的机会也在增加,能够有效地减少系统的复杂性。
在这个模型中,状态机是这个主动对象的核心。传统的状态机是有限状态机(Fine State Machine,FSM),当所需解决的问题规模较小时,FSM是一个很好的选择。然而,当所需搭建的系统规模较大时,即使规模适中,采用FSM也很难对所搭建的系统进行管理。这是由于FSM所搭建的状态图具有爆炸性、重复性的特点,使得FSM的复杂性剧增,超过了所描述的基于反应性系统的复杂度。模型中的主动对象基于面向对象的思想,结合了抽象和层次的处理方式,采用行为继承的方法,建立层次式状态机,简化了状态机设计,极大地减少了重复性,从而摆脱了状态机状态爆炸的现象。图1展示了简单形式下的层次状态机。
图1 层次式状态机
如图2所示,主动对象的控制线程中,都有一个对事件循环处理的泵,只要事件队列中存在事件,它就不断地通过Queue.get()操作提取事件进行处理。而当事件队列空闲时,它便有效地阻塞这个循环,直到新的事件到来。
主动对象的执行模型是采用运行到完成(Run-To-Complete,RTC)方式。RTC意味着状态机对每个到来的事件的处理都是不可分割的,当前事件Dispatch()操作处理完成之前,新到来的事件只能在队列中等待,而不能中断当前执行过程。RTC模型并不意味着当前执行的状态机不能被抢断,在多任务系统中,如Windows环境下不同线程中执行的任务也是可以执行的,它可能抢占了其他线程中正在执行RTC步骤的任务。然而采用RTC模型的主动对象要实现这样的多任务抢占性、并发性,就必须要求主动对象之间的耦合性降到最低,即它们之间不共享资源,这样才不会出现并发性、抢占性危险。
图2 主动对象系统
图3展示了出版-订阅式模式下主动对象之间的交互通信。主动对象相互之间不需要共享资源,通过中间层平台(Quantum Platform,QP)来实现彼此的通信,并通过中间层的平台抽象层(Platform Abstract Layer,PAL)提供接口访问底层的组件/库和实时操作系统提供的服务,实现了低耦合高聚合的特性。QF是这个QP架构的核心,它负责上层主动对象的核心调度、事件池的管理、时间事件管理、通信、注册等。主动对象通过出版-订阅式异步通信,采用事件零复制机制实现通信。每个主动对象在注册初始化时订阅它们所关心的事件,每个主动对象产生的事件通过QF中间层进行发布。
图3 出版-订阅式中间层平台
图4展示了主动对象的类实现图。主动对象继承基类CActiveObject,CActiveOject类则包含了前面所述的主动对象的三个要素:状态机(CHsm类)、控制的线程Thread和事件队列Queue。
图4 主动对象类实现图
采用主动对象计算模型需要设计一个新的工业机器人软件系统架构,传统的工业机器人软件系统架构需要改变。根据主动对象计算模型,构建如图5所示的体系架构。
图5 系统体系架构图
运行系统总体架构可分为以下几部分:
(1)实时操作系统层:实时操作系统负责提供整个控制软件运行的基本环境、系统资源。不同的实时操作系统有着不同的实时性特性。
(2)中间层:中间层是这个分层体系架构的核心层。它包含了平台抽象、组件接口服务、实时框架服务三个部分。平台抽象将实时操作系统相关的一些资源和接口封装起来。组件接口服务功能是对组件层提供的接口进一步抽象封装,以提供对系统可重构性和开放性的支持。实时框架采用QF来负责任务的调度、事件管理、时间管理、通信管理以及应用层的管理。中间层的三个部分不是独立工作的,QF提供了上层运行时的基本的环境,而平台抽象则隐藏了运行时硬件和软件的差异,组件接口服务则实现了系统动态配置的功能。
(3)应用层:应用层是由各个主动对象构成的,不同的主动对象负责处理不同的事务。由于应用层的平台无关性,当底层发生变动时,若客户需求没有改变,应用层同样也不需改动,极大地提高了系统软件的可移植性,减少了系统软件的设计开发成本。
HN-Robot是以Windows CE6.0为软件平台的开放式可重构嵌入式机器人控制系统,可以根据具体需求实现对Scara、Puma等多种机器人的控制。表1所示为HN-Robot 机器人控制系统的规格参数。在这一部分将重点展示中间层和应用层的实现。
表1 HN-Robot系统规格参数
3.1.1框架服务
为了实现对上层应用的管理,部分框架的接口定义如下。
void QF_init()
//初始化框架
void QF_poolInit()
//初始化上层事件池
void QF_psInit()
//初始化事件订阅表
void QActive_ctor()
//初始化上层活动对象
void QActive_start()
//开启活动对象线程
int16_t QF_run()
//运行框架服务
void QF_publish()
//事件出版
void QAcitve_subscribe()
//事件订阅
框架提供上层应用运行时的环境。例如,上层主动对象之间通过框架的出版-订阅式的服务接口QF_publish()和QActive_subscribe()就能实现通信。这样,框架便隐藏了操作系统的异构性,使得上层应用与实时操作系统解耦,大大提高了上层应用的可移植性。
3.1.2组件接口服务
为了实现对组件/库的管理,部分组件接口服务定义如下。
bool CLI_OpenHMI()
//打开HMI模块
void CLI_CloseHMI()
//关闭HMI模块
void CLI_MOVEP()
//机器人指定点位运动
void CLI_MOVEL()
//机器人指定直线运动
void CLI_MOVEC()
//机器人指定圆弧运动
int CLI_HOME()
//机器人回原点
int CLI_Stop()
//机器人停止运动
void CLI_ReadDO()
//读取输出口状态
组件接口服务对那些提供相似服务的接口进行抽象,这种抽象能够在不改变系统其他部分的情况下实现组件的替换或更新。如在实现四自由度和六自由度的点位运动中,将具有这些相似功能的点位运动接口定义为CLI_MOVEP(P1,P2,…),就能实现控制这类型的运动。通过这样一种抽象封装,上层就无需了解底层的实现细节,系统也能够在不改动的情况下实现正常运行。
3.1.3平台抽象
平台抽象通过一系列的宏定义和接口定义,将不同操作系统的资源和API接口进行了统一。这样,平台抽象层就能隐藏框架运行时软硬件环境的不同。部分抽象层宏定义和接口定义如下。
//宏定义,通过改写宏进行相应系统移植
#define QF_INT_LOCK …
#define QF_INT_UNLOCK …
#define QACITVE_EQUEUE_WAT …
#define QACITVE_EQUEUE_SIGNAL …
#define QACITVE_EQUEUE_ONEMPTY …
主动对象采用UML进行设计,并使用QM建模工具(QM Modeling Tool,QMMT)进行开发。以下给出了HN-Robot机器人控制系统中几个主动对象UML状态图设计,它们隐藏了大部分的细节,从整体上给出状态分析及转换的实现方式。
3.2.1译码主动对象
如图6所示,译码主动对象负责管理对程序的编译处理。初始化后,主动对象处于Get_Code状态,等待用户选择相应程序。当收到CODE事件后,转换到Interpret状态,之后根据DECODE事件对程序进行编译。如果操作失败,则进入Error状态报错。
图6 译码主动对象UML图
3.2.2运行主动对象
如图7所示,运行主动对象负责管理程序的运行。初始化后,主动对象处于wait状态,等待用户设置运行程序。用户可以进行自动运行或者单步运行操作,主动对象则根据相应的事件进行处理,并进入working状态。主动对象接收到PAUSE事件后进入Pause状态,暂停等待用户进一步操作。
图7 运行主动对象UML图
3.2.3示教主动对象
如图8所示,示教主动对象负责管理HMI中的示教操作。初始化后,主动对象从disable状态转换到enable的ready子状态,等待用户的示教指令。当有示教指令产生后,主动对象会根据不同的指令进行不同的事件处理。
图8 示教主动对象UML图
各个事务处理的主动对象设计好后,就可以在中间层上进行创建了。设计译码主动对象的伪代码实现如下:
//主动对象创建实例
$declare(AOs::Interpret)
//封装了译码主动对象的声明
static Interpret l_Interpret;
//唯一的译码主动对象实例
//译码主动对象唯一的公共接口
QActive *AO_Interpret = (QActive *)&l_Interpret;
$define(AOs::Interpret_ctor)
//译码主动对象创建函数
$define(AOs::Interpret)
//译码主动对象状态机实现
//主动对象创建运行
int Create_ActiveObject(){
Interpret_ctor();
//译码主动对象创建
…
//其他主动对象创建
QF_init();
//框架服务初始化
….
//其他初始化
QActive_start(AO_Interpret,…)
//译码主动对象运行线程创建
…
//其他主动对象运行线程创建
QF_run();
//框架服务启动运行}
代码中首先创建唯一一个译码主动对象l_Interpret,并采用QM内置函数MYMdefine(AOs::Interpret)将UML图的状态机转化成代码,最后通过QActive_start(AO_Interpret,…)函数创建主动对象的运行线程。当所有主动对象完成创建后,就可以通过调用QP中间层平台提供的接口QF_run()启动框架的服务。
图9为HN-Robot机器人控制系统的HMI整体展示。从整体上可将区域划分为菜单区、功能区、状态区、信息提示区。该图展示了手动模式下进行手动示教的过程。
图9 HN-Robot 人机界面
从上述软件设计过程可以看出:
(1)层次式状态能够帮助设计者隐藏内部细节,行为继承方式使得主动对象通过重用机制(Umltimate Hook模式)减小系统复杂性。中间层架构的出版-订阅式平台降低了主动对象之间的耦合性,有效提高了程序的灵活性和可维护性。
(2)可视化主动对象设计。应用层采用UML图形化设计开发,如图6、图7、图8所示,使得软件分析和逻辑结构清晰,能够有效、快速开发出机器人控制软件相应的业务功能,降低了软件设计的复杂度。
(3)采用主动对象计算模型设计的分层架构有效实现对各个资源的有效划分和管理。在该架构的实现中,底层对上层而言是透明的,中间层封装了实时操作系统和组件的服务接口,隐藏了软/硬件的差异,为应用层提供了独立于平台的运行环境,提高了软件的可移植性。
[1] 高美原, 秦现生, 白晶,等. 基于ROS和LinuxCNC的工业机器人控制系统开发[J]. 机械制造, 2015, 53(10):21-24.
[2] 毕鲁雁, 刘立生. 基于RTX的工业机器人控制系统设计与实现[J]. 组合机床与自动化加工技术, 2013(3):87-89.
[3] 王力宇, 曹其新, 董忠. 基于EtherCAT总线的工业机器人控制系统设计[J]. 组合机床与自动化加工技术, 2017(10):79-81,86.
[4] 曹波, 曹其新, 陈培华. 基于模块化设计的码垛机器人控制系统开发[J]. 机床与液压, 2012, 40(23):90-92.
[5] 周伟花. 软件构件化技术在工业机器人集成系统的应用研究[D]. 长沙:中南大学, 2013.
[6] 陆伟. 一种工业机器人三层软件架构的设计与实现[J]. 电气自动化, 2016, 38(2):18-19.
[7] Fang Jian, Zhao Jianghai, He Feng, et al. Design and research of three-layers open architecture model for industrial robot software system[C]// IEEE International Conference on Mechatronics and Automation. IEEE, 2013:104-109.
[8] MIRO S.Practical UML Statcharts in C/C++ (Second Edition)[M]. Burlington: Newnes, 2008.
[9] PETZOLD C, PAUL Y. Programming Windows 95[M].Microsoft Press, 1996.