2015-06-06 2 views
1

Я пытаюсь написать простое приложение, которое будет имитировать аппаратное устройство GPS, основываясь на уже принятом файле журнала . Технология, которую я выбрал, - Qt5.4.1. потому что он уже получил класс, который должен заботиться о задаче, которую я пытаюсь сделать. Название класса: QNmeaPositionInfoSource. Я предположил, что, установив правильный интервал времени ожидания обновления, QNmeaPositionInfoSource уведомит меня о новой позиции. Однако, когда я устанавливаю интервал в 1s, я получаю только одну позицию, и после этого тайм-аут уведомляется. Когда я устанавливаю интервал 0, я получаю сразу все уведомления о позиции.Разбор * .nmea с ключом QNmeaPositionInfoSource возвращает таймаут.

Пожалуйста найти код моей программы ниже:

mainwindow.cpp

#include <QDebug> 
#include <QFile> 
#include <QNmeaPositionInfoSource> 
#include "mainwindow.h" 
#include "ui_mainwindow.h" 

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 
    logFile = new QFile(":/files/dummy.nmea"); 
    nmeaSource = new QNmeaPositionInfoSource(
     QNmeaPositionInfoSource::SimulationMode); 
    nmeaSource->setDevice(logFile); 
    nmeaSource->setUpdateInterval(1000); 
    connect(nmeaSource, SIGNAL(positionUpdated(QGeoPositionInfo)), 
      this, SLOT(positionUpdated(QGeoPositionInfo))); 
    connect(nmeaSource, SIGNAL(updateTimeout()), this, SLOT(updateTimeout())); 
    connect(nmeaSource,SIGNAL(error(QGeoPositionInfoSource::Error)), 
      this,SLOT(error(QGeoPositionInfoSource::Error))); 
    nmeaSource->startUpdates(); 
} 

MainWindow::~MainWindow() 
{ 
    delete ui; 
} 

void MainWindow::positionUpdated(QGeoPositionInfo positionInfo) 
{ 
    qDebug() << __PRETTY_FUNCTION__; 
    qDebug() << QString("Lat: %1").arg(QString::number(positionInfo.coordinate().latitude())); 
    qDebug() << QString("Lon: %1").arg(QString::number(positionInfo.coordinate().longitude())); 
} 

void MainWindow::updateTimeout(void) 
{ 
    qDebug() << __PRETTY_FUNCTION__; 
} 

void MainWindow::error(QGeoPositionInfoSource::Error positioningError) 
{ 
    qDebug() << __PRETTY_FUNCTION__; 
    qDebug() << QString::number(positioningError); 
} 

mainwindow.h

#ifndef MAINWINDOW_H 
#define MAINWINDOW_H 

#include <QMainWindow> 
#include <QGeoPositionInfo> 
#include <QGeoPositionInfoSource> 

class QFile; 
class QNmeaPositionInfoSource; 
//class QGeoPositionInfoSource; 

namespace Ui 
{ 
     class MainWindow; 
} 

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    explicit MainWindow(QWidget *parent = 0); 
    ~MainWindow(); 

private: 
    Ui::MainWindow *ui; 
    QFile *logFile; 
    QNmeaPositionInfoSource *nmeaSource; 
private slots: 
     void positionUpdated(QGeoPositionInfo positionInfo); 
     void updateTimeout(void); 
     void error(QGeoPositionInfoSource::Error positioningError); 
}; 

#endif // MAINWINDOW_H 

dummy.nmea

