1. 引言
飞行数据记录了飞机各系统的工作状态和飞行员的操作过程,对指导飞行、地面保障和科学研究都具有重要的意义 [1] [2]。随着航空技术的发展,需要记录数据的种类和数量越来越多。不同型号飞机记录的数据类型存在非常大的差异 [3],同时飞机在生命周期内也存在增加记录数据类型的需求,这给配套的地面数据处理系统提出了较高的要求。不同数据单独记录并配套专用的地面数据处理软件是当前飞行数据记录普遍存在的现状 [4] [5] [6] [7]。随着电子技术的进步和对飞行数据需求的提高,综合采集和地面通用处理已成为未来飞行数据应用的趋势。通用飞行数据地面处理系统用于完成多种航空记录数据的地面管理和使用,与传统的飞行数据地面处理系统相比,存在以下特点:
(1) 数据集中存储,不同客户端完成对数据的操作;
(2) 支持数据源即数据类型的扩展;
(3) 支持数据应用方式扩展;
这里面最重要的是数据类型的扩展,只有有效解决了在不改动原有程序的前提下实现新数据类型的扩展,处理系统才真正实现了通用性,这也是目前地面处理系统没有解决的难题。本文将研究利用.NET反射技术实现飞行记录数据源扩展,进而实现飞行数据地面处理系统的通用性设计。
2. 飞行数据通用地面处理系统
飞行数据通用地面处理系统用来实现不同单位、不同机型飞行记录数据的地面综合管理、调度和基本使用。为了实现机载记录数据的有效管理和使用,通用飞行数据地面处理系统还需要具备管理人员、设备、用户的功能。具体来讲,通用飞行数据地面处理系统功能包括数据卸载与上传、数据解码、数据预处理、数据管理与调度、数据处理、数据回放、系统管理等,详细内容如图1所示。

Figure 1. Function schematic diagram of data synthesize process system
图1. 数据综合处理调度系统功能示意图
1) 数据卸载与上传。系统通过客户端从机载记录设备或者转录设备中卸载数据,也可在客户端将数据写入到记录设备或者转录设备,并且可以删除记录设备或者转录设备中指定的数据。
2) 数据解码。为了用户能够操作和使用数据,系统需要将原始数据解析为有物理意义的数值数据。
3) 数据预处理。在机载记录数据卸载到客户端之后、存储到数据服务器之前,需要对数据进行野值剔除、滤波、和初步的数据处理工作等。
4) 数据管理和调度。对飞行数据进行管理是数据综合处理调度系统的一项重要内容,数据管理内容包括数据的浏览、检索、查找、数据保护和数据处理。系统还必须具有数据调度的功能,即将不同用户需要的数据合理分配到正确的客户端,并将经过客户端修改后的数据更新到数据服务器。
5) 数据处理。数据处理包括对数据信息、事件标签、部门日志和对数据本身的编辑和处理,其中对数据本身的处理又包括数据精简、压缩、删除等。
6) 数据回放。数据回放是将记录数据内容进行再现的过程,包括飞行过程回放、参数曲线、数据表格、音视频回放等。系统将用户选择数据从服务器传递到用户所在客户端以后,由客户端完成数据的回放。
7) 数据应用。系统将用户选择数据从服务器传递到用户所在客户端以后,用户在客户端完成对数据的应用。对数据的应用方式包括事件报表、故障诊断和其它扩展的应用方式。
8) 系统管理。为了保证系统正常运行,系统还需要对用户、设备、飞行员、参数库、数据应用方式等内容进行管理。
3. .NET反射技术
.NET的反射技术是指软件在运行过程中动态发现类型信息的能力 [8]。软件系统有时需要在运行时处理一些信息,而这些信息在设计时是未知的。反射支持后期绑定,并且允许程序与设计时未知的代码进行交互,因此反射技术极大地提高了.NET程序的可扩展性。反射技术可以在主程序开发完成后,在不改变原有代码的前提下实现程序扩展,这也是反射技术的价值所在。
要理解反射技术首先要熟悉程序集(Assembly)的概念。在.NET平台中,软件组件是以程序集的方式存在的,它包含模块,而模块包含类,类又包含成员。程序集是.NET所采用的应用程序的构造模块,它替代了以前的EXE与DLL程序结构,构成了部署、版本控制、重复使用、激活范围控制和安全权限的基本单元 [9]。程序集具有以下优点:
1) 形成安全边界。程序集是请求和授予权限的单元。
2) 形成类型边界。每一类型的标识均包括该类型所驻留的程序集的名称。
3) 形成引用范围边界。程序集的清单包含用于解析类型和满足资源请求的程序集元数据。它指定在该程序集之外公开的类型和资源。该清单还枚举它所依赖的其他程序集。
4) 形成版本边界。程序集是公共语言运行库中最小的可版本化单元,同一程序集中的所有类型和资源均会被版本化为一个单元。
5) 形成部署单元。当一个应用程序启动时,只有该应用程序最初调用的程序集必须存在。其他程序集(例如本地化资源和包含实用工具类的程序集)可以按需检索,按需加载。
反射技术支持显式加载一个程序集、动态发现类型和类型成员的信息,以及调用这些类型和成员的操作。反射通常具有以下用途 [10] :
1) 使用Assembly定义和加载程序集,加载在程序集清单中列出的模块,以及从此程序集中查找类型并创建该类型的实例;
2) 使用Module获取模块的程序集以及模块中的类等信息;
3) 使用ConstructorInfo获取构造函数的名称、参数、访问修饰符和实现详细信息等;
4) 使用MethodInfo来获取方法的名称、返回类型、参数、访问修饰符和实现详细信息等;
5) 使用FieldInfo来获取字段的名称、访问修饰符和实现详细信息等,并获取或设置字段值;
6) 使用EventInfo来获取事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,并添加或移除事件处理程序;
7) 使用PropertyInfo来获取属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,并获取或设置属性值;
8) 使用ParameterInfo来获取如下的类似信息,如参数的名称、数据类型、参数是输入参数还是输出参数,以及参数在方法签名中的位置等。
4. 反射技术在地面处理系统通用性设计中的应用
.NET的反射技术支持晚绑定,允许程序与设计时未知的代码进行交互,因此具有强大的可扩展性,合理利用.NET的反射技术可以实现地面处理系统的通用性设计。地面处理系统通用性设计的关键在于通用解码器的设计,通用地面处理系统的解码器不仅能够对所有已有的数据源进行解码,同时还需要能够扩展新的数据源中的新数据类型。而不同类型数据源的数据存储格式存在较大差异,用同一个解码器来实现所有数据类型的解码是不现实的。本文采用的方法是采用一个动态解码器集来实现不同类型数据的解码,用户可以通过.NET反射技术添加新的解码器到动态解码器集来扩展新数据源,解析器根据数据文件头中包含的数据类型信息确定是否属于本身处理的数据。
4.1. 定义IParameterAnalyze接口
IParameterAnalyze接口规范了参数解析器需要实现的功能,每个解析器类都必须实现该接口。IParameterAnalyze接口的定义如图2。

