天天看點

GPS編碼格式及C語言的解碼代碼

 GPS接收機隻要處于工作狀态就會源源不斷地把接收并計算出的GPS導航定位資訊通過序列槽傳送到計算機中。前面的代碼隻負責從序列槽接收資料并将其放置于緩存,在沒有進一步處理之前緩存中是一長串位元組流,這些資訊在沒有經過分類提取之前是無法加以利用的。是以,必須通過程式将各個字段的資訊從緩存位元組流中提取出來,将其轉化成有實際意義的,可供高層決策使用的定位資訊資料。同其他通訊協定類似,對GPS進行資訊提取必須首先明确其幀結構,然後才能根據其結構完成對各定位資訊的提取。對于本文所使用的GARMIN GPS天線闆,其發送到計算機的資料主要由幀頭、幀尾和幀内資料組成,根據資料幀的不同,幀頭也不相同,主要有"$GPGGA"、"$GPGSA"、"$GPGSV"以及"$GPRMC"等。這些幀頭辨別了後續幀内資料的組成結構,各幀均以回車符和換行符作為幀尾辨別一幀的結束。對于通常的情況,我們所關心的定位資料如經緯度、速度、時間等均可以從"$GPRMC"幀中擷取得到,該幀的結構及各字段釋義如下:

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

  <1> 目前位置的格林尼治時間,格式為hhmmss

  <2> 狀态, A 為有效位置, V為非有效接收警告,即目前天線視野上方的衛星個數少于3顆。

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

  <4> 标明南北半球, N 為北半球、S為南半球

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

  <6> 标明東西半球,E為東半球、W為西半球

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

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

  <9> 日期, 格式為ddmmyy

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

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

  至于其他幾種幀格式,除了特殊用途外,平時并不常用,雖然接收機也在源源不斷地向主機發送各種資料幀,但在處理時一般先通過對幀頭的判斷而隻對"$GPRMC"幀進行資料的提取處理。如果情況特殊,需要從其他幀擷取資料,處理方法與之也是完全類似的。由于幀内各資料段由逗号分割,是以在處理緩存資料時一般是通過搜尋ASCII碼"$"來判斷是否是幀頭,在對幀頭的類别進行識别後再通過對所經曆逗号個數的計數來判斷出目前正在處理的是哪一種定位導航參數,并作出相應的處理。下面就是對緩存Data中的資料進行解幀處理的主要代碼,本文在此隻關心時間(日期和時間)和地理坐标(經、緯度):

for(int i=0;i  if(Data=='$') file://幀頭,SectionID為逗号計數器

  SectionID=0;

  if(Data==10){ file://幀尾

}

 if(Data==',') file://逗号計數

  SectionID++;

 else {

  switch(SectionID){

   case 1: file://提取出時間

    m_sTime+=Data;

    break;

   case 2: file://判斷資料是否可信(當GPS天線能接收到有3顆GPS衛星時為A,可信)

    if(Data=='A')

     GPSParam[m_nNumber].m_bValid=true;

     break;

   case 3: file://提取出緯度

     m_sPositionY+=Data;

     break;

   case 5: file://提取出經度

     m_sPositionX+=Data;

     break;

   case 9: file://提取出日期

     m_sDate+=Data;

     break;

     default:

     break;

  }

 }

}

  現在已将所需資訊提取到記憶體,即時間、日期以及經緯度分别儲存在CString型變量 m_sTime、m_Data、m_sPositionY和m_sPositionX中。在實際應用中往往要根據需要對其做進一步的運算處理,比如從GPS接收機中獲得的時間資訊為格林尼治時間,是以需要在擷取時間上加8小時才為我國标準時間。而且GPS使用的WGS-84坐标系也與我國采用的坐标系不同,有時也要對此加以變換。而這些變換運算必須通過數值運算完成,是以需要将前面擷取的字元型變量轉化為數值型變量,這部分工作可放在檢測到幀尾完成:

::strcpy(buf,m_sTime);

str.Format("%c%c",buf[0],buf[1]);

GPSParam[m_nNumber].m_nHour=(atoi(str)+8)%24; file://提取出小時并轉化為24小時制中原標準時間

file://buf第2、3位元組為分鐘,4、5位元組為秒,提取方法同上

……

::strcpy(buf,m_sDate);

str.Format("%c%c",buf[0],buf[1]); file://提取出月份

file://buf第2、3位元組為天,4、5位元組為年,提取方法同上

……

::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://經度超過90度(如東經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://提取出經度(機關為分)

}

if(m_sPositionX.GetLength()==9) file://經度未超過90度(如東經89度)

{

 file://處理方法同上,隻是buf的第0、1位元組為度數,2~9為分數。

}

  到此為止,已将時間和經緯度資訊提取到GPS結構數組GPSParam中的各個變量中去,後續的處理和高層決策可根據該結構中存儲的資料作出相應的處理。

下一篇: GPS

繼續閱讀