曾培彬
(中国民用航空汕头空中交通管理站 技术保障部,广东 汕头 515000)
航空器的航迹重绘是空中交通管制(以下简称“空管”)过程分析、事件复盘分析的重要工具,广泛应用于事件调查、不安全事件分析等空管运行保障中[1-2]。空管的现场技术维护通常也需要设计相关的航迹分析系统用于现场运维。其中如若涉及航迹重绘,独立的航迹分析系统需要设计相应的记录航迹数据模块,后期分析需要重绘时则回放自定义记录格式的数据,这种方式将会占用更多系统处理的资源,同时也需要花费更多的人力对相关模块进行开发。虽然当前空管自动化系统具有相关的记录航迹的文件,但是多数是基于设备厂家的内部数据流文件,数据格式复杂也不开源,这使得现场技术保障的分析利用而言也不容易实现。ADS-B(Automatic Dependent Surveillance-Broadcast,广播式自动相关监视)则是当前民航空管大力推进应用的技术,可以自动从相关机载设备获取参数并向其他飞机或地面站广播飞机的位置、高度、速度、航向、识别号等信息,以供管制员对飞机状态进行监控。目前,民航空管系统已基本完成ADS-B地面站和数据站的部署,可以实现管制区域的基本覆盖。ADS-B地面站是接收航空器数据的第一个节点,目前中南地区站主要采用九州公司生产的地面站设备并配套相应的集中监控软件,该软件可以实现一个月内的区域内多个地面站的航迹回放,记录有本地管制区域内的航迹数据。本文基于该地面站集中监控的ADS-B记录数据提出一种航迹重绘方法,为相关技术改造抛砖引玉。
九州公司生产的ADS-B地面站是民航中南地区的ADS-B地面接收设备,覆盖了广东、广西、湖南、湖北、海南、河南六个省空域,分析其数据记录有一定的推广意义。九州公司ADS-B地面站的监控终端每个小时生成一个.cat文本文件,用于记录区域内所有地面站监视到的目标的历史报文数据。主要记录的格式为“时间戳+地面站IP+Cat021报文”,随着时间戳的增长,系统将顺序记录区域内不同地面站所监视到的所有目标报文信息,因此,重绘算法只需要按顺序从文件开始遍历到文件结束即可。Cat021(Asterix Category 021)是欧洲航空安全组织一系列标准文件的一部分,主要包含数据项目录、数据块、数据类、数据字段、数据项、记录和用户应用程序框架UAP(User Application Profile)。其中,UAP是一种数据规范,不同版本的Cat021有不同的UAP。数据项可以根据UAP分配到具体的数据字段,并且每个数据项都有相应的字段参考号,数据项的出现也可以通过UAP进行判断[3]。Cat021明确定义了ADS-B报文数据项和其组成的序列,描述了各个数据项的内容和适用的范围,通常是由十六进制数据组成,主要组成有包类型、长度、字段、描述符等数据项。九州公司的ADS-B地面站记录数据主要采用V0.26版本报文,其UAP部分信息如表1所示。
表1 九州地面站Cat021报文UAP部分信息
ADS-B的字段描述符对后续的十六进制字符串里的数据项做了标明,根据字段描述符解出存在的数据项并对照UAP表里的数据项格式进行解析可以得到数据项信息。
Cat021报文解析步骤如下:
(1)判断原始数据是否为Cat021格式(根据报头);
(2)从第六个字符之后开始以两个字符的长度读取并将十六进制转成二进制,按顺序从左至右记录存在的数据项索引并判断最末尾二进制数是否为1,如果为1,则继续往后读两个字符长度并重复上述操作,为0则终止;
(3)将步骤(2)中记录的数据项索引对照UAP表按顺序进行数据项解析得到具体数据。
用户对报文数据项的获取需要查找对应的数据项结构,例如若需要对飞行高度进行获取需要解析数据项I021/145,其由2个二进制数据组成,一个二进制数据有8位,第1位定义位LSB标识为1/4个飞行高度层,剩余各个数据表示飞行高度,将其对应转化为十进制即是以LSB为单位的所需飞行高度,其他数据项也有相应的格式转换,用户只需要按照Cat021给定的规范进行解析即可完成ADS-B各个数据项的信息获取。
航迹重绘至少需要考虑目标航迹的识别要素、历史位置,通过历史位置将航迹的轨迹重绘。用户需要通过航迹的识别要素(例如航班号、二次代码、24位地址码)实现对具体航迹的分析,主要通过对记录数据的相关数据项检索。当前主流的计算方法是通过报文数据项划分先提取出报头部分,获取报头信息(主要包括类型、长度、字段描述符等),结合字段描述符和UAP可以将报文数据报尾部分依次按照数据项组成序列依次分割,获得各个数据项的原值[4]。对于数据记录文件,这种方法需要对记录文件中的Cat021报文进行解析后再逐个与用户提供的目标航迹对比。
对于航迹识别要素的检索,以航班号为例,在解析航班号数据项时,按正常的解析流程,先将表示航班号的十六进制字符串(长度为12个字符)转换成二进制字符串(共48个字符),再对二进制字符串以每六位一组进行分割,可将其分为八组,代表航班号的八个字符,将六位一组的二进制字符串转换成十进制数并对应航班号对照表(按照文件规范,可以在程序中定义变量表chars=“ABCDEFGHIJKLMNOPQRSTUVWXYZ#####_###############0123456789######”)得出航班号,然后与目标航班号进行比较。 这个过程不可避免产生大量的报文文本分割计算,实践表明字符串的分割计算对算法的执行效率影响较大,耗时较多。ADS-B地面站记录数据文件,除了需要重绘的目标航迹报文还有区域内的其他目标信息报文,以民航汕头空管站所在中小型机场所辖区域为例:一个正常的ADS-B地面站记录文件有500万行至600万行的报文数据,而一个航班完整的航迹重绘需要基于1-2个文件,如若是广州区域管制中心所辖的大型高空区域,分析的数据量更大,如若对报文数据一一分割并将航班数据项直接转换,系统需要进行航班号字符串分割、字符转换等预处理后再针对用户提供的航班号进行航迹报文检索,同时也占用大量的系统资源对非关注的航迹报文进行处理,算法对于计算机的计算性能要求将更高,基于此方法的航迹分析耗时将无法估计,算法执行效率低,用户体验差。本文提出的方法是先将用户提供的航班号转换为报文内部的十六进制格式字符串(例如航班JYH1173,根据上述chars转换表可以逆向转换为十进制数字符串“10 25 8 49 49 55 51” ,进而转换二进制字符串为“001010 011001 001000 110001 110001 110111 110011 100000”,最终转换为Cat021的十六进制报文字符串格式),直接检索相应记录数据Cat021报文中对应的十六进制字符串,并在检索得到的报文中获取航迹坐标、高度和速度等数据项。此方法避免了对记录数据的所有航班字符串数据项的分割、转换和对比,提高算法数据处理性能。另一方面,方法按照文件名和记录文件中的时间戳存储报文数据当前时间与上一次获取到的该目标报文数据时间戳的差,当时间差超过20 min认为航班数据已结束可以不继续检索报文数据,提前结束检索运算。此方法完成一个航迹重绘耗时在15 s以内,符合相关技术改造的要求。
数据项获取完毕后除了具体位置的绘制还需完成相应信息的标注,航迹标牌是航迹信息标注的主要形式,也是航迹分析的关键要素。当前主要的设计方法有两种,一种是直接通过控件加载完成绘制(如采用GMap.NET地图的Markers层添加标注点,采用Marker点表示目标[5]),一种是直接通过软件编译平台调用画笔绘制相应的图标或文字[6]。前者实现简单快捷却占用资源较大,目标数据量较多的情况下对硬件要求较高。后者在设计上则由于设计思路的不同,方法流程各式各样,但多数设计需要采用较为复杂的算法。此处采用第二种方式进行重绘,结合实际工作经验实现简洁的、用户满意度较高的航迹标牌重绘。
航迹标牌用于显示飞机在途经该航路点时所处的状态信息,标牌内的信息可以包括航迹的航班号、二次代码、24位地址码、速度、高度和爬升下降率等目标状态信息以供用户分析。由于形成航迹的点数较多,如若所有位置点都标注标牌将出现大量重叠显示的标牌,界面绘制复杂的且不符合实际需要,结合实际经验,此处每隔3分钟对目标航迹进行标牌标注,并提供标牌可隐藏功能。当然,即便如此,标牌在绘制过程中依旧不可避免会重叠显示,为了用户能够全面、清楚获取相应航迹信息,标牌的重绘需要提供航迹标牌拖动功能,实现对重叠标牌的分别显示读取。另一方面,为了降低操作复杂度,很多航迹重绘也同时提供了基于鼠标动作的地图缩放和拖动,因此实际中用户实现根据自身需要进行标牌拖动和地图的缩放,必须对方法的标牌图形化进行进一步的设计,主要考虑地图缩放、拖动以及航迹标牌自身拖动带来的航迹标牌坐标绘制影响,需满足实现的功能:鼠标按下左键如若是在标牌范围内则方法判断为用户需要拖动标牌,如若在无标牌的区域则方法判断为用户需要拖动地图。
通常,航迹标牌的图形化构成是由目标位置点、引线(用于连接目标位置点与标牌中心点)、标牌外框以及内部的文本信息组成。由于航迹重绘初始化时,航迹标牌的位置与目标航迹的相对位置是固定的,因此,可以基于标牌中心点坐标完成对其绘制。方法定义变量列表List
在软件实现上,首先根据在ADS-B记录文件中获取的相关信息初始化标牌坐标并在地图上绘制显示。当鼠标点击时,会触发鼠标按下事件的响应,当鼠标左键产生点击时会进入标牌坐标范围的判断。因为存在多个标牌重合的情况,所以在判断存在标牌内部之后还需求出鼠标与这些重合的标牌哪个距离更近,识别对应需要拖动的目标标牌。
判断鼠标当前位置是否处于标牌内部以及获取目标标牌的算法如下(以C#设计为例):
(1)获取当前鼠标的所在的屏幕坐标:
Point choose = Control.MousePosition;
(2)循环遍历屏幕中的所有标牌并判断鼠标位置是否位于标牌内,如果鼠标位于标牌内,则计算当前标牌与鼠标坐标位置的直线距离:
distance = (choose.X - label_center_point[j][i].X) ^ 2 + (choose.Y - label_center_point[j][i].Y) ^ 2;
(3)找出直线距离distance为最小值时的标牌即为鼠标选择的标牌。
实现该算法,可以定义int类型变量label_min以及label_index用于记录当前找到的最小直线距离以及对应的标牌索引,label_min的初始值需设的足够大,至少应比屏幕的对角线距离更大。循环遍历标牌时,如果鼠标在标牌范围内,则求出直线距离distance并与label_min进行比较,如果distance的值小,则将值赋给label_min并更新label_index标牌索引的值,如果label_min的值小,则保持不变。在循环遍历完所有航迹标牌时,如果label_min的值与初始值不同,说明鼠标在标牌范围内并且拖动了该目标标牌,如果label_min的值与初始值一致,说明鼠标不在所有标牌的范围之内,此时判断为触发地图拖动操作。实现流程见图1。
图1 标牌绘制流程图
航迹标牌和地图的绘制函数置于timer()时间控制器中调用,实践表明将timer()时间设置100毫秒(即每100毫秒进行一次标牌背景地图的绘制)可以满足实际工作需要,当鼠标选择标牌并进行拖动时,需时刻更新被拖动标牌的中心点坐标与相对位置坐标。所以当触发鼠标移动事件时,通过变量Point label_mouselater时刻记录鼠标的位移量并立即更新被拖动标牌的中心点坐标label_center_point和相对位置坐标label_temp,完成标牌位置绘制的更新。
本文从实际出发,提出一种基于ADS-B记录数据文件的航迹重绘方法,通过改变检索设计思路实现了在ADS-B记录文件中快速获取用户关注航迹相关信息,并提供了在标牌绘制等地图处理方面的相关思路,最终通过C#设计实现。该方法应用于中南空管局科技项目,完成了对航迹的历史轨迹快速重绘,用户体验较好。此处的总结和分享可以为相关航迹重现分析方面的技术改造提供一种参考。