NMEA-0813协议报文解析(QT/C++)

文章目录


一、协议说明

"GN-" 联合模式协议头;

"GP-"GPS模式协议头;

"GL-"GLONASS模式协议头;

"GB-/BD-"北斗模式协议头;

示例:

$GNRMC,073114.00,A,2237.56240,N,11401.59614,E,1.329,21.11,020916,,,A,V*37

名称示例单位描述
讯息代号$GNRMCRMC 规范抬头
标准定位时间073114.00时时分分秒秒.秒秒秒
定位状态AA:已定位有效,V:未定位无效
纬度2237.56240度度分分.分分分分
北半球或南半球指示器N北半球(N)或南半球(S)
经度11401.59614度度度分分.分分分分
东半球或西半球指示器E东(E)半球或西(W)半球
对地速度1.329对地速度
对地方向21.11对地方向
日期020916日日月月年年
---
---
-A-
-V-
总和检查码*37
<CR> <LF>讯息终点

 $GNVTG,21.11,T,,M,1.329,N,2.462,K,A*1B

名称示例单位描述
讯息代号$GNVTGVTG 规范抬头
对地方向21.11对地方向
-T-
磁极对地方向-
-M-
对地速度1.329对地速度
单位N
对地速度2.462公里/小时公里/小时
单位K公里/小时公里/小时
-A-
总和检查码*1B
<CR> <LF>讯息终点

$GNGGA,073114.00,2237.56240,N,11401.59614,E,1,12,0.78,112.9,M,-2.5,M,,*54

名称示例单位描述
讯息代号$GNGGAGGA 规范抬头
标准定位时间73114时时分分秒秒.秒秒秒
纬度2237.5624度度分分.分分分分
北半球或南半球指示器N北半球(N)或南半球(S)
经度11401.59614度度度分分.分分分分
东半球或西半球指示器E东(E)半球或西(W)半球
定位代号指示器10:未定位或无效的定位
1:已定位 标准 GPS(2D/3D)
2:已定位 差分 GPS
6:已定位 惯导 GPS
使用中的卫星数目12
水平稀释精度0.78
海拔高度112.9
单位M
地表平均高度-2.5
单位M
---
总和检查码*54
<CR> <LF>讯息终点

$GNGSA,A,3,19,05,02,06,17,12,09,13,,,,,1.48,0.78,1.26,1*01

名称示例单位描述
讯息代号$GNGSAGSA 规范抬头
模式  1A手动—强迫于二维定位或三维定位模式运作
自动—允许自动切换二维定位
模式  231:未定位;2:2D 定位;3:3D 定位
卫星使用19信号频道  1
卫星使用5信号频道  2
……
卫星使用信号频道  12
位置精度稀释值 PDOP1.48
水平精度稀释值 HDOP0.78
垂直精度稀释值 VDOP1.26
-1-
总和检查码*01
<CR> <LF>讯息终点

$GPGSV,4,1,13,02,46,340,36,05,52,254,37,06,42,041,41,09,22,053,40,0*6E

名称实例单位描述
讯息代号$GPGSVGSV 规范抬头
讯息总数4
讯息号码1
天空中卫星总数13
卫星编号2
卫星仰角46
卫星方位角340
讯号噪声比(C/No)36
……
卫星编号9
卫星仰角22
卫星方位角53
讯号噪声比(C/No)40
-0-
总和检查码*6E
<CR> <LF>讯息终点

$GNGLL,2237.56240,N,11401.59614,E,073114.00,A,A*7C

名称实例单位描述
讯息代号$GNGLLGLL 规范抬头
纬度2237.5624度度分分.分分分分
北半球或南半球指示器N北半球(N)或南半球(S)
经度11401.59614度度度分分.分分分分
东半球或西半球指示器E东(E)半球或西(W)半球
标准定位时间73114时时分分秒秒
状态AA:已定位有效,V:未定位无效
-A-
总和检查码*7C
<CR> <LF>讯息终点

二、具体实现

1. $GNRMC

