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)结构体信息
- typedef struct{
- int year;
- int month;
- int day;
- int hour;
- int minute;
- int second;
- }date_time;
- typedef struct{
- date_time D;//时间
- char status; //接收状态
- double latitude; //纬度
- double longitude; //经度
- char NS; //南北极
- char EW; //东西
- double speed; //速度
- double high; //高度
- }GPS_INFO;
typedef struct{int year; int month; int day;int hour;int minute;int second;}date_time;typedef struct{ date_time D;//时间 char status; //接收状态 doublelatitude; //纬度 double longitude; //经度 char NS; //南北极 char EW; //东西 double speed; //速度 double high; //高度}GPS_INFO;
(2)得到指定序号的逗号位置,以解析各个定义段
- static int GetComma(int num,char *str)
- {
- int i,j=0;
- int len=strlen(str);
- for(i=0;i<len;i++)
- {
- if(str[i]==',')j++;
- if(j==num)return i+1; //返回当前找到的逗号位置的下一个位置
- }
- return 0;
- }
static int GetComma(int num,char *str){int i,j=0;int len=strlen(str);for(i=0;i<len;i++){if(str[i]==',')j++;if(j==num)return i+1;//返回当前找到的逗号位置的下一个位置}return 0;}
得到精度纬度等高精度数据
- static double get_double_number(char *s)
- {
- char buf[128];
- int i;
- double rev;
- i=GetComma(1,s); //得到数据长度
- strncpy(buf,s,i);
- buf[i]=0; //加字符串结束标志
- rev=atof(buf); //字符串转float
- return rev;
- }
static double get_double_number(char *s){char buf[128];int i;double rev;i=GetComma(1,s); //得到数据长度strncpy(buf,s,i);buf[i]=0;//加字符串结束标志rev=atof(buf);//字符串转floatreturn rev;}
将世界时转换为北京时间
- static void UTC2BTC(date_time *GPS)
- {
- //***************************************************
- //如果秒号先出,再出时间数据,则将时间数据+1秒
- GPS->second++; //加一秒
- if(GPS->second>59){
- GPS->second=0;
- GPS->minute++;
- if(GPS->minute>59){
- GPS->minute=0;
- GPS->hour++;
- }
- }
- //***************************************************
- GPS->hour+=8; //北京时间跟UTC时间相隔8小时
- if(GPS->hour>23)
- {
- GPS->hour-=24;
- GPS->day+=1;
- if(GPS->month==2 ||GPS->month==4 ||GPS->month==6 ||GPS->month==9 ||GPS->month==11 ){
- if(GPS->day>30){ //上述几个月份是30天每月,2月份还不足30
- GPS->day=1;
- GPS->month++;
- }
- }
- else{
- if(GPS->day>31){ //剩下的几个月份都是31天每月
- GPS->day=1;
- GPS->month++;
- }
- }
- if(GPS->year % 4 == 0 ){//
- if(GPS->day > 29 && GPS->month ==2){ //闰年的二月是29天
- GPS->day=1;
- GPS->month++;
- }
- }
- else{
- if(GPS->day>28 &&GPS->month ==2){ //其他的二月是28天每月
- GPS->day=1;
- GPS->month++;
- }
- }
- if(GPS->month>12){
- GPS->month-=12;
- GPS->year++;
- }
- }
- }
static void UTC2BTC(date_time *GPS){//***************************************************//如果秒号先出,再出时间数据,则将时间数据+1秒GPS->second++; //加一秒if(GPS->second>59){GPS->second=0;GPS->minute++;if(GPS->minute>59){GPS->minute=0;GPS->hour++;}}//***************************************************GPS->hour+=8;//北京时间跟UTC时间相隔8小时if(GPS->hour>23){GPS->hour-=24;GPS->day+=1;if(GPS->month==2 ||GPS->month==4 ||GPS->month==6 ||GPS->month==9 ||GPS->month==11 ){if(GPS->day>30){//上述几个月份是30天每月,2月份还不足30 GPS->day=1;GPS->month++;}}else{if(GPS->day>31){//剩下的几个月份都是31天每月 GPS->day=1;GPS->month++;}}if(GPS->year % 4 == 0 ){// if(GPS->day > 29 && GPS->month ==2){//闰年的二月是29天 GPS->day=1;GPS->month++;}}else{ if(GPS->day>28 &&GPS->month ==2){//其他的二月是28天每月 GPS->day=1;GPS->month++;}}if(GPS->month>12){GPS->month-=12;GPS->year++;}}}
(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
- void gps_parse(char *line,GPS_INFO *GPS)
- {
- int i,tmp,start,end;
- char c;
- char* buf=line;
- c=buf[5];
- if(c=='C'){//"GPRMC"
- GPS->D.hour =(buf[ 7]-'0')*10+(buf[ 8]-'0');
- GPS->D.minute =(buf[ 9]-'0')*10+(buf[10]-'0');
- GPS->D.second =(buf[11]-'0')*10+(buf[12]-'0');
- tmp = GetComma(9,buf); //得到第9个逗号的下一字符序号
- GPS->D.day =(buf[tmp+0]-'0')*10+(buf[tmp+1]-'0');
- GPS->D.month =(buf[tmp+2]-'0')*10+(buf[tmp+3]-'0');
- GPS->D.year =(buf[tmp+4]-'0')*10+(buf[tmp+5]-'0')+2000;
- //------------------------------
- GPS->status =buf[GetComma(2,buf)]; //状态
- GPS->latitude =get_double_number(&buf[GetComma(3,buf)]); //纬度
- GPS->NS =buf[GetComma(4,buf)]; //南北纬
- GPS->longitude=get_double_number(&buf[GetComma(5,buf)]); //经度
- GPS->EW =buf[GetComma(6,buf)]; //东西经
- UTC2BTC(&GPS->D); //转北京时间
- }
- if(c=='A'){ //"$GPGGA"
- GPS->high = get_double_number(&buf[GetComma(9,buf)]);
- }
- }
void gps_parse(char *line,GPS_INFO *GPS){int i,tmp,start,end;char c;char* buf=line;c=buf[5];if(c=='C'){//"GPRMC"GPS->D.hour =(buf[ 7]-'0')*10+(buf[ 8]-'0');GPS->D.minute =(buf[ 9]-'0')*10+(buf[10]-'0');GPS->D.second =(buf[11]-'0')*10+(buf[12]-'0');tmp = GetComma(9,buf);//得到第9个逗号的下一字符序号GPS->D.day =(buf[tmp+0]-'0')*10+(buf[tmp+1]-'0');GPS->D.month =(buf[tmp+2]-'0')*10+(buf[tmp+3]-'0');GPS->D.year =(buf[tmp+4]-'0')*10+(buf[tmp+5]-'0')+2000;//------------------------------GPS->status =buf[GetComma(2,buf)];//状态GPS->latitude =get_double_number(&buf[GetComma(3,buf)]);//纬度GPS->NS =buf[GetComma(4,buf)];//南北纬GPS->longitude=get_double_number(&buf[GetComma(5,buf)]);//经度GPS->EW =buf[GetComma(6,buf)];//东西经UTC2BTC(&GPS->D);//转北京时间}if(c=='A'){ //"$GPGGA"GPS->high = get_double_number(&buf[GetComma(9,buf)]);}}
显示解析结果
- void show_gps(GPS_INFO *GPS)
- {
- printf("DATE : %ld-%02d-%02d \n",GPS->D.year,GPS->D.month,GPS->D.day);
- printf("TIME : %02d:%02d:%02d \n",GPS->D.hour,GPS->D.minute,GPS->D.second);
- printf("Latitude : %10.4f %c\n",GPS->latitude,GPS->NS);
- printf("Longitude: %10.4f %c\n",GPS->longitude,GPS->EW);
- printf("high : %10.4f \n",GPS->high);
- printf("STATUS : %c\n",GPS->status);
- }
- GPS数据包解析
- GPS数据包解析
- GPS数据包解析
- GPS数据包解析
- GPS数据包解析
- [整理]GPS数据包解析
- GPS数据包格式+数据解析
- GPS数据包格式+数据解析
- GPS数据包解析--android端
- GPS数据包格式和数据解析
- GPS模块/数据包解析/ u-blox/NEO-5Q
- GPS数据解析 GPS 数据格式
- 如何解析数据包
- 网络数据包的解析
- 解析ARP数据包
- 解析IP数据包
- cap数据包文件解析
- NS2数据包结构解析
- wx.python事件的绑定
- C++ Primer 【第四版】第十四章 重载操作符与转换
- 关于IOS中的KeyChain(转载自网上)
- 扑克牌洗牌算法
- 通过工具类将图片转成圆形图,并加上边框
- GPS数据包解析
- 三大发生的发生的发
- X86架构下VMM的挑战
- ffmpeg的内部Video Buffer管理和传送机制
- UFLDL稀疏编码器练习实现
- ZOJ 1232 Adventure of Super Mario(最短路, DP)
- 统治世界的十大算法
- C++ Primer 【第四版】第十五章 面向对象编程
- [leetcode] LRU Cache