西西软件园多重安全检测下载网站、值得信赖的软件下载站!
软件
软件
文章
搜索

首页编程开发其它知识 → GPS消息处理通用命令处理类

GPS消息处理通用命令处理类

相关软件相关文章发表评论 来源:本站整理时间:2010/11/2 18:05:47字体大小:A-A+

作者:佚名点击:188次评论:0次标签: GPS。消息处理

  • 类型:音频处理大小:1M语言:中文 评分:5.1
  • 标签:
立即下载

(1)综合运用以前学到的控制语句、继承、封装、接口等知识,完成具有实际运用功能的程序。

(2)通过运用学过的知识进一步的巩固和掌握学到的知识。

实验内容

使用GPS GATE软件模拟GPS卫星发出的GPS信号,编写程序对GPS GATE发出的信息进行接收、解析、处理。将处理好的信息按照固定的格式存储至文件中(经度、纬度、时间、速度、高度)。

下面是主要用到的GPS信息的格式:

1. GPS/TRANSIT Data(RMC)推荐定位信息 (在项目中就使用了这个报文的定位数据)

$GPRMC,(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)*hh(CR)(LF)

(1)UTC时间,hhmmss(时分秒)格式
(2)定位状态,A=有效定位,V=无效定位
(3)纬度ddmm.mmmm(度分)格式(前面的0也将被传输)
(4)纬度半球N(北半球)或S(南半球)
(5)经度dddmm.mmmm(度分)格式(前面的0也将被传输)
(6)经度半球E(东经)或W(西经)
(7)地面速率(000.0~999.9节,前面的0也将被传输)

(8)地面航向(000.0~359.9度,以真北为参考基准,前面的0也将被传输) (9)UTC日期,ddmmyy(日月年)格式
(10)磁偏角(000.0~180.0度,前面的0也将被传输)
(11)磁偏角方向,E(东)或W(西)
(12)模式指示(仅NMEA0183 3.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效)

(13) hh(CR)(LF) hh是前面从第一个数据到最后一个数据的校验和,(CR)(LF)是回车换行,表示一个字符串的结束。

具体示例:

$GPRMC,121212.456,A,3232.1234,N,12121.3322,W,0.15,305.12,121299, ,*22

 

2. GPS Fix Data(GGA)GPS定位信息

$GPGGA,(1),(2),(3),(4),(5),(6),(7),(8),(9),M,(10),M,(11),(12)*hh(CR)(LF)

(1)UTC时间,hhmmss(时分秒)格式
(2)纬度ddmm.mmmm(度分)格式(前面的0也将被传输)
(3)纬度半球N(北半球)或S(南半球)
(4)经度dddmm.mmmm(度分)格式(前面的0也将被传输)
(5)经度半球E(东经)或W(西经)
(6)GPS状态:0=未定位,1=非差分定位,2=差分定位,6=正在估算
(7)正在使用解算位置的卫星数量(00~12)(前面的0也将被传输)
(8)HDOP水平精度因子(0.5~99.9)
(9)海拔高度(-9999.9~99999.9)
(10)地球椭球面相对大地水准面的高度
(11)差分时间(从最近一次接收到差分信号开始的秒数,如果不是差分定位将为空)
(12)差分站ID号0000~1023(前面的0也将被传输,如果不是差分定位将为空)

(13) hh(CR)(LF) hh是前面从第一个数据到最后一个数据的校验和,(CR)(LF)是回车换行,表示一个字符串的结束。

具体示例:

$GPGGA,092204.999,4250.5589,S,14718.5084,E,1,04,24.4,19.7,M,,,,0000*1F

校验和是指这一行的所有非数字字符,按照"字母、空格、句点、正号= 0;负号=1"的规则换算成0和1后,将这一行中原来的全部数字加起来,以10为模计算后所得的和。校验和可以检查出90%的数据存储或传送错误。按十进制加起来的个位数字的校验和,用于精确纠正误差。

 

使用异常处理,对接收信息的过程中可能产生的异常进行处理。(选作)编写C#Winfrom 程序,能够将解析到的数据轨迹绘制到相应的地图上。

详细设计

    该实现主要是实践我在前文《谈谈我处理异常的一般方法》中提出的一些观点,以及一些面向对象设计的思想,和一些设计模式的运用。

    在看到这个问题的时候,首先要对需求进行分析。该问题的数据流程比较清晰,见Figure 1。

Figure 1 数据流

    从个人经验来讲,我认为在指令的解析部分可以抽象出一个比较通用的方式,我们把GPS指令文本流替换为二进制流,将单条指令文本替换为单条指令的二进制信息。

Figure 2 通用数据流

    我做的抽象框架如所示Figure 3 类视图所示。

Figure 3 类视图

    首先我们应当有一个类来处理整个问题,称之为CommandProcessor。它负责从外部设备接收数据、并且将处理后的消息通过事件的方式向外部提供。该类还应当能够将单条指令从流中取出来,因而我在这个类中提供了一个虚的方法GetSingleCommandString(),并且进行了一个通用的简单实现、即每行为一条指令。这里参数都用string来表示了,用string来表示二进制数据也没太大问题,但对于纯文本的数据处理起来则比较方便。

    在将命令分出来之后,我们需要将一条单独的指令转换为一个强类型的命令。我们用ICommand来表示一个被分析后的命令,则问题就是如何由一个string产生一个ICommand。

    根据面向对象设计的一些原则,数据与实现应都放在一个类当中。那么对于特殊的Command,它自身才知道如何对它对应的string进行分析。我们在ICommand中定义Parse(string s)方法对string进行分析。

    ICommand的定义如下,关于DoCommand()方法在后文将有说明。

 01
