魏 辉,刘 春
(沈阳航空航天大学航空航天工程学部,辽宁沈阳110136)
飞行器航迹在数字地图上的显示可以让用户了解较大范围内的飞行环境,目前常见的航迹显示方法或组件大多借助一些第三方工具开发。本文给出一种借助于图像处理和可视化开发技术实现的航迹显示方法。主要实现的功能包括对二维电子地图的平移缩放操作及飞行器航迹的实时显示。鉴于实时仿真对时间效率要求较高,航迹显示部分采用了高效的算法及一些时间控制策略保证航迹显示与飞行器实际飞行轨迹的同步性。电子地图采用最常见的JPG格式文件,不仅可以借助于图像处理技术方便的进行操作,而且地图资源的获取非常容易。本文给出的实现方法完全可以借助计算机编程语言自主开发实现,有效的解决了开头提出的问题。
该方法主要包括两大功能:地图操作和航迹显示,如图1所示。
图1 航迹显示系统组成
地图操作通过鼠标的移动和点击实现。在地图界面内按下鼠标并移动,地图会跟随鼠标进行相应的移动。选择好放大或缩小状态,然后在模块界面内双击鼠标,就可以实现地图的放大或缩小。地图采用的是普通的JPG格式文件。
航迹显示部分通过动力学模型提供的接口接收飞行器的位置信息,然后把动力学模型实时解算的飞行器位置变换为电子地图上相应的位置并显示。随着飞行器位置的不断变化,航迹也进行同步的刷新。
整个显示界面如图2所示。在图形框内按下鼠标左键并移动,地图会跟随鼠标相应移动;选择放大或缩小按钮,然后在图形框内双击鼠标,地图就会按一定比例放大或缩小,航迹也会跟随地图等比例放缩。
图2 航迹显示界面
地图及航迹的显示在一个图形框中实现。地图采用的是一张JPG文件,在程序开始运行时将其局部作为背景显示在图形框中。当前窗口只显示地图文件的一个局部,可以用鼠标移动地图以观察不同的区域,也可放大或缩小地图以扩大或减小当前显示的范围。
当移动或放缩地图时,当前显示的内容就会发生变化。由于整个地图文件较大,如果直接从整张地图文件中读取要显示的部分,会大大增加程序的响应时间,甚至对整个仿真程序的正常执行产生影响。因此,这里专门开辟一个缓冲区,程序从该缓冲区而不是原地图文件中读取要显示在窗口中的地图数据,很好的解决了以上问题。
为方便阐述,区域的表示采用式 (1)中的格式
其中,Z为区域的名称,x,y分别为区域Z左上顶点在原地图文件中以像素为单位的横坐标和纵坐标,且向右表示x坐标增大方向,向下表示y坐标增大方向。width表示区域Z的以像素为单位的宽度,height表示区域Z的以像素为单位的高度。原地图文件的表示方法与此类似,并以原地图文件的左上顶点为坐标原点。
缓冲区的大小如图3所示。图中阴影部分为当前窗口显示范围,设为S(x,y,width,height)。B为当前缓冲区的范围,B的长度和宽度分别为S长度和宽度的3倍,且S位于B的中央,所以B可以表示为B(x-width,y-height,3*width,3*height)。这样,无论在显示窗口中怎样操作地图,将要显示的内容都在缓冲区中,所以要显示的地图可以从缓冲区直接加载,提高了地图操作指令的响应速度。每次地图操作完成后,由于S发生了变化,B也要进行相应的更新。B的更新要从原地图文件读取数据,因此需要的计算时间相对较长,同样会造成响应速度慢的问题。为了解决这一问题,B的更新放在两次地图操作的中间进行。上一次操作完成时即开始更新缓冲区,这时B锁定为不可用状态,直到更新完毕恢复可用状态。在B处于不可用状态时,程序不响应用户的地图操作。这种缓冲区更新方法充分利用了用户两次操作之间的时间空隙,提高了计算机计算能力的利用率和地图浏览的流畅程度。
图3 缓冲区
地图操作分为平移和放缩两种。首先设置一个全局的放缩系数m,用m去控制当前显示地图块的宽度和高度。当执行一次放大操作,m减小一个固定的步长d,当前显示地图块的范围变小,由于显示窗口大小不变,就表现为地图的放大,反之地图则缩小。地图平移的距离通过捕捉鼠标在显示窗口内按下左键时移动的距离获取。
以图3为例,加上放缩系数,则当前显示区域为S(x,y,width*m,height*m)。假设鼠标在显示窗口按下左键并向右平移a个像素单位,向下平移b个像素单位。则平移后的窗口显示区域为S'(x-a*m,y-b*m,width*m,height*m),缓冲区则相应更新为B'(x-width*m-a*m,y-height*m-b*m,3*width*m,3*height*m)。
执行一次放大操作时,放缩系数m减小步长d,变为m'=m-d。放大后显示范围的中心点为执行放大操作时鼠标在显示窗口中点击的点。若当前显示区域为S(x,y,width*m,height*m),鼠标双击点在地图中的坐标 (需要从窗口坐标转换成地图中的坐标)为 (x',y'),则放大一次后显示区域变为S'(x'-width*m'/2,y'-height*m’/2,width*m’,height*m’)。缓冲区则相应更新为B’(x’-3*width*m’/2,y’-3*height*m’/2,width*m’*3,height*m’*3)。缩小时与此类似,只需将放缩系数增大步长d。
飞行器的实际飞行轨迹为一条连续的曲线,但在飞行仿真中,必须先将飞行器的航迹离散化,变成一个个的航迹点,通过一系列的航迹点去描述飞行器的飞行,然后再把离散的航点还原为连续的航线显示出来。本方法从动力学模型中实时获取飞行器当前的航迹点后,通过一定的算法把当前航迹点和上一个航迹点之间的航线计算并显示出来。
首先设置两个集合A和B,A中为所有从动力学模型中获取并转化为用地图文件中像素坐标表示的航迹点,B中为通过计算得到的航线上的所有航迹点 (航线在地图文件中是通过一个个的像素点表示出来的,所以可以把航线上的所有航迹点都列举出来)。航迹显示一个刷新周期的流程如图4所示。
图4 单个刷新周期
动力学模型中提供的航迹点是用经纬度坐标表示的,应用本方法时需转换为地图文件中的像素坐标。以图5为例,图5中方框表示地图文件的边界,地图左上顶点的经纬度坐标为 (lon1,lat1),像素坐标为 (0,0)。地图右下顶点的经纬度坐标为 (lon2,lat2),像素坐标为 (width,height),其中width为地图的像素宽度,height为地图的像素高度。
则对于地图范围内的任意一点A,已知其经纬度坐标为 (lon,lat),其像素坐标 (x,y)按式 (2)和式 (3)得到
图5 坐标转换
由于程序从动力学模型获取航迹点的时间间隔非常小(一般在30毫秒左右),所以把这段时间内飞行器飞过的航迹近似为一条直线段。这样问题就转化为已知一条直线段的两个端点坐标,求直线段上某些点处的坐标,这可以根据直线段所在直线的方程求解。具体到本问题,还需要做一些特别的考虑。
计算两航迹点之间的航线,如图6所示。
图6 计算两航迹点之间的航线
以地图文件的左上角为坐标原点建立坐标系,A(x1,y1),B(x2,y2)两点为从动力学模型中获取的相邻两个航迹点。则线段AB上的任一点C(x,y)有两种求法 (此处假设x1≠x2且y1≠y2):
(1)已知x坐标,可求得y坐标
(2)已知y坐标,可求得x坐标
在x和y坐标为连续实数的情况下,上面两种方法产生的结果相同。而这里的x和y表示的是在地图文件中的像素坐标,为离散的整数值,这就会导致按照式 (4)和式(5)计算可能产生不同的效果。
要想把A和B之间的航线计算出来,必须计算出线段AB经过的每个像素点的坐标。在A点和B点坐标已知的情况下,可以从x1到x2遍历x从而按照4式求出对应的也可以从y1到y2遍历y按照5式求出对应的x(当求出的值为非整数时按四舍五入取整)。设A和B两点横坐标的距离为△x,纵坐标的距离为△y。当△x<△y时,若按照4式遍历x求相应的y值,就会出现y1和y2间有些y值没有对应的x值,按照像素构成图形的原理这就会使显示出来的线段AB在这些地方出现间断,不能满足显示连续航线的要求。此时若按照5式遍历y求出各个x的值,则x1和x2之间的每个x都有对应的y值,y1和y2之间的每个y也都有对应的x值 (只不过有些y对应相同的x),这样就不会出现上述问题。综上,计算航迹点A,B之间航线的方法是
△y<△x时,按照4式遍历x求相应y
若x1=x2,此时可以遍历y坐标,令各y处对应的x值均为x1。y1=y2时类似的遍历x即可。
航线的显示是通过对当前缓冲区中的像素点进行处理实现的,也即把航线显示在缓冲区中。这样当显示窗口从缓冲区加载要显示的内容时就同时把飞行器飞过的航线也加载并显示给用户。例如要把飞行器飞过的航线显示为红色,只要在地图缓冲区中把航线所经过的像素点的颜色设置为红色即可,这可以通过图像处理中的像素处理函数实现。这里选择把整个缓冲区内的航线表示出来而不是仅把显示窗口中的航线表示出来主要有两个原因:一是考虑到在显示航线的同时用户有可能会对地图进行操作,这样当前窗口显示的内容就会发生变化,把航线显示在缓冲区中可以使用户移动地图时航线不会消失而且航线和地图是作为一个整体移动,视觉效果更好;另外若仅在窗口显示范围内把航线显示出来,当操作地图时需要同时绘制航线,增加了算法的计算量,使程序响应变慢。
飞行器的航线有可能会超出缓冲区的范围,只有在当前缓冲区范围内的部分才需要显示,因此在缓冲区中表示航线的时候要首先判断航线是否在当前缓冲区范围内。这只需根据航线上每个点与缓冲区范围的坐标关系进行判断。随着用户对地图的操作,缓冲区也在不断的变化,随之缓冲区中的航线就要重新绘制。前文中提到存放航线上所有航迹点的集合B,每次缓冲区更新时只要遍历B中所有航迹点,将处于新缓冲区范围内的航迹点绘制出来即可。
飞行器当前的位置也需要显示出来。把从动力学模型最后获取的航迹点作为飞行器当前的位置,以该位置为中心连同周围的点一起形成一个点集,把该点集中的点以相同的颜色显示出来表示飞行器当前的位置,这样显示的效果会比较明显,便于观察。
3.3 节介绍的是对于飞行器已经飞过的固定的航线部分的显示,在实时仿真中,飞行器的位置一直在变化之中,航线也一直在动态的更新,这就要求航线的显示要能实时跟随飞行器的位置。
每次从动力学模型获取一个新的航迹点后航线就要刷新,此时若将已飞过的全部航线刷新显然不是最佳方法。前文中给出了存放所有从动力学模型获取的航迹点的集合A,每次从动力学模型获取一个航迹点,首先按照3.2节中方法计算A中最后一个航迹点与最新获取的航迹点之间的航线,并将计算出的航线位于当前缓冲区中的部分绘制到缓冲区中,同时更新飞行器当前位置,然后把计算出的航线上的所有航迹点加入到集合B中,最后将最新获取的航迹点加入到集合A中。这样每次只刷新飞行器最新飞过的航迹点和上一个航迹点之间的航线,减少了计算量。
将最新飞过的航线绘制到缓冲区后,还需要把当前显示窗口显示的内容刷新,否则最新飞行的航线体现不到当前显示窗口。
在仿真程序中,航线的刷新并不需要与主程序的刷新同步。可以根据需要设置主程序刷新一定的帧数时航线刷新一次,这样可以减少计算机的计算量。
作为实时仿真程序,单线程模型很难满足需要,本方法的实现采用了多线程模型。
程序中开辟了两个线程。由于缓冲区加载需要较多的计算时间,因此单独用一个线程进行处理,除此之外的功能实现则放在另一个线程中处理。这样,当用户执行地图操作触发缓冲区加载的执行时,程序还能继续响应用户的其它操作,否则就要等到缓冲区加载完毕用户才能执行其它操作。这里把加载缓冲区的线程称为加载线程,另一个线程称为主线程。线程工作的流程如图7所示。
图7 线程模型
程序开始执行时主线程处于工作状态,加载线程处于休眠状态。当主线程中触发了缓冲区的加载操作时,加载线程被唤醒。此时加载线程锁定缓冲区,开始缓冲区的加载更新。在加载线程锁定缓冲区时,主线程不响应用户的与缓冲区有关的操作。缓冲区加载完毕时,加载线程释放缓冲区锁,继续进入休眠状态。此时主线程重新开始响应用户与缓冲区有关的操作。
介绍了一种采用图像处理技术实现的飞行器航迹显示方法,该方法可以作为一个组成部分应用在飞行仿真中
。本方法已经成功应用到实际飞行仿真系统中。在Intel酷睿2双核E4500、2GB内存的普通PC机上运行整个仿真程序的同时执行一次航线刷新需要的时间为15ms左右,再加上航线的刷新频率远低于仿真主程序的刷新频率,所以完全能够满足实时仿真需要。
该方法的特点主要在于解决了实际仿真应用中航迹显示的开发多通过第三方软件实现,而且需要用到较多地图绘制和处理专业技术的问题,同时地图资源的获取也更为方便。
[1]LIU Xuanming,LIN Lianlei,JIANG Shouda.Loading of the geographic pictures for digital map [J].Computer Applications,2009,28(10):34-41(in Chinese).[刘轩明,林达雷,姜守达.一种数字地图图片加载方法[J].自动化技术与应用,2009,28(10):34-41.]
[2]LI Yang,SUN Yongwei,XU Yifeng,et al.Design and implementation of platform-type flight simulator[J].Joumalo of Jilin University(Information Science Edition),2009,27(5):550-556(in Chinese).[李洋,孙永维,胥义丰,等.台式飞行仿真模拟器的设计与实现 [J].吉林大学学报 (信息科学版),2009,27(5):550-556.]
[3]NING Tao,WANG Zheng,LONG Chuan.Gen,et al.Application oriented dynamic lo-ading mechanism [J].Computer Engineering,2008,34(17):79-81(in Chinese).[宁涛,王铮,龙川.面向一般应用的动态加载机制 [J].计算机工程,2008,34(17):79-81.]
[4]JIA Fenli,YOU Xiong,SONG Guomin,et al.Implementation of“Magnifier”effect in multi-scale display of electronic map [J].Journal of Geomatics Science and Tech-nology,2009,26(1):29-32(in Chinese).[贾奋励,游雄,宋国民,等.电子地图多尺度显示中放大镜效果的实现 [J].测绘科学技术学报,2009,26(1):29-32.]
[5]WANG Jingcun,CHEN Bin,CHEN Heping.Design and realization of fast map display model for GISsystem [J].Computer Engineering and Design,2007,28(5):1179-1222(in Chinese).[王景存,陈彬,陈和平.GIS系统地图快速显示模型设计与实现[J].计算机工程与设计,2007,28(5):1179-1222.]
[6]HUANG Guoyan,GUO Hui.Study on dataexchange method of CSCD based on XML [J].Computer Engineering and Design,2007,28(24):6000-6047(in Chinese).[黄国言,郭徽.基于XML的协同设计中数据交换方法的研究 [J].计算机工程与设计,2007,28(24):6000-6047.]
[7]MENG Xiaoxuan,LI Yiming,BU Qingzhong,et al.Storage service-oriented BufferManagement model[J].Computer Engineering,2009,35(1):30-32(in Chinese).[孟晓烜,李一鸣,卜庆忠,等.一种面向存储服务的缓存管理模型[J].计算机工程,2009,35(1):30-32.]
[8]LIU Qiaohong.Construction of computer virtual campus and humancomputer interaction technology[J].Computer Engineering and Design,2010,31(19):4332-4335(in Chinese).[刘巧红.计算机虚拟校园的建造与人机交互的实现[J].计算机工程与设计,2010,31(19):4332-4335.]
[9]YUAN Man,ZHANG Leying.Application of dynamic on-demand loading algorithm in GISmap [J].Computer Enginee-ring,2010,36(15):245-247(in Chinese).[袁满,张乐英.动态按需加载算法在GIS地图中的应用 [J].计算机工程,2010,36(15):245-247.]
[10]TANG Yong,LIU Changzhong,WU Honggang.3D flight track and 6-DOF flight simulation based on Google Eatrh[J].Journal of Computer Applications,2009,29(12):3385-3387(in Chinese).[唐勇,刘昌忠,吴宏刚.基于Google Eatrh的三维航迹监视及六自由度飞行仿真 [J].计算机应用,2009,29(12):3385-3387.]