日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

远程定位gps linux,GPS(NMEA)数据解析

發布時間:2025/3/20 linux 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 远程定位gps linux,GPS(NMEA)数据解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、GPS定位信息

設置好gps模式,啟動gps,正常的話在gps通路有NMEA數據上報,如下:

$GPGSV,3,1,11,01,62,130,42,07,61,201,43,11,72,075,28,17,20,251,38*7A

$GPGSV,3,2,11,30,63,272,44,03,00,149,,08,34,046,,13,05,309,*76

$GPGSV,3,3,11,22,08,127,,27,03,057,,28,34,312,*4C

$GPGGA,042523.0,3413.610533,N,10854.063257,E,1,05,2.6,438.5,M,-28.0,M,,*78

$GPVTG,245.9,T,245.9,M,0.0,N,0.0,K,A*23

$GPRMC,042523.0,A,3413.610533,N,10854.063257,E,0.0,245.9,190716,0.0,E,A*0F

$GPGSA,A,2,01,07,11,17,30,,,,,,,,2.8,2.6,1.0*3F

(1)?$GPGGA?(GPS定位信息)

協議格式:$GPGGA,161229.487,3723.2475,N,12158.3416,W,1,07,1.0,9.0,M, , ,,0000*18

協議格式詳細分析:

(2)?$GPGLL?(地理定位信息)

協議格式:$GPGLL,<1>,<2>,<3>,<4>,<5>,<6>*hh

樣例數據:$GPGLL,3723.2475,N,12158.3416,W,161229.487,A*2C

協議格式詳細分析:

(3)?$GPGSA?(當前衛星信息)

協議格式:$GPGSA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>,<13>,<14>,<15>,<16>,<17>*hh

樣例數據:$GPGSA,A,3,07,02,26,27,09,04,15, , , , , ,1.8,1.0,1.5*33

協議格式詳細分析:

(4) $GPGSV(可見衛星信息)

協議格式:$GPGSV, <1>,<2>,<3>,<4>,<5>,<6>,<7>,...,<4>,<5>,<6>,<7>*hh

樣例數據:$GPGSV,2,1,07,07,79,048,42,02,51,062,43,26,36,256,42,27,27,138,42*71$GPGSV,2,2,07,09,23,313,42,04,19,159,41,15,12,041,42*41

需要注意的是這里的樣例數據有2條,這是因為當前可見衛星一共有7個,但是每條語句最多包括四顆衛星的信息,所以分成了2條語句。每顆衛星的信息有四個數據項,即:<4>(衛星編號)、<5>(衛星仰角)、<6>(衛星方位角)、<7>(信噪比)。

協議格式詳細分析(只分析第1條樣例數據語句):

(5)?$GPRMC(最簡定位信息)

協議格式:$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>*hh

樣例數據:$GPRMC,161229.487,A,3723.2475,N,12158.3416,W,0.13,309.62,120598,,*10

協議格式詳細分析:

(6)?$GPVTG(地面速度信息)

協議格式:$GPVTG,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>*hh

樣例數據:$GPVTG,309.62,T, ,M,0.13,N,0.2,K*6E

協議格式詳細分析:

二、GPS(NMEA)數據解析

/*********************************************************************************/

ingps.h

/*********************************************************************************/

#include

#include

#include

#include

#include

#include

#include

#include

#include

/*********************************************************************************/

degps.h

/*********************************************************************************/

#include "ingps.h"

#define TTYUSB "/dev/ttyUSB3" ?/*串口設備*/

#define BAUD_RATE 4800 ? ? ?/*波特率 */

#define DATA_BITS 8 ? ? /*數據位*/

#define NEVENT 'N' ? ? ? /*校驗 */

#define NSTOP 1 ? ? ? ? /*停止位*/

#define BUFLEN 512 ? ? ? /*可隨意取,但要大于GPGGA_MAX*/

#define GPGGA_MAX 100 ? ? ? /*"$GPGGA……"的最大值,待定*/

#define DBG_GPS

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; ? ? ? ? ? /*東西 */

int num; ? ? ? ? ? /*衛星數*/

double speed; ? ? ?/*速度 */

double high; ? ? ? /*高度*

}GPS_INFO;

/*********************************************************************************/

getgps.c

/*********************************************************************************/

#include “degps.h”

#include "ingps.h"

static int GetComma(int num,char *str)

{

int i,j=0;

int len=strlen(str);

for(i=0;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 int get_int_number(char *s)

{

char buf[128];

int i;

double rev;

i=GetComma(1,s); ? ?/*得到數據長度*/

strncpy(buf,s,i);

buf[i]=0; ? ? ? ? ? /*加字符串結束標志 */

rev=atoi(buf); ? ? ?/*字符串轉float */

return 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++;

}

}

}

void gps_parse(char *line,GPS_INFO *GPS)

{

int tmp;

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)]);

GPS->num =get_int_number(&buf[GetComma(7,buf)]);

}

}

voidshow_gps(GPS_INFO *GPS)