Figure 2. Interface structure of parameter analyzor
图2. 参数解析器接口结构
该接口提供了参数解析相关的四个方法,各方法的详细解释如下:
1) 确定解析器是否适用于该类型的记录数据
Boolean FlightFileVerify(String flightFile,out FlightFileInfo filghtInfo);
2) 完成对源文件进行数据解析
Boolean DataDecode(String SourceFile, List
Parameters,out List
parametersValue, out List
IncidentReports);
3) 提供该解析器包含的所有参数的详细信息
List
GetAllParametersInfo();
4) 参数校准;
Boolean ParameterAdjust(String planeNo, String nickName, List
adjustItems);
4.2. 创建解析器集
为了保证后续数据类型的动态扩展,系统应包含私有的、一个长度可变的IParameterAnalyze接口列表即解析器集,用来记录已注册的所有数据解析器。
List
_ParameterAnalyzator = new List
();
4.3. 开发适用的新解析器,并在数据库或配置文件中注册该解析器
每个新数据源都必须提供相关的解析器类,每个解析器类必须继承IParameterAnalyze接口并实现其所有的方法。新数据源解析器开发完毕后,需要在配置文件或数据库中注册新解码器信息,包括解析器类、所在程序集等,然后系统才能使用新解析器。
4.4. 解析器集加载
系统读取保存在数据库或配置文件中的解析器信息,并通过反射技术建立所有解析器实例,并添加到动态解码器集_ParameterAnalyzator中。下面为从数据库中读取解析器信息,并建立解析器的示例代码。
//**************************************
String setFile = curRow[解析程序集].ToString(); //读取解析集文件
if (File.Exists(setFile))
{
Assembly a = Assembly.LoadFrom(setFile); //载入解析器所在程序集
String analy = curRow[解析器].ToString();
foreach (Type curAnaly in a.GetTypes())
{
String name = curAnaly.Name;
if (name == analy)
{
IParameterAnalyze newAnalyzor = (IParameterAnalyze) a.CreateInstance (curAnaly.FullName); //创建解析器实例
break;
}
}
}
//**************************************
新数据源对应的解析器被加载、添加到动态解析器_ParameterAnalyzator以后,就可以利用该解析器实现对新类型数据源的参数解析。
5. 结论
通过引入.NET反射技术,可以动态扩展航空客观检查飞行记录数据类型,进而保证飞行数据地面处理系统通用性设计。扩展新数据类型只需要开发新的解码器组件并注册组件信息就可以实现,而不需要改动和重新编译生成已有系统。因此,利用.NET反射技术既可以实现数据源的灵活扩展,又可以避免原有系统被修改的风险。