基于Qt的车载GPS监控系统(6)GPS信息处理

GPS模块(NEO-6M UBLOX)

GPS模块通过串口同tiny6410开发板连接,向开发板传递GPS定位信息(NMEA-0183协议)。

NMEA-0183 协议简介

NMEA 0183是美国国家海洋电子协会(National Marine Electronics Association)为海用电子设备制定的标准格式。目前业已成了GPS导航设备统一的RTCM(Radio Technical Commission for Maritime services)标准协议。

NMEA-0183协议采用ASCII码来传递GPS定位信息,我们称之为帧。

$GPRMC(推荐定位信息,Recommended Minimum Specific GPS/Transit Data)

GPRMCGPRMC,(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)*hh(CR)(LF)

例如:
$GPRMC,033308.00,A,3022.29739,N,11454.04296,E,0.044,,111116,,,A*75

(1) UTC时间,hhmmss(时分秒)
(2) 定位状态,A=有效定位,V=无效定位
(3) 纬度ddmm.mmmmm(度分)
(4) 纬度半球N(北半球)或S(南半球)
(5) 经度dddmm.mmmmm(度分)
(6) 经度半球E(东经)或W(西经)
(7) 地面速率(000.0~999.9节)
(8) 地面航向(000.0~359.9度,以真北方为参考基准)
(9) UTC日期,ddmmyy(日月年)
(10)磁偏角(000.0~180.0度,前导位数不足则补0)
(11) 磁偏角方向,E(东)或W(西)
(12) 模式指示(A=自主定位,D=差分,E=估算,N=数据无效)

串口接收GPS完整数据

$GPRMC,033308.00,A,3022.29739,N,11454.04296,E,0.044,,111116,,,A*75                                 
$GPVTG,,T,,M,0.044,N,0.081,K,A*2A                                                                  
$GPGGA,033308.00,3022.29739,N,11454.04296,E,1,08,0.96,115.5,M,-9.0,M,,*4D                          
$GPGSA,A,3,05,02,06,19,12,09,25,29,,,,,1.75,0.96,1.46*02                                           
$GPGSV,4,1,14,02,63,013,38,05,64,281,33,06,43,074,31,07,01,084,*71                                 
$GPGSV,4,2,14,09,18,043,27,12,24,249,32,13,24,179,,15,02,203,*7F                                   
$GPGSV,4,3,14,17,13,148,,19,30,147,20,20,14,249,18,25,16,288,27*7F                                 
$GPGSV,4,4,14,29,12,321,25,30,01,113,*72                                                           
$GPGLL,3022.29739,N,11454.04296,E,033308.00,A,A*6B   

GPS信息解析函数


//GPS信息
struct st_gps_info{
    double  latitude;                       //经度
    double  longitude;                      //纬度
    float   speed;                          //速度
    float   direction;                      //航向
    unsigned char NS;
    unsigned char EW;
};


int GpsDialog::getGPSinfo(QString& str)
{
    st_gps_info gps;
    QString cHead = "$GPRMC";
    QString tmp;
    bool ok;
    str = str.mid(str.indexOf(cHead,1),100);
    str = str.section('$',1,1);
    qDebug() << str;
    tmp = str.section(',',2,2);
    if(tmp == "V"){
        postion = tr("无效定位");
        return -1;
    }
    tmp = str.section(',',3,3);
    qDebug() << tmp;
    gps.longitude = tmp.toDouble(&ok)/100;
    tmp = str.section(',',5,5);
    gps.latitude = tmp.toDouble(&ok)/100;
    tmp = str.section(',',4,4);
    if(tmp == "N")
        gps.NS = 'N';
    else
        gps.NS = 'S';
    tmp = str.section(',',6,6);
    if(tmp == "E")
        gps.EW = 'E';
    else
        gps.EW = 'W';
    tmp = str.section(',',7,7);
    gps.speed = tmp.toFloat(&ok)*1.85;
    tmp = str.section(',',8,8);
    gps.direction = tmp.toFloat(&ok);
    if(gps.NS == 'N')
        postion = tr("北纬: ");
    else
        postion = tr("南纬: ");
    postion += QString::number(gps.longitude,'f',2);
    postion += "    ";
    if(gps.EW == 'E')
        postion += tr("东经: ");
    else
        postion += tr("西经: ");
    postion += QString::number(gps.latitude,'f',2);

    speed = tr("时速: ");
    speed += QString::number(gps.speed,'f',2);
    speed += " Km/H";
    speed += "    ";
    speed += tr("方向(北偏): ");
    speed += QString::number(gps.direction,'f',2);
    speed += tr("度");
    return 0;
}

GPS调试信息

com_info===== 
"$GPRMC,045424.00,A,3022.29979,N,11454.03987,E,0.516,,111116,,,A*79
$GPVTG,,T,,M,0.516,N,0.956,K,A*2B
$GPGGA,045424.00,3022.29979,N,11454.03987,E,1,09,1.02,124.6,M,-9.0,M,,*4F
$GPGSA,A,3,05,02,06,07,20,29,13,30,15,,,,1.82,1.02,1.50*04
$GPGSV,3,1,12,02,57,095,29,04,71,104,31,05,59,009,27,06,22,112,17*7D
$GPGSV,3,2,12,07,06,051,15,12,03,219,10,13,64,169,20,15,37,209,14*73
$GPGSV,3,3,12,20,37,282,30,25,03,254,,29,41,302,32,30,14,081,28*7B
$GPGLL,3022.29979,N,11454.03987,E,045424.00,A,A*65
" 
section====== 
"GPRMC,045424.00,A,3022.29979,N,11454.03987,E,0.516,,111116,,,A*79
" 
tmp===== 
"3022.29979" 

Qt程序运行界面

头文件