{

printf("年份 ? ? : %ld-%02d-%02d\n",GPS->D.year,GPS->D.month,GPS->D.day);

printf("時間 ? ? : %02d:%02d:%02d\n",GPS->D.hour,GPS->D.minute,GPS->D.second);

printf("緯度 ? ? : %s %10.4f\n",(GPS->NS=='N')?"北緯":"南緯",GPS->latitude);

printf("經度 ? ? : %s %10.4f\n",(GPS->EW=='W')?"西經":"東經",GPS->longitude);

printf("衛星數 ? : %02d\n",GPS->num);

printf("高度 ? ? : %.4f\n",GPS->high);

printf("狀態 ? ? : %s\n",(GPS->status=='A')?"定位":"導航");

printf("--------------------\n");

}

int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)

{

struct termios newtio,oldtio;

if ?( tcgetattr( fd,&oldtio) ?!= ?0) {

perror("SetupSerial 1");

return -1;

}

bzero( &newtio, sizeof( newtio ) );

newtio.c_cflag ?|= ?CLOCAL | CREAD;

newtio.c_cflag &= ~CSIZE;

switch( nBits )

{

case 7:

newtio.c_cflag |= CS7;

break;

case 8:

newtio.c_cflag |= CS8;

break;

}

switch( nEvent )

{

case 'o':

case 'O':

newtio.c_cflag |= PARENB;

newtio.c_cflag |= PARODD;

newtio.c_iflag |= (INPCK | ISTRIP);

break;

case 'e':

case 'E':

newtio.c_iflag |= (INPCK | ISTRIP);

newtio.c_cflag |= PARENB;

newtio.c_cflag &= ~PARODD;

break;

case 'n':

case 'N':

newtio.c_cflag &= ~PARENB;

break;

case?'s':

case?'S':

newtio.c_cflag?&=?~PARENB;

newtio.c_cflag?&=?~CSTOPB;

break;

default:

printf("Unsupported parity\n");

return?-1;

}

switch( nSpeed )

{

case 2400:

cfsetispeed(&newtio, B2400);

cfsetospeed(&newtio, B2400);

break;

case 4800:

cfsetispeed(&newtio, B4800);

cfsetospeed(&newtio, B4800);

break;

case 9600:

cfsetispeed(&newtio, B9600);

cfsetospeed(&newtio, B9600);

break;

case 115200:

cfsetispeed(&newtio, B115200);

cfsetospeed(&newtio, B115200);

break;

case 460800:

cfsetispeed(&newtio, B460800);

cfsetospeed(&newtio, B460800);

break;

default:

cfsetispeed(&newtio, B9600);

cfsetospeed(&newtio, B9600);

break;

}

if( nStop == 1 )

newtio.c_cflag &= ?~CSTOPB;

else if ( nStop == 2 )

newtio.c_cflag |= ?CSTOPB;

newtio.c_cc[VTIME] ?= 0;/*超時 重要*/

newtio.c_cc[VMIN] = 100;/*返回的最小值 ?重要*/

tcflush(fd,TCIFLUSH);

if((tcsetattr(fd,TCSANOW,&newtio))!=0)

{

perror("com set error");

return -1;

}

return 0;

}

int Get_GPSData(char* gpd,char* buf,char* tar_value)

{

char *pos = NULL;

int cur = 0,counter=1,i =0;

pos = strstr(buf,gpd);

if(pos == NULL){

return counter;

}

cur = pos - buf;

tar_value[0]='$';

for(i = cur; i < BUFLEN; i++){

if(buf[i]!='$' && buf[i]!='\n' ){

tar_value[counter]=buf[i];

counter++;

} else{

tar_value[counter]='\0';

break;

}

}

return counter;

}

int main(void)

{

GPS_INFO GPS;

int fd1,nset1,nread;

char buf[BUFLEN],tar_value[512];

fd1 = open(TTYUSB, O_RDWR);/*打開串口*/

if (fd1 == -1)

exit(1);

nset1 = set_opt(fd1,BAUD_RATE, DATA_BITS, NEVENT, NSTOP);/*設置串口屬性*/

if (nset1 == -1)

exit(1);

while(1)

{

memset(buf,0,BUFLEN);

memset(tar_value,0,sizeof(tar_value));

nread = read(fd1, buf, BUFLEN);/*讀串口*/

if (nread > 0){

if(Get_GPSData("GPGGA",buf,tar_value) <70){

sleep(2);

continue;

}

gps_parse(tar_value,&GPS);

memset(tar_value,0,sizeof(tar_value));

if(Get_GPSData("GPRMC",buf,tar_value) <70){

sleep(2);

continue;

}

gps_parse(tar_value,&GPS);

show_gps(&GPS);

}

sleep(2);/*睡眠,等待數據多一點 */

}

close(fd1);

return 0;

}執行結果如下:年份 ? ? : 2014-07-20

時間 ? ? : 10:16:20

緯度 ? ? : ?北緯 3913.6049

經度 ? ? : ?東經 10154.0622

衛星數 ? : 05

高度 ? ? ?: 449.3000

狀態 ? ? ?: 定位

參考文:http://www.cnblogs.com/tianciliangen/p/3796701.html ,http://blog.csdn.net/zhandoushi1982/article/details/7947682

總結

以上是生活随笔為你收集整理的远程定位gps linux,GPS(NMEA)数据解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。