西西軟件園多重安全檢測(cè)下載網(wǎng)站、值得信賴的軟件下載站!
軟件
軟件
文章
搜索

首頁(yè)編程開(kāi)發(fā)其它知識(shí) → GPS消息處理通用命令處理類

GPS消息處理通用命令處理類

相關(guān)軟件相關(guān)文章發(fā)表評(píng)論 來(lái)源:本站整理時(shí)間:2010/11/2 18:05:47字體大。A-A+

作者:佚名點(diǎn)擊:188次評(píng)論:0次標(biāo)簽: GPS。消息處理

  • 類型:音頻處理大小:1M語(yǔ)言:中文 評(píng)分:5.1
  • 標(biāo)簽:
立即下載

(1)綜合運(yùn)用以前學(xué)到的控制語(yǔ)句、繼承、封裝、接口等知識(shí),完成具有實(shí)際運(yùn)用功能的程序。

(2)通過(guò)運(yùn)用學(xué)過(guò)的知識(shí)進(jìn)一步的鞏固和掌握學(xué)到的知識(shí)。

實(shí)驗(yàn)內(nèi)容

使用GPS GATE軟件模擬GPS衛(wèi)星發(fā)出的GPS信號(hào),編寫(xiě)程序?qū)PS GATE發(fā)出的信息進(jìn)行接收、解析、處理。將處理好的信息按照固定的格式存儲(chǔ)至文件中(經(jīng)度、緯度、時(shí)間、速度、高度)。

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

1. GPS/TRANSIT Data(RMC)推薦定位信息 (在項(xiàng)目中就使用了這個(gè)報(bào)文的定位數(shù)據(jù))

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

(1)UTC時(shí)間,hhmmss(時(shí)分秒)格式
(2)定位狀態(tài),A=有效定位,V=無(wú)效定位
(3)緯度ddmm.mmmm(度分)格式(前面的0也將被傳輸)
(4)緯度半球N(北半球)或S(南半球)
(5)經(jīng)度dddmm.mmmm(度分)格式(前面的0也將被傳輸)
(6)經(jīng)度半球E(東經(jīng))或W(西經(jīng))
(7)地面速率(000.0~999.9節(jié),前面的0也將被傳輸)

(8)地面航向(000.0~359.9度,以真北為參考基準(zhǔn),前面的0也將被傳輸) (9)UTC日期,ddmmyy(日月年)格式
(10)磁偏角(000.0~180.0度,前面的0也將被傳輸)
(11)磁偏角方向,E(東)或W(西)
(12)模式指示(僅NMEA0183 3.00版本輸出,A=自主定位,D=差分,E=估算,N=數(shù)據(jù)無(wú)效)

(13) hh(CR)(LF) hh是前面從第一個(gè)數(shù)據(jù)到最后一個(gè)數(shù)據(jù)的校驗(yàn)和,(CR)(LF)是回車換行,表示一個(gè)字符串的結(jié)束。

具體示例:

$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時(shí)間,hhmmss(時(shí)分秒)格式
(2)緯度ddmm.mmmm(度分)格式(前面的0也將被傳輸)
(3)緯度半球N(北半球)或S(南半球)
(4)經(jīng)度dddmm.mmmm(度分)格式(前面的0也將被傳輸)
(5)經(jīng)度半球E(東經(jīng))或W(西經(jīng))
(6)GPS狀態(tài):0=未定位,1=非差分定位,2=差分定位,6=正在估算
(7)正在使用解算位置的衛(wèi)星數(shù)量(00~12)(前面的0也將被傳輸)
(8)HDOP水平精度因子(0.5~99.9)
(9)海拔高度(-9999.9~99999.9)
(10)地球橢球面相對(duì)大地水準(zhǔn)面的高度
(11)差分時(shí)間(從最近一次接收到差分信號(hào)開(kāi)始的秒數(shù),如果不是差分定位將為空)
(12)差分站ID號(hào)0000~1023(前面的0也將被傳輸,如果不是差分定位將為空)

(13) hh(CR)(LF) hh是前面從第一個(gè)數(shù)據(jù)到最后一個(gè)數(shù)據(jù)的校驗(yàn)和,(CR)(LF)是回車換行,表示一個(gè)字符串的結(jié)束。

具體示例:

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