#ifndef GPSDIALOG_H
#define GPSDIALOG_H
#include <QtGui>
#include "mapwidget.h"

#define COM0 "/dev/ttyUSB0"

class GpsDialog:public QDialog
{
    Q_OBJECT
public:
    GpsDialog(QWidget *parent = 0);
    int gpsInit(void);
    int getGPSinfo(QString& str);
public slots:
    void gpsRun(void);
private:
    int fd_gps;
    char* buff;
    QString postion;
    QString speed;
    MapWidget *mapGps;
    QGridLayout *layout;
    QLabel *labelBg;
    QLineEdit *lineGps;
    QLineEdit *lineSpeed;
    QToolButton *toolButton;
};

#endif // GPSDIALOG_H

实现源程序

#include "gpsdialog.h"
#include "dht9000.h"


GpsDialog::GpsDialog( QWidget *parent)
    : QDialog( parent)
{
    this->setMinimumSize(800,480);
    this->setMaximumSize(800,480);
    //窗口标题
    this->setWindowIcon(QPixmap( ":/images/1.png") );
    this->setWindowTitle(tr("GP9001车载GPS监控系统"));
    //窗口背景
    labelBg = new QLabel(this);
    labelBg->setGeometry(QRect(0, 0, 800, 480));
    labelBg->setPixmap(QPixmap(":/images/9001bg.jpg"));
    labelBg->setScaledContents(true);

    //计时器对象,1秒钟发送一个timeout()信号,调用showState()函数
    QTimer *timer = new QTimer(this);
    timer->start(1000);
    connect(timer, SIGNAL(timeout()), this, SLOT(gpsRun()));

    postion = "GPS no init.";
    buff = (char*)malloc(1024);

    mapGps = new MapWidget(this);

    lineGps = new QLineEdit(this);
    lineGps->setReadOnly(true);
    lineGps->setAlignment(Qt::AlignHCenter);
    lineGps->setText(tr("经度:123.44 纬度:34.54"));

    lineSpeed = new QLineEdit(this);
    lineSpeed->setReadOnly(true);
    lineSpeed->setAlignment(Qt::AlignHCenter);
    lineSpeed->setText(QString::number(12.55,'f',2)+tr("公里/小时"));

    toolButton = new QToolButton(this);
    toolButton->setText( tr( "返  回" ) );
    toolButton->setIcon( QPixmap( ":/images/6.png") );
    toolButton->setIconSize( QPixmap( ":/images/6.png").size() );
    toolButton->setAutoRaise( TRUE );
    toolButton->setToolButtonStyle( Qt::ToolButtonTextUnderIcon);
    connect(toolButton,SIGNAL(clicked()),this,SLOT(accept()));

    gpsInit();

    layout = new QGridLayout;
    layout->setSpacing(5);
    layout->addWidget(mapGps,1,0,1,3);
    layout->addWidget(lineGps,2,0);
    layout->addWidget(toolButton,2,1);
    layout->addWidget(lineSpeed,2,2);
    setLayout(layout);
}

int GpsDialog::getGPSinfo(QString& str)
{
    st_gps_info gps;
    QString cHead = "$GPRMC";
    QString tmp;
    bool ok;
    str = str.mid(str.indexOf(cHead,1),100);
    str = str.section('$',1,1);
    qDebug() << "section======" <<endl  << str;
    tmp = str.section(',',2,2);
    if(tmp == "V"){
        postion = tr("无效定位");
        return -1;
    }
    tmp = str.section(',',3,3);
    qDebug() << "tmp=====" <<endl << tmp;
    gps.longitude = tmp.toDouble(&ok)/100;
    tmp = str.section(',',5,5);
    gps.latitude = tmp.toDouble(&ok)/100;
    tmp = str.section(',',4,4);
    if(tmp == "N")
        gps.NS = 'N';
    else
        gps.NS = 'S';
    tmp = str.section(',',6,6);
    if(tmp == "E")
        gps.EW = 'E';
    else
        gps.EW = 'W';
    tmp = str.section(',',7,7);
    gps.speed = tmp.toFloat(&ok)*1.85;
    tmp = str.section(',',8,8);
    gps.direction = tmp.toFloat(&ok);
    if(gps.NS == 'N')
        postion = tr("北纬: ");
    else
        postion = tr("南纬: ");
    postion += QString::number(gps.longitude,'f',2);
    postion += "    ";
    if(gps.EW == 'E')
        postion += tr("东经: ");
    else
        postion += tr("西经: ");
    postion += QString::number(gps.latitude,'f',2);

    speed = tr("时速: ");
    speed += QString::number(gps.speed,'f',2);
    speed += " Km/H";
    speed += "    ";
    speed += tr("方向(北偏): ");
    speed += QString::number(gps.direction,'f',2);
    speed += tr("度");
    return 0;
}

void GpsDialog::gpsRun(){
    int nread;
    QString gpsInfo;
    memset(buff,0,1024);
    if((nread = read(fd_gps,buff,1024))>0){
        gpsInfo = buff;

        qDebug() << "com_info=====" << endl  << gpsInfo;
        if(gpsInfo.length()>0)
            this->getGPSinfo(gpsInfo);
    }else{
        postion = "GPS recvie error.";
        speed = postion;
    }
    lineGps->setText(postion);
    lineSpeed->setText(speed);
}


int GpsDialog::gpsInit(void){
    fd_gps = ::open(COM0,O_RDONLY);
    if(fd_gps < 0){
            postion = "Can't Open Serial Port!";
            postion += COM0;
            return -1;
    }
    if(init_com(fd_gps) < 0){
            postion = "Serial Init error!";
            return -1;
    }
    postion = "GPS init OK.";
    lineGps->setText(postion);
    return 0;
}

Copyright © 2016 www.91arm.com 【91创客学堂】