朱湘龙,于天朋,侯 师
(1北京理工大学,北京 100081;2国营304厂,福建三明 365000)
现代战争越来越依赖于复杂、昂贵的武器系统。由于新型武器系统的复杂性,要形成战斗力必须反复训练其使用者,其相比于传统武器更依赖于熟练的使用者。而新型武器系统一般价格昂贵,实弹训练费用高,很难像传统武器系统一样采用大规模的实弹训练,严重阻碍了其战斗力的快速形成。针对这种情况,各国普遍为新型武器系统开发相应的虚拟训练系统,以较低的成本和较好的效果完成使用者的初步训练。
虚拟训练系统设计的难点在于高度仿真的虚拟视景设计。传统虚拟训练系统大多采用OpenGVS、Vega等软件设计虚拟视景,但这些软件有价格高、开发难度较大、视觉沉浸感不够优秀等问题。法国VIRTOOLS公司的Virtools是一款非常优秀的、大量应用于游戏领域的三维交互软件。它能将现有常用的虚拟视景档案整合在一起,如3D的模型、2D图形、音效等构成三维交互系统[2]。Virtools采用图形化编程语言。开发人员无需编写底层代码,只需要拖动打包好的行为模块(building block)即可构建优秀的三维交互系统,开发难度小,Virtools软件本自带了大量打包好的行为模块供开发者调用。其三维引擎已获得微软Xbox认可。Virtools主要用于网络游戏领域,与实物系统数据通信能力较为薄弱,未提供标准模块。文中深入分析了Virtools的运行机制和Virtools SDK开发构架,通过调用回调函数,完成了基于Virtools SDK半实物串行通信接口的设计。
本虚拟训练系统由仿真弹筒和仿真计算机两部分组成。仿真弹筒用于模拟导弹发射的全过程,给受训者真实的触觉感受。仿真计算机主要功能是虚拟视景的生成和弹道仿真。虚拟视景经过渲染之后输送到虚拟瞄具,给受训者逼真的视觉感受。虚拟训练系统通过音箱播放训练过程音效给受训者逼真的听觉感受。仿真弹筒为本系统的实物部分,仿真计算机为虚拟部分。两部分中间通过全双工异步串行通信接口连接进行通信,如图1所示。通信接口设计重点在串口通信行为模块(SerialBB)的设计。SerialBB通过Virtools行为模块实现。在每一个仿真周期内,SerialBB读取一组仿真弹筒发送的数据,然后解包,提取执行本帧所需数据,传送给虚拟视景,供虚拟视景运行。
图1 虚拟训练系统总体构架
Virtools是一个实时引擎,能对自身场景变化做出实时准确的反应。一个Virtools场景只有一个系统进程,也是单线程运行。因而其能够自行决定其任务的优先级,让所有任务在Virtools本身的时间轴上实时的运行,而不受宿主非实时操作系统的限制。
Virtools视景执行过程中,以帧的方式在自身时间轴上推进视景进程。每一帧内按固定的时序执行一次过程循环,如图2所示。最先执行的是管理预处理,在此Virtools会运行视景脚本中的管理预处理模块。然后执行的是行为模块,视景脚本中的行为模块依次运行。执行完毕后进入后置管理处理段,在此执行视景脚本中的后置管理模块。执行完毕后对场景进行渲染,完成一帧的执行。
图2 Virtools帧结构
本虚拟训练系统中,Virtools虚拟视景不仅需要对自身场景中的事件做出实时准确的反应,还需对仿真弹筒上的操作做出实时的反应。而仿真弹筒时序以现实世界的时间轴为基础。所以虚拟视景时间轴需与现实世界时间轴有可解析关系。因此,本虚拟视景采用固定帧率的方式运行。确定好虚拟视景帧率之后,仿真计算机性能足够的前提下,虚拟视景时间轴能与现实世界的时间轴同步。因而就实现了仿真弹筒时间轴与虚拟视景时间轴的同步。
Vrtools虚拟视景在事件发生时会调用相应的回调函数来处理。在本虚拟训练系统视景运行过程中主要的事件有:打开VT、开始执行视景、停止视景、暂停视景、复位视景。经测试事件和回调函数对应关系如表1所示。
表1 回调函数调用逻辑
Virtools软件架构高度模块化。图3所示为其API整体构架。所有的Virtools可执行程序都是在该架构上通过动态链接库(DLLs)的形式实现的。其核心组件有两个DLLs:CK2和VxMath。VxMath提供较为底层的函数;CK2提供核心的行为函数,并且负责管理关联其他组件。本系统设计的SerialBB就是通过调用CK2和VxMath提供的API实现的[1]
图3 Virtools API整体构架
SerialBB中行为模块框架通过调用Virtools API实现。串口打开/关闭时序部分通过回调函数实现。串口通信部分、数据处理部分通过调用Win32 API实现。
3.1.1 行为模块框架实现
行为模块软件结构包括5部分,通过这5部分就能实现行为模块框架。
1)Plugin信息注册函数:该函数用于Plugin信息的注册,调用CKGetPluginInfo()函数创建了指向CKPluginInfo结构类型的指针对Plugin版本号、插件类型、作者等相关信息进行指定,调用CKGetPluginInfo-Count()函数获取注册的Plugin的个数。上述两个函数将最后生成的DLL文件声明为Building Block Plugin,该 Plugin用来执行 BB,BB的执行是 Building Block Plugin的一部分。最后调用 RegisterBehavior-Declaration()函数注册Building Block Plugin将要执行的BB,完成对BB的注册。
2)BB声明函数:该函数用于BB描述函数的声明,通过调用CreateCKObjectDeclaration()创建CKObjectDeclaration类型的指针,该指针指向BB描述函数结构体。通过该函数指定BB的类型、版本号、功能等相关参数和信息。
3)BB创
建函数:该函数用于BB实体的创建,包括输入输出接口、输入输出参数接口、功能函数指定等。函数用CreateBehaviorPrototype()创建CKBehaviorPrototype类型的指针,用来指向将要创建的BB原型的函数。创建函数则只有在BB真正使用的时候才会被调用。
4)BB执行函数:该函数用于定义BB的行为功能,是BB的核心。BB的每次调用都会执行该函数。BB执行过程中参数处理过程为:首先用ActiveInput()函数激活模块的输入端,开始执行模块。然后调用函数GetInputParameterValue()从参数入口读取输入参数。然后对参数进行处理,处理完成之后通过SetOutputParameterValue()函数将处理结果输出到参数输出口,供其它模块调用。模块每次调用都会更新输出端口值。参数处理完毕后停止模块运行并激活模块输出端口,标志BB的一次调用完成。
5)BB回调函数:该函数用于对一些特定事件(如键盘、鼠标等)做出响应,以及对BB是时间依赖还是帧依赖做出选择[1,5]。
以上5部分函数依靠指针按图4所示顺序执行,实现行为模块框架。
3.1.2 串口开关逻辑切换实现
虚拟视景状态流图如图5所示。系统正常运行需保证计算机COM口在视景停止和暂停状态为关闭,在视景运行状态为开启。
对照表1经分析,最后选择在回调函数CKM_BEHAVIORRESUME中调用打开串口函数,在回调函数CKM_BEHAVIORPAUSE和KM_BEHAVIORRESET中调用关闭串口函数。从而保证计算机COM的开关时序[6]。
3.1.3 串口通信部分的实现
图4 行为模块软件构架
串口通信部分通过调用Win32 API中的文件操作函数实现。打开串口通过调用CreateFile()函数实现。发送数据通过调用WriteFile()函数实现。接受数据通过调用ReadFile()函数实现[3-4]。串口的打开和关闭在回调函数中实现。程序运行到BB执行函数时BB被激活。程序首先初始化参数,然后向仿真弹筒发送握手信号,如果收到握手成功的反馈信号则将握手成功位置位,否则在BB下一次激活时继续给仿真弹筒发送握手信号直至成功握手。成功握手后,BB在每个帧循环都会调用ReadFile()函数从计算机COM口读取一组数据。经过解包和数据处理之后输出供其它模块调用。直至 BB不再被激活。因为Virtools以基于帧的方式运行,所以行为模块程序本身并不需要写循环,图中帧循环是通过Virtools脚本实现的。这种方式可以保证程序读数周期与Virtools运行周期相同。
图5 虚拟视景状态流图
图6 SerialBB程序流程图
图7 串口行为模块
程序编译之后生成SeialBB如图 7所示。SerialBB模块输入端和输出端相连,形成一个循环,每帧结束后都会激活输出端,然后由输出端激活输入端,保证在下一帧时SerialBB仍旧处于激活状态。
将SerialBB集成到Virtools行为脚本中测试发现半实物接口能够很好的工作,仿真弹筒发送的数据都及时、准确的到达了虚拟视景。虚拟视景实时的对仿真弹筒的操作做出了正确的反应。虚拟弹筒的瞄准过程、发射信号等都能实时准确的反应到虚拟视景,并由虚拟视景仿真出来。系统整体运行流畅,未出现可觉察到延迟现象,受训者感受到预期的沉浸效果。视景在各种操作组合下,计算机COM口都能正确的在打开和关闭状态间切换,避免了异常数据接受。
文中在Virtools SDK开发构架下,通过调用Virtools API和Win 32 API完成了虚拟训练系统半实物接口的设计和开发。通过合理的使用Virtools回调函数,准确地控制了接口的开关逻辑。实现了基于Virtools虚拟训练系统仿真弹筒和仿真计算机的实时通信。
这些工作是针对计算机COM做的,但并不局限于COM口。在相同的构架下,通过其它Win32 API的调用理论上能实现任意计算机支持的接口与Virtools虚拟视景间的通信。
[1]VIRTOOLS.Virtools SDK Documentation[S].FRANCE:VIRTOOLS,2006.
[2]王立群,李红.简明教程[M].上海:复旦大学出版社,2008.
[3]艾塞明格.Win32开发人员参考库[M].北京:机械工业出版社,2001.
[4]龚建伟,熊光明.Visual C++/Turbo C串口通信编程实践[M].北京:电子工业出版社,2007.
[5]杨国平.Virtools SDK初探[J].程序员:游戏创造,2006,6:73-75.
[6]吴明勋.VIRTOOLS使用手册(一)[M].台湾:爱迪斯通股份有限公司,2006.
[7]陈定方,罗亚波.虚拟设计[M].北京:机械工业出版社,2007.