校驗(yàn)和是指這一行的所有非數(shù)字字符,按照"字母、空格、句點(diǎn)、正號(hào)= 0;負(fù)號(hào)=1"的規(guī)則換算成0和1后,將這一行中原來(lái)的全部數(shù)字加起來(lái),以10為模計(jì)算后所得的和。校驗(yàn)和可以檢查出90%的數(shù)據(jù)存儲(chǔ)或傳送錯(cuò)誤。按十進(jìn)制加起來(lái)的個(gè)位數(shù)字的校驗(yàn)和,用于精確糾正誤差。

 

使用異常處理,對(duì)接收信息的過(guò)程中可能產(chǎn)生的異常進(jìn)行處理。(選作)編寫(xiě)C#Winfrom 程序,能夠?qū)⒔馕龅降臄?shù)據(jù)軌跡繪制到相應(yīng)的地圖上。

詳細(xì)設(shè)計(jì)

    該實(shí)現(xiàn)主要是實(shí)踐我在前文《談?wù)勎姨幚懋惓5囊话惴椒ā分刑岢龅囊恍┯^點(diǎn),以及一些面向?qū)ο笤O(shè)計(jì)的思想,和一些設(shè)計(jì)模式的運(yùn)用。

    在看到這個(gè)問(wèn)題的時(shí)候,首先要對(duì)需求進(jìn)行分析。該問(wèn)題的數(shù)據(jù)流程比較清晰,見(jiàn)Figure 1。

Figure 1 數(shù)據(jù)流

    從個(gè)人經(jīng)驗(yàn)來(lái)講,我認(rèn)為在指令的解析部分可以抽象出一個(gè)比較通用的方式,我們把GPS指令文本流替換為二進(jìn)制流,將單條指令文本替換為單條指令的二進(jìn)制信息。

Figure 2 通用數(shù)據(jù)流

    我做的抽象框架如所示Figure 3 類視圖所示。

Figure 3 類視圖

    首先我們應(yīng)當(dāng)有一個(gè)類來(lái)處理整個(gè)問(wèn)題,稱之為CommandProcessor。它負(fù)責(zé)從外部設(shè)備接收數(shù)據(jù)、并且將處理后的消息通過(guò)事件的方式向外部提供。該類還應(yīng)當(dāng)能夠?qū)螚l指令從流中取出來(lái),因而我在這個(gè)類中提供了一個(gè)虛的方法GetSingleCommandString(),并且進(jìn)行了一個(gè)通用的簡(jiǎn)單實(shí)現(xiàn)、即每行為一條指令。這里參數(shù)都用string來(lái)表示了,用string來(lái)表示二進(jìn)制數(shù)據(jù)也沒(méi)太大問(wèn)題,但對(duì)于純文本的數(shù)據(jù)處理起來(lái)則比較方便。

    在將命令分出來(lái)之后,我們需要將一條單獨(dú)的指令轉(zhuǎn)換為一個(gè)強(qiáng)類型的命令。我們用ICommand來(lái)表示一個(gè)被分析后的命令,則問(wèn)題就是如何由一個(gè)string產(chǎn)生一個(gè)ICommand。

    根據(jù)面向?qū)ο笤O(shè)計(jì)的一些原則,數(shù)據(jù)與實(shí)現(xiàn)應(yīng)都放在一個(gè)類當(dāng)中。那么對(duì)于特殊的Command,它自身才知道如何對(duì)它對(duì)應(yīng)的string進(jìn)行分析。我們?cè)贗Command中定義Parse(string s)方法對(duì)string進(jìn)行分析。

    ICommand的定義如下,關(guān)于DoCommand()方法在后文將有說(shuō)明。

 01