void CGPSPositionWidget::GPSParse(QByteArray GPSBuffer)
{
	double gpslat = 0.0;
	double gpsLon = 0.0;
	double gpsElevation = 0.0;

	if (GPSBuffer.contains("$GNRMC"))
	{
		QList<QByteArray> gpsByteArrays = GPSBuffer.split(',');
		if (ConvertCharArrayToQString(gpsByteArrays.at(2)) == ConvertCharArrayToQString("A"))
		{
			ui->statusLabel->setText(ConvertCharArrayToQString("已定位 标准定位"));
			int  gpsLat_1 = static_cast<int>(gpsByteArrays.at(3).toDouble()/100);
			double gpsLat_2 = (gpsByteArrays.at(3).toDouble() - gpsLat_1 * 100)/60;
			if (ConvertCharArrayToQString(gpsByteArrays.at(4)) == ConvertCharArrayToQString("N"))
			{
				gpslat=gpsLat_1 + gpsLat_2;
			}
			if (ConvertCharArrayToQString(gpsByteArrays.at(4)) == ConvertCharArrayToQString("S"))
			{
				gpslat= -1 * (gpsLat_1 + gpsLat_2);
			}
			int gpsLon_1 = static_cast<int>(gpsByteArrays.at(5).toDouble()/100);
			double gpsLon_2 = (gpsByteArrays.at(5).toDouble()-gpsLon_1 * 100)/60;
			if (ConvertCharArrayToQString(gpsByteArrays.at(6)) == ConvertCharArrayToQString("E"))
			{
				gpsLon = gpsLon_1 + gpsLon_2;
			}
			if (ConvertCharArrayToQString(gpsByteArrays.at(6)) == ConvertCharArrayToQString("W"))
			{
				gpsLon = -1 * (gpsLon_1 + gpsLon_2);
			}
			ui->timelineEdit->setText(ConvertCharArrayToQString(gpsByteArrays.at(1)));
			ui->latlineEdit->setText(QString::number(gpslat,'g',9));
			ui->lonlineEdit->setText(QString::number(gpsLon,'g',9));
			gpsElevation = 0.0;
			ui->elevationlineEdit->setText(ConvertCharArrayToQString("NULL"));
		}
        else
		{
			ui->statusLabel->setText(ConvertCharArrayToQString("信号丢失!"));
			return;
		}
	}
}

2. $GNGGA

void CGPSPositionWidget::GPSParse(QByteArray GPSBuffer)
{
	double gpslat=0.0;
	double gpsLon=0.0;
	double gpsElevation=0.0;
	if (GPSBuffer.contains("$GNGGA"))
	{
		QList<QByteArray> gpsByteArrays = GPSBuffer.split(',');
		if (ConvertCharArrayToQString(gpsByteArrays.at(6)) != ConvertCharArrayToQString("0"))
		{
			if (ConvertCharArrayToQString(gpsByteArrays.at(6)) == ConvertCharArrayToQString("1"))
			{
				ui->statusLabel->setText(ConvertCharArrayToQString("已定位 标准GPS"));
			}
			else if (ConvertCharArrayToQString(gpsByteArrays.at(6)) == ConvertCharArrayToQString("2"))
			{
				ui->statusLabel->setText(ConvertCharArrayToQString("已定位 差分GPS"));
			}
			else
			{
				ui->statusLabel->setText(ConvertCharArrayToQString("已定位 惯导GPS"));
			}
			int  gpsLat_1 = static_cast<int>(gpsByteArrays.at(2).toDouble()/100);
			double gpsLat_2 = (gpsByteArrays.at(2).toDouble() - gpsLat_1 * 100)/60;
			if (ConvertCharArrayToQString(gpsByteArrays.at(3)) == ConvertCharArrayToQString("N"))
			{
				gpslat=gpsLat_1 + gpsLat_2;
			}
			if (ConvertCharArrayToQString(gpsByteArrays.at(3)) == ConvertCharArrayToQString("S"))
			{
				gpslat= -1 * (gpsLat_1 + gpsLat_2);
			}
			int gpsLon_1 = static_cast<int>(gpsByteArrays.at(4).toDouble()/100);
			double gpsLon_2 = (gpsByteArrays.at(4).toDouble()-gpsLon_1 * 100)/60;
			if (ConvertCharArrayToQString(gpsByteArrays.at(5)) == ConvertCharArrayToQString("E"))
			{
				gpsLon = gpsLon_1 + gpsLon_2;
			}
			if (ConvertCharArrayToQString(gpsByteArrays.at(5)) == ConvertCharArrayToQString("W"))
			{
				gpsLon = -1 * (gpsLon_1 + gpsLon_2);
			}
			ui->timelineEdit->setText(ConvertCharArrayToQString(gpsByteArrays.at(1)));
			ui->latlineEdit->setText(QString::number(gpslat,'g',9));
			ui->lonlineEdit->setText(QString::number(gpsLon,'g',9));
			gpsElevation = gpsByteArrays.at(9).toDouble();
			if(!gpsByteArrays.at(9).isEmpty())
			{
				ui->elevationlineEdit->setText(gpsByteArrays.at(9));
			}
		}
		else
		{
			ui->statusLabel->setText(ConvertCharArrayToQString("信号丢失!"));
			return;
		}
	
	}
}

总结

注:获取GPS报文协议一般需要读取串口信息,需要在头文件添加

#include <QSerialPort>
#include <QSerialPortInfo>

如使用Qt Creator开发需要在.pro文件添加

 QT += serialport

如果使用vs + Qt 插件开发则:右键解决方案-Qt Project Settings-Qt Modules,然后勾选Serial Port选项。

串口读取方法见串口读取(Qt C++)

评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值