发明内容
本发明针对上述协同设计中出现的问题,提出一种基于协同模板的协同设计方法,将模板和协同设计相结合起来,形成协同模板,其是具有语义功能的可以描述几何及属性信息的抽象的通用的数据表示,其不仅包含几何属性、工程属性,更有网络属性、任务属性等支持协同机制的特殊属性信息,支持协同工程设计的全过程。协同模板采用分解、复合、替换、继承等多种方式提高了网络中设计模型的可扩充性与多样性。
本发明的目的
本发明的目的是在协同设计和模板技术的研究基础上,结合工程设计的实际问题,探索具有协同机制和模板相结合的协同模板的设计环境和流程框架,研究网络协同环境下设计任务的分解、发布和控制以及模板的定义和表示、模板的复合、参数与结构分离等方法,为新的网络化产品设计提供原型框架和基础。
本发明的技术方案
一种基于协同模板的协同设计方法,其特征在于:先在计算机内搜索模板库的模板和相应的任务匹配情况,有模板存在,在计算机内进行模板协同编辑工作,没有模板存在,根据设计任务的外部约束、整体约束规则、部件位置关系、操作连接信息,在计算机内创建相应的任务数据库并通过任务数据库创建接口;在计算机内总设计端将设计任务划分为一系列由一个或若干个相关部件组成,并且有相应的子模板对应子设计任务,根据任务数据库的约束信息,产生反映任务的串并行关系并控制子任务进行的任务前趋图,在计算机内发布任务到可以显示任务发布信息和前趋图信息,并进行子任务的申请和竞争的子设计端;计算机根据子任务申请状态来进行任务的分配或者强行进行子任务的分配;计算机任务分配后,子设计端接到分配的子任务和子任务设计要求文件,该子任务没有前趋任务或者其前趋任务都已完成,则子设计者可以进行子任务的设计,否则子设计者在其子任务的所有前趋任务都完成了后进行子任务的设计;子设计者依据子模板结构文件和子任务设计要求文件进行子任务的设计,得到并向总设计端提交子模板参数文件;总设计端进行模板复合,实时解释设计结果,检测提交子任务的正确性,无错则确认子任务结果,子任务由提交状态变为完成状态,子任务确认后,激活该任务的后继子任务并且将相关信息传递给受之约束的其他子任务,其他子任务接到激活信息后,判断其前趋任务是否都已经完成,没有则继续等待,否则该子任务开始进行设计;在设计过程中,并行任务之间、存在环约束的子任务之间通过文本通信、语音通信、白板***等协同交流手段供设计者之间进行信息交流;所有子任务完成之后,计算机内总设计端进行检查、验证看结果是否符合设计要求,满足则任务完成保存设计结果的模板,否则,计算机将那些不符合设计要求的子任务退回重新进行设计,重复进行前面的过程,直到设计结果符合要求为止。
所述的一种基于协同模板的协同设计方法,其特征在于:所述的协同模板的结构与参数分离,在计算机内将模板的结构和参数分离开来,用模板参数文件表示设计对象的数据,用模板结构文件来表示设计对象的框架结构,用一个模板结构来表示一类设计对象,而用不同的参数文件来表示该设计对象的不同实例,子设计端将表示设计结果的模板参数文件传递给总设计端,总设计端根据模板参数文件得到与模板参数文件一一对应的模板结构文件,根据模板结构通过模板解释器去解析模板参数文件,得出设计结果的完整信息,并通过造型解释模块将造型结果显示出来。
所述的一种基于协同模板的协同设计方法,其特征在于:所述的协同模板的复合与装配,包括总设计端发起任务时通过任务数据库创建接口产生的子模板参数文件和结构文件、设计约束文件、位置关系文件、操作和连接文件,计算机首先判断模板文件存在情况,模板文件不存在,计算机产生模板文件及基本模板元素框架,根据任务数据库到XML的转换接口产生总任务的设计约束文件、位置关系文件、操作连接文件,并复合到总模板中,子模板文件是参数文件时,将子模板参数文件和结构文件相结合产生可以复合的子模板文件,预处理子模板文件,处理子模板多次复合问题以及模板中部件名称冲突问题复合子模板文件,复合时根据子模板是否已经复合来做相应的动作,子模板复合后更改任务数据库中的任务复合标志,保存模板,结束一次子模板复合。
所述的一种基于协同模板的协同设计方法,其特征在于:所述的基于协同模板的协同设计方法采用模板设计标记语言。
本发明的原理
协同模板概念正是在协同设计技术近些年来迅速发展的前提下,结合模板在工程设计领域内的应用基础应运而生的。它在模板的基础上被赋予了新的网络特性。协同模板同样是具有语义功能的可以描述几何及属性信息的抽象的通用的数据表示,符合工程设计标准和规范,其不仅包含几何属性、工程属性,更有网络属性、任务属性等支持协同机制的特殊属性信息,支持协同工程设计的全过程。CoT是协同模板的简称,其形式化描述可以表示为:CoT=<M-ID,T-ID,C,E,T,RU,RE,OP>,其中M-ID表示独立的协同任务ID号;T-ID代表唯一的协同模板ID号;C指协同模板中的部件集;E则是一系列的表达式;T记录了网络协同和工作流程进行所需的任务信息;RU指部件和任务的约束规则库;RE描述了位置关系;OP则是存储模板操作的集。
模板设计标记语言形式上以XML(The eXtensible Markup Language)作为表达的基础,不仅符合XML的语法规范,同时为了适应描述设计对象,描述模板结构及协同模板操作的特殊需要,TDML也具有自身的一套语法和语义规则。TDML作为协同模板及其操作的描述语言,主要具有以下几个优点:
可读性好:TDML的字段都是由文本和标签组成,通过匹配相应的标签和文本,非常易于理解和解释。
严格的语法规范:TDML具有极强的语法定义,十分适合用于描述富含标准和规则的协同模板。
可扩展性:基于XML定义的TDML具有充分的灵活性,可以为模板扩充新的字段及规则创造条件。
独立的内容和结构:TDML同样被定义为一种语义—结构语言,其内容和标签可以很轻易的被剥离开来,满足了协同模板结构与参数分离的特殊需要。
通用的标准:在XML的支持下,TDML能够跨学科跨领域的描述多种信息。
协同模板的表示方式与结构:
模板设计标记语言(TDML)是用于协同交流、命令控制及协同模板结构、设计参数的描述语言,符合XML的语法规范,是协同模板的组织与表达方式。根据描述设计对象信息的需要,在模板设计标记语言中定义了七大基本字段(七个模板基本元素):InputPara、Components、Expressions、Rules、Relations、Operations和Links,分别对应七种设计信息。各个字段有各自相应的词汇和语法语义,每个词汇表示一定的语法构成和语义;并且每个字段由具有特定语义的子字段词汇构成。一个用于描述设计对象信息的TML文件(也叫模板文件)有一个模板根元素Template,它有TID、name等属性,并由上述七个基本子元素组成。
TDML的语法:
[1]TMLDocument∷=XMLDecl Comment*Template Comment*
[2]Template∷=‘<Template>’InputPara?Components Expressions Rules?
Relations?Operations?Links?… ‘</Template>’
[3]InputPara∷=‘<InputPara>’(table|if|default|express|string|graph…)+
‘</InputPara>’
[4]Components∷=‘<Components>’ComponentInfo+‘</Components>’
[5]Exressions∷=‘<Expressions>’(table|if|default|express|string|
graph|…)+‘</Expressions>’
[6]Rules∷=‘<Rules>’(table|if|default|express|string|graph|…)+
‘</Rules>’
[7]Relations∷=‘<Relations>’(UpComponent|LeftComponent|Parallel|
Tangency
|…)+‘</Relations>’
[8]Operations∷=‘<Operations>’(Embedding|Luoliaokong|…)+
‘</Operations>’
[9]Links∷=‘<Links>’(luoding|xiaoding|daohuald|dagan|…)+
‘</Links>’
[10]UpComponent∷=‘<UpComponent>’Component1 Component2 xDistance
yDistance zDistance‘</UpComponent>’
[11]Embedding∷=‘<Embedding>’Component1 Component2 Distance
‘</Embedding>’
[12]Table∷=‘<table>’Varname TableName DatabaseName QueryItem Condition
</table>’
[13]if∷=‘<if>’Varname Condition ifValue ElseValue‘</if>’
[14]default|express|string|graph∷=‘<’(‘default’|‘express’|
‘string’|‘graph’)‘>’
Varname Value‘</’(‘default’|
‘express’|‘string’|‘graph’)‘>’
[15]luoding/xiaoding/daohuald/dagan∷=‘<’(‘luoding’|‘Xiaoding’
‘daohuald’|
‘dagan’)‘>’Linkname Component+‘</’(‘luoding’
‘xiaoding’|‘daohuald’|‘dagan’)‘>’
[16]ComponentInfo∷=‘<’ComponentType‘>’parent name‘</’
ComponentType‘>’
[17]Component∷=‘<Component>’ComponentName‘</Component>’
[18]Varname∷=‘<Varname>’ComponentName“.”Name </Varname>’
[19]Linkname∷=‘<Linkname>’LinkObjName‘</Linkname>’
[20]parent∷=‘<parent>’ComponentType‘</parent>’
[21]name∷=‘<name>’ComponentName‘</name>’
[22]LinkObjName|ComponentName|ComponentType∷=Name
[23]Value∷=‘<Value>’numberValue|expressValue|stringValue
‘</Value>’
[24]numberValue∷=(‘+’|‘-’)?([0-9])+(‘.’[0-9]+)?
[25]expressValue∷=expressValue(‘+’|‘-’|‘*’|‘/’)expressValue
|‘(‘expressValue‘)’
|numberValue|Varname
[26]stringValue∷=Char*
[27]Char∷=[#x1-#xD7FF]|[#xE000-#xFFFD]|[#x10000-#x10FFFF]
/*any Unicode character,excluding the surrogate blocks,FFFE,and FFFF.
*/
[28]NameStartChar∷=″:″|[A-Z]|″_″|[a-z]|[#xC0-#xD6]|[#xD8-#xF6]|
[#xF8-#x2FF]|[#x370-#x37D]|[#x37F-#x1FFF]|[#x200C-#x200D]|[#x2070-#x218F]
|[#x2C00-#x2FEF]|[#x3001-#xD7FF]|[#xF900-#xFDCF]|[#xFDFO#xFFFD]
[#x10000-#xEFFFF]
[29]NameChar∷=NameStartChar|″-″[0-9]|#xB7|[#x0300-#x036F]|
[#x203F-#x2040]
[30]Name∷=NameStartChar(NameChar)*
句[1]说明一个TML文件由XML申明、注释及一个Template根元素组成。XMLDecl和Comment的EBNF表示与参考文献[2]中XML语法表示是一样的,这里没有写出。句[2]说明一个Template模板根元素的构成:七大基本元素。在这里我们用“…”表示Template根元素可以扩展新的基本元素字段。其他出现“…”的地方亦表示可扩充性。[3]、[5]、[6]是InputPara、Expressions和Rules的语法构成,它们有相似的子元素组成,只是所表示的设计信息含义不同。[12]、[13]、[14]是说明其六个子元素语法构成的。[4]所描述的是Components部件整体信息内容。[7]、[8]、[9]分别表示Relations装配关系、Operations操作及Links连接信息的表示。其他表示的分别是其子元素及子子元素的语法构成。在[14]、[15]、[22]中“∷=”左边出现了“|”符合表示或的关系,在EBNF中“|”只出现在右边,我们在这里表示的含义是:由“|”连接的并列成分有相同的语法构成,只是他们的名称不同,他们名称和右边出现“|”的地方是一一对应的。这里对TML的语法表示我们并没有完整的都列出来,主要由于篇幅的考虑,我们列出了最主要的语法表示部分。
TDML的语义:
InputPara输入参数段
在我们对设计对象进行研究时,发现某些设计对象如冷冲模***中需要一些外部输入参数信息,这些信息对该设计对象起外部约束作用。如冷冲模中首先需要根据输入制件等的信息得到输入处理的参数,我们把输入处理的结果作为模板文件输入参数信息。还有就是冷冲模中还要用到一些全局参数信息,如模柄嵌入距离、offset、global.lx_bian等,对这些信息,我们也作为输入参数信息提供给模板,定义了InputPara元素来描述该类信息。这些外部输入参数值的表示方法和Expressions中表示部件属性值的表示方法是一样的,我们将在介绍Expressions字段时介绍如何表示参数值的信息。
Components部件信息段
设计对象是由一系列基本部件按一定关系形成的,部件有零部件和连接件之分。为了描述设计对象的部件构成信息,及每个部件的类型、名称及父类等信息,模板标记语言提供了Components字段来描述部件的信息。Components的各个子元素表示的是各种类型的部件信息,我们以部件类型的名称作为部件元素的名称。
Expresssions属性表达式段
对于详细设计来说,最主要的设计信息是设计对象各个部件的属性信息。部件的属性是指在描述一个部件时所需要的材料、颜色及几何尺寸和形状方面的信息。长、宽、高就是长方形类型部件的三个必要属性,半径就是一个球类型部件的属性。Exprssions元素就是用来表示这些属性及其属性的值信息。Expressions的属性信息是设计者可以进行相应的修改设计的部件属性信息。
我们把属性值的类型分为default、express、if、table、string、graph六种类型,每个属性的描述就用一个元素名为某个属性值类型的元素来表示。每个属性元素的构成又有所不同,但它们都有一个表示属性名称的子元素Varname,以“部件名.部件属性名”表示。下段是Expressions元素及其三种类型属性元素的描述方式(default、string和graph的描述方式和express一样)。
<Expressions>
<express>
<Varname>xieliaoban.holeheight</Varname>
<Value>3*global.thickness</Value>
</express>
<table>
<Varname>aomo.box_height</Varname>
<DatabaseName>moju</DatabaseName>
<TableName>btch</TableName>
<QueryItem>h</QueryItem>
<Condition>b=global.length,t=global.thickness</Conditi
on>
</table>
<if>
<Varname>aomo.box_height</Varname>
<Condition>aomo.box_height<;global.height</Condition
>
<ifValue>global.height+10</ifValue>
<ElseValue>aomo.box_height</ElseValue>
</if>
</Expressions>
属性元素default、express、string、graph由Varname和Value组成。Value表示一个数值(default元素),或者是由数字、部件属性名称Varname通过四则运算组合起来的表达式字符串(express元素),或者是表示材料颜色信息的字符串(string元素),或者是表示图形文件的位置(graph元素)。属性元素if则由Varname、Condition、ifValue和elseValue组成,分别表示部件属性名、if条件表达式、条件表达式为true的属性值和条件表达式为false的属性值。属性table由Varname、Databasename、Tablename、QueryItem和Condition,分别表示部件属性名、数据库名称、表名称、查询项及查询条件,属性值就是查询数据库所得的值。
Rules规则段
它的元素组成和语法与Expressjons元素相同,只是规则段表示的是模板中部件的属性设计信息中不可改变的部分,它主要表示的是不同部件的属性之间的约束关系,如几何尺寸的约束关系等,所以Rules段中主要是express属性元素,表示一个属性与其它属性之间的关系。Expressions和Rules中的属性信息加在一起就表示所有的部件的属性信息,部件对象的每个属性信息都在Expressions或者Rules可以找到唯一一个对应的属性值信息。
Relations部件位置装配关系段
表示设计对象各个部件的装配位置关系。设计对象是由一系列部件按照一定的装配关系组装而成的,装配信息是设计对象重要的结构信息。Relations元素就是表示设计对象各个部件之间的装配位置关系信息的。部件之间常用的位置关系是上下位置关系,以及左右位置关系;还有平行、垂直、相切也属于部件的位置关系。
我们用UpComponent表示部件在Z方向(上下方向)的位置关系,它的语法构成:由Component1、Component2、zDistance、yDistance和xDistance五个子元素组成。Component1和Component2分别表示存在位置关系的两个部件(用部件名表示)。zDistance表示部件1和部件2(参考部件)之间的Z方向间距。yDistance和xDistance表示Y方向(前后)和X方向(左右)的偏移距离。这主要是为了避免用多条不同位置关系语句来描述两个部件之间的关系,而且也为了减少模板位置关系词汇量,我们不必定义形如UpLeftComponent的元素来表示部件的位置关系。下段是一个表示Relations中的UpComponent位置关系的例子。
<Relations>
<UpComponent>
<Component1>aomo</Component1>
<Component2>chongtou</Component2>
<zDistance>-global.thickness</zDistance>
<yDistance/>
<xDistance/>
</UpComponent>
</Relations>
LeftComponent元素的语法构成和UpComponent一样,只不过表示的语义是两部件的左右位置关系。对于平行、垂直和相切等位置关系,我们暂时还没有定义详细的词汇和语法语义,我们会在后面的工作中扩展这方面的工作,总结出一套可以描述部件之间各种位置关系的位置关系词汇元素并对其的语义进行描述。
Operations操作关系字段
在描述设计对象的信息时,我们发现有些对象中有些特殊的设计信息,无法用装配等方式来描述,我们扩展增加了操作字段来描述这类信息。比如在冷冲模领域中经常遇到嵌入和打落料孔两种操作,这种操作仅用位置关系是无法完整描述的,它一方面表示了部件之间的某种位置关系,而且还表示一定的操作语义,我们解释时要对其造型做一定的处理操作。我们用Operaitons元素来表示设计对象中的这类信息。比如我们用embedding和luoliaokong两种操作元素分别描述冷冲模中常用的嵌入和打落料孔两种操作。下段是冷冲模落料模板中的操作字段的luoliaokong信息的表示。
<Operations>
<luoliaokong>
<PlineGraph>
pline_luoliao.sat
</PlineGraph>
<Component>xiadianban</Component>
<Component>xiamojia</Component>
<Distance>offdist</Distance>
</luoliaokong>
</Operations>
Links连接关系段
连接件是机械装配中常用的用于连接和固定零部件的,对于连接件我们不仅要给出它的属性信息,更重要的是它描述的是一组连接件穿过零件的信息,对于连接件穿过的部件我们还要做相应的造型处理,这不是简单的确定位置关系。我们定义了Links元素来专门描述连接信息。Links的子元素是以连接件的类型来表示,不同的连接件就对应特定的连接语义,在模板标记语言中定义了四种连接子元素表示luoding(螺钉)、xiaoding(销钉)、daohuald(导滑螺钉)、dagan(打杆)等四种类型的连接件的连接信息。下段是luoding连接信息,连接信息元素的名称luoding表示连接件的类型是螺钉,它有一个Linkname子元素和若干Component元素组成。Linkname表示螺钉的名称,(omponent表示螺钉穿过的部件的名称,各个Component元素是按sequence顺序表示螺钉依次穿过的各个零部件的名称。连接件的属性信息,如螺钉半径、螺钉数目、螺钉分布方式等都是在Expressions和Rules元素中可以找到。
<Links>
<luoding>
<Linkname>luoding1</Linkname>
<Component>shangmojia</Component>
<Component>shangdianban</Component>
<Component>gudingban</Component>
</luoding>
</Links>
连接元素xiaoding、daohuald与luoding语法构成和含义一样。
模板复合与装配
在协同模板运行过程中,一个设计任务被分成若干子任务,每个子任务由一个或若干部件组成。每个子任务可以根据相应的子模板进行设计,设计结果以子模板参数文件的形式保存起来并传递给总设计端,而总设计端则利用模板复合操作将子任务设计结果复合起来,最后形成完整的设计对象的模板信息。模板装配就是将子模板按照分配的设计、装配顺序,仿照部件的装配,累加合并成完整的设计结果。
在实际的操作过程中,结构与参数分离就是将文件中用于描述结构的相对固定的信息与设计者设计的可修改的相对灵活的信息分离成两个文件部分。完整的模板描述逻辑上具有结构和设计参数两大部分的信息,为了体现协同模板在网络中应用的优势,减少网络上的信息传输量,将协同模板的结构与参数分离,在传输的过程中在已经拥有模板结构的前提下,只传输设计的内容,可以大大减少传输负担,提高效率。
任务前趋图,顾名思义,是一种反映了先后执行关系的抽象的图结构,存储了任务节点以及它们之间的前趋后继关系。在协同模板的设计环境中,任务控制及设计进程皆以任务前趋图为基础,其作用是不容忽视的。任务的发布与分配,设计任务的相互制约,串并行设计流程的控制,乃至模板最终的复合与检测都依托于任务前趋图的定义。任务前趋图TPG=(PV,PE)PV集的每一个任务节点vi表示设计子任务,PE集中的每一条有向边则表示任务之间的直接驱动关系,是一种前趋与后继关系,具有传递性。
在协同模板运行过程中,一个设计任务被分成若干子任务,每个子任务由一个或若干部件组成。每个子任务可以根据相应的子模板进行设计,设计结果以子模板参数文件的形式保存起来并传递给总设计端,而总设计端则利用模板复合操作将子任务设计结果复合起来,最后形成完整的设计对象的模板信息。
模板的复合需要的信息包括:子模板参数文件(设计结果)和结构文件、设计约束文件、位置关系文件、操作和连接文件。其中子模板参数文件是子任务的设计结果。而设计约束、位置关系、操作连接文件则是总设计端发起总任务时的任务总体约束信息、各个子任务间的任务关系信息。这些信息是总设计端发起任务时通过任务数据库创建接口产生的,我们在模板复合时要根据任务数据库中的总体约束信息,转换为模板中描述约束、位置关系和操作连接的XML文件信息,并复合到总模板中去。
模板复合就是把子模板参数文件信息和结构文件相组合,得到复合所需的子模板信息,再加上设计约束信息、位置关系信息、操作连接信息,就得到整个模板所需的完整内容。
CXMLTemplateReadAndWrite类的CompositeSubTemplate()接口是用于实现模板复合的函数,参数为模板文件名,子模板文件名和参数文件标志。在模板复合的过程中,总模板原先是不存在的。经过第一次子模板复合后总模板创建并产生相应的约束、装配、操作连接等总体信息。其主要复合过程为:
1)判断模板文件是否存在。如不存在说明是第一次进行复合,产生模板文件Document及一些基本模板元素框架。如果已经存在则跳到第三步。
2)如果是第一次复合则根据任务数据库到XML的转换接口产生总任务的设计约束文件、位置关系文件、操作连接文件等,并复合到总模板中。
3)判断子模板义件是否为参数文件,如是参数文件则将子模板参数文件和结构文件相结合产生可以复合的子模板文件。
4)预处理子模板文件,主要是处理子模板多次复合问题以及模板中部件名称冲突问题。因为我们的模板中必须保证部件名称的唯一性。
5)复合子模板文件。复合时要根据子模板是否已经复合来做相应的动作。子模板复合后更改任务数据库中的任务复合标志。
6)保存模板Document,一次子模板复合结束。
协同模板的结构与参数分离
协同模板概念的提出,其中一个主要原因是为了解决网络上图形文件的传输问题。采用模板对设计对象进行描述可以大大降低设计对象文件的大小。模板之所以可以大大降低设计结果的大小,主要是因为我们将设计结果的再现留给模板解释器和底层的造型解释模块。离开模板解释器,模板文件也就没有任何意义。
但是模板解释器解释的内容必须是有数据和结构语义的模板文件。仔细研究我们模板的构成,可以发现模板实际上是由表示模板结构的部分和表示数据的部分构成的。如Components段、属性名称、装配段、操作段表示的就是设计对象的结构信息,而设计对象的数据信息则对应于属性表达式段的属性值。如果我们可以将模板的结构和参数分离开来,用模板参数文件表示设计对象的数据,用模板结构文件来表示设计对象的框架结构,则可以进一步降低设计结果的大小。我们目前实现了子模板的参数和结构分离,因为在协同模板中大量要传输、复合的设计结果都是跟子模板相关的。
另一方面,对于某种设计对象类,其设计数据不同就代表有不同的实例。当我们需要保存同一设计对象类的不同实例时,他们的模板除了数据部分不同之外,模板的结构框架是完全一样的。如果将模板的结构和参数分离开来,则我们可以用一个模板结构来表示一类设计对象,而用不同的参数文件来表示该设计对象的不同实例。这样对于模板的管理,我们只需要管理模板的结构就可以了。这样也就将模板的功能及结构框架和模板的参数数据分离开来,不仅便于模板的管理,也进一步大大降低了设计对象数据的大小。
将模板结构和参数分离之后,我们在网络上进行设计时,子设计端只需要将表示设计结果的模板参数文件传递给总设计者,模板参数文件中含有唯一标志模板结构文件的模板ID。总设计端根据模板ID可以得到模板结构文件(模板ID和模板结构文件是一一对应的关系),然后根据模板结构去解析模板参数文件,最终得出设计结果的完整信息,并将造型结果显示出来。这里有一个条件,就是相互传递模板参数文件的双方必须都拥有相应的模板结构文件才能解释模板参数文件。
所以,将模板参数和结构分离,不仅是合理的,而且很有必要。下一节我们将介绍如何将模板参数和结构分离开来。
要实现模板结构和参数的分离,最关键的是如何界定模板的结构和参数,以及如何描述模板的结构,参数如何表示。当然还要考虑分离了再如何组合起来。
模板由输入参数段、部件段、属性表达式段、规则段、位置关系段、操作段及连接段。我们在协同模板中主要涉及到的是子模板的参数和结构分离、子模板的提交和复合等操作。所以我们主要实现的是子模板的参数和结构分离。对于子模板来说,模板的某些字段大部分情况下内容为空,如输入参数段、操作段和连接段。而对于位置关系段来说,如果子模板描述的是单个部件则也为空,如果子模板表示的是若干相关部件组成,则可以有位置关系段、操作段和连接段。
对于子模板的结构,部件段表示的是模板描述对象,属于结构内容,由部件类型和名称信息组成。然而对于部件的名称信息,一个子模板结构描述的是一种设计对象的结构框架内容,同一部件类型在不同设计领域或者不同的设计场合可能名称并不一定都以结构文件中的为准,或者一个子模板结构在同一个设计任务中多次用到,这时部件名称如果都以结构文件的部件名称为准,肯定会产生部件名称冲突,不符合前面所说的名称唯一性规则。所以必须把部件名称作为设计信息的一部分,提供给设计者修改部件名称的权利。当然,这只在必需的时候才这样做,如果一个模板结构在设计任务中只用了一次,不会产生名称冲突,就没有必要修改部件名称。则段是模板中不可改变的部分,不属于设计范畴,也属于模板结构;对于位置关系,有两种方式:一种是位置关系不可改变,即模板描述对象的装配位置不可改变,这说明了模板描述的对象的结构是不可改变的。另一种是设计对象各部件的位置关系可以进行调整。相应的如果位置关系不可调整,则位置关系段也作为模板结构的一部分;如果位置关系可以调整的话,则位置关系内容也是设计数据的一部分,应该和结构分离。在我们的协同模板中,各子任务部件的位置关系作为整体设计对象中由总设计者指定不可改变的部分,所以在我们的子模板中也体现了这种思路,即位置关系段内容作为模板结构的一部分,没有进行分离。对于操作段和连接段我们也是将之作为模板结构,并没有分离其参数。
模板的属性段是设计对象各个部件的属性内容,这是设计的主要内容,也是我们参数和结构分离的所解决的主要问题:属性的参数和结构如何分离,在结构文件和参数文件中如何表示相应的属性内容。
对于属性段,每个属性由属性名称和属性值部分组成。属性值由于类型不同,又分为default、express、table、if等六种。属性值的类型不同,其值的表示方式也不相同。因而我们将属性段分为两部分:属性名称和属性值,属性名称是模板结构部分,而属性值部分(包括属性值类型和值的表示方式)属于模板的参数部分。模板的参数和结构从模板中分离出来,这样模板的表示更加清晰,参数文件和结构文件的内容之和构成模板文件的内容。模板的结构描述的是某类设计对象或部件,模板参数文件则表示该类设计对象的一个特定实例,也就是一个有具体属性的对象。
具体实施方式
参见图1-3。
总设计任务:对于一个复杂的设计对象或者大型工程,可能涉及到不同领域的专业知识,仅一个人完成所有设计几乎是不可能的。必需将总任务划分成若干子任务由不同设计者完成。在我们的协同模板中,主要针对的是一个复杂设计对象的设计任务。复杂是相对的,我们的例子中的个人沙发、冷冲模、包层等就是作为总设计任务对象的。这些设计对象也许并不十分复杂,不过这并不影响我们研究利用协同模板来进行复杂对象的设计过程。
子任务:相对简单的设计对象,一般是由一个或若干相关的部件组成。子任务主要是降低任务的复杂度。
任务划分、发布、分配、申请、复合等:任务划分是指总设计者将总设计任务分解为若干子任务,一个子任务一般是一个或若干部件。任务发布指任务划分之后,总设计者将各个子任务的信息,及子任务的约束关系(任务前趋图)等传给各个子设计端。任务分配是指总设计者将一个子任务分配给某个子设计者。任务申请指每个子设计者可以根据任务发布信息,去竞争某个子任务。任务复合指各个子任务完成之后,总设计者将子任务的结果合成到一起,这主要是借助模板的复合来实现的。
任务数据库:为了实现任务的分解、控制以及任务的复合,我们总结了在一个设计任务中需要的约束、关系信息,这些信息是任务分解的依据。主要有设计任务需要的外部信息、设计对象内部的尺寸和位置约束、操作连接信息等。这些信息也是任务前趋图产生的依据,对任务的控制和复合都起重要作用。因为这些任务信息非常重要而且在任务的各个阶段都需要,所以我们设计了任务数据库来输入和保存这些任务信息。
任务约束:一个总设计约束对象内部存在各种约束关系,如尺寸、位置、拓扑关系、材料、力学等,将设计任务分解后,这些约束就反应为各个子任务之间的约束。这种约束决定了任务的前趋后继关系、串行并行关系。在我们的***中通过任务前趋图来反应和控制任务之间的这种约束关系。
任务前趋图:根据设计任务的约束信息,体现各个子任务的前趋后继、并行串行关系的图。类似于操作***中的进程前趋图。
总设计者:一次协同设计任务的发起者,其拥有对任务的总体控制、协调各子设计者的工作,对设计结果进行复合、检测和确认。总设计者对应总设计任务。
子设计者:协同设计任务的参与者,总设计者将总设计任务分解成一个个子任务,每个子任务分配给一个子设计者。子设计者对子任务进行设计,完成之后提交给总设计者。子设计者是和子任务相对应的。
服务器端、客户端:我们协同模板***的结构采用MCAM同构协同设计平台的结构-基于C/S的同构复制式结构。事实上我们是基于MCAM同构协同设计平台基础上进行开发的。对于一次协同设计过程或者协同模板过程,总设计者发起一个任务,打开协同服务器端;其他子设计者进行参与,连接服务器端的机器,子设计端就对应协同的客户端。在我们的表达方式中,总设计端就指服务器端,子设计端指的是客户端。
元模板:不可再分的模板,元模板描述的造型对象是基本的造型元素。比如说:点、线、圆、长方体、圆柱等的模板就属于元模板。这是跟模板描述的对象级别有关,元模板可以对应元部件的概念。元模板的解释需要底层造型库的支持,就是说元模板的描述对象和解释是和底层造型库及造型方法紧密联系的。
子模板:描述一个简单设计对象的模板,比如说一个子任务的设计对象是一个或若干部件组成。一个简单部件是由若干元部件构成,对应的一个子模板是由若干元模板按一定的组合方式构成。我们现在的造型库是建立在部件级别上的,因而模板也是建立在子模板级别上。一个子任务对应一个子模板。
总模板:我们提出总模板的概念,主要是针对复杂设计对象而言的。总模板和子模板的区别仅仅是在对象的复杂程度上和约束关系上。一个复杂对象内部存在各种约束:位置关系、尺寸关系、操作连接等;而对于一个简单对象内部约束很简单或者没有。总模板对应的是我们协同模板中的总设计任务,即一个复杂的设计对象。对于这个复杂设计对象,其模板并不存在,我们通过将任务分解成一个个可用子模板来设计的简单对象,作为子任务分配下去。然后通过模板复合将一些列子任务合成一个总任务,得到设计对象的总模板。一方面设计数据部分作为这次设计任务的结果;总模板的结构也可以保存下来,以后再要设计类似设计对象或者需要对该设计对象的数据作修改,通过模板可以很方便的实现,不需要再经过复杂的设计过程了。
模板结构文件和参数文件:对于一个模板来描述的设计对象来说,它应该既有对象的结构、属性信息,也有对象的设计数据。对于同一类型的设计对象,其不同之处仅在于参数数据不同,对象的结构是一样的。这类似于面向对象中类和对象之间的关系。模板一方面描述设计对象的结构,另一方面是表示具体设计对象的结果。所以我们将模板的结构和参数分开,模板结构文件是描述模板结构的信息,也就是设计对象的结构;模板参数文件是描述模板参数数据的,也就是设计对象的设计数据信息,子任务的设计结果其实就是一个子模板参数文件。
模板复合:我们借助模板的复合来实现各个子任务的合成和装配。借助模板复合操作,设计对象的装配过程演变成了子模板的复合,大大降低了任务合成的复杂性,而且可以更好的控制对象的装配。
我们的协同模板所做的任务是针对一个还有没有相应模板的设计对象,通过总设计者任务分解,也就是将设计对象分成一系列子任务,每个子任务是由一个或若干相关的部件组成,他们有相应的子模板对应。也就是说将设计对象分解成一系列可以由子模板来进行的子任务。然后通过任务的分配、子任务的设计提交、子任务的复合,最终得到设计对象的模板。将该模板保存起来,以后再遇到该设计对象的设计问题时,可不需要再进行任务划分过程,只要利用已有的模板和模板操作工具,就可以很容易地进行该对象的设计。所以协同模板的过程不仅是完成一个新的设计任务的过程,更主要的是产生新的设计对象的模板、保存设计任务并重用及扩充模板库的过程。
协同模板的过程主要有任务数据库的创建,任务的划分、发布与分配,子任务的设计、提交,子任务的复合与检测等主要功能模块,其中涉及到任务的申请和竞争,任务前趋图的产生和任务的控制,设计要求文件的产生,设计者之间的信息交流,模板的复合与解释等主要问题。协同模板设计整体流程如下:
1)总设计者设计之前,先搜索模板库看是否有模板和相应的任务匹配。如果有模板存在,则只需进行模板协同编辑工作即可。如果没有则进行下一步工作。
2)总设计端根据设计任务的外部约束、整体约束规则、部件位置关系、操作连接信息等创建相应的任务数据库(通过任务数据库创建接口)。
3)总设计者将设计任务划分为一系列子设计任务,根据任务数据库的约束信息产生任务前趋图,发布任务。每个子任务由一个或若干个相关部件组成,并且有相应的子模板对应。任务前趋图用于反映任务的串并行关系并控制子任务的进行。
4)子设计端可以显示任务发布信息和前趋图信息,并进行子任务的申请和竞争。总设计者根据子任务申请状态来进行任务的分配或者强行进行子任务的分配。
5)任务分配后,子设计端接到分配的子任务和子任务设计要求文件,如果该子任务没有前趋任务或者其前趋任务都已完成,则子设计者可以进行子任务的设计;否则子设计者必须等到其子任务的所有前趋任务都完成了才能开始子任务的设计。
6)子设计者进行子任务的设计,设计依据是子模板结构文件和子任务设计要求文件,设计结果是子模板参数文件。设计完成后子设计者提交设计结果。
7)总设计端接到子设计端提交的子任务(子模板参数文件)后进行模板复合,实时解释设计结果,检测提交子任务的正确性。如果无错则确认子任务结果,子任务由提交状态变为完成状态。子任务确认后,激活该任务的后继子任务并且将相关信息传递给受之约束的其他子任务。其他子任务接到激活信息后,判断其前趋任务是否都已经完成,如果没有则继续等待,否则该子任务也可以开始进行设计。
8)在设计过程中,并行任务之间、存在环约束的子任务之间需要交流设计信息,我们提供了文本通信、语音通信、白板***等协同交流手段供设计者之间进行信息交流。
9)所有子任务完成之后,总设计端进行检查、验证看结果是否符合设计要求。如果满足则任务完成保存设计结果的模板。否则,将那些不符合设计要求的子任务退回重新进行设计。重复进行前面的过程,直到设计结果符合要求为止。
根据上一节协同模板的整体流程,***按照功能模块可以分为以下几部分。
1)任务数据库及其创建
任务数据库设计任务要求、约束信息,装配关系、操作连接信息等数据库中记录了设计对象的整体约束信息和各子部件之间的约束关系和位置关系等信息,以及记录子任务分配信息、子模板文件等信息。这个数据库是划分子任务的依据,而且在整个设计过程中其内容也是不断更新的。它也是模板复合时的依据。任务数据库是通过我们提供相应的输入接口来产生的,当然也可以手工输入。
2)模板匹配模块
根据一定的规则去查找、匹配模板,以判断是否已经存在模板与设计任务相对应。但是如何根据设计任务的信息去查找、匹配模板,目前还没有很好的解决办法,此模块留待以后扩充实现,暂时只留一接口。
3)任务划分、任务前趋图的产生和子任务的分配
任务划分模块将设计任务划分为各个子任务,并且将子任务信息保存起来,更新任务数据库;根据子任务间的约束信息产生任务前趋图,以反映各个子任务之间的前趋后继关系,也就是任务串并行关系。将任务信息及前趋图发布给各个子设计端。
子任务分配模块主要是用于分配子任务,并根据任务数据库中跟该子任务相关的约束设计信息产生子任务设计要求文件,并传递给子设计者。
4)子模板定制模块(子模板创建器)
根据模板库中对相应子模板的定制和设计,子模板结构的确定。这也是解决子模板来源问题的一个途径。子模板设计时根据子模板结构框架进行设计,增加相应的部件信息,部件尺寸信息及约束信息等。此模块接口留待以后扩充完善。
5)子任务设计模块
子任务设计模块,主要解决如何子任务根据子任务所用的子模板结构文件和子任务设计要求文件进行子任务的设计,并将设计结果以子模板参数文件的形式保存起来。
6)子模板参数与结构的分离和结合模块
协同模板中一个重要的环节是实现模板的参数和结构分离,并且在子任务设计时利用模板结构文件进行子任务设计,设计结果保存为参数文件。提交子模板参数文件作为设计结果,对于子模板参数文件的解释必须在与对应的子模板结构文件结合后才可进行。
7)子模板解释器
对子模板文件进行解释分为两步,首先读取XML模板文件,将相关信息读出并存入相应的数据结构(部件信息),然后从给定的数据结构中获得数据,依据零部件的几何特点形成三维模型。
8)模板复合器
依据任务数据库,在总设计者端对已提交的子任务参数文件进行复合。模板复合器能够对具有逻辑顺序的若干子任务进行复合,而不仅仅是对所有子任务的复合。
9)总模板解释器
模板解释器读取模板文件的部件、约束、位置、操作和连接等信息,并解释为相关的模板造型信息,然后进行部件的几何造型。
网络协同交流与控制方法
“消息”与文件通信机制
基于协同模板的协同设计方法,主要采用Socket通信的方式进行各个设计端之间的互连与交流。设计者之间除了要进行消息——任务发布、申请、分配等协同消息的传递以外,还要进行模板文件——包括设计要求文件、模板的结构文件、参数文件等的相互传输。类似于这些的交流都是通过建立Socket连接实现的。“消息”通信机制
基于协同模板的协同设计方法,利用了基于“消息”的通信机制,将设计中对三维信息模型的编辑操作包装为网络传输的“消息”,大大减少了网络传输中的数据量,并较好的实现了三维信息模型的协同编辑技术。
在本方法中,消息的传递机制是这样的,当一个设计端发出操作或控制命令时,***将此消息命令通过网络传递给服务端,通过服务端将此消息转发给其他客户端,各个客户端获得消息后,在本地***中查找对应于此消息的消息处理函数,执行后得到相应的操作效果。这种方式可以实现三维信息模型的协同浏览、三维信息模型的协同编辑等功能。下面一节将具体介绍三维信息模型协同编辑功能的实现。
将所有的操作命令和控制命令归纳为一个消息类CMsg,通过一个消息类和一个消息处理函数联系起来,当设计人员进行一个操作的时候,***根据消息类型查找到相应消息处理函数执行操作。消息类格式如下:
CMsg∷CObject
{
int type; //消息的类型号
int EntityID; //操作三维信息模型的实体ID号
CPoint pstart,pend; //操作的参数
…… //其他参数
};
其中,type为消息的类型号,唯一的标示消息的类型,这样便于识别不同的消息并进行相应的操作,消息的类型号定义为一个枚举型的结构;EntityID项指操作三维信息模型的实体ID号,在对大型三维信息模型进行编辑操作时,如何标示对模型中哪一个三维实体进行操作,***提供实体ID的概念,通过ID来唯一标示实体;CMsg类中其它成员变量都为此消息的操作参数值,对于不同的消息操作参数具有不同的几何涵义,例如Block消息用于产生一个长方体,它的操作参数为特定坐标系下的两个三维点,分别为长方体对角线上的两点;
***根据不同的操作和控制命令,定义了几十种消息,用枚举型结构MsgType说明。消息的类型定义如下:
enum MsgType
{
Requestcontrol, //请求控制权消息
Block, //绘制矩形消息
Intersect, //实体“交”运算消息
Material, //三维信息模型中材料属性消息
…… //其他消息类型
}
对应于不同类型的消息有一个相应的消息处理函数,***定义了消息处理函数类CHandleMsg,此类中为每一个消息定义了一个处理函数,下面为此类的C++伪代码,其中每一个函数都与上面MsgType中消息相对应;
class CHandleMsg
{
BOOL HandleBlockMsg(CMsg*Msg);//处理绘制长方体消息
BOOL HandleIntersectMsg(CMsg*Msg);//处理实体“交”运算消息
BOOL HandleMaterialMsg(CMsg*Msg);//处理三维信息模型中材料属性消息
………… //其他消息处理函数
}
消息在网络上的传输分为服务端和客户端两种,根据消息类和消息处理函数的定义,我们相应的定义了负责消息传输的数据结构。在服务端的数据结构如下:
class CCollaborate
{
CListenSoeket m_ListenSoeket; //监听套接字
CArray<CConnectSocket*,CConnectSocket*>m_connectSocket;
//已连接客户端套接字链表
BOOL Broadcast(CMsg*pMsg); //广播消息
…… //其他成员
}
其中,CListenSocket和CConnectSocket都派生自CSocket类,m_ListenSocket为服务端的监听Socket,监听客户端的连接;m_connectSocket保存了所有已经连接上的客户端套接字;服务端从客户端接收到消息之后,会使用Broadcast函数来将此消息广播到所有其它的客户端;在客户端数据结构相对简单,它只需要有一个与服务端连接的套接字,同时可以接收来自服务端的消息和向服务端发送消息。
消息的传递通过WinSock技术实现,充分使用了MFC提供的CSocketFile和CArchive类来实现CSocket类数据通信,网络上传递的数据信息都通过序列化把数据发送到网络文件中,当相应的套接字上有可读信息到来时,Windows Sockets DLL就会发出WM_READ消息通知应用程序调用相应的函数在该套节字上读取数据。在数据的发送和接收过程中,调用各自相应的序列化函数对网络文件进行操作,减轻了开发的工作量。
在协同模板的操作中关键涉及到以下几种消息:
PublicMission:总设计端发布任务给子设计端的消息
DisplayPublicInfo:总设计端通知子设计端显示发布任务的消息
AssignMission:总设计端分配任务给子设计端的消息
ApplyMission:子设计端向总设计端申请任务的消息
ShowMsg:设计端之间相互通知任务进程及设计状态的消息
AquireStatus:子设计端向总设计端询问任务状态的消息
StatusBack:总设计端向子设计端传递查询的任务状态的消息
ChangeAfterMission:子设计端完成设计任务后更新其约束的后继任务的状态的消息
ChangeStatus:总设计端通知各子设计端改变相应任务的状态的消息
CompleteMission:总设计端通知提交完成设计任务的子设计端设计结果已经通过检查、确定完成的消息
CancelMission:子设计端放弃任务设计的消息
CheckJoinAfterPublic:子设计端加入协同时检查是否接收过总设计端发布的任务信息的消息
设计端接收到消息后根据消息的类型进行相应的操作和反应,以达到协同通信与控制的目的,操作函数主要有:
BOOL HandlePublicMsg(CMsg*Msg);
子设计端接收到总设计端的发布任务信息后的操作函数
BOOL HandleApplyMsg(CMsg*Msg);
总设计端接收到子设计端申请信息后的操作函数
BOOL HandleAssignMissionMsg(CMsg*Msg);
客户端接收到总设计端分配的任务后的操作函数
BOOL HandleShowMsg(CMsg*Msg);
子设计端接收到总设计端显示信息后的操作函数
BOOL HandleAquireStatusMsg(CMsg*Msg);
总设计端接收接收到子设计端要求获取任务状态信息后的操作函数
BOOL HandleStatusBackMsg(CMsg*Msg);
子设计端接收接收到总设计端任务状态信息后的操作函数
BOOL HandleChangeAfterMissionMsg(CMsg*Msg);
子任务完成后改变其约束任务的相关数据及界面函数
BOOL HandleChangeStatusMsg(CMsg*Msg);
各设计端接收到任务状态改变消息后的操作函数
BOOL HandleDisplayPublicInfoMsg(CMsg*Msg);
子设计端接收到发布任务消息后的操作函数
BOOL HandleCompleteMissionMsg(CMsg*Msg);
子设计端接收到设计任务被通过后的操作函数
BOOL HandleCancelMissionMsg(CMsg*Msg);
总设计端接收到子设计端放弃进行设计任务消息的操作函数
BOOL HandleCheckJoinAfterPublicMsg(CMsg*Msg);
总设计端接收到子设计端加入协同后要求检查是否在发布信息后加入的消息的操作函数
文件的通信
为了实现设计端之间文件的交流,建立了文件Socket。文件的传输主要是实现xml格式的模板相关文件在设计端之间的传输,包括要求文件、设计结果参数文件以及模板文件的传输。
任务的发布
总设计者在任务前趋图产生之后,将任务通过函数CCommission∷Public()发布给各个连接的子设计端。发布的过程如下,首先利用消息传输通过循环发送的方式将任务信息传输到各子设计端,传输的任务信息的内容:任务ID,受其约束的任务的ID,该任务设计的部件名称,任务的次序,约束的类型,任务锁的数目等等。其次,通知子设计端显示发布任务信息。任务的发布是针对各个连接的子设计端进行的,且发布的任务信息是初始的任务状态。当用户在总设计端发布任务之后再加入连接时,同样可以接收发布信息,此时该信息则反映了当前最新的任务状态。
任务的申请与分配
在子设计端接收到发布的任务信息之后,通过函数CCommission∷Apply()可根据自身需求向总设计端申请设计任务,对于申请来说,各子设计端的地位是平等的,申请时将本地的主机名称及ip地址传至总设计端,供其参考和抉择。总设计端在接收到来自各地的申请信息之后,可以根据子设计者的请求,分配其相应的子任务,或者根据划分的任务分配各子任务。分配过程主要通过函数CCommission∷Assign()来实现:记录本地分配状态,更新本地显示,告知被分配的子设计端并通知各子设计端改变任务状态,继而将相应的设计要求文件传输与之。
总设计端的申请与分配信息单独记录于任务申请信息链表CArray<ApplyCommission.ApplyCommission>m_applyList和任务分配信息链表CArray<AssignCommission,AssignCommission>m_assignList之中。
协同串并行参数的交流
任务前趋图反映了任务的串并行关系以及前趋任务对于后继任务的约束关系。存在约束的串行的任务以及并行任务之间存在参数的交流,每一个任务都受制于约束其若干设计参数的前趋任务,即前趋任务的完成驱动后继约束任务,当设计任务通过检查完成后便通知其后继子设计端任务已完成的消息,子设计端打开相应的任务锁,当所有的任务锁被打开后,子任务被激活,即需要的约束参数全部设计完毕,子设计者方可开始设计任务。串行任务之间的参数传递主要是通过程序控制消息的传递,不需要设计者之间的交流。而并行任务之间的参数交流则主要通过设计者之间选择性的沟通和交互,灵活性更强。