日本好好热aⅴ|国产99视频精品免费观看|日本成人aV在线|久热香蕉国产在线

  • <cite id="ikgdy"><table id="ikgdy"></table></cite>
    1. 西西軟件園多重安全檢測(cè)下載網(wǎng)站、值得信賴(lài)的軟件下載站!
      軟件
      軟件
      文章
      搜索

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

      GPS消息處理通用命令處理類(lèi)

      相關(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。消息處理

      • 類(lèi)型:音頻處理大小: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)是回車(chē)換行,表示一個(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)是回車(chē)換行,表示一個(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 類(lèi)視圖所示。

      Figure 3 類(lèi)視圖

          首先我們應(yīng)當(dāng)有一個(gè)類(lèi)來(lái)處理整個(gè)問(wèn)題,稱(chēng)之為CommandProcessor。它負(fù)責(zé)從外部設(shè)備接收數(shù)據(jù)、并且將處理后的消息通過(guò)事件的方式向外部提供。該類(lèi)還應(yīng)當(dāng)能夠?qū)螚l指令從流中取出來(lái),因而我在這個(gè)類(lèi)中提供了一個(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)類(lèi)型的命令。我們用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è)類(lèi)當(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è)列表,在多線(xiàn)程編程時(shí)就會(huì)產(chǎn)生一些同步問(wèn)題。在編程時(shí)需要在Parse(string s)方法中先對(duì)傳入的string做一個(gè)初步檢測(cè),如果非該指令則立即返回false。而在當(dāng)前的設(shè)計(jì)中,沒(méi)法對(duì)子類(lèi)重寫(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接口的類(lèi)中找到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)通知其他類(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類(lèi)型進(jìn)行顯示分析。當(dāng)然,我們需要借助IOC容器來(lái)進(jìn)行這樣的實(shí)現(xiàn)。這里不闡述IOC容器的具體功能,有興趣Google下就好啦。當(dāng)然這樣實(shí)現(xiàn)也許還是有一些復(fù)雜性的,我們需要對(duì)每一個(gè)Command類(lèi)進(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類(lèi)視圖




      如果您有興趣,可以在這里下載代碼,如果有問(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)

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