城轨列车虚拟司机控制台的研究
2014-11-29孔繁虹
张 亮,孔繁虹
(同济大学 电子与信息工程学院,上海 200331)
列车驾驶仿真系统对驾驶环境的逼真度要求比较高,驾驶环境可分为视景环境与司机室控制台环境,本文主要研究司机控制台环境。在城轨列车司机培训系统中,涉及到许多司机室的控制设备和显示器件,单纯的图片和基于MFC的二维绘图是无法满足其逼真的要求,而利用OpenGL绘制三维模型则需要大量的点、线、面等基础元素进行绘制,建模过程费时费力,同时又无法通过材质赋予来增加形象感。3DS Max具备强大的建模与环境渲染能力,通过在3DS Max中建立司机控制台的模型,再对其进行合适的材质赋予以及灯光设置,能够得到一个逼真的司机室控制台模型。最后再编写程序,以VC++2005为平台,基于OpenGL函数包,对建好的模型进行显示与控制。该方法能够提高学员模拟驾驶的真实感。
1 司机控制台模型的建立
1.1 司机控制台的结构
司机控制台是司机培训系统的直接接口,在列车运行过程中,与司机关系最密切的是司机控制器和开门、关门按钮,以及紧急情况下的紧急按钮,除此以外,司机控制台上还有大量的控制转换开关、按钮以及仪表和指示灯,这些控制及显示设备可采用计算机模拟的方法实现。本文以上海3号线司机室控制台为实体样本,图1是上海3号线司机控制台的全景图。
图1 司机控制台结构
从图1可知,整个司机台共有7个面板、1个司机显示屏、1个主控器。要逼真模拟司机室,当司机的操作引起列车状态发生变化时,应该在虚拟控制台上有所反映。例如当司机按下关左门按钮,列车的左门将被关上,当确认门已关上并锁闭后,门关好指示灯将会亮。当驾驶控制手柄移动至牵引时,在控制台上速度表也要根据牵引计算之后反馈回来的速度做出响应显示,同时对于后续工作中的视景画面的变化也要产生影响。这样,控制台和司机之间就实现了交互性。
1.2 软件环境介绍
3DS Max是基于PC系统的三维动画渲染和制作软件,其广泛应用于影视制作、学习娱乐、建筑装潢、机械制造等行业。3DS Max具备强大的建模能力,用户可以在较短的时间内迅速建立起复杂模型,弥补了OpenGL构建复杂模型的局限性。然而模型在3DS Max中缺乏与用户的交互性,难以实现实时控制,所以不能直接用于仿真。因此,本文将结合OpenGL技术和3DS Max技术,以VC++2005为平台,在OpenGL绘图环境中读取构建好的司机控制台3D模型并驱动控制。
1.3 模型建立的过程
构建司机控制台模型的过程如图2所示。
图2 建模过程
确定司机控制台所需的尺寸数据、材质贴图等信息:可以通过查阅资料以及翻阅3号线司机手册及现场接触实物等方式收集;基础模型建立:利用3DS Max提供的基本模型对象、扩展模型对象、二维线等进行构建司机控制台的基本轮廓模型,3DS Max提供了布尔命令、可编辑多边形等高级三维建模命令,利用这些命令可以组合、修改出不规则、复杂的司机控制台模型,可以在修改堆栈器中添加所需的命令。针对司机控制台上众多的设备器件,对其进行分类建模、以面板为单位,从而可以提高开发周期。设备器件大致可以分为以下几类:旋钮、按钮、指示灯、仪表、显示屏、主控器等。其中主控器模块主要包括钥匙、模式选择开关、司机控制手柄。每个子模块都有自己的行为动作,因此对其分开建模;纹理材质赋予:对以上建好的模型进行必要的纹理赋予、材质贴图等细化,以提高司机控制台模型的逼真度;灯光渲染:赋予材质后的模型必须要添加一些光照才会令模型看起来更有体积感、层次感,同时和材质的相互配合使模型更加的逼真;模型最终优化、渲染:通过观察渲染之后的模型,针对局部需要调整的部分进行参数更改优化。
在3DS Max中构建的司机台模型渲染之后的效果图如图3所示。
图3 司机控制台渲染结果
2 司机控制台模型的读取与控制
2.1 司机控制台模型文件的读取显示
利用第三方软件将在3DS Max中建好的模型转换成OpenGL的格式文件后添加到工程项目中读取、显示,但是会出现一些纹理、材质贴图丢失问题,这就使得读出来的模型缺乏逼真度。通过定义一个类,利用编制程序来进行对3D模型的读取与显示。读取的司机控制台模型文件是.3DS格式,按照.3DS文件结构读取。
3DS文件结构由块组成,其层次结构如图4。而块由ID和下一个数据块的位置组成。每个块是一个层次结构,由ID表示,3DS文件都有一个主块,ID是0x4D4D,这个主块正是程序读取3DS文件的入口。此外还有两个主要块是编辑块和关键帧块,编辑块用于描述3D对象的数据,关键帧块用于描述关键帧数据。材质块的读取也是读取3DS文件的主要步骤。
程序在读取块时根据ID值来确定当前读取的是哪个信息块,然后再对具体的信息块内容进行读取。需要编写用户自定义函数读取文件的字符串信息、子块信息、颜色信息,顶点信息、多边形信息、纹理坐标、对象材质等信息,可以定义各自的结构体存放数据、信息。例举几个主要的读取函数定义,如下:
int Read3DSChunk(FILE*fp, Chunk3DS&chunk);//读入块
int ReadColor(FILE* fp, float& red, float&green, float& blue);//读入颜色
int ReadPointArray (CTriObject* newchild,long fileSize, FILE *fp);//读入顶点坐标
int ReadFaceArray (CTriObject* newchild,long unsigned fileSize, FILE* fp);//读入多边形
int ReadMeshMatGroup(CTriObject*newchild, MaterialDict* matdict, long fileSize,FILE* fp);//读入材质
在读取块时还要注意文件指针的偏移量,需要跳过一些不需要读取或者还不了解的块,程序中可以加入如下代码处理块的跳过。
fseek(fp, chunkStart + chunk.len, SEEK_SET)。
在编写读取3D模型文件程序时,首先搭建OpenGL编程环境,本文在MFC框架下搭建,新建一个基于单文档的MFC工程项目,为OpenGL设置好窗口属性及风格,以及像素格式。
cs.style |=WS_CLIPCHILDREN | WS_CLIPSIBLINGS;//设置窗口属性、风格
定义OpenGL自己的设备上下文,同时与Windows的设备描述表联系起来。
m_pDC = new CClientDC(this)。
调用OpenGL的库函数进行图形读取显示、重绘等。程序在读取模型时,将模型的面、体等信息以三角形定点的形式存储于链表中,利用OpenGL提供的API函数来进行绘制。如设置当前颜色glColor3f(float red,float green,float blue)、设置法线向量坐标glNormal3f()、设置顶点坐标glVertex3f()。
在视口函数OnSize(UINT nType, int cx,int cy)中需要添加窗口缩放时的图形变换函数glViewport(0,0,cx,cy)用于对窗口和显示比例进行调整。
模型的显示是通过函数OnDraw(CDC* pDC)对绘制3DS文件绘制函数Draw3ds()的调用来实现。
在退出程序,即窗口销毁时需要释放设备上下文。即在OnDestroy()函数中delete m_pDC。
根据前面读取到的顶点、三角面、纹理坐标信息等调用OpenGL的函数库进行对象绘制、纹理绑定等工作来完成对司机控制台的读取显示。读取模型文件的流程图如图5所示。
在MFC单文档视图下司机控制台的导入效果如图6所示。
图4 3DS文件的层次图
图5 读取3DS文件的流程图
2.2 司机控制台模型的控制
由于3DS Max坐标系和OpenGL坐标系存在差异如图7所示,所以在读取显示程序时要进行坐标转换,并且为了提升培训的效果,针对导入进来的司机控制台模型需要进行合适的移动、旋转、缩放等控制,以便取得一个良好的视角,纵览司机台模型的全貌。
图6 MFC视图下的司机台模型
图7 OpenGL和3dsmax的坐标系
实现缩放动作的做法是根据模型的最大最小坐标和场景中实际需要的高度和宽度来进行比例缩放。可以使用OpenGL提供的函数glScalef(GLdouble x,GLdouble y,GLdouble z),x、y、z的值就是模型在三维空间轴上的倍增值。
使用函数glRotatef(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)来实现对模型的旋转,使用右手定则,拇指从原点(0,0,0)指向函数中点的参数(x,y,z),按照四指弯曲指向旋转角度angle。
使用函数glTranslatef(GLdouble x,GLdouble y,GLdouble z)实现对模型的移动,x、y、z分别是模型沿三轴移动的位移。
同时,需要为程序添加鼠标事件响应,以建立模型与用户之间的交互性。如添加WM_ONLBUTTONUP、WM_ONLBUTTONDOWN、WM_ONRBUTTONUP、WM_ONRBUTTONDOWN、WM_MOVSEMOVE。
下面以对模型进行缩放为例,阐述鼠标事件函数之间的联系。
当函数OnRButtonDown()执行后,调用鼠标捕获SetCapture()同时将变量mouserightdown标志为TRUE并记录好点击的位置坐标;当函数OnRButtonUp()执行后,释放鼠标捕获ReleaseCapture(),同时将变量mouserightdown标志为FALSE;这样当OnMouseMove()函数执行时会首先判断变量mouserightdown的值,若为真,则执行将鼠标移动的位移转换为对模型缩放倍增值的大小,并调用函数OnDraw()来实现视图的重绘。
3 结束语
本文利用VC++2005中MFC为平台,基于OpenGL函数库,实现对3DS Max建立的虚拟司机控制台的读取与控制,基本完成了本文所要实现的功能,该方法对城轨列车模拟驾驶系统的仿真有着重要意义。
[1]潘修强. 利用Open GL和3DSMAX构建复杂模型[J].浙江工贸职业技术学院学报,2006,6(4).
[2]陈玉军,张 琦,苏凡囤,郭 霞. 基于MFC的Open GL仿真与3D模型的获取[J].现代设计技术,2005 (4).
[3]吴 斌,段海波,薛凤武. Open GL编程权威指南[M].北京:中国电力出版社,2001.
[4]叶华平,朱 鸣,钱雪军. 通用桌面模拟驾驶台的研究[J].城市轨道交通研究,2012(4).
[5]陶 静,孔繁虹. 桌面型地铁驾驶仿真系统的研究[D].上海:同济大学,2010.