2. 火箭军工程大学作战保障学院,西安市同心路2号,710025;
3. 陆军勤务学院军事设施系,重庆市北一路20号,410331;
4. 91937部队,舟山市,316000
GNSS数据格式和数据类型多样,数据处理模式丰富,处理过程复杂,平差方法繁多。全球和区域各大卫星导航系统都在加快建设、升级与改造,这些都对GNSS数据处理软件的可维护性、可复用性和可扩展性提出了新的要求。目前成熟应用的GNSS软件多数采用面向过程的语言编写,少数采用面向对象的机制,而易维护、易复用、松耦合、易扩展和灵活多样一直是GNSS测量数据处理面向对象软件架构设计的目标[1-2]。随着面向对象技术的深入发展和广泛应用,设计模式(design pattern)为实现该目标提供了丰富的解决方案,并已经逐渐成为系统架构设计分析与开发维护人员开发大型计算程序的首选方案[3-4]。1994年“四人组”(Gang of Four, GoF)最早将设计模式引入软件工程,他们归纳发表了23种在软件开发中使用频率较高的设计模式[5]。文献[6-7]利用设计模式对GIS软件和数字地图制图软件进行设计与重构,解决GIS领域和数字地图制图领域反复出现的问题,提高代码的复用性。GNSS数据处理同时具有数据密集型和计算密集型的特点[8],其处理模式丰富多样,非常适合采用设计模式进行程序开发。而目前对GNSS数据处理软件的研发集中在计算性能方面,多采用执行效率较高的Fortran、C语言开发,尚未见GNSS数据处理软件采用基于设计模式、面向对象机制进行设计与开发。
本文利用其中一些成熟的设计模式,采用其提供的一套通用的设计词汇和一种通用的语言,开发了GNSS数据处理软件GNSSer (GNSS data parallel processer)(http://www.gnsser.com/),使GNSS数据处理方案更加通俗易懂,有效避免各大卫星导航系统在建设、升级和改造过程中出现的设计方案不可重复使用的问题。
1 设计原则与设计模式应用如何同时提高GNSS数据处理软件的可维护性和可复用性是面向对象设计需要解决的核心问题之一,可维护的复用性以面向对象的设计原则为基础。本文利用6种设计原则和6种设计模式提升GNSSer软件结构的设计水平。
1.1 6种面向对象设计原则应用1) 单一职责原则(single responsibility principle, SRP):每个对象只包含单一职责,并被完整封装在一个类中,这就决定了类的粒度大小。当发现类的多重职责时,将其分离、重构,如对解算辅助文件(星历、钟差、天线文件等),采用单个类对某类文件进行所有操作时会降低代码的复用性,更优的解决方式是分别设计数据格式类、读取类、计算类、服务类和生成与显示类,从而实现程序设计的高内聚和低耦合。
2) 开闭原则(open-closed principle, OCP):对GNSS程序的升级与扩展开放,对修改闭合。多频多系统GNSS建设与升级加快,GNSS数据处理的需求随着时间推移、用户群体需要和技术发展而发生变化。当产生新的需求时,应尽量保证软件的设计架构稳定、可延续,抽象化设计是关键技术,顶层设计时可定义一个相对稳定的抽象层,将不同的实现移至具体的实现层。
3) 里氏代换原则(Liskov substitution principle, LSP):所有引用基类的地方必须能够透明地使用其子类的对象。GNSSer顶层设计均采用接口实现,父类对象设计为抽象类或实现父接口,子类实现采用在父类中声明的方法。运行时,子类实例替换父类实例,可以很方便地扩展系统的功能,无须修改原有子类的代码,增加新的功能可以通过增加一个新的子类来实现。
4) 依赖倒转原则(dependency inversion principle, DIP):高层模块不应该依赖低层模块,它们都应该依赖抽象;抽象不应该依赖细节,细节应该依赖抽象。GNSSer开发时针对接口进行编程,而不是针对实现。具体类只实现(多个)接口或继承(一个)抽象类中声明过的方法,尽量不给出多余方法。若出现新的方法,则通过重构改善既有代码设计。
5) 接口隔离原则(interface segregation principle, ISP):不依赖不需要的接口。随着对误差源认识的不断深入、误差模型的精化和GNSS互操作中参数的增加,如系统时间偏差、频间偏差和相位偏差等参数的不断引入,需要在接口中定义精化模型或估计参数的方法,GNSS程序中接口不断增大。不同的实现类不得不实现接口中定义的所有方法,从而使灵活性变差,GNSSer按SRP将其分割成一些更细小、角色相对独立、可提供定制服务的接口。
6) 合成复用原则(composite reuse principle, CRP):优先使用对象组合,而不是继承,来达到复用的目的。继承针对“Is-A”关系,而组合/聚合针对“Has-A”关系,降低了类与类之间的耦合度。
1.2 6种设计模式应用 1.2.1 工厂模式(factory pattern)以构建不同GNSS数据处理模式为例,统一建模语言(unified modeling language, UML)类,如图 1所示。
1) 顶层的接口预先定义为IGnssSolver,包含MatrixBuilder()方法;
2) 抽象类AbstractGnssSolver是接口IGnssSolver的实现,单站、多站和单历元、多历元解算抽象类SingleSiteEpochSolver、SingleSitePeriodSolver、MultiSiteEpochSolver和MultiSitePeriodSolver继承抽象类AbstractGnssSolver;
3) 对于抽象类单站单历元解算器SingleSiteEpochSolver,对伪距定位Pseudo-RangePosition、单频PPP SingleFreqPpp、无电离层组合PPP IonoFreePpp等具体类进行重写。
4) 最终由计算器生成工厂类GnssSolverFactory中的Create()方法构建不同的处理模式。
1.2.2 模板方法模式(template method pattern)模板方法模式定义一个操作中的算法框架,而将一些步骤延迟到子类中。它使得子类不改变一个算法的结构即可重新定义该算法的某些特定步骤。以工厂模式创建的不同GNSS计算器为例,进一步构建不同计算器对应的观测方程,对应图 1中接口IGnssSolver中的属性MatrixBuilder。以采用Kalman滤波进行观测方程构建为例,需要分别构建设计矩阵、观测向量、观测值权阵、初值权阵、转移系数和转移噪声等,具体实现如图 2所示。
1) 抽象模板BaseAdjustMatrixBuilder实现顶层接口IAdjustMaterixBuilder,给出顶级逻辑架构,定义一系列基本操作,这些操作部分是具体的,部分是抽象的,实现了模板方法MatrixBuild(),执行滤波平差方程构建与检核的操作;
2) 抽象类SimpleBaseGnssMatrixBuilder继承BaseAdjustMatrixBuilder,GNSS计算矩阵生成器BaseGnssMatrixBuilder进一步继承SimpleBaseGnssMatrixBuilder;
3) 单站、多站和单历元、多历元矩阵生成抽象类SingleSitePeriodMatrixBuilder、SingleSiteEpoch-MatrixBuilder、MultiSitePeriodMatrixBuilder和Mu-ltiSiteEpochMatrixBuilder继承BaseGnssMatrixBu-ilder;
4) 以单站单历元矩阵生成类SingleSiteEpochMatrixBuilder为例,具体类伪距定位矩阵构建PseudoRangeMatrixBuilder、单频PPP矩阵构建SingleFreqPppMatrixBuilder、无电离层组合PPP矩阵构建IonoPppMatrixBuilder对其继承,实现了对模板方法MatrixBuild()中操作的重写。
1.2.3 职责链模式(responsibility chain pattern)需要GNSS信号对观测值进行众多类型的误差改正。本文采用职责链模式,基于单一职责原则和开闭原则,形成如下5条数据链,分别对观测值进行预处理,以得到“干净”的站星距离。
1) 观测值和产品过滤及卫星位置计算责任链:主要包括移除不参与解算的卫星系统,移除伪距为0和载波为0的卫星、连续观测历元较少的卫星、不可用卫星、小于指定截止高度角的卫星、处在地影的卫星等;进行周跳探测,并选择是否进行修复。在过滤观测值和产品的基础上,建立星历赋值器,迭代循环计算卫星位置和卫星钟差。
2) 不区分频率的通用距离改正链:对流层延迟、引力延迟、固体潮、海潮、极潮和接收机天线参考点归心改正均与频率无关,因此将这些改正项纳入不区分频率的通用距离改正;此外,由于电离层延迟在各个频率之间存在一定的数学关系,因此也将其纳入不区分频率的通用距离改正。
3) 区分频率的距离改正链:对卫星端和接收机端的天线相位中心改正,配置并处理传来的“请求”——每个历元每颗卫星的载波相位观测值和伪距观测值,分别进行各个频率上观测值的相位中心改正。
4) 伪距观测值改正链:不同类型码观测量的硬件延迟存在偏差,需对伪距观测值进行卫星端的DCB (differential code bias)改正。
5) 载波相位观测值改正链:卫星天线和接收机天线间的相对旋转使相位产生误差,对相位观测值进行改正。
1.2.4 迭代器模式(iterator pattern)在C#语言中,Foreach in、IEnumerable等接口都是为迭代器模式准备的。为进一步适应GNSS数据逐历元、流式访问的特点,如图 3所示,GNSSer实现了数据流式操作。
1) 接口IEnumer继承于接口IEnumerable和IEnumerator;
2) 抽象类AbstractEnumer实现接口IEnumer;
3) 数据流式缓存获取器BufferedStreamService、反向数据流获取器ReversedEnumber等继承抽象类AbstractEnumer,上述数据流获取器访问具体聚集器SingleSiteObsStreamer和MultiSiteObsStreamer。
在GNSS数据处理过程中,迭代器的应用也非常普遍,包括:1)采用正向和反向Kalman滤波解算GNSS观测文件,使用迭代器模式实现逐历元流式正向和反向读取;2)采用多种方式遍历星历、钟差、gpt2格网等文件。
1.2.5 单例模式(singleton pattern)定义一个统一的全局变量可以确保对象随时都可以被访问,但不能防止创建多个对象。单例模式就是确保一个类只有一个实例,并提供一个全局访问点访问这个唯一实例。
GNSSer开发中,卫星位置和钟差、太阳和月亮位置等计算都采用了单例模式。本文以卫星位置计算为例,如图 4所示。对于外部代码,不能实例化卫星位置计算,但利用Instance返回一个类实例,通过调用private构造方法实例化。实例化的工作由负责计算卫星位置的类SatellitePositionProvider来完成。该类保证没有其他计算卫星位置的实例可以被创建,并且只提供了一个可以访问该实例的方法。此外,采用SatelliteTimeStorage字典存储卫星位置,多站同时计算时可直接从字典中检索,减少重复计算。
矩阵运算是GNSS数据处理的基础,为使用已经存在的矩阵运算类,GNSSer采用适配器模式,在不同计算模式下统一调用同一接口,这样可以更简单、直接和紧凑。
对已经存在的运算类,如内插、拟合和外推运算等,其方法和要求不相符时,均可采用适配器模式将其利用起来。
2 GNSSer软件利用上述6种设计模式和设计原则,采用C#语言,在.NET 4.5框架下开发了GNSS分布式数据处理软件GNSSer。准备、查看、分析、计算等功能模块相互分离,界面友好,用户体验良好,与用户交互方便。
GNSSer软件在底层采用了云存储、分布式和并行化数据处理技术,致力于大规模、高精度、自动化、云服务的GNSS数据快速处理和服务。该软件可以在Windows系统下运行,具有详细的数据配置和强大的数据处理能力,支持GPS、BDS、GLONASS和Galileo等卫星导航系统的数据处理,已在西安总站和国家自然资源部大地测量数据处理中心的局域网分布式集群中安装部署,处理了中国大陆构造环境监测网络250个基准站2013~2015年的观测数据和某省CORS 7 a(近30万个文件)的观测数据,与GAMIT/GLOBK处理结果的差异为mm级。具体的数据处理实践和应用可见文献[1-2, 9-10]等。
3 结语GNSS的数据类型和处理特点以及不断的升级与改造,对GNSS数据处理软件的可维护性、可复用性和可扩展性提出了新的要求。本文采用6种面向对象的设计原则和6种设计模式,利用设计模式提供的一套通用的设计词汇和一种通用语言,开发了GNSS数据处理软件GNSSer,可有效避免GNSS建设、升级和改造过程中导致的设计方案不可重复使用的问题。
实际上,在GNSSer软件设计、开发与重构的过程中,灵活运用设计模式,实现面向对象的设计原则,将使软件设计更加简洁,软件架构清晰易懂,模块耦合性大为降低,最终提高软件的开发效率、质量和代码的复用性。
[1] |
陈正生.大规模GNSS测量数据分布式计算关键技术研究[D].郑州: 信息工程大学, 2014 (Chen Zhengsheng. Research on the Key Techniques of Distributed Processing on Large Scale GNSS Observation Data[D]. Zhengzhou: Information Engineering University, 2014) http://www.cnki.com.cn/Article/CJFDTotal-WHCH201503017.htm
(0) |
[2] |
崔阳, 陈正生, 吕志平, 等. 非差模式的GNSS数据并行解算设计及实现[J]. 测绘科学技术学报, 2015, 32(6): 565-569 (Cui Yang, Chen Zhengsheng, Lü Zhiping, et al. Design and Implementation of Parallel Processing Strategy for GNSS Data Based on the Undifferenced Method[J]. Journal of Geomatics Science and Technology, 2015, 32(6): 565-569 DOI:10.3969/j.issn.1673-6338.2015.06.004)
(0) |
[3] |
刘伟, 胡志刚, 阎朝坤. C#设计模式[M]. 北京: 清华大学出版社, 2013 (Liu Wei, Hu Zhigang, Yan Chaokun. C# Design Patterns[M]. Beijing: Tsinghua University Press, 2013)
(0) |
[4] |
程杰. 大话设计模式[M]. 北京: 清华大学出版社, 2016 (Cheng Jie. Big Talk Design Patterns[M]. Beijing: Tsinghua University Press, 2016)
(0) |
[5] |
Gamma E, Helm R, Johnson R, et al. Design Patterns Elements of Reusable Object-Oriented Software[M]. Addison-Wesley Professional, 1994
(0) |
[6] |
Gordillo S, Balaguer F, Mostaccio C, et al. Developing GIS Applications with Objects: A Design Patterns Approach[J]. Geoinformatica, 1999, 3(1): 7-32
(0) |
[7] |
肖计划, 刘海砚, 张吉才. 设计模式在地图制图软件开发中的应用[J]. 测绘工程, 2008, 17(5): 4-7 (Xiao Jihua, Liu Haiyan, Zhang Jicai. The Application of Design Pattern in Software Development of Mapmaking[J]. Engineering of Surveying and Mapping, 2008, 17(5): 4-7 DOI:10.3969/j.issn.1006-7949.2008.05.002)
(0) |
[8] |
李林阳, 崔阳, 陈正生, 等. 大规模GNSS网分布式存储与解算方法[J]. 测绘科学技术学报, 2013, 33(5): 464-469 (Li Linyang, Cui Yang, Chen Zhengsheng, et al. A Distributed Storage and Processing Method of Large-Scale GNSS Network[J]. Journal of Geomatics Science and Technology, 2013, 33(5): 464-469)
(0) |
[9] |
崔阳, 吕志平, 李林阳, 等. GNSS大网双差模型并行快速解算方法[J]. 测绘学报, 2017, 46(7): 848-856 (Cui Yang, Lü Zhiping, Li Linyang, et al. A Fast Parallel Processing Strategy of Double Difference Model for GNSS Huge Networks[J]. Acta Geodaetica et Cartographica Sinica, 2017, 46(7): 848-856)
(0) |
[10] |
李林阳, 吕志平, 翟树峰, 等. Galileo/GPS精密单点定位收敛时间与定位精度的比较与分析[J]. 测绘科学技术学报, 2018(2): 159-164 (Li Linyang, Lü Zhiping, Zhai Shufeng, et al. Convergence Time and Positioning Accuracy Comparison and Analysis between Galileo and GPS Precise Point Positioning[J]. Journal of Geomatics Science and Technology, 2018(2): 159-164)
(0) |
2. Operational Support School, Rocket Force University of Engineering, 2 Tongxin Road, Xi'an 710025, China;
3. Military Installations Department, Army Logistics University of PLA, 20 Beiyi Road, Chongqing 410331, China;
4. 91937 Troops of PLA, Zhoushan 316000, China