1. gzyueqian
      13352868059

      VC++實(shí)現(xiàn)GPS全球定位系統(tǒng)定位數(shù)據(jù)的提取

      更新時(shí)間: 2006-02-16 17:43:45來(lái)源: 粵嵌教育瀏覽量:3326

        引言

        衛(wèi)星導(dǎo)航技術(shù)的飛速發(fā)展已逐漸取代了無(wú)線(xiàn)電導(dǎo)航、天文導(dǎo)航等傳統(tǒng)導(dǎo)航技術(shù),而成為一種普遍采用的導(dǎo)航定位技術(shù),并在精度、實(shí)時(shí)性、全天候等方面取得了長(zhǎng)足進(jìn)步。現(xiàn)不僅應(yīng)用于物理勘探、電離層測(cè)量和航天器導(dǎo)航等諸多民用領(lǐng)域,在軍事領(lǐng)域更是取得了廣泛的應(yīng)用--在彈道導(dǎo)彈、野戰(zhàn)指揮系統(tǒng)、精確彈道測(cè)量以及軍用地圖快速測(cè)繪等領(lǐng)域均大量采用了衛(wèi)星導(dǎo)航定位技術(shù)。有鑒于衛(wèi)星導(dǎo)航技術(shù)在民用和軍事領(lǐng)域的重要意義,使其得到了許多國(guó)家的關(guān)注。我國(guó)也于2000年10月31日和12月21日成功發(fā)射了顆和第二顆導(dǎo)航定位試驗(yàn)衛(wèi)星并建立了我國(guó)代衛(wèi)星導(dǎo)航定位系統(tǒng)--"北斗導(dǎo)航系統(tǒng)",但由于起步晚也沒(méi)有得到廣泛應(yīng)用。目前在我國(guó)應(yīng)用多的還是美國(guó)的GPS系統(tǒng)。本文就針對(duì)當(dāng)前比較普及的GPS系統(tǒng),對(duì)其衛(wèi)星定位信息的接收及其定位參數(shù)提取的實(shí)現(xiàn)方法予以介紹。

        定位信息的接收

        通常GPS定位信息接收系統(tǒng)主要由GPS接收天線(xiàn)、變頻器、信號(hào)通道、微處理器、存儲(chǔ)器以及電源等部分組成。由于GPS定位信息內(nèi)容較少,因此多用RS-232串口將定位信息(NEMA0183語(yǔ)句)從GPS接收機(jī)傳送到計(jì)算機(jī)中進(jìn)行信息提取處理。從串口讀取數(shù)據(jù)有多種方法,在此直接使用 Win32 API函數(shù)對(duì)其進(jìn)行編程處理。在Windows下不允許直接對(duì)硬件端口進(jìn)行控制操作,所有的端口均被視為"文件",因此在對(duì)串口進(jìn)行偵聽(tīng)之前需要通過(guò)打開(kāi)文件來(lái)打開(kāi)串口,并對(duì)其進(jìn)行相關(guān)參數(shù)配置:

      m_hCom=CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING, FILE_FLAG_OVERLAPPED,NULL); file://以異步方式打開(kāi)COM1口
      SetCommMask (m_hCom, EV_RXCHAR ) ; file://添加或修改Windows所報(bào)告的事件列表
      SetupComm (m_hCom,READBUFLEN/*讀緩沖*/,WRITEBUFLEN/*寫(xiě)緩沖*/); // 初始化通訊設(shè)備參數(shù)
      // 清除緩沖信息
      PurgeComm (m_hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR) ;
      // 對(duì)異步I/O進(jìn)行設(shè)置
      CommTimeOuts.ReadIntervalTimeout = MAXDWORD ; file://接收兩連續(xù)字節(jié)的時(shí)間間隔
      CommTimeOuts.ReadTotalTimeoutMultiplier =0; file://接收每字節(jié)的平均允許時(shí)間
      CommTimeOuts.ReadTotalTimeoutConstant = 0 ; file://接收時(shí)間常數(shù)
      SetCommTimeouts (m_hCom , &CommTimeOuts) ;
      file://獲取并設(shè)置串口
      GetCommState ( m_hCom, &dcb) ;
      dcb.BaudRate = CBR_4800;
      dcb.ByteSize = 8;
      dcb.Parity = ODDPARITY;
      dcb.StopBits = ONESTOPBIT ;
      SetCommState( m_hCom, &dcb);

        在成功打開(kāi)并設(shè)置通訊口后,可采取輪詢(xún)串口和事件觸發(fā)兩種方式對(duì)數(shù)據(jù)進(jìn)行接收處理,本文在此采取效率比較高的事件觸發(fā)方式進(jìn)行接收處理,通過(guò)等待EV_RXCHAR事件的發(fā)生來(lái)啟動(dòng)ReadFile函數(shù)完成對(duì)GPS定位信息的接收:

      while(true){
       WaitCommEvent (m_hCom,&dwEvtMask,NULL);
       if (dwEvtMask&EV_RXCHAR == EV_RXCHAR)
        if(ComStat.cbInQue>0)
         ReadFile(m_hCom,m_readbuf,ComStat.cbInQue,&nLength,&olRead);
      }

        提取定位數(shù)據(jù)

        GPS接收機(jī)只要處于工作狀態(tài)就會(huì)源源不斷地把接收并計(jì)算出的GPS導(dǎo)航定位信息通過(guò)串口傳送到計(jì)算機(jī)中。前面的代碼只負(fù)責(zé)從串口接收數(shù)據(jù)并將其放置于緩存,在沒(méi)有進(jìn)一步處理之前緩存中是一長(zhǎng)串字節(jié)流,這些信息在沒(méi)有經(jīng)過(guò)分類(lèi)提取之前是無(wú)法加以利用的。因此,必須通過(guò)程序?qū)⒏鱾€(gè)字段的信息從緩存字節(jié)流中提取出來(lái),將其轉(zhuǎn)化成有實(shí)際意義的,可供高層決策使用的定位信息數(shù)據(jù)。同其他通訊協(xié)議類(lèi)似,對(duì)GPS進(jìn)行信息提取必須首先明確其幀結(jié)構(gòu),然后才能根據(jù)其結(jié)構(gòu)完成對(duì)各定位信息的提取。對(duì)于本文所使用的GARMIN GPS天線(xiàn)板,其發(fā)送到計(jì)算機(jī)的數(shù)據(jù)主要由幀頭、幀尾和幀內(nèi)數(shù)據(jù)組成,根據(jù)數(shù)據(jù)幀的不同,幀頭也不相同,主要有"$GPGGA"、"$GPGSA"、"$GPGSV"以及"$GPRMC"等。這些幀頭標(biāo)識(shí)了后續(xù)幀內(nèi)數(shù)據(jù)的組成結(jié)構(gòu),各幀均以回車(chē)符和換行符作為幀尾標(biāo)識(shí)一幀的結(jié)束。對(duì)于通常的情況,我們所關(guān)心的定位數(shù)據(jù)如經(jīng)緯度、速度、時(shí)間等均可以從"$GPRMC"幀中獲取得到,該幀的結(jié)構(gòu)及各字段釋義如下:

        $GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>*hh

        <1> 當(dāng)前位置的格林尼治時(shí)間,格式為hhmmss

        <2> 狀態(tài), A 為有效位置, V為非有效接收警告,即當(dāng)前天線(xiàn)視野上方的衛(wèi)星個(gè)數(shù)少于3顆。

        <3> 緯度, 格式為ddmm.mmmm

        <4> 標(biāo)明南北半球, N 為北半球、S為南半球

        <5> 徑度,格式為dddmm.mmmm

        <6> 標(biāo)明東西半球,E為東半球、W為西半球

        <7> 地面上的速度,范圍為0.0到999.9

        <8> 方位角,范圍為000.0到 359.9 度

        <9> 日期, 格式為ddmmyy

        <10> 地磁變化,從000.0到 180.0 度

        <11> 地磁變化方向,為E 或 W

        至于其他幾種幀格式,除了特殊用途外,平時(shí)并不常用,雖然接收機(jī)也在源源不斷地向主機(jī)發(fā)送各種數(shù)據(jù)幀,但在處理時(shí)一般先通過(guò)對(duì)幀頭的判斷而只對(duì)"$GPRMC"幀進(jìn)行數(shù)據(jù)的提取處理。如果情況特殊,需要從其他幀獲取數(shù)據(jù),處理方法與之也是完全類(lèi)似的。由于幀內(nèi)各數(shù)據(jù)段由逗號(hào)分割,因此在處理緩存數(shù)據(jù)時(shí)一般是通過(guò)搜尋ASCII碼"$"來(lái)判斷是否是幀頭,在對(duì)幀頭的類(lèi)別進(jìn)行識(shí)別后再通過(guò)對(duì)所經(jīng)歷逗號(hào)個(gè)數(shù)的計(jì)數(shù)來(lái)判斷出當(dāng)前正在處理的是哪一種定位導(dǎo)航參數(shù),并作出相應(yīng)的處理。下面就是對(duì)緩存Data中的數(shù)據(jù)進(jìn)行解幀處理的主要代碼,本文在此只關(guān)心時(shí)間(日期和時(shí)間)和地理坐標(biāo)(經(jīng)、緯度):

      for(int i=0;i  if(Data[i]=='$') file://幀頭,SectionID為逗號(hào)計(jì)數(shù)器
        SectionID=0;
        if(Data[i]==10){ file://幀尾
      }
       if(Data[i]==',') file://逗號(hào)計(jì)數(shù)
        SectionID++;
       else {
        switch(SectionID){
         case 1: file://提取出時(shí)間
          m_sTime+=Data[i];
          break;
         case 2: file://判斷數(shù)據(jù)是否可信(當(dāng)GPS天線(xiàn)能接收到有3顆GPS衛(wèi)星時(shí)為A,可信)
          if(Data[i]=='A')
           GPSParam[m_nNumber].m_bValid=true;
           break;
         case 3: file://提取出緯度
           m_sPositionY+=Data[i];
           break;
         case 5: file://提取出經(jīng)度
           m_sPositionX+=Data[i];
           break;
         case 9: file://提取出日期
           m_sDate+=Data[i];
           break;
           default:
           break;
        }
       }
      }

        現(xiàn)在已將所需信息提取到內(nèi)存,即時(shí)間、日期以及經(jīng)緯度分別保存在CString型變量 m_sTime、m_Data、m_sPositionY和m_sPositionX中。在實(shí)際應(yīng)用中往往要根據(jù)需要對(duì)其做進(jìn)一步的運(yùn)算處理,比如從GPS接收機(jī)中獲得的時(shí)間信息為格林尼治時(shí)間,因此需要在獲取時(shí)間上加8小時(shí)才為我國(guó)標(biāo)準(zhǔn)時(shí)間。而且GPS使用的WGS-84坐標(biāo)系也與我國(guó)采用的坐標(biāo)系不同,有時(shí)也要對(duì)此加以變換。而這些變換運(yùn)算必須通過(guò)數(shù)值運(yùn)算完成,因此需要將前面獲取的字符型變量轉(zhuǎn)化為數(shù)值型變量,這部分工作可放在檢測(cè)到幀尾完成:

      ::strcpy(buf,m_sTime);
      str.Format("%c%c",buf[0],buf[1]);
      GPSParam[m_nNumber].m_nHour=(atoi(str)+8)%24; file://提取出小時(shí)并轉(zhuǎn)化為24小時(shí)制北京時(shí)間
      file://buf第2、3字節(jié)為分鐘,4、5字節(jié)為秒,提取方法同上
      ……
      ::strcpy(buf,m_sDate);
      str.Format("%c%c",buf[0],buf[1]); file://提取出月份
      file://buf第2、3字節(jié)為天,4、5字節(jié)為年,提取方法同上
      ……
      ::strcpy(buf,m_sPositionY);
      str.Format("%c%c",buf[0],buf[1]);
      PositionValue=atoi(str);
      str.Format("%c%c%c%c%c%c%c",buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],buf[8]);
      GPSParam[m_nNumber].m_dPositionY=PositionValue*60+atof(str); file://提取出緯度
      ……
      ::strcpy(buf,m_sPositionX);
      if(m_sPositionX.GetLength()==10) file://經(jīng)度超過(guò)90度(如東經(jīng)125度)
      {
       str.Format("%c%c%c",buf[0],buf[1],buf[2]);
       PositionValue=atoi(str);
       str.Format("%c%c%c%c%c%c%c",buf[3],buf[4],buf[5],buf[6],buf[7],buf[8],buf[9]);
       GPSParam[m_nNumber].m_dPositionX=PositionValue*60+atof(str); file://提取出經(jīng)度(單位為分)
      }
      if(m_sPositionX.GetLength()==9) file://經(jīng)度未超過(guò)90度(如東經(jīng)89度)
      {
       file://處理方法同上,只是buf的第0、1字節(jié)為度數(shù),2~9為分?jǐn)?shù)。
      }


        到此為止,已將時(shí)間和經(jīng)緯度信息提取到GPS結(jié)構(gòu)數(shù)組GPSParam中的各個(gè)變量中去,后續(xù)的處理和高層決策可根據(jù)該結(jié)構(gòu)中存儲(chǔ)的數(shù)據(jù)作出相應(yīng)的處理。

        小結(jié)

        本文結(jié)合主要的相關(guān)程序代碼對(duì)GPS全球定位系統(tǒng)的定位導(dǎo)航信息的接收和參數(shù)數(shù)據(jù)的提取進(jìn)行了討論,同時(shí)也對(duì)串口的程序設(shè)計(jì)作了簡(jiǎn)要的講述。通過(guò)本文的設(shè)計(jì)方法可以將GPS定位導(dǎo)航信息從GPS接收機(jī)完整接收,通過(guò)對(duì)定位參數(shù)的提取可將其應(yīng)用于其他高層應(yīng)用決策如各種GIS、RS系統(tǒng)等。本文程序在Windows 98下,由Microsoft Visual C++ 6.0編譯通過(guò)。

      免費(fèi)預(yù)約試聽(tīng)課

      亚洲另类欧美综合久久图片区_亚洲中文字幕日产无码2020_欧美日本一区二区三区桃色视频_亚洲AⅤ天堂一区二区三区

      
      

      1. 久久亚洲国产精品五月天婷 | 日本在线不卡视频 | 亚洲特级视频在线观看 | 亚洲日本va一区二区 | 久久精品最新视频免费观看 | 亚洲第一a在线网站 |