publicinterfaceICommand
02
    {
03
  
04
        ///


05
        /// If it is right command,return true
06
        ///

07
        ///
08
        ///
09
        boolParse(stringstr);
10
        voidDoCommand();
11
    }
    那么如何找到string->ICommand的对应关系呢?

    比较简单的实现是我们维护一个ICommand的列表,然后用穷举的方式调用Parse方法,直到该方法返回true。如果没有方法返回true,则表示该string是一个未知的命令。这样实现是比较OO,在编程阶段添加ICommand比较方便。缺点是效率比较低,而且还需要维护一个已经实例化ICommand的列表。而有这样一个列表,在多线程编程时就会产生一些同步问题。在编程时需要在Parse(string s)方法中先对传入的string做一个初步检测,如果非该指令则立即返回false。而在当前的设计中,没法对子类重写Parse方法内的内容进行约束,如果实现不好则会更大的造成效率的降低。

    我现在的实现是,引入一个ICommandFactory对象,那么这个问题就成为了string->ICommandFactory->ICommand的问题了,由于实现接口ICommandFactory与ICommand都是同一开发者实现的,该开发者可以分析string的特殊性,在实现ICommandFactory接口的类中找到string->ICommand的关系。还有一个优点是,我们完全可以在自己定义的CommandFactory中实现在上一段提到的方法。以下是该部分具体的实现代码。

publicinterfaceICommandFactory
2
{
3
///


4
/// return an ICommand object from a string.
5
///

6
///
7
///
8
ICommand Parse(stringstr);
9
}

//实现该接口的一个具体示例

01
publicclassGPSCommandFactory : ICommandFactory
02
    {
03
        publicIUnityContainer UnityContainer { get; set; }
04
  
05
        privateICommand Parse(stringstr)
06
            where C : ICommand
07
        {
08
            var cmd = UnityContainer.Resolve();
09
            if(!cmd.Parse(str))
10
            {
11
                thrownewInvalidCommandStringException(str, null);
12
            }
13
            returncmd;
14
        }
15
  
16
        #region ICommandFactory Members
17
  
18
        publicICommand Parse(stringstr)
19
        {
20
            try
21
            {
22
                stringcommand;
23
                command = str.Substring(0, str.IndexOf(','));
24
                switch(command)
25
                {
26
                    case"$GPRMC":
27
                        returnParse(str);
28
                    case"$GPGGA":
29
                        returnParse(str);
30
                }
31
                thrownewInvalidCommandStringException(str, null);
32
            }
33
            catch(ArgumentOutOfRangeException ex)
34
            {
35
               …
36
            }
37
        }
38
  
39
        #endregion
40
    }

    在解决完命令分析的问题之后,最后的一个问题是如何将分析出的命令应用的问题。在这个设计中,我通过事件来通知其他类。

    在前文给出ICommand的描述中给出了一个DoCommand()方法。我们可以在需要应用的项目中重写该方法,做出相应的动作。这样就完全的实现了多态,在接收到CommandReceived事件的消息后直接调用DoCommand()方法就好了,不需要对Command类型进行显示分析。当然,我们需要借助IOC容器来进行这样的实现。这里不阐述IOC容器的具体功能,有兴趣Google下就好啦。当然这样实现也许还是有一些复杂性的,我们需要对每一个Command类进行重写,然后更改IOC容器的映射关系。

    还有一种实现是使用is操作,对ICommand对象进行测试,然后将ICommand中的信息进行利用。下面给出第二种实现方法的一个示例。

01
voidCommandProcessor_CommandRecevied(objectsender, CommandEventArgs e)
02
{
03
    Invoke(newThreadStart(delegate()
04
    {
05
        if(e.Command isGPGGACommmand)
06
        {
07
            ProcessCommand((GPGGACommmand)e.Command);
08
        }
09
        if(e.Command isGPRMCommand)
10
        {
11
            ProcessCommand((GPRMCommand)e.Command);
12
        }
13
    }));
14
 
15
    //throw new NotImplementedException();
16
}

     这样一个基本的命令分析器的Library工程就基本写完了。然后就应当着手解决GPS消息的问题了。在前面的示例中已经贴了一些实现。

    分析GPS的消息,很容易的发现每条命令是以$\.+?, 方式开始的,我们可以根据这样的特性实现ICommandFactory,这里再贴一下主要的实现代码
1
stringcommand;
2
command = str.Substring(0, str.IndexOf(','));
3
switch(command)
4
{
5
case"$GPRMC":
6
returnParse(str);
7
case"$GPGGA":
8
returnParse(str);
9
}
     然后就可以产生Command了。我们根据要求建立了两个Command,分别是GPRMCommand和GPGGACommmand。然后根据对应的命令格式重写Parse()方法。而消息分割正好是每行一条命令的方式,因而就无需重写CommandProcessor的GetSingleCommand方法了。然后就完了,不需要写什么了,基本的东西都已经在我们之前谈到的项目中定义好了。

    具体视图如下:

Figure 4 GPS类视图




如果您有兴趣,可以在这里下载代码,如果有问题欢迎与我联系:)

http://loningproject.googlecode.com/svn/trunk/cnblogs/gps.7z

    相关评论

    阅读本文后您有什么感想? 已有人给出评价!

    • 8 喜欢喜欢
    • 3 顶
    • 1 难过难过
    • 5 囧
    • 3 围观围观
    • 2 无聊无聊

    热门评论

    最新评论

    发表评论 查看所有评论(0)

    昵称:
    表情: 高兴 可 汗 我不要 害羞 好 下下下 送花 屎 亲亲
    字数: 0/500 (您的评论需要经过审核才能显示)