publicinterfaceICommand
02
    {
03
  
04
        ///


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

07
        ///
08
        ///
09
        boolParse(stringstr);
10
        voidDoCommand();
11
    }
    那么如何找到string->ICommand的對(duì)應(yīng)關(guān)系呢?

    比較簡(jiǎn)單的實(shí)現(xiàn)是我們維護(hù)一個(gè)ICommand的列表,然后用窮舉的方式調(diào)用Parse方法,直到該方法返回true。如果沒(méi)有方法返回true,則表示該string是一個(gè)未知的命令。這樣實(shí)現(xiàn)是比較OO,在編程階段添加ICommand比較方便。缺點(diǎn)是效率比較低,而且還需要維護(hù)一個(gè)已經(jīng)實(shí)例化ICommand的列表。而有這樣一個(gè)列表,在多線程編程時(shí)就會(huì)產(chǎn)生一些同步問(wèn)題。在編程時(shí)需要在Parse(string s)方法中先對(duì)傳入的string做一個(gè)初步檢測(cè),如果非該指令則立即返回false。而在當(dāng)前的設(shè)計(jì)中,沒(méi)法對(duì)子類重寫(xiě)Parse方法內(nèi)的內(nèi)容進(jìn)行約束,如果實(shí)現(xiàn)不好則會(huì)更大的造成效率的降低。

    我現(xiàn)在的實(shí)現(xiàn)是,引入一個(gè)ICommandFactory對(duì)象,那么這個(gè)問(wèn)題就成為了string->ICommandFactory->ICommand的問(wèn)題了,由于實(shí)現(xiàn)接口ICommandFactory與ICommand都是同一開(kāi)發(fā)者實(shí)現(xiàn)的,該開(kāi)發(fā)者可以分析string的特殊性,在實(shí)現(xiàn)ICommandFactory接口的類中找到string->ICommand的關(guān)系。還有一個(gè)優(yōu)點(diǎn)是,我們完全可以在自己定義的CommandFactory中實(shí)現(xiàn)在上一段提到的方法。以下是該部分具體的實(shí)現(xiàn)代碼。

publicinterfaceICommandFactory
2
{
3
///


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

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

//實(shí)現(xiàn)該接口的一個(gè)具體示例

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
    }

    在解決完命令分析的問(wèn)題之后,最后的一個(gè)問(wèn)題是如何將分析出的命令應(yīng)用的問(wèn)題。在這個(gè)設(shè)計(jì)中,我通過(guò)事件來(lái)通知其他類。

    在前文給出ICommand的描述中給出了一個(gè)DoCommand()方法。我們可以在需要應(yīng)用的項(xiàng)目中重寫(xiě)該方法,做出相應(yīng)的動(dòng)作。這樣就完全的實(shí)現(xiàn)了多態(tài),在接收到CommandReceived事件的消息后直接調(diào)用DoCommand()方法就好了,不需要對(duì)Command類型進(jìn)行顯示分析。當(dāng)然,我們需要借助IOC容器來(lái)進(jìn)行這樣的實(shí)現(xiàn)。這里不闡述IOC容器的具體功能,有興趣Google下就好啦。當(dāng)然這樣實(shí)現(xiàn)也許還是有一些復(fù)雜性的,我們需要對(duì)每一個(gè)Command類進(jìn)行重寫(xiě),然后更改IOC容器的映射關(guān)系。

    還有一種實(shí)現(xiàn)是使用is操作,對(duì)ICommand對(duì)象進(jìn)行測(cè)試,然后將ICommand中的信息進(jìn)行利用。下面給出第二種實(shí)現(xiàn)方法的一個(gè)示例。

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
}

     這樣一個(gè)基本的命令分析器的Library工程就基本寫(xiě)完了。然后就應(yīng)當(dāng)著手解決GPS消息的問(wèn)題了。在前面的示例中已經(jīng)貼了一些實(shí)現(xiàn)。

    分析GPS的消息,很容易的發(fā)現(xiàn)每條命令是以$\.+?, 方式開(kāi)始的,我們可以根據(jù)這樣的特性實(shí)現(xiàn)ICommandFactory,這里再貼一下主要的實(shí)現(xiàn)代碼
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
}
     然后就可以產(chǎn)生Command了。我們根據(jù)要求建立了兩個(gè)Command,分別是GPRMCommand和GPGGACommmand。然后根據(jù)對(duì)應(yīng)的命令格式重寫(xiě)Parse()方法。而消息分割正好是每行一條命令的方式,因而就無(wú)需重寫(xiě)CommandProcessor的GetSingleCommand方法了。然后就完了,不需要寫(xiě)什么了,基本的東西都已經(jīng)在我們之前談到的項(xiàng)目中定義好了。

    具體視圖如下:

Figure 4 GPS類視圖




如果您有興趣,可以在這里下載代碼,如果有問(wèn)題歡迎與我聯(lián)系:)

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

    相關(guān)評(píng)論

    閱讀本文后您有什么感想? 已有人給出評(píng)價(jià)!

    • 8 喜歡喜歡
    • 3 頂
    • 1 難過(guò)難過(guò)
    • 5 囧
    • 3 圍觀圍觀
    • 2 無(wú)聊無(wú)聊

    熱門(mén)評(píng)論

    最新評(píng)論

    發(fā)表評(píng)論 查看所有評(píng)論(0)

    昵稱:
    表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
    字?jǐn)?shù): 0/500 (您的評(píng)論需要經(jīng)過(guò)審核才能顯示)