source: ntrip/trunk/BNC/src/bncgetthread.cpp@ 6813

Last change on this file since 6813 was 6812, checked in by stoecker, 10 years ago

integrate RTCM3 parsing into BNC and directly fill target structures, add doxygen documentation

File size: 24.9 KB
RevLine 
[280]1// Part of BNC, a utility for retrieving decoding and
[464]2// converting GNSS data streams from NTRIP broadcasters.
[280]3//
[464]4// Copyright (C) 2007
[280]5// German Federal Agency for Cartography and Geodesy (BKG)
6// http://www.bkg.bund.de
[464]7// Czech Technical University Prague, Department of Geodesy
[280]8// http://www.fsv.cvut.cz
9//
10// Email: euref-ip@bkg.bund.de
11//
12// This program is free software; you can redistribute it and/or
13// modify it under the terms of the GNU General Public License
14// as published by the Free Software Foundation, version 2.
15//
16// This program is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU General Public License for more details.
20//
21// You should have received a copy of the GNU General Public License
22// along with this program; if not, write to the Free Software
23// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
[35]24
25/* -------------------------------------------------------------------------
[93]26 * BKG NTRIP Client
[35]27 * -------------------------------------------------------------------------
28 *
29 * Class: bncGetThread
30 *
31 * Purpose: Thread that retrieves data from NTRIP caster
32 *
33 * Author: L. Mervart
34 *
35 * Created: 24-Dec-2005
36 *
37 * Changes:
38 *
39 * -----------------------------------------------------------------------*/
40
[277]41#include <stdlib.h>
[1044]42#include <iomanip>
[1218]43#include <sstream>
[277]44
[35]45#include <QFile>
46#include <QTextStream>
[5524]47#include <QMutex>
[35]48#include <QtNetwork>
[356]49#include <QTime>
[35]50
51#include "bncgetthread.h"
[192]52#include "bnctabledlg.h"
[5070]53#include "bnccore.h"
[352]54#include "bncutils.h"
[423]55#include "bnczerodecoder.h"
[1621]56#include "bncnetqueryv0.h"
[1387]57#include "bncnetqueryv1.h"
58#include "bncnetqueryv2.h"
[1410]59#include "bncnetqueryrtp.h"
[1721]60#include "bncnetqueryudp.h"
[1779]61#include "bncnetqueryudp0.h"
[1753]62#include "bncnetquerys.h"
[1535]63#include "bncsettings.h"
[1558]64#include "latencychecker.h"
[3168]65#include "upload/bncrtnetdecoder.h"
[243]66#include "RTCM/RTCM2Decoder.h"
[297]67#include "RTCM3/RTCM3Decoder.h"
[1318]68#include "serial/qextserialport.h"
[35]69
70using namespace std;
71
[1143]72// Constructor 1
[35]73////////////////////////////////////////////////////////////////////////////
[2519]74bncGetThread::bncGetThread(bncRawFile* rawFile) {
[1138]75
[2519]76 _rawFile = rawFile;
77 _format = rawFile->format();
[3548]78 _staID = rawFile->staID();
[2519]79 _rawOutput = false;
[2390]80 _ntripVersion = "N";
81
[1555]82 initialize();
[1138]83}
84
[1143]85// Constructor 2
86////////////////////////////////////////////////////////////////////////////
[278]87bncGetThread::bncGetThread(const QUrl& mountPoint,
[366]88 const QByteArray& format,
89 const QByteArray& latitude,
90 const QByteArray& longitude,
[1353]91 const QByteArray& nmea,
[3527]92 const QByteArray& ntripVersion) {
[2519]93 _rawFile = 0;
[1555]94 _mountPoint = mountPoint;
[3003]95 _staID = mountPoint.path().mid(1).toAscii();
[1555]96 _format = format;
97 _latitude = latitude;
98 _longitude = longitude;
99 _nmea = nmea;
[1353]100 _ntripVersion = ntripVersion;
[1139]101
[2386]102 bncSettings settings;
103 if (!settings.value("rawOutFile").toString().isEmpty()) {
104 _rawOutput = true;
[3734]105 } else {
106 _rawOutput = false;
[2386]107 }
108
[1139]109 initialize();
[3523]110 initDecoder();
[1139]111}
112
[1555]113// Initialization (common part of the constructor)
[1143]114////////////////////////////////////////////////////////////////////////////
[1139]115void bncGetThread::initialize() {
116
[3528]117 bncSettings settings;
118
[1555]119 setTerminationEnabled(true);
120
121 connect(this, SIGNAL(newMessage(QByteArray,bool)),
[5068]122 BNC_CORE, SLOT(slotMessage(const QByteArray,bool)));
[1555]123
[1525]124 _isToBeDeleted = false;
[1555]125 _query = 0;
126 _nextSleep = 0;
[3528]127 _miscMount = settings.value("miscMount").toString();
[3560]128 _decoder = 0;
[255]129
[1555]130 // Serial Port
131 // -----------
[1710]132 _serialNMEA = NO_NMEA;
133 _serialOutFile = 0;
134 _serialPort = 0;
135
[3532]136 if (!_staID.isEmpty() &&
137 settings.value("serialMountPoint").toString() == _staID) {
[1710]138 _serialPort = new QextSerialPort(settings.value("serialPortName").toString() );
139 _serialPort->setTimeout(0,100);
140
141 // Baud Rate
142 // ---------
[1330]143 QString hlp = settings.value("serialBaudRate").toString();
144 if (hlp == "110") {
145 _serialPort->setBaudRate(BAUD110);
146 }
147 else if (hlp == "300") {
148 _serialPort->setBaudRate(BAUD300);
149 }
150 else if (hlp == "600") {
151 _serialPort->setBaudRate(BAUD600);
152 }
153 else if (hlp == "1200") {
154 _serialPort->setBaudRate(BAUD1200);
155 }
156 else if (hlp == "2400") {
157 _serialPort->setBaudRate(BAUD2400);
158 }
159 else if (hlp == "4800") {
160 _serialPort->setBaudRate(BAUD4800);
161 }
162 else if (hlp == "9600") {
163 _serialPort->setBaudRate(BAUD9600);
164 }
165 else if (hlp == "19200") {
166 _serialPort->setBaudRate(BAUD19200);
167 }
168 else if (hlp == "38400") {
169 _serialPort->setBaudRate(BAUD38400);
170 }
171 else if (hlp == "57600") {
172 _serialPort->setBaudRate(BAUD57600);
173 }
174 else if (hlp == "115200") {
175 _serialPort->setBaudRate(BAUD115200);
176 }
[1710]177
178 // Parity
179 // ------
[1330]180 hlp = settings.value("serialParity").toString();
181 if (hlp == "NONE") {
182 _serialPort->setParity(PAR_NONE);
183 }
184 else if (hlp == "ODD") {
185 _serialPort->setParity(PAR_ODD);
186 }
187 else if (hlp == "EVEN") {
188 _serialPort->setParity(PAR_EVEN);
189 }
190 else if (hlp == "SPACE") {
191 _serialPort->setParity(PAR_SPACE);
192 }
[1710]193
194 // Data Bits
195 // ---------
[1330]196 hlp = settings.value("serialDataBits").toString();
197 if (hlp == "5") {
198 _serialPort->setDataBits(DATA_5);
199 }
200 else if (hlp == "6") {
201 _serialPort->setDataBits(DATA_6);
202 }
203 else if (hlp == "7") {
204 _serialPort->setDataBits(DATA_7);
205 }
206 else if (hlp == "8") {
207 _serialPort->setDataBits(DATA_8);
208 }
209 hlp = settings.value("serialStopBits").toString();
210 if (hlp == "1") {
211 _serialPort->setStopBits(STOP_1);
212 }
213 else if (hlp == "2") {
214 _serialPort->setStopBits(STOP_2);
215 }
[1710]216
217 // Flow Control
218 // ------------
219 hlp = settings.value("serialFlowControl").toString();
[1711]220 if (hlp == "XONXOFF") {
[1710]221 _serialPort->setFlowControl(FLOW_XONXOFF);
222 }
223 else if (hlp == "HARDWARE") {
224 _serialPort->setFlowControl(FLOW_HARDWARE);
225 }
[1711]226 else {
227 _serialPort->setFlowControl(FLOW_OFF);
228 }
[1710]229
230 // Open Serial Port
231 // ----------------
[1326]232 _serialPort->open(QIODevice::ReadWrite|QIODevice::Unbuffered);
[1331]233 if (!_serialPort->isOpen()) {
234 delete _serialPort;
235 _serialPort = 0;
[1451]236 emit(newMessage((_staID + ": Cannot open serial port\n"), true));
[1331]237 }
[1606]238 connect(_serialPort, SIGNAL(readyRead()),
239 this, SLOT(slotSerialReadyRead()));
240
[1710]241 // Automatic NMEA
242 // --------------
[6785]243 QString nmeaMode = settings.value("serialAutoNMEA").toString();
244 if (nmeaMode == "Auto") {
[1710]245 _serialNMEA = AUTO_NMEA;
246 QString fName = settings.value("serialFileNMEA").toString();
247 if (!fName.isEmpty()) {
248 _serialOutFile = new QFile(fName);
249 if ( Qt::CheckState(settings.value("rnxAppend").toInt()) == Qt::Checked) {
250 _serialOutFile->open(QIODevice::WriteOnly | QIODevice::Append);
251 }
252 else {
253 _serialOutFile->open(QIODevice::WriteOnly);
254 }
[1634]255 }
[1606]256 }
[1710]257 // Manual NMEA
258 // -----------
[6785]259 if ((nmeaMode == "Manual GPGGA") ||(nmeaMode == "Manual GNGGA")) {
[1710]260 _serialNMEA = MANUAL_NMEA;
[6751]261 bncSettings settings;
262 _manualNMEASampl = settings.value("serialManualNMEASampling").toInt();
263 QString hlp = settings.value("serialHeightNMEA").toString();
264 if (hlp.isEmpty()) {
265 hlp = "0.0";
266 }
267 QByteArray _serialHeightNMEA = hlp.toAscii();
[6785]268 _manualNMEAString = ggaString(_latitude, _longitude, _serialHeightNMEA, nmeaMode);
[1636]269 }
[1318]270 }
271
[3532]272 if (!_staID.isEmpty()) {
273 _latencyChecker = new latencyChecker(_staID);
[2004]274 }
[3532]275 else {
276 _latencyChecker = 0;
277 }
[3523]278}
279
280// Instantiate the decoder
281//////////////////////////////////////////////////////////////////////////////
282t_irc bncGetThread::initDecoder() {
283
[3560]284 _decoder = 0;
285
[1744]286 if (_format.indexOf("RTCM_2") != -1 || _format.indexOf("RTCM2") != -1 ||
287 _format.indexOf("RTCM 2") != -1 ) {
[1555]288 emit(newMessage(_staID + ": Get data in RTCM 2.x format", true));
[3560]289 _decoder = new RTCM2Decoder(_staID.data());
[1555]290 }
[1744]291 else if (_format.indexOf("RTCM_3") != -1 || _format.indexOf("RTCM3") != -1 ||
292 _format.indexOf("RTCM 3") != -1 ) {
[1555]293 emit(newMessage(_staID + ": Get data in RTCM 3.x format", true));
[3558]294 RTCM3Decoder* newDecoder = new RTCM3Decoder(_staID, _rawFile);
[3560]295 _decoder = newDecoder;
[3558]296 connect((RTCM3Decoder*) newDecoder, SIGNAL(newMessage(QByteArray,bool)),
[1555]297 this, SIGNAL(newMessage(QByteArray,bool)));
298 }
299 else if (_format.indexOf("ZERO") != -1) {
300 emit(newMessage(_staID + ": Get data in original format", true));
[3560]301 _decoder = new bncZeroDecoder(_staID);
[1555]302 }
[3168]303 else if (_format.indexOf("RTNET") != -1) {
304 emit(newMessage(_staID + ": Get data in RTNet format", true));
[3560]305 _decoder = new bncRtnetDecoder();
[3168]306 }
[1555]307 else {
308 emit(newMessage(_staID + ": Unknown data format " + _format, true));
309 _isToBeDeleted = true;
[3523]310 return failure;
[1555]311 }
312
[319]313 msleep(100); //sleep 0.1 sec
[3523]314
[3560]315 _decoder->initRinex(_staID, _mountPoint, _latitude, _longitude,
316 _nmea, _ntripVersion);
317
318 if (_rawFile) {
319 _decodersRaw[_staID] = _decoder;
[3530]320 }
321
[3523]322 return success;
[35]323}
324
[3523]325// Current decoder in use
326////////////////////////////////////////////////////////////////////////////
327GPSDecoder* bncGetThread::decoder() {
[3560]328 if (!_rawFile) {
329 return _decoder;
[3523]330 }
331 else {
[3560]332 if (_decodersRaw.contains(_staID) || initDecoder() == success) {
333 return _decodersRaw[_staID];
334 }
[3523]335 }
[3560]336 return 0;
[3523]337}
338
[35]339// Destructor
340////////////////////////////////////////////////////////////////////////////
341bncGetThread::~bncGetThread() {
[1928]342 if (isRunning()) {
343 wait();
344 }
[1527]345 if (_query) {
346 _query->stop();
[1708]347 _query->deleteLater();
[1527]348 }
[3560]349 if (_rawFile) {
350 QMapIterator<QString, GPSDecoder*> it(_decodersRaw);
351 while (it.hasNext()) {
352 it.next();
353 delete it.value();
354 }
[3523]355 }
[3560]356 else {
357 delete _decoder;
358 }
[2519]359 delete _rawFile;
[1607]360 delete _serialOutFile;
[1328]361 delete _serialPort;
[1557]362 delete _latencyChecker;
[1556]363 emit getThreadFinished(_staID);
[35]364}
365
[1390]366//
367////////////////////////////////////////////////////////////////////////////
368void bncGetThread::terminate() {
[1525]369 _isToBeDeleted = true;
[1559]370 if (!isRunning()) {
371 delete this;
372 }
[1390]373}
374
[136]375// Run
376////////////////////////////////////////////////////////////////////////////
377void bncGetThread::run() {
378
[35]379 while (true) {
[629]380 try {
[1555]381 if (_isToBeDeleted) {
382 QThread::exit(0);
383 this->deleteLater();
384 return;
[629]385 }
[621]386
[1555]387 if (tryReconnect() != success) {
[3532]388 if (_latencyChecker) {
389 _latencyChecker->checkReconnect();
390 }
[1555]391 continue;
[621]392 }
[1555]393
394 // Delete old observations
395 // -----------------------
[3560]396 if (_rawFile) {
397 QMapIterator<QString, GPSDecoder*> itDec(_decodersRaw);
398 while (itDec.hasNext()) {
399 itDec.next();
400 GPSDecoder* decoder = itDec.value();
401 decoder->_obsList.clear();
402 }
[3515]403 }
[3560]404 else {
405 _decoder->_obsList.clear();
406 }
[621]407
[1555]408 // Read Data
409 // ---------
[1377]410 QByteArray data;
411 if (_query) {
412 _query->waitForReadyRead(data);
[1138]413 }
[2519]414 else if (_rawFile) {
[2527]415 data = _rawFile->readChunk();
[3523]416 _format = _rawFile->format();
417 _staID = _rawFile->staID();
[2388]418
[5903]419 QCoreApplication::processEvents();
420
[1555]421 if (data.isEmpty()) {
422 cout << "no more data" << endl;
[5068]423 BNC_CORE->stopCombination();
[5900]424 BNC_CORE->stopPPP();
[5903]425 ::exit(0);
[1555]426 }
[1138]427 }
[1555]428 qint64 nBytes = data.size();
[1138]429
[1555]430 // Timeout, reconnect
431 // ------------------
432 if (nBytes == 0) {
[3532]433 if (_latencyChecker) {
434 _latencyChecker->checkReconnect();
435 }
[1555]436 emit(newMessage(_staID + ": Data timeout, reconnecting", true));
[2355]437 msleep(10000); //sleep 10 sec, G. Weber
[1555]438 continue;
439 }
440 else {
[567]441 emit newBytes(_staID, nBytes);
[5648]442 emit newRawData(_staID, data);
[1555]443 }
[567]444
[1555]445 // Output Data
446 // -----------
[2386]447 if (_rawOutput) {
[5068]448 BNC_CORE->writeRawData(data, _staID, _format);
[2386]449 }
[2385]450
[1555]451 if (_serialPort) {
[1633]452 slotSerialReadyRead();
[1555]453 _serialPort->write(data);
454 }
[5647]455
[1555]456 // Decode Data
457 // -----------
458 vector<string> errmsg;
[3526]459 if (!decoder()) {
460 _isToBeDeleted = true;
461 continue;
462 }
[3523]463 decoder()->_obsList.clear();
464 t_irc irc = decoder()->Decode(data.data(), data.size(), errmsg);
[1137]465
[1555]466 // Perform various scans and checks
467 // --------------------------------
[3532]468 if (_latencyChecker) {
469 _latencyChecker->checkOutage(irc == success);
470 _latencyChecker->checkObsLatency(decoder()->_obsList);
471 _latencyChecker->checkCorrLatency(decoder()->corrGPSEpochTime());
472
473 emit newLatency(_staID, _latencyChecker->currentLatency());
474 }
[1567]475
[1555]476 scanRTCM();
[1138]477
[1555]478 // Loop over all observations (observations output)
479 // ------------------------------------------------
[6137]480 QListIterator<t_satObs> it(decoder()->_obsList);
[5524]481
[6137]482 QList<t_satObs> obsListHlp;
[5524]483
[1555]484 while (it.hasNext()) {
[6137]485 const t_satObs& obs = it.next();
[2711]486
[6137]487 QString prn(obs._prn.toString().c_str());
488 long iSec = long(floor(obs._time.gpssec()+0.5));
489 long obsTime = obs._time.gpsw()*7*24*3600 + iSec;
[3303]490
[1555]491 // Check observation epoch
492 // -----------------------
[5739]493 if (!_rawFile) {
[3303]494 int week;
[1555]495 double sec;
496 currentGPSWeeks(week, sec);
[3304]497 long currTime = week * 7*24*3600 + long(sec);
[1555]498 const double maxDt = 600.0;
[3303]499 if (fabs(currTime - obsTime) > maxDt) {
[2308]500 emit( newMessage(_staID + ": Wrong observation epoch(s)", false) );
[1555]501 continue;
[940]502 }
[686]503 }
[6812]504
[3305]505 // Check observations coming twice (e.g. KOUR0 Problem)
506 // ----------------------------------------------------
[3535]507 if (!_rawFile) {
508 QMap<QString, long>::const_iterator it = _prnLastEpo.find(prn);
509 if (it != _prnLastEpo.end()) {
510 long oldTime = it.value();
511 if (obsTime < oldTime) {
512 emit( newMessage(_staID +
513 ": old observation " + prn.toAscii(), false));
514 continue;
515 }
516 else if (obsTime == oldTime) {
517 emit( newMessage(_staID +
518 ": observation coming more than once " + prn.toAscii(), false));
519 continue;
520 }
[3302]521 }
[3535]522 _prnLastEpo[prn] = obsTime;
[3301]523 }
524
[3528]525 decoder()->dumpRinexEpoch(obs, _format);
526
[5524]527 // Save observations
528 // -----------------
529 obsListHlp.append(obs);
530 }
[2030]531
[5524]532 // Emit signal
533 // -----------
534 if (!_isToBeDeleted && obsListHlp.size() > 0) {
535 emit newObs(_staID, obsListHlp);
[249]536 }
[5524]537
[3523]538 decoder()->_obsList.clear();
[35]539 }
[3311]540 catch (Exception& exc) {
541 emit(newMessage(_staID + " " + exc.what(), true));
542 _isToBeDeleted = true;
543 }
[1555]544 catch (...) {
[3311]545 emit(newMessage(_staID + " bncGetThread exception", true));
[1559]546 _isToBeDeleted = true;
[1555]547 }
[35]548 }
549}
550
[136]551// Try Re-Connect
552////////////////////////////////////////////////////////////////////////////
[1555]553t_irc bncGetThread::tryReconnect() {
554
555 // Easy Return
556 // -----------
557 if (_query && _query->status() == bncNetQuery::running) {
558 _nextSleep = 0;
[3560]559 if (_rawFile) {
560 QMapIterator<QString, GPSDecoder*> itDec(_decodersRaw);
561 while (itDec.hasNext()) {
562 itDec.next();
563 GPSDecoder* decoder = itDec.value();
564 decoder->setRinexReconnectFlag(false);
565 }
[1709]566 }
[3560]567 else {
568 _decoder->setRinexReconnectFlag(false);
569 }
[1555]570 return success;
[408]571 }
[1555]572
573 // Start a new query
574 // -----------------
[2519]575 if (!_rawFile) {
[1555]576
[138]577 sleep(_nextSleep);
[1555]578 if (_nextSleep == 0) {
579 _nextSleep = 1;
[138]580 }
581 else {
[1555]582 _nextSleep = 2 * _nextSleep;
[442]583 if (_nextSleep > 256) {
584 _nextSleep = 256;
[152]585 }
[1816]586#ifdef MLS_SOFTWARE
[1817]587 if (_nextSleep > 4) {
588 _nextSleep = 4;
[1816]589 }
590#endif
[138]591 }
[1555]592
593 delete _query;
[1722]594 if (_ntripVersion == "U") {
[1721]595 _query = new bncNetQueryUdp();
596 }
[1722]597 else if (_ntripVersion == "R") {
[1555]598 _query = new bncNetQueryRtp();
599 }
[1744]600 else if (_ntripVersion == "S") {
[1753]601 _query = new bncNetQueryS();
[1744]602 }
[1621]603 else if (_ntripVersion == "N") {
604 _query = new bncNetQueryV0();
605 }
[1779]606 else if (_ntripVersion == "UN") {
607 _query = new bncNetQueryUdp0();
608 }
[1555]609 else if (_ntripVersion == "2") {
[3337]610 _query = new bncNetQueryV2(false);
[1555]611 }
[3334]612 else if (_ntripVersion == "2s") {
[3337]613 _query = new bncNetQueryV2(true);
[3334]614 }
[1555]615 else {
616 _query = new bncNetQueryV1();
617 }
[6770]618 if (_nmea == "yes") {
619 if (_serialNMEA == MANUAL_NMEA) {
620 _query->startRequest(_mountPoint, _manualNMEAString);
621 _lastManualNMEA = QDateTime::currentDateTime();
622 }
623 else if (_serialNMEA == AUTO_NMEA) {
624 if (_serialPort) {
625 int nb = _serialPort->bytesAvailable();
626 if (nb > 0) {
627 QByteArray data = _serialPort->read(nb);
628 int i1 = data.indexOf("$GPGGA");
629 if (i1 == -1) {
630 i1 = data.indexOf("$GNGGA");
631 }
632 if (i1 != -1) {
633 int i2 = data.indexOf("*", i1);
634 if (i2 != -1 && data.size() > i2 + 1) {
635 QByteArray gga = data.mid(i1, i2 - i1 + 3);
636 _query->startRequest(_mountPoint, gga);
637 }
638 }
639 }
640 }
641 }
[1555]642 }
643 else {
644 _query->startRequest(_mountPoint, "");
645 }
[6770]646
[1555]647 if (_query->status() != bncNetQuery::running) {
648 return failure;
649 }
[138]650 }
[658]651
[3560]652 if (_rawFile) {
653 QMapIterator<QString, GPSDecoder*> itDec(_decodersRaw);
654 while (itDec.hasNext()) {
655 itDec.next();
656 GPSDecoder* decoder = itDec.value();
657 decoder->setRinexReconnectFlag(false);
658 }
[658]659 }
[3560]660 else {
661 _decoder->setRinexReconnectFlag(false);
662 }
[1555]663
664 return success;
[658]665}
[1044]666
[1555]667// RTCM scan output
[1044]668//////////////////////////////////////////////////////////////////////////////
[1555]669void bncGetThread::scanRTCM() {
[1044]670
[4476]671 if ( !decoder() ) {
[3558]672 return;
673 }
674
[1555]675 bncSettings settings;
[1574]676 if ( Qt::CheckState(settings.value("scanRTCM").toInt()) == Qt::Checked ) {
677
678 if ( _miscMount == _staID || _miscMount == "ALL" ) {
[1575]679 // RTCM message types
680 // ------------------
[4476]681 for (int ii = 0; ii < decoder()->_typeList.size(); ii++) {
[3523]682 QString type = QString("%1 ").arg(decoder()->_typeList[ii]);
[1574]683 emit(newMessage(_staID + ": Received message type " + type.toAscii(), true));
684 }
[1044]685
[4476]686 // Check Observation Types
687 // -----------------------
688 for (int ii = 0; ii < decoder()->_obsList.size(); ii++) {
[6137]689 t_satObs& obs = decoder()->_obsList[ii];
690 QVector<QString>& rnxTypes = _rnxTypes[obs._prn.system()];
[4476]691 bool allFound = true;
[6137]692 for (unsigned iFrq = 0; iFrq < obs._obs.size(); iFrq++) {
[6579]693 if (obs._obs[iFrq]->_codeValid) {
694 QString rnxStr('C');
695 rnxStr.append(obs._obs[iFrq]->_rnxType2ch.c_str());
[6580]696 if (_format.indexOf("RTCM_2") != -1 ||
697 _format.indexOf("RTCM2") != -1 ||
698 _format.indexOf("RTCM 2") != -1 ) {
699 rnxStr = t_rnxObsFile::type3to2(obs._prn.system(), rnxStr);
700 }
[6579]701 if (rnxTypes.indexOf(rnxStr) == -1) {
702 rnxTypes.push_back(rnxStr);
703 allFound = false;
704 }
[4476]705 }
[6579]706 if (obs._obs[iFrq]->_phaseValid) {
707 QString rnxStr('L');
708 rnxStr.append(obs._obs[iFrq]->_rnxType2ch.c_str());
[6580]709 if (_format.indexOf("RTCM_2") != -1 ||
710 _format.indexOf("RTCM2") != -1 ||
711 _format.indexOf("RTCM 2") != -1 ) {
712 rnxStr = t_rnxObsFile::type3to2(obs._prn.system(), rnxStr);
713 }
[6579]714 if (rnxTypes.indexOf(rnxStr) == -1) {
715 rnxTypes.push_back(rnxStr);
716 allFound = false;
717 }
718 }
719 if (obs._obs[iFrq]->_dopplerValid){
720 QString rnxStr('D');
721 rnxStr.append(obs._obs[iFrq]->_rnxType2ch.c_str());
[6580]722 if (_format.indexOf("RTCM_2") != -1 ||
723 _format.indexOf("RTCM2") != -1 ||
724 _format.indexOf("RTCM 2") != -1 ) {
725 rnxStr = t_rnxObsFile::type3to2(obs._prn.system(), rnxStr);
726 }
[6579]727 if (rnxTypes.indexOf(rnxStr) == -1) {
728 rnxTypes.push_back(rnxStr);
729 allFound = false;
730 }
731 }
732 if (obs._obs[iFrq]->_snrValid){
733 QString rnxStr('S');
734 rnxStr.append(obs._obs[iFrq]->_rnxType2ch.c_str());
[6580]735 if (_format.indexOf("RTCM_2") != -1 ||
736 _format.indexOf("RTCM2") != -1 ||
737 _format.indexOf("RTCM 2") != -1 ) {
738 rnxStr = t_rnxObsFile::type3to2(obs._prn.system(), rnxStr);
739 }
[6579]740 if (rnxTypes.indexOf(rnxStr) == -1) {
741 rnxTypes.push_back(rnxStr);
742 allFound = false;
743 }
744 }
[4476]745 }
746 if (!allFound) {
[4477]747 QString msg;
748 QTextStream str(&msg);
[6579]749 QString s;
750 str << obs._prn.system() << " " << s.sprintf("%2d", rnxTypes.size()) << " ";
[4476]751 for (int iType = 0; iType < rnxTypes.size(); iType++) {
[4478]752 str << " " << rnxTypes[iType];
[4476]753 }
[4477]754 emit(newMessage(_staID + ": Observation Types: " + msg.toAscii(), true));
[4476]755 }
756 }
757
[1574]758 // RTCMv3 antenna descriptor
759 // -------------------------
[4476]760 for (int ii = 0; ii < decoder()->_antType.size(); ii++) {
[3523]761 QString ant1 = QString("%1 ").arg(decoder()->_antType[ii]);
[1574]762 emit(newMessage(_staID + ": Antenna descriptor " + ant1.toAscii(), true));
763 }
[1555]764
[1575]765 // RTCM Antenna Coordinates
766 // ------------------------
[4476]767 for (int ii=0; ii < decoder()->_antList.size(); ii++) {
[1574]768 QByteArray antT;
[3523]769 if (decoder()->_antList[ii].type == GPSDecoder::t_antInfo::ARP) {
[1574]770 antT = "ARP";
771 }
[3523]772 else if (decoder()->_antList[ii].type == GPSDecoder::t_antInfo::APC) {
[1574]773 antT = "APC";
774 }
[1575]775 QByteArray ant1, ant2, ant3;
[3523]776 ant1 = QString("%1 ").arg(decoder()->_antList[ii].xx,0,'f',4).toAscii();
777 ant2 = QString("%1 ").arg(decoder()->_antList[ii].yy,0,'f',4).toAscii();
778 ant3 = QString("%1 ").arg(decoder()->_antList[ii].zz,0,'f',4).toAscii();
[1575]779 emit(newMessage(_staID + ": " + antT + " (ITRF) X " + ant1 + "m", true));
780 emit(newMessage(_staID + ": " + antT + " (ITRF) Y " + ant2 + "m", true));
781 emit(newMessage(_staID + ": " + antT + " (ITRF) Z " + ant3 + "m", true));
[3595]782 double hh = 0.0;
[3523]783 if (decoder()->_antList[ii].height_f) {
[3595]784 hh = decoder()->_antList[ii].height;
785 QByteArray ant4 = QString("%1 ").arg(hh,0,'f',4).toAscii();
[1575]786 emit(newMessage(_staID + ": Antenna height above marker " + ant4 + "m", true));
787 }
[3523]788 emit(newAntCrd(_staID, decoder()->_antList[ii].xx,
789 decoder()->_antList[ii].yy, decoder()->_antList[ii].zz,
[3595]790 hh, antT));
[1218]791 }
792 }
[1044]793 }
[1575]794
[1770]795#ifdef MLS_SOFTWARE
[3523]796 for (int ii=0; ii <decoder()->_antList.size(); ii++) {
[1770]797 QByteArray antT;
[3523]798 if (decoder()->_antList[ii].type == GPSDecoder::t_antInfo::ARP) {
[1770]799 antT = "ARP";
800 }
[3523]801 else if (decoder()->_antList[ii].type == GPSDecoder::t_antInfo::APC) {
[1770]802 antT = "APC";
803 }
[3595]804 double hh = 0.0;
805 if (decoder()->_antList[ii].height_f) {
806 hh = decoder()->_antList[ii].height;
807 }
[3523]808 emit(newAntCrd(_staID, decoder()->_antList[ii].xx,
809 decoder()->_antList[ii].yy, decoder()->_antList[ii].zz,
[3595]810 hh, antT));
[1770]811 }
[2356]812
[3523]813 for (int ii = 0; ii <decoder()->_typeList.size(); ii++) {
814 emit(newRTCMMessage(_staID, decoder()->_typeList[ii]));
[2356]815 }
[1770]816#endif
817
[3523]818 decoder()->_typeList.clear();
819 decoder()->_antType.clear();
820 decoder()->_antList.clear();
[1044]821}
[1555]822
[1606]823// Handle Data from Serial Port
824////////////////////////////////////////////////////////////////////////////
825void bncGetThread::slotSerialReadyRead() {
[6770]826
[1607]827 if (_serialPort) {
[6770]828
[6773]829 if (_nmea == "yes" && _serialNMEA == MANUAL_NMEA) {
830 if (_manualNMEASampl) {
831 int dt = _lastManualNMEA.secsTo(QDateTime::currentDateTime());
832 if (dt && (fmod(double(dt), double(_manualNMEASampl)) == 0.0)) {
833 _query->sendNMEA(_manualNMEAString);
834 _lastManualNMEA = QDateTime::currentDateTime();
835 }
836 }
837 }
838
[1633]839 int nb = _serialPort->bytesAvailable();
840 if (nb > 0) {
841 QByteArray data = _serialPort->read(nb);
[1711]842
[6695]843 if (_nmea == "yes" && _serialNMEA == AUTO_NMEA) {
[1725]844 int i1 = data.indexOf("$GPGGA");
[6651]845 if (i1 == -1) {
846 i1 = data.indexOf("$GNGGA");
847 }
[1725]848 if (i1 != -1) {
[6751]849 int i2 = data.indexOf("*", i1);
[1725]850 if (i2 != -1 && data.size() > i2 + 1) {
[6751]851 QByteArray gga = data.mid(i1, i2 - i1 + 3);
[1725]852 _query->sendNMEA(gga);
[6751]853 }
854 }
[1711]855 }
856
[1633]857 if (_serialOutFile) {
858 _serialOutFile->write(data);
859 _serialOutFile->flush();
860 }
[1607]861 }
862 }
[1606]863}
Note: See TracBrowser for help on using the repository browser.