1. X语言的提出背景
近年来,基于模型的系统工程(Model-based Systems Engineering, MBSE) 已成为支持体系建模与开发的重要手段。以复杂产品为例,MBSE将传统的基于文档和 物理模型的研发模式,转变为模型驱动的研发模式,这种形式化描述方式使得MBSE具 有可重用、无歧义、易理解、易传播等优点,受到学术界和企业界的广泛重视。MBSE 采用系统建模语言(Systems Modeling Language, SysML)对系统进行全流程 建模,以实现产品研制全过程的基于模型的统一管理和优化。由于SysML不具备产品的 物理模型描述能力,无法直接进行仿真,因此,需要通过其他多领域建模仿真方法来验 证模型的正确性和完备性。
一种主流的做法是基于统一建模语言对不同领域的系统组件进行统一描述,从而实现多 领域模型的无缝集成和数据交换。针对机、电、液、控一体化类型的复杂产品,首先基于 系统建模语言(如SysML、IDEF等)进行需求建模和架构设计,然后基于物理建模语言 (如Modelica等)并配合集成标准规范(FMI、HLA等),实现物理模型的开发和集成, 最后通过开发系统模型和物理模型之间的映射转换进行全系统建模和仿真,实现产品研发 不同阶段的统一管理。
然而,由于系统建模语言与物理域建模语言脱节,需要通过转换实现连接,因此该方法 难以保证全流程全系统模型和仿真过程的一致性和可追溯性,而且,该方法缺乏对智能 产品和智能化建模和仿真的支持。
为了解决以上问题,本文提出了面向体系的新一代一体化智能化建模语言,贯穿架构设计、 多领域建模和仿真验证等全流程、多学科、跨阶段的协同设计建模与仿真。在系统层面, 采用面向对象的思想设计了定义、连接、方程、活动和状态5个类,表达系统的结构和行为; 在模型构建和仿真层面,借助DEVS仿真框架对于多领域模型的统一能力,将连续模型、离散模型 和智能体模型统一于DEVS的耦合模型之下,并借助解释器连通建模和底层仿真,从而实现对 复杂产品全系统规范化协同化智能化建模和仿真。
2. X语言总体组成架构
图1 X语言层次结构
抽取现有主流建模语言的描述特征,形成X语言的层次结构。如图1所示,在系统设计层面,采用面向 对象的思想设计了定义、连接、方程、活动和状态5个类,表达系统的结构和行为;在模型构建层面, 借助DEVS仿真框架对于多领域模型的统一能力,将连续模型、离散模型和智能体模型统一于DEVS的 耦合模型之下,支持物理行为的描述及仿真验证,实现对复杂产品全系统规范化协同化智能化建模。 基于此,赋予X语言以下建模仿真能力:
① 支持图形化建模,并能实现图形与文本之间的相互转换;
② 支持系统级结构与物理行为的描述以及仿真验证能力;
③ 支持对各类复杂智能体模型进行建模,包括智能体的学习过程、通讯过程,以及多智能体的并行仿真过程;
④ 支持连续、离散和连续/离散混合仿真。
3. X语言的文本组成
类是X语言中构成模型的基本单元,可进一步分为基础类和受限类。基础类是X语言中最基本的类,由关键字 class修饰。class会包含描述任意实体的结构特性以及行为特性。X语言还定义了一系列受限类,受限类 主要是为了更精确的描述不同特性模型实体以及增强模型的易用性和可读性,在模型中受限类可以被class替代, 而不会改变对模型的定义。
受限类由特定的关键字修饰,包括couple、continuous、discrete、agent、record、function和connector。 X语言中所有类具有描述不同特性的实体以及描述实体模型的部分组件以及功能等。具体如表1和表2所示。
表1 X语言类的描述能力
| Class | Functions |
|---|---|
| class | 支持任何模型的描述 |
| continuous | 支持具有连续行为模型实体的描述 |
| discrete | 支持基于事件触发行为模型实体的描述 |
| agent | 支持具有智能行为模型实体的描述 |
| couple | 支持具有多组件的系统级模型的描述 |
| record | 支持各类模型实体中复杂数据结构的描述 |
| function | 支持各类模型解决过程式建模所需算法的描述 |
| connector | 支持各类模型具有遵循基尔霍夫定律连接器的描述 |
表2 X语言类两种建模形式的架构组成
| 类/CLASS | 不同类的图形建模组成 | 不同类的文本建模组成 |
|---|---|---|
| class | 定义图、连接图、方程图、状态机图、活动图 | 定义部分、连接部分、方程部分、状态部分、活动部分 |
| continuous | 定义图、方程图 | 定义部分、方程部分 |
| discrete | 定义图、状态机图 | 定义部分、状态部分 |
| agent | 定义图、活动图 | 定义部分、活动部分 |
| couple | 定义图、连接图 | 定义部分、连接部分 |
| record | 定义图 | 定义部分 |
| function | 定义图、活动图 | 定义部分、活动部分 |
| connector | 定义图 | 定义部分 |
下面将具体说明每个类的包含元素及语法结构。
1)Continuous module
连续类是针对具有连续行为实体定义的。具有连续行为实体的行为是随着时间不断发生改变,可以通过数学方程进行描述。 具有连续行为实体的结构特性包括需实例化的参数及其类型定义、状态变量的定义、端口的定义;行为特性可以基于数学方程 定义。基于此,X语言中的连续类在图形和文本建模时分别通过定义图和定义部分描述其结构特性、方程图和方程部分描述其 行为特性。具体如表3所示。
表3 连续类定义
| 连续类 | 连续类属性 | 用途 |
|---|---|---|
| 定义图/定义部分 | parameter | 需实例化参数及其类型定义 |
| value | 状态变量定义 | |
| port | 端口定义 | |
| 方程图/方程部分 | equation | 以数学方程描述的行为定义 |
2)Discrete module
离散类是针对离散模型定义的。离散模型的行为是基于事件触发的,可以通过对其状态的定义进行抽象。离散模型的结构特性 一般包括需实例化的参数及其类型、状态变量以及端口的定义;行为特性基于状态机理论进行定义。基于此,X语言中的离散类 在图形和文本建模时分别通过定义图和定义部分描述其结构特性、方程图和方程部分描述其行为特性。具体如表4所示。
表4 离散类定义
| 离散类 | 离散类属性 | 用途 |
|---|---|---|
| 定义图/定义部分 | parameter | 需实例化参数及其类型定义 |
| value | 状态变量定义 | |
| port | 端口定义 | |
| 状态机图/状态部分 | state | 以状态机描述的行为定义 |
3)Couple module
耦合类是针对耦合模型定义的。耦合类的设计初衷是赋予X语言描述系统级的实体模型能力,其核心就是描述系统级实体中 所包含的组件及其之间的连接关系。基于此,X语言中的耦合类在图形和文本建模时分别通过定义图和定义部分描述其系统 组成、连接图和连接部分描述组件连接关系。具体如表5所示。
表5 耦合类定义
| 耦合类 | 耦合类属性 | 用途 |
|---|---|---|
| 定义图/定义部分 | reference | 调用其他模块 |
| part | 组件定义 | |
| 连接图/连接部分 | connection | 组件连接关系定义 |
4)Agent module
X语言中智能体类的设计遵循BDI架构,但又更加简洁。其中,保留了goal指导plan的执行这一最为核心的内容,而将环境感知 等一系列内容留给了用户自己去定义,以提升语言的扩展性。在利用Agent类进行建模时,整个结构可以分为两部分,分别是 definition部分和action部分。definition部分用来初始化参数和变量的值,以及函数和计划的声明也在该部分完成; action部分用来控制计划的执行,以及设置智能体仿真的开始和终止条件。
计划对应于BDI架构中的Intention部分,执行部分定义的内容对应于goal部分,而Belief部分则被融入到了整个智能体 与环境交互感知的过程中。在保留了原始BDI架构特点的基础上,与X语言的语法语义进行了融合,赋予了X语言智能化特性。
表6 智能体类定义
| 智能体类 | 智能体类属性 | 用途 |
|---|---|---|
| 定义图/定义部分 | parameter | 需实例化参数及其类型定义 |
| value | 状态变量定义 | |
| reference | 调用其他模块 | |
| plan | 智能体行为序列定义 | |
| 活动图/活动部分 | active | 计划执行逻辑定义 |
智能体类是针对智能体模型定义的,智能体模型一般会具有与其他实体通讯交互的行为。基于此,X语言中的智能体类在 图形和文本建模时分别通过定义图和定义部分结构特性、活动图和活动部分描述行为特性。具体如表6所示。
5)record module
记录类秉持方便具有不同数据类型的实体模型目的定义的。基于此,X语言中的记录类在图形和文本建模时通过定义图和定义 部分描述所包含的数据类型。具体如表7所示:
表7 记录类定义
| 记录类 | 记录类属性 | 用途 |
|---|---|---|
| 定义图/定义部分 | value | 不同数据类型定义 |
6)function module
函数类秉持方便具有复杂功能行为的实体模型目的定义的。函数会包括输入输出的参数以及具体功能实现定义。基于此, X语言中的函数类在图形和文本建模时通过定义图和定义部分描述其输入输出参数、活动图和活动部分描述其具体功能实现过程。 具体如表8所示:
表8 函数类定义
| 函数类 | 函数类属性 | 用途 |
|---|---|---|
| 定义图/定义部分 | value | 输入/输出参数定义 |
| 活动图/活动部分 | active | 功能实现过程定义 |
7)connector module
连接器类是为具有遵循基尔霍夫定律连接器的实体模型所定义的。连接器中会定义实体与其他实体之间传输数据的类型。 基于此,X语言中的连接器类在图形和文本建模时通过定义图和定义部分描述所传输数据的类型,具体如表9所示:
表9 连接类定义
| 连接器类 | 连接器类属性 | 用途 |
|---|---|---|
| 定义图/定义部分 | value | 输入/输出数据类型定义 |
4. X语言的解释器架构
X语言是面向对象的多领域系统建模语言,不仅包括了面向对象的语言特性,还囊括了基于方程的建模语言的特性,而二者 在进行解释时所采用的路线一般都不一致,所以对X语言进行解释时需要采用不同的技术路线。
图2 X语言解释器框架
解释流程分为三个阶段,分别是预处理阶段,中间处理阶段和后处理阶段。
预处理阶段同上述的两种方法之间并没有显式的差别,负责对源代码进行词法分析和语法分析得到抽象语法树,并收集 模型中元素的信息制作符号表。
中间处理阶段将会根据所解释的文件中包括的模型的类型使用不同的技术手段,对于基于方程的连续模型,首先对其进行 扁平化处理,得到扁平化方程组。然后在因果化阶段将方程组转化为适合微分方程求解器求解的形式。对于基于赋值的 模型,即智能体模型和基于DEVS规范的模型,首先借助上一阶段构造的符号表对模型中包含的每一条语句进行静态类型 检查,然后根据模型类型的不同分别选用不同的技术方法。在这里采用不同的解释路线是因为DEVS模型的解释和代码生成 相对的能够同仿真代码一一对应,而智能体模型的上层模型表示则和底层相去较远,需要经过参数的对应和生成文件的 整合才能够确保不丢失必要的信息,所以二者所需的操作复杂程度也就不一致。在中间阶段后,模型仿真所需的所有 数据结构已经处理完毕。
在最后一个阶段,将三个技术路径中得到的处理后的数据结构进行遍历并得到各自模型可仿真文件,如果模型存在层级 结构,则还需要文件层级整合才能得到整个模型的可仿真文件。
5. X语言的仿真器架构
X语言针对多领域建模的能力要求其具备对多领域学科模型进行仿真。DEVS作为支持多领域建模的框架,完全能够满足 X语言的需求,为语言提供对多领域模型仿真验证的支持。
DEVS仿真算法最有效的实现是由Zeigler等人开发的层次递归程序,如图5所示,针对DEVS仿真结构,每一个原子模型 对应到仿真器中的一个simulator,执行该原子模型的内部和外部事件;耦合模型对应为coordinator,负责调度模型 内部的原子模型的事件。在整个模型的最顶层,对应为root-coordinator,其管理整个模型的事件推进。
在X语言中,保持了DEVS仿真器的架构,并根据语言的特殊性做出了一些拓展:
1)首先,连续模型在仿真器中以原子模型的形式存在,这是基于DEV&DEVS对连续模型的拓展,连续模型中定义的状态 事件和时间事件在框架中进一步抽象为原子模型的内部事件,在内部事件和外部事件触发的时间节点对方程进行求解。
2)智能体模型作为耦合模型存在,但是根据DEVS理论,耦合模型能够被视作特殊的原子模型,所以在仿真器结构中将其 作为原子模型。X-语言的智能体模型是基于BDI架构实现的,其将智能体模型分为了goal、schedule、plan和 interaction四个模块。在设计中,其能够基于interaction同其他的原子模型或智能体模型进行事件交互。
3)通过上述两点将智能体和连续模型表示为DEVS模型,使得智能体、离散、连续三种模型之间的连接抽象为以事件为 基础的连接,能够支持多领域模型的建模和仿真。
在整个X语言仿真器中,相连的simulator和coordinator之间基于消息进行通信。每次事件发生(内部事件或者 外部事件),coordinator将会向其子节点发送转换消息通知子节点执行转换。Simulator在执行其内部事件或外部 事件时,将会计算其下一个状态,如果执行的是内部转换,还需要将输出发送给其父coordinator。所以在simulator 和coordinator之间共存在三种类型的通信,如图一所示,分别是coordinator到simulator的内部和外部事件通知 以及从simulator发往coordinator的输出。
每个simulator和coordinator都定义了下一次内部转换发生的时间。在simulator中,该时间由原子模型的时间 推进函数计算。在coordinator中,通过获取所有子节点的下一事件发生时间并取最小值作为自己的下一事件发生时间。 所以,root-coordinator的下一事件发生时间就是系统中所有模型的下一事件时间中的最小值。root-coordinator 不断将全局时间t向前推进到其对应到事件发生时间,向它的子节点发送事件消息,通知子节点执行事件。然后重复这个 循环,直到模拟结束。
a.模型层级结构
b.仿真器层级结构
图3 仿真器结构图
X语言宣传视频