$GPGGA,222437.000,2734.33926,S,15305.44310,E,1,07,1.3,50.6,M,39.2,M,,*72 
$GPGLL,2734.33926,S,15305.44310,E,222437.000,A,A*49 
$GPGSA,A,3,16,25,23,20,13,27,11,,,,,,2.3,1.3,1.9*3D 
$GPGST,222437.000,13.3,7.4,6.6,85.1,6.0,6.8,13.7*56 
$GPGSV,3,1,10,16,49,115,42,25,39,269,36,23,58,176,29,20,72,335,35*75 
$GPGSV,3,2,10,19,02,028,,04,06,241,22,13,30,223,30,27,19,284,35*78 
$GPGSV,3,3,10,11,06,337,30,03,13,055,25*7C 
$GPRMC,222437.000,A,2734.33926,S,15305.44310,E,33.9,157.8,030308,11.2,W,A*0F 
$GPVTG,157.8,T,169.0,M,33.9,N,62.9,K,A*22 
$GPGGA,222438.000,2734.34821,S,15305.44697,E,1,07,1.2,50.8,M,39.2,M,,*79 
$GPGLL,2734.34821,S,15305.44697,E,222438.000,A,A*4D 
$GPGSA,A,3,16,25,23,20,13,27,03,,,,,,2.1,1.2,1.7*33 
$GPGST,222438.000,12.4,6.4,9.3,16.2,6.1,8.3,16.4*5F 
$GPGSV,3,1,10,16,49,115,41,25,39,269,36,23,58,176,28,20,72,335,36*74 
$GPGSV,3,2,10,19,02,028,,04,06,241,20,13,30,223,28,27,19,284,35*73 
$GPGSV,3,3,10,11,06,337,28,03,13,055,25*75 
$GPRMC,222438.000,A,2734.34821,S,15305.44697,E,33.8,158.3,030308,11.2,W,A*0E 
$GPVTG,158.3,T,169.5,M,33.8,N,62.5,K,A*2E 
$GPGGA,222439.000,2734.35696,S,15305.45072,E,1,06,1.7,51.2,M,39.2,M,,*78 
$GPGLL,2734.35696,S,15305.45072,E,222439.000,A,A*43 
$GPGSA,A,3,16,25,23,20,13,27,,,,,,,3.3,1.7,2.8*3A 
$GPGST,222439.000,10.3,9.1,12.2,44.6,9.8,9.9,25.2*62 
$GPGSV,3,1,10,16,49,115,34,25,39,269,36,23,58,175,29,20,72,335,35*77 
$GPGSV,3,2,10,19,02,028,,04,06,241,20,13,30,223,27,27,19,284,32*7B 
$GPGSV,3,3,10,11,06,337,28,03,14,055,25*72 
$GPRMC,222439.000,A,2734.35696,S,15305.45072,E,33.2,158.7,030308,11.2,W,A*0E 
$GPVTG,158.7,T,169.9,M,33.2,N,61.5,K,A*2F 
$GPGGA,222440.000,2734.36580,S,15305.45446,E,1,07,1.3,52.0,M,39.2,M,,*76 
$GPGLL,2734.36580,S,15305.45446,E,222440.000,A,A*49 
$GPGSA,A,3,16,25,23,20,13,27,11,,,,,,2.3,1.3,1.9*3D 
$GPGST,222440.000,13.0,8.0,13.4,6.2,7.4,12.2,20.9*64 
$GPGSV,3,1,10,16,49,115,40,25,39,269,38,23,58,175,31,20,72,335,34*72 
$GPGSV,3,2,10,19,02,028,,04,06,241,20,13,30,223,26,27,19,284,30*78 
$GPGSV,3,3,10,11,06,337,26,03,14,055,25*7C 
$GPRMC,222440.000,A,2734.36580,S,15305.45446,E,33.7,159.1,030308,11.2,W,A*06 
$GPVTG,159.1,T,170.3,M,33.7,N,62.4,K,A*2D 
$GPGGA,222441.000,2734.37483,S,15305.45825,E,1,07,1.3,52.7,M,39.2,M,,*7A 
$GPGLL,2734.37483,S,15305.45825,E,222441.000,A,A*42 
$GPGSA,A,3,16,25,23,20,13,27,11,,,,,,2.3,1.3,1.9*3D 
$GPGST,222441.000,14.0,7.6,14.1,17.6,7.7,12.5,21.0*51 
$GPGSV,3,1,10,16,49,115,41,25,39,269,39,23,58,175,29,20,72,335,35*7A 
$GPGSV,3,2,10,19,02,028,,04,06,241,20,13,30,223,24,27,19,284,30*7A 
$GPGSV,3,3,10,11,06,337,28,03,14,055,25*72 
$GPRMC,222441.000,A,2734.37483,S,15305.45825,E,34.6,159.4,030308,11.2,W,A*0E 
$GPVTG,159.4,T,170.6,M,34.6,N,64.1,K,A*28 
$GPGGA,222442.000,2734.38407,S,15305.46216,E,1,06,1.3,53.3,M,39.2,M,,*77 
$GPGLL,2734.38407,S,15305.46216,E,222442.000,A,A*4B 
$GPGSA,A,3,16,25,20,13,27,11,,,,,,,2.3,1.3,1.9*3C 
$GPGST,222442.000,16.6,7.0,14.4,14.6,7.0,12.8,21.6*5A 
$GPGSV,3,1,10,16,49,115,40,25,39,269,38,23,58,175,22,20,72,335,35*71 

Вопрос почему Я получаю время извещение?

+0

Вы решили это? Я пытаюсь сделать то же самое с той же проблемой: вызывается только updateTimeout(). И это никогда не восстанавливается. Я попытался отфильтровать все, кроме GPGGA и GPRMC, как предлагает другой ответ, но это не исправить. И удаление или изменение интервала обновления тоже не было. Спасибо – Hhut

+0

Нет, я не исправил это, я только что написал парсер nmea самостоятельно. Просто загляните в источники Qt, это хорошая база для этой задачи. – Lazureus

ответ

0

Encounter с той же проблемой.

Он будет работать так, как он есть, если вы оставите только строки $ GPGGA и $ GPRMC в файле NMEA. $ GPVTG действительно вызывает описанную вами проблему, $ GPGSV - нет (так что вы можете оставить его тоже, а не важно). Другие сообщения NMEA Я не тестировал отдельно.

«Чистый» файл NMEA работает отлично, как описано в справке: даже без вызова setUpdateInterval() (по-видимому, такой же, как и с нулевым аргументом) вы получите интервалы обновления в соответствии с отметками времени в линиях NMEA.

Это, очевидно, ошибка Qt. Даже если вы запустите пример GeoFlickr на рабочем столе (чтобы начать работу с QNmeaPositionInfoSource в SimulationMode), вы увидите, что нажатие кнопки «Найти & обновление» отображает данные о широте и долготе только один раз при первом щелчке. После этого он показывает «получение обновления», и ничего не происходит, но в соответствии с кодом он должен.

Еще одно подтверждение того, что дело может быть только в сообщениях $ GPVTG: вместо вашего «dummy.nmea» «nmealog.txt» из примера GeoFlickr я использовал два вызова positionUpdated до таймаута. Один для $ GPGGA и один для $ GPRMC. Однако в вашем «dummy.nmea» есть только одно сообщение $ GPRMC перед $ GPVTG, поэтому вы уведомили только о одном вызове positionUpdated.

(только в случае, если играть с тем, что на Qt5.5.1 на Windows 7)

+0

Это не сработало для меня. Я попытался отфильтровать входной поток только для GPGGA и GPRMC. Но до тех пор, пока я не удалил GPRMC, я получил хотя бы ответ об ошибке, отличный от тайм-аута, который говорит: дата и время недоступны. Что подсказывает, что он обрабатывает поток nmea, но не сигнализирует правильно? – Hhut

0

Я просмотрел источники Qt и пришли к следующему выводу. Если вы комментируете строку nmeaSource->setUpdateInterval(1000); или установить значение 0, то пример будет работать, как и следовало ожидать, поскольку в документации к QGeoPositionInfoSource говорит:

Если интервал обновления не установлен (или установлен в 0) источник будет предоставлять обновления так часто, как это необходимо.

Inspite тот факт, что вы установили ненулевое значение для setUpdateInterval() функции в SimulationMode исходный файл (dummy.nmea) читается все сразу, так что нет никаких новых данных, доступных для чтения и поэтому тайм-аут происходит , Несколько строк из источников Qt:

// some data may already be available 
if (m_updateMode == QNmeaPositionInfoSource::SimulationMode) { 
    if (m_nmeaReader && m_device->bytesAvailable()) 
     m_nmeaReader->readAvailableData(); 

Я не уверен, является ли это ошибка или нет, но я думаю, что некоторая информация может быть добавлена ​​в отношении этого к документации Qt.