GPS数据包解析

来源:互联网 发布:高一数学优化方案答案 编辑:程序博客网 时间:2024/05/21 23:32

 

节,海里每小时1节等于每小时1海里,也就是每小时行驶1.852千米(公里)。

 

http://write.blog.csdn.net/postedit

GPS数据包解析  

很多朋友都不知道GPS数据包怎么解析,给大家分享一下,GPS上电后,每隔一定的时间就会返回一定格式的数据,数据格式为:

$信息类型,x,x,x,x,x,x,x,x,x,x,x,x,x

每行开头的字符都是‘$’,接着是信息类型,后面是数据,以逗号分隔开。一行完整的数据如下:

    $GPRMC,080655.00,A,4546.40891,N,12639.65641,E,1.045,328.42,170809,,,A*60

 

信息类型为:

GPGSV:可见卫星信息

GPGLL:地理定位信息

GPRMC:推荐最小定位信息

GPVTG:地面速度信息

GPGGA:GPS定位信息

GPGSA:当前卫星信息

 

 

1、 GPS DOP and Active Satellites(GSA)当前卫星信息

$GPGSA,<1>,<2>,<3>,<4>,,,,,<12>,<13>,<14>, <15>,<16>,<17>,<18><CR><LF>

<1>模式 :M = 手动, A = 自动。 
<2>定位型式 1 = 未定位, 2 = 二维定位, 3 = 三维定位。 
<3>到<14>PRN 数字:01 至 32 表天空使用中的卫星编号,最多可接收12颗卫星信息

      (上面蓝色处,总共有12个)。 
<15> PDOP位置精度因子(0.5~99.9) 
<16> HDOP水平精度因子(0.5~99.9) 
<17> VDOP垂直精度因子(0.5~99.9) 
<18> Checksum.(检查位).


2、 GPS Satellites in View(GSV)可见卫星信息 
$GPGSV, <1>,<2>,<3>,<4>,<5>,<6>,<7>,?<4>,<5>,<6>,<7>,<8><CR><LF>

<1> GSV语句的总数 
<2> 本句GSV的编号 
<3> 可见卫星的总数,00 至 12。 
<4> 卫星编号, 01 至 32。 
<5>卫星仰角, 00 至 90 度。 
<6>卫星方位角, 000 至 359 度。实际值。 
<7>讯号噪声比(C/No), 00 至 99 dB;无表未接收到讯号。 
<8>Checksum.(检查位).

第<4>,<5>,<6>,<7>项个别卫星会重复出现,每行最多有四颗卫星。其余卫星信息会于次一行出现,若未使用,这些字段会空白。


3、Global Positioning System 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也将被传输,如果不是差分定位将为空)


4、Recommended Minimum Specific 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=数据无效)


5、 Track Made Good and Ground Speed(VTG)地面速度信息 
$GPVTG,<1>,T,<2>,M,<3>,N,<4>,K,<5>*hh<CR><LF> 
<1> 以真北为参考基准的地面航向(000~359度,前面的0也将被传输) 
<2> 以磁北为参考基准的地面航向(000~359度,前面的0也将被传输) 
<3> 地面速率(000.0~999.9节,前面的0也将被传输) 
<4> 地面速率(0000.0~1851.8公里/小时,前面的0也将被传输) 
<5> 模式指示(仅NMEA0183 3.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效)

6、GPZDA日期和时间

$GPZDA,<1>,<2>, <3> , <4> , <5> , <6> *CC<CR><LF>

<1> UTC时间,hhmmss(时分秒)格式 
<2> 日
<3> 月
<4> 年
<5> 本地时区小时便宜量

<6>本地时区分钟便宜量

 

 http://www.cnblogs.com/csMapx/archive/2011/11/02/2232663.html

 

GPS数据包解析

GPS 上电后,每隔一定的时间就会返回一定格式的数据,数据格式为:
$信息类型,x,x,x,x,x,x,x,x,x,x,x,x,x每行开头的字符都是‘$’,接着是信息类型,后面是数据,以逗号分隔开。
一行完整的数据如下:
$GPRMC,080655.00,A,4546.40891,N,12639.65641,E,1.045,328.42,170809,,,A*60

信息类型为:
GPGSV:可见卫星信息
GPGLL:地理定位信息
GPRMC:推荐最小定位信息
GPVTG:地面速度信息
GPGGA:GPS定位信息
GPGSA:当前卫星信息


GPRMC 最小定位信息
数据详解:$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh
<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>模式指示(仅NMEA01833.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效)

解析内容:
1.时间,这个是格林威治时间,是世界时间(UTC),我们需要把它转换成北京时间(BTC),BTC和UTC差了8个小时,要在这个时间基础上加8个小时。
2. 定位状态,在接收到有效数据前,这个位是‘V’,后面的数据都为空,接到有效数据后,这个位是‘A’,后面才开始有数据。
3. 纬度,我们需要把它转换成度分秒的格式,计算方法:如接收到的纬度是:4546.40891
4546.40891/100=45.4640891可以直接读出45度, 4546.40891–45*100=46.40891, 可以直接读出46分
46.40891–46 =0.40891*60=24.5346读出24秒, 所以纬度是:45度46分24秒。
4. 南北纬,这个位有两种值‘N’(北纬)和‘S’(南纬)
5. 经度的计算方法和纬度的计算方法一样
6. 东西经,这个位有两种值‘E’(东经)和‘W’(西经)
7.速率,这个速率值是海里/时,单位是节,要把它转换成千米/时,根据:1海里=1.85公里,把得到的速率乘以1.85。
8. 航向,指的是偏离正北的角度
9. 日期,这个日期是准确的,不需要转换

GPGGA GPS定位数据
数据详解:$GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M,<10>,M,<11>,<12>*xx<CR><LF>
$GPGGA:起始引导符及语句格式说明(本句为GPS定位数据);
<1> UTC 时间,格式为hhmmss.sss;
<2> 纬度,格式为ddmm.mmmm(第一位是零也将传送);
<3> 纬度半球,N 或S(北纬或南纬)
<4> 经度,格式为dddmm.mmmm(第一位零也将传送);
<5> 经度半球,E 或W(东经或西经)
<6> 定位质量指示,0=定位无效,1=定位有效;
<7>使用卫星数量,从00到12(第一个零也将传送)
<8>水平精确度,0.5到99.9
<9>天线离海平面的高度,-9999.9到9999.9米M指单位米
<10>大地水准面高度,-9999.9到9999.9米M指单位米
<11>差分GPS数据期限(RTCMSC-104),最后设立RTCM传送的秒数量
<12>差分参考基站标号,从0000到1023(首位0也将传送)。

解析内容:第9,10 个字段,海平面高度和大地水准面高度,单位是米


GPVTG 地面速度信息   
$GPVTG,<1>,T,<2>,M,<3>,N,<4>,K,<5>*hh
   <1> 以正北为参考基准的地面航向(000~359度,前面的0也将被传输)
   <2> 以磁北为参考基准的地面航向(000~359度,前面的0也将被传输)
   <3> 地面速率(000.0~999.9节,前面的0也将被传输)
   <4> 地面速率(0000.0~1851.8公里/小时,前面的0也将被传输)
   <5> 模式指示(仅NMEA0183 3.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效

GPGSV 可视卫星状态

   例:$GPGSV,2,1,08,06,33,240,45,10,36,074,47,16,21,078,44,17,36,313,42*78
   标准格式: $GPGSV,(1),(2),(3),(4),(5),(6),(7),…(4),(5),(6),(7)*hh(CR)(LF)   
各部分含义为:
   (1)总的GSV语句电文数;2;
   (2)当前GSV语句号:1;
   (3)可视卫星总数:08;
   (4)PRN码(伪随机噪声码) 也可以认为是卫星编号
   (5)仰角(00~90度):33度;
   (6)方位角(000~359度):240度;
   (7)信噪比(00~99dB):45dB(后面依次为第10,16,17号卫星的信息);   *总和校验域;    hh 总和校验数:78;   (CR)(LF)回车,换行。   
注:每条语句最多包括四颗卫星的信息,每颗卫星的信息有四个数据项,即:
    (4)-卫星号,(5)-仰角,(6)-方位角,(7)-信噪比。   
      例:
  $GPGSV,3,1,10,24,82,023,40,05,62,285,32,01,62,123,00,17,59,229,28*70
   每条语句包含四部分内容,例如:第一部分是“24,82,023,40”,第二部分是“05,62,285,32”等等。
每部分的第一个词为PRC,第二个词为卫星高程,跟着为方位角和信号强度。
  这个语句里最重要的指标应该算是“信号躁声比(signal-to-noise ratio)”(以下简称为SNR)。
这个数值标示卫星信号的接收率。我们知道,卫星是以相同的强度发射信号,但是传播过程中难免会遇到诸如树和墙之类的 障碍物,这样就影响了信号的识别。
   典型的SNR值在0到50之间,其中50表示非常好的信号。(SNR可以达到99)。

GPGSA 当前卫星信息
  例:$GPGSA,A,3,01,20,19,13,,,,,,,,,40.4,24.4,32.2*0A  
 
字段0:$GPGSA,语句ID,表明该语句为GPS DOP and Active Satellites(GSA)当前卫星信息   
字段1:定位模式,A=自动手动2D/3D,M=手动2D/3D   
字段2:定位类型,1=未定位,2=2D定位,3=3D定位   
字段3:PRN码(伪随机噪声码),第1信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)   
字段4:PRN码(伪随机噪声码),第2信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)   
字段5:PRN码(伪随机噪声码),第3信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)   
字段6:PRN码(伪随机噪声码),第4信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)   
字段7:PRN码(伪随机噪声码),第5信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)   
字段8:PRN码(伪随机噪声码),第6信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)   
字段9:PRN码(伪随机噪声码),第7信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)   
字段10:PRN码(伪随机噪声码),第8信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)   
字段11:PRN码(伪随机噪声码),第9信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)   
字段12:PRN码(伪随机噪声码),第10信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)   
字段13:PRN码(伪随机噪声码),第11信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)   
字段14:PRN码(伪随机噪声码),第12信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)   
字段15:PDOP综合位置精度因子(0.5 - 99.9)   
字段16:HDOP水平精度因子(0.5 - 99.9)   
字段17:VDOP垂直精度因子(0.5 - 99.9)   
字段18:校验值

 

 

http://blog.csdn.net/zhandoushi1982/article/details/7947682

GPS的NMEA数据解析

 

NMEA是一套定义接收机输出的标准信息,有几种不同的格式,每种都是独立相关的ASCII格式,逗点隔开数据流,数据流长度从30-100字符不等,通常以每秒间隔选择输出,最常用的格式为"GGA",它包含了定位时间,纬度,经度,高度,定位所用的卫星数,其他的有速度,跟踪,日期等。

        NMEA-0183协议定义的语句非常多,但是常用的或者说兼容性最广的语句只有$GPGGA、$GPGSA、$GPGSV、$GPRMC、$GPVTG、$GPGLL等,说明如下:

$GPGGA(定位信息)
eg:$GPGGA,092204.999,4250.5589,S,14718.5084,E,1,04,24.4,19.7,M,,,,0000*1F
$GPGSA(当前卫星信息)
eg:$GPGSA,A,3,01,20,19,13,,,,,,,,,40.4,24.4,32.2*0A
$GPGSV(可见卫星信息)
eg:$GPGSV,3,1,10,20,78,331,45,01,59,235,47,22,41,069,,13,32,252,45*70
$GPVTG(地面速度信息)
eg:$GPVTG,89.68,T,,M,0.00,N,0.0,K*5F
$GPGLL(地理定位信息)
$GPGLL,4250.5589,S,14718.5084,E,092204.999,A*2D

        以下以代码段来说明$GPGGA的解析过程,其他类推。假设已从串口读到字符串。

(1)结构体信息

[cpp] view plaincopyprint?
  1. typedef struct{  
  2.     int year;    
  3.     int month;   
  4.     int day;  
  5.     int hour;  
  6.     int minute;  
  7.     int second;  
  8. }date_time;  
  9.   
  10. typedef struct{  
  11.      date_time D;//时间   
  12.      char status;       //接收状态  
  13.      double latitude;   //纬度  
  14.      double longitude;  //经度  
  15.      char NS;           //南北极  
  16.      char EW;           //东西  
  17.      double speed;      //速度  
  18.      double high;       //高度  
  19. }GPS_INFO;  

(2)得到指定序号的逗号位置,以解析各个定义段

[cpp] view plaincopyprint?
  1. static int GetComma(int num,char *str)  
  2. {  
  3.     int i,j=0;  
  4.     int len=strlen(str);  
  5.     for(i=0;i<len;i++)  
  6.     {  
  7.         if(str[i]==',')j++;  
  8.         if(j==num)return i+1;   //返回当前找到的逗号位置的下一个位置  
  9.     }  
  10.     return 0;     
  11. }  

        得到精度纬度等高精度数据

[cpp] view plaincopyprint?
  1. static double get_double_number(char *s)  
  2. {  
  3.     char buf[128];  
  4.     int i;  
  5.     double rev;  
  6.     i=GetComma(1,s);    //得到数据长度   
  7.     strncpy(buf,s,i);  
  8.     buf[i]=0;           //加字符串结束标志   
  9.     rev=atof(buf);      //字符串转float  
  10.     return rev;  
  11. }  

        将世界时转换为北京时间

[cpp] view plaincopyprint?
  1. static void UTC2BTC(date_time *GPS)  
  2. {  
  3. //***************************************************  
  4. //如果秒号先出,再出时间数据,则将时间数据+1秒   
  5.         GPS->second++; //加一秒   
  6.         if(GPS->second>59){  
  7.             GPS->second=0;  
  8.             GPS->minute++;  
  9.             if(GPS->minute>59){  
  10.                 GPS->minute=0;  
  11.                 GPS->hour++;  
  12.             }  
  13.         }     
  14.   
  15. //***************************************************  
  16.         GPS->hour+=8;        //北京时间跟UTC时间相隔8小时  
  17.         if(GPS->hour>23)  
  18.         {  
  19.             GPS->hour-=24;  
  20.             GPS->day+=1;  
  21.             if(GPS->month==2 ||GPS->month==4 ||GPS->month==6 ||GPS->month==9 ||GPS->month==11 ){  
  22.                 if(GPS->day>30){          //上述几个月份是30天每月,2月份还不足30  
  23.                     GPS->day=1;  
  24.                     GPS->month++;  
  25.                 }  
  26.             }  
  27.             else{  
  28.                 if(GPS->day>31){          //剩下的几个月份都是31天每月  
  29.                     GPS->day=1;  
  30.                     GPS->month++;  
  31.                 }  
  32.             }  
  33.             if(GPS->year % 4 == 0 ){//  
  34.                 if(GPS->day > 29 && GPS->month ==2){       //闰年的二月是29天  
  35.                     GPS->day=1;  
  36.                     GPS->month++;  
  37.                 }  
  38.             }  
  39.             else{  
  40.                 if(GPS->day>28 &&GPS->month ==2){      //其他的二月是28天每月  
  41.                     GPS->day=1;  
  42.                     GPS->month++;  
  43.                 }  
  44.             }  
  45.             if(GPS->month>12){  
  46.                 GPS->month-=12;  
  47.                 GPS->year++;  
  48.             }         
  49.         }  
  50. }  

(3)解析GPS数据,以line作为传入的字符串数据,GPS是待赋值的全局变量。以下第一行是字符顺序号

//0      7  0   4 6   0     6 8 0        90         0  3      0        9  
//$GPRMC,091400,A,3958.9870,N,11620.3278,E,000.0,000.0,120302,005.6,W*62
//$GPGGA,091400,3958.9870,N,11620.3278,E,1,03,1.9,114.2,M,-8.3,M,,*5E

[cpp] view plaincopyprint?
  1. void gps_parse(char *line,GPS_INFO *GPS)  
  2. {  
  3.     int i,tmp,start,end;  
  4.     char c;  
  5.     char* buf=line;  
  6.     c=buf[5];  
  7.   
  8.     if(c=='C'){//"GPRMC"  
  9.         GPS->D.hour   =(buf[ 7]-'0')*10+(buf[ 8]-'0');  
  10.         GPS->D.minute =(buf[ 9]-'0')*10+(buf[10]-'0');  
  11.         GPS->D.second =(buf[11]-'0')*10+(buf[12]-'0');  
  12.         tmp = GetComma(9,buf);      //得到第9个逗号的下一字符序号  
  13.         GPS->D.day    =(buf[tmp+0]-'0')*10+(buf[tmp+1]-'0');  
  14.         GPS->D.month  =(buf[tmp+2]-'0')*10+(buf[tmp+3]-'0');  
  15.         GPS->D.year   =(buf[tmp+4]-'0')*10+(buf[tmp+5]-'0')+2000;  
  16.         //------------------------------   
  17.         GPS->status   =buf[GetComma(2,buf)];     //状态  
  18.         GPS->latitude =get_double_number(&buf[GetComma(3,buf)]); //纬度  
  19.         GPS->NS       =buf[GetComma(4,buf)];             //南北纬  
  20.         GPS->longitude=get_double_number(&buf[GetComma(5,buf)]); //经度  
  21.         GPS->EW       =buf[GetComma(6,buf)];             //东西经  
  22.         UTC2BTC(&GPS->D);                        //转北京时间  
  23.     }  
  24.     if(c=='A'){ //"$GPGGA"  
  25.         GPS->high     = get_double_number(&buf[GetComma(9,buf)]);  
  26.           
  27.     }  
  28. }  

       显示解析结果

[cpp] view plaincopyprint?
  1. void show_gps(GPS_INFO *GPS)  
  2. {  
  3.     printf("DATE     : %ld-%02d-%02d \n",GPS->D.year,GPS->D.month,GPS->D.day);  
  4.     printf("TIME     :  %02d:%02d:%02d \n",GPS->D.hour,GPS->D.minute,GPS->D.second);  
  5.     printf("Latitude : %10.4f %c\n",GPS->latitude,GPS->NS);     
  6.     printf("Longitude: %10.4f %c\n",GPS->longitude,GPS->EW);    
  7.     printf("high     : %10.4f \n",GPS->high);      
  8.     printf("STATUS   : %c\n",GPS->status);     
  9. }  

 

0 0
原创粉丝点击