source: ntrip/trunk/BNC/src/RTCM3/RTCM3coDecoder.cpp @ 9048

Last change on this file since 9048 was 9048, checked in by stuerze, 2 months ago

minor changes

File size: 23.4 KB
Line 
1// Part of BNC, a utility for retrieving decoding and
2// converting GNSS data streams from NTRIP broadcasters.
3//
4// Copyright (C) 2007
5// German Federal Agency for Cartography and Geodesy (BKG)
6// http://www.bkg.bund.de
7// Czech Technical University Prague, Department of Geodesy
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.
24
25/* -------------------------------------------------------------------------
26 * BKG NTRIP Client
27 * -------------------------------------------------------------------------
28 *
29 * Class:      RTCM3coDecoder
30 *
31 * Purpose:    RTCM3 Clock Orbit Decoder
32 *
33 * Author:     L. Mervart
34 *
35 * Created:    05-May-2008
36 *
37 * Changes:
38 *
39 * -----------------------------------------------------------------------*/
40
41#include <stdio.h>
42#include <math.h>
43
44#include "RTCM3coDecoder.h"
45#include "bncutils.h"
46#include "bncrinex.h"
47#include "bnccore.h"
48#include "bncsettings.h"
49#include "bnctime.h"
50
51using namespace std;
52
53// Constructor
54////////////////////////////////////////////////////////////////////////////
55RTCM3coDecoder::RTCM3coDecoder(const QString& staID) {
56
57  _staID = staID;
58
59  // File Output
60  // -----------
61  bncSettings settings;
62  QString path = settings.value("corrPath").toString();
63  if (!path.isEmpty()) {
64    expandEnvVar(path);
65    if ( path.length() > 0 && path[path.length()-1] != QDir::separator() ) {
66      path += QDir::separator();
67    }
68    _fileNameSkl = path + staID;
69  }
70  _out = 0;
71
72  connect(this, SIGNAL(newOrbCorrections(QList<t_orbCorr>)),
73          BNC_CORE, SLOT(slotNewOrbCorrections(QList<t_orbCorr>)));
74
75  connect(this, SIGNAL(newClkCorrections(QList<t_clkCorr>)),
76          BNC_CORE, SLOT(slotNewClkCorrections(QList<t_clkCorr>)));
77
78  connect(this, SIGNAL(newCodeBiases(QList<t_satCodeBias>)),
79          BNC_CORE, SLOT(slotNewCodeBiases(QList<t_satCodeBias>)));
80
81  connect(this, SIGNAL(newPhaseBiases(QList<t_satPhaseBias>)),
82          BNC_CORE, SLOT(slotNewPhaseBiases(QList<t_satPhaseBias>)));
83
84  connect(this, SIGNAL(newTec(t_vTec)),
85          BNC_CORE, SLOT(slotNewTec(t_vTec)));
86
87  connect(this, SIGNAL(providerIDChanged(QString)),
88          BNC_CORE, SIGNAL(providerIDChanged(QString)));
89
90  connect(this, SIGNAL(newMessage(QByteArray,bool)),
91          BNC_CORE, SLOT(slotMessage(const QByteArray,bool)));
92
93  reset();
94
95  _providerID[0] = -1;
96  _providerID[1] = -1;
97  _providerID[2] = -1;
98
99  _ssrCorr = 0;
100}
101
102// Destructor
103////////////////////////////////////////////////////////////////////////////
104RTCM3coDecoder::~RTCM3coDecoder() {
105  delete _out;
106  delete _ssrCorr;
107  _IODs.clear();
108  _orbCorrections.clear();
109  _clkCorrections.clear();
110  _lastClkCorrections.clear();
111  _codeBiases.clear();
112  _phaseBiases.clear();
113  _vTecMap.clear();
114}
115
116//
117////////////////////////////////////////////////////////////////////////////
118void RTCM3coDecoder::reset() {
119  memset(&_clkOrb,    0, sizeof(_clkOrb));
120  memset(&_codeBias,  0, sizeof(_codeBias));
121  memset(&_phaseBias, 0, sizeof(_phaseBias));
122  memset(&_vTEC,      0, sizeof(_vTEC));
123}
124
125// Reopen Output File
126////////////////////////////////////////////////////////////////////////
127void RTCM3coDecoder::reopen() {
128
129  if (!_fileNameSkl.isEmpty()) {
130
131    bncSettings settings;
132
133    QDateTime datTim = currentDateAndTimeGPS();
134
135    QString hlpStr = bncRinex::nextEpochStr(datTim,
136                                      settings.value("corrIntr").toString(), false);
137
138    QString fileNameHlp = _fileNameSkl
139      + QString("%1").arg(datTim.date().dayOfYear(), 3, 10, QChar('0'))
140      + hlpStr + datTim.toString(".yyC");
141
142    if (_fileName == fileNameHlp) {
143      return;
144    }
145    else {
146      _fileName = fileNameHlp;
147    }
148
149    delete _out;
150    if ( Qt::CheckState(settings.value("rnxAppend").toInt()) == Qt::Checked) {
151      _out = new ofstream( _fileName.toLatin1().data(), ios_base::out | ios_base::app );
152    }
153    else {
154      _out = new ofstream( _fileName.toLatin1().data() );
155    }
156  }
157}
158
159//
160////////////////////////////////////////////////////////////////////////////
161t_irc RTCM3coDecoder::Decode(char* buffer, int bufLen, vector<string>& errmsg) {
162
163  errmsg.clear();
164
165  _buffer.append(QByteArray(buffer,bufLen));
166
167  t_irc retCode = failure;
168
169  while(_buffer.size()) {
170
171    struct SsrCorr::ClockOrbit clkOrbSav;
172    struct SsrCorr::CodeBias   codeBiasSav;
173    struct SsrCorr::PhaseBias  phaseBiasSav;
174    struct SsrCorr::VTEC       vTECSav;
175    memcpy(&clkOrbSav,    &_clkOrb,    sizeof(clkOrbSav)); // save state
176    memcpy(&codeBiasSav,  &_codeBias,  sizeof(codeBiasSav));
177    memcpy(&phaseBiasSav, &_phaseBias, sizeof(phaseBiasSav));
178    memcpy(&vTECSav,      &_vTEC,      sizeof(vTECSav));
179
180    int bytesused = 0;
181    if (_type == e_type::RTCMssr) {
182      _ssrCorr = new SsrCorrRtcm();
183    }
184    else {
185      _ssrCorr = new SsrCorrIgs();
186    }
187    GCOB_RETURN irc = _ssrCorr->GetSSR(&_clkOrb, &_codeBias, &_vTEC, &_phaseBias,
188                             _buffer.data(), _buffer.size(), &bytesused);
189
190    if      (irc <= -30) { // not enough data - restore state and exit loop
191      memcpy(&_clkOrb,    &clkOrbSav,    sizeof(clkOrbSav));
192      memcpy(&_codeBias,  &codeBiasSav,  sizeof(codeBiasSav));
193      memcpy(&_phaseBias, &phaseBiasSav, sizeof(phaseBiasSav));
194      memcpy(&_vTEC,      &vTECSav,      sizeof(vTECSav));
195      break;
196    }
197
198    else if (irc < 0) {    // error  - skip 1 byte and retry
199      reset();
200      _buffer = _buffer.mid(bytesused ? bytesused : 1);
201    }
202
203    else {                 // OK or MESSAGEFOLLOWS
204      _buffer = _buffer.mid(bytesused);
205
206      if (irc == GCOBR_OK || irc == GCOBR_MESSAGEFOLLOWS ) {
207
208        setEpochTime(); // sets _lastTime
209
210        if (_lastTime.valid()) {
211          reopen();
212          checkProviderID();
213          sendResults();
214          retCode = success;
215        }
216        else {
217          retCode = failure;
218        }
219
220        reset();
221      }
222    }
223  }
224
225  return retCode;
226}
227
228//
229////////////////////////////////////////////////////////////////////////////
230void RTCM3coDecoder::sendResults() {
231
232  // Orbit and clock corrections of all satellites
233  // ---------------------------------------------
234  for (unsigned ii = 0; ii <  CLOCKORBIT_NUMGPS
235                            + CLOCKORBIT_NUMGLONASS
236                            + CLOCKORBIT_NUMGALILEO
237                            + CLOCKORBIT_NUMQZSS
238                            + CLOCKORBIT_NUMSBAS
239                            + _clkOrb.NumberOfSat[CLOCKORBIT_SATBDS];
240    ii++) {
241    char sysCh = ' ';
242    int flag = 0;
243    if      (ii < _clkOrb.NumberOfSat[CLOCKORBIT_SATGPS]) {
244      sysCh = 'G';
245    }
246    else if (ii >= CLOCKORBIT_OFFSETGLONASS &&
247        ii < CLOCKORBIT_OFFSETGLONASS + _clkOrb.NumberOfSat[CLOCKORBIT_SATGLONASS]) {
248      sysCh = 'R';
249    }
250    else if (ii >= CLOCKORBIT_OFFSETGALILEO &&
251        ii < CLOCKORBIT_OFFSETGALILEO + _clkOrb.NumberOfSat[CLOCKORBIT_SATGALILEO]) {
252      sysCh = 'E';
253      flag = 1; // I/NAV clock has been chosen as reference clock for Galileo SSR corrections
254    }
255    else if (ii >= CLOCKORBIT_OFFSETQZSS &&
256        ii < CLOCKORBIT_OFFSETQZSS + _clkOrb.NumberOfSat[CLOCKORBIT_SATQZSS]) {
257      sysCh = 'J';
258    }
259    else if (ii >= CLOCKORBIT_OFFSETSBAS &&
260        ii < CLOCKORBIT_OFFSETSBAS + _clkOrb.NumberOfSat[CLOCKORBIT_SATSBAS]) {
261      sysCh = 'S';
262    }
263    else if (ii >= CLOCKORBIT_OFFSETBDS &&
264        ii < CLOCKORBIT_OFFSETBDS + _clkOrb.NumberOfSat[CLOCKORBIT_SATBDS]) {
265      sysCh = 'C';
266    }
267    else {
268      continue;
269    }
270
271    // Orbit correction
272    // ----------------
273    if ( _clkOrb.messageType == _ssrCorr->COTYPE_GPSCOMBINED     ||
274         _clkOrb.messageType == _ssrCorr->COTYPE_GLONASSCOMBINED ||
275         _clkOrb.messageType == _ssrCorr->COTYPE_GALILEOCOMBINED ||
276         _clkOrb.messageType == _ssrCorr->COTYPE_QZSSCOMBINED ||
277         _clkOrb.messageType == _ssrCorr->COTYPE_SBASCOMBINED ||
278         _clkOrb.messageType == _ssrCorr->COTYPE_BDSCOMBINED ||
279         _clkOrb.messageType == _ssrCorr->COTYPE_GPSORBIT ||
280         _clkOrb.messageType == _ssrCorr->COTYPE_GLONASSORBIT ||
281         _clkOrb.messageType == _ssrCorr->COTYPE_GALILEOORBIT ||
282         _clkOrb.messageType == _ssrCorr->COTYPE_QZSSORBIT ||
283         _clkOrb.messageType == _ssrCorr->COTYPE_SBASORBIT ||
284         _clkOrb.messageType == _ssrCorr->COTYPE_BDSORBIT ) {
285
286      t_orbCorr orbCorr;
287      orbCorr._prn.set(sysCh, _clkOrb.Sat[ii].ID, flag);
288      orbCorr._staID     = _staID.toStdString();
289      orbCorr._iod       = _clkOrb.Sat[ii].IOD;
290      orbCorr._time      = _lastTime;
291      orbCorr._updateInt = _clkOrb.UpdateInterval;
292      orbCorr._system    = sysCh;
293      orbCorr._xr[0]     = _clkOrb.Sat[ii].Orbit.DeltaRadial;
294      orbCorr._xr[1]     = _clkOrb.Sat[ii].Orbit.DeltaAlongTrack;
295      orbCorr._xr[2]     = _clkOrb.Sat[ii].Orbit.DeltaCrossTrack;
296      orbCorr._dotXr[0]  = _clkOrb.Sat[ii].Orbit.DotDeltaRadial;
297      orbCorr._dotXr[1]  = _clkOrb.Sat[ii].Orbit.DotDeltaAlongTrack;
298      orbCorr._dotXr[2]  = _clkOrb.Sat[ii].Orbit.DotDeltaCrossTrack;
299
300      _orbCorrections[_lastTime].append(orbCorr);
301
302      _IODs[orbCorr._prn] = _clkOrb.Sat[ii].IOD;
303    }
304
305    // Clock Corrections
306    // -----------------
307    if ( _clkOrb.messageType == _ssrCorr->COTYPE_GPSCOMBINED     ||
308         _clkOrb.messageType == _ssrCorr->COTYPE_GLONASSCOMBINED ||
309         _clkOrb.messageType == _ssrCorr->COTYPE_GALILEOCOMBINED ||
310         _clkOrb.messageType == _ssrCorr->COTYPE_QZSSCOMBINED ||
311         _clkOrb.messageType == _ssrCorr->COTYPE_SBASCOMBINED ||
312         _clkOrb.messageType == _ssrCorr->COTYPE_BDSCOMBINED ||
313         _clkOrb.messageType == _ssrCorr->COTYPE_GPSCLOCK ||
314         _clkOrb.messageType == _ssrCorr->COTYPE_GLONASSCLOCK ||
315         _clkOrb.messageType == _ssrCorr->COTYPE_GALILEOCLOCK ||
316         _clkOrb.messageType == _ssrCorr->COTYPE_QZSSCLOCK ||
317         _clkOrb.messageType == _ssrCorr->COTYPE_SBASCLOCK ||
318         _clkOrb.messageType == _ssrCorr->COTYPE_BDSCLOCK) {
319
320      t_clkCorr clkCorr;
321      clkCorr._prn.set(sysCh, _clkOrb.Sat[ii].ID, flag);
322      clkCorr._staID      = _staID.toStdString();
323      clkCorr._time       = _lastTime;
324      clkCorr._updateInt  = _clkOrb.UpdateInterval;
325      clkCorr._dClk       = _clkOrb.Sat[ii].Clock.DeltaA0 / t_CST::c;
326      clkCorr._dotDClk    = _clkOrb.Sat[ii].Clock.DeltaA1 / t_CST::c;
327      clkCorr._dotDotDClk = _clkOrb.Sat[ii].Clock.DeltaA2 / t_CST::c;
328
329      _lastClkCorrections[clkCorr._prn] = clkCorr;
330
331      if (_IODs.contains(clkCorr._prn)) {
332        clkCorr._iod = _IODs[clkCorr._prn];
333        _clkCorrections[_lastTime].append(clkCorr);
334      }
335    }
336
337    // High-Resolution Clocks
338    // ----------------------
339    if ( _clkOrb.messageType == _ssrCorr->COTYPE_GPSHR     ||
340         _clkOrb.messageType == _ssrCorr->COTYPE_GLONASSHR ||
341         _clkOrb.messageType == _ssrCorr->COTYPE_GALILEOHR ||
342         _clkOrb.messageType == _ssrCorr->COTYPE_QZSSHR ||
343         _clkOrb.messageType == _ssrCorr->COTYPE_SBASHR ||
344         _clkOrb.messageType == _ssrCorr->COTYPE_BDSHR) {
345      t_prn prn(sysCh, _clkOrb.Sat[ii].ID, flag);
346      if (_lastClkCorrections.contains(prn)) {
347        t_clkCorr clkCorr;
348        clkCorr            = _lastClkCorrections[prn];
349        clkCorr._time      = _lastTime;
350        clkCorr._updateInt = _clkOrb.UpdateInterval;
351        clkCorr._dClk     += _clkOrb.Sat[ii].hrclock / t_CST::c;
352        if (_IODs.contains(clkCorr._prn)) {
353          clkCorr._iod = _IODs[clkCorr._prn];
354          _clkCorrections[_lastTime].push_back(clkCorr);
355        }
356      }
357    }
358  }
359
360  // Code Biases
361  // -----------
362  for (unsigned ii = 0; ii <  CLOCKORBIT_NUMGPS
363                            + CLOCKORBIT_NUMGLONASS
364                            + CLOCKORBIT_NUMGALILEO
365                            + CLOCKORBIT_NUMQZSS
366                            + CLOCKORBIT_NUMSBAS
367                            + _codeBias.NumberOfSat[CLOCKORBIT_SATBDS];
368    ii++) {
369    char sysCh = ' ';
370    if      (ii < _codeBias.NumberOfSat[CLOCKORBIT_SATGPS]) {
371      sysCh = 'G';
372    }
373    else if (ii >= CLOCKORBIT_OFFSETGLONASS &&
374        ii < CLOCKORBIT_OFFSETGLONASS + _codeBias.NumberOfSat[CLOCKORBIT_SATGLONASS]) {
375      sysCh = 'R';
376    }
377    else if (ii >= CLOCKORBIT_OFFSETGALILEO &&
378        ii < CLOCKORBIT_OFFSETGALILEO + _codeBias.NumberOfSat[CLOCKORBIT_SATGALILEO]) {
379      sysCh = 'E';
380    }
381    else if (ii >= CLOCKORBIT_OFFSETQZSS &&
382        ii < CLOCKORBIT_OFFSETQZSS + _codeBias.NumberOfSat[CLOCKORBIT_SATQZSS]) {
383      sysCh = 'J';
384    }
385    else if (ii >= CLOCKORBIT_OFFSETSBAS &&
386        ii < CLOCKORBIT_OFFSETSBAS + _codeBias.NumberOfSat[CLOCKORBIT_SATSBAS]) {
387      sysCh = 'S';
388    }
389    else if (ii >= CLOCKORBIT_OFFSETBDS &&
390        ii < CLOCKORBIT_OFFSETBDS + _codeBias.NumberOfSat[CLOCKORBIT_SATBDS]) {
391      sysCh = 'C';
392    }
393    else {
394      continue;
395    }
396    t_satCodeBias satCodeBias;
397    satCodeBias._prn.set(sysCh, _codeBias.Sat[ii].ID);
398    satCodeBias._staID     = _staID.toStdString();
399    satCodeBias._time      = _lastTime;
400    satCodeBias._updateInt = _codeBias.UpdateInterval;
401    for (unsigned jj = 0; jj < _codeBias.Sat[ii].NumberOfCodeBiases; jj++) {
402      const SsrCorr::CodeBias::BiasSat::CodeBiasEntry& biasEntry = _codeBias.Sat[ii].Biases[jj];
403      t_frqCodeBias frqCodeBias;
404      frqCodeBias._rnxType2ch.assign(_ssrCorr->codeTypeToRnxType(sysCh, biasEntry.Type));
405      frqCodeBias._value      = biasEntry.Bias;
406      if (!frqCodeBias._rnxType2ch.empty()) {
407        satCodeBias._bias.push_back(frqCodeBias);
408      }
409    }
410    _codeBiases[_lastTime].append(satCodeBias);
411  }
412
413  // Phase Biases
414  // -----------
415  for (unsigned ii = 0; ii <  CLOCKORBIT_NUMGPS
416                            + CLOCKORBIT_NUMGLONASS
417                            + CLOCKORBIT_NUMGALILEO
418                            + CLOCKORBIT_NUMQZSS
419                            + CLOCKORBIT_NUMSBAS
420                            + _phaseBias.NumberOfSat[CLOCKORBIT_SATBDS];
421    ii++) {
422    char sysCh = ' ';
423    if      (ii < _phaseBias.NumberOfSat[CLOCKORBIT_SATGPS]) {
424      sysCh = 'G';
425    }
426    else if (ii >= CLOCKORBIT_OFFSETGLONASS &&
427        ii < CLOCKORBIT_OFFSETGLONASS + _phaseBias.NumberOfSat[CLOCKORBIT_SATGLONASS]) {
428      sysCh = 'R';
429    }
430    else if (ii >= CLOCKORBIT_OFFSETGALILEO &&
431        ii < CLOCKORBIT_OFFSETGALILEO + _phaseBias.NumberOfSat[CLOCKORBIT_SATGALILEO]) {
432      sysCh = 'E';
433    }
434    else if (ii >= CLOCKORBIT_OFFSETQZSS &&
435        ii < CLOCKORBIT_OFFSETQZSS + _phaseBias.NumberOfSat[CLOCKORBIT_SATQZSS]) {
436      sysCh = 'J';
437    }
438    else if (ii >= CLOCKORBIT_OFFSETSBAS &&
439        ii < CLOCKORBIT_OFFSETSBAS + _phaseBias.NumberOfSat[CLOCKORBIT_SATSBAS]) {
440      sysCh = 'S';
441    }
442    else if (ii >= CLOCKORBIT_OFFSETBDS &&
443        ii < CLOCKORBIT_OFFSETBDS + _phaseBias.NumberOfSat[CLOCKORBIT_SATBDS]) {
444      sysCh = 'C';
445    }
446    else {
447      continue;
448    }
449    t_satPhaseBias satPhaseBias;
450    satPhaseBias._prn.set(sysCh, _phaseBias.Sat[ii].ID);
451    satPhaseBias._staID      = _staID.toStdString();
452    satPhaseBias._time       = _lastTime;
453    satPhaseBias._updateInt  = _phaseBias.UpdateInterval;
454    satPhaseBias._dispBiasConstistInd = _phaseBias.DispersiveBiasConsistencyIndicator;
455    satPhaseBias._MWConsistInd        = _phaseBias.MWConsistencyIndicator;
456    satPhaseBias._yaw     = _phaseBias.Sat[ii].YawAngle;
457    satPhaseBias._yawRate = _phaseBias.Sat[ii].YawRate;
458    for (unsigned jj = 0; jj < _phaseBias.Sat[ii].NumberOfPhaseBiases; jj++) {
459      const SsrCorr::PhaseBias::PhaseBiasSat::PhaseBiasEntry& biasEntry = _phaseBias.Sat[ii].Biases[jj];
460      t_frqPhaseBias frqPhaseBias;
461      frqPhaseBias._rnxType2ch.assign(_ssrCorr->codeTypeToRnxType(sysCh, biasEntry.Type));
462      frqPhaseBias._value                = biasEntry.Bias;
463      frqPhaseBias._fixIndicator         = biasEntry.SignalIntegerIndicator;
464      frqPhaseBias._fixWideLaneIndicator = biasEntry.SignalsWideLaneIntegerIndicator;
465      frqPhaseBias._jumpCounter          = biasEntry.SignalDiscontinuityCounter;
466      if (!frqPhaseBias._rnxType2ch.empty()) {
467        satPhaseBias._bias.push_back(frqPhaseBias);
468      }
469    }
470    _phaseBiases[_lastTime].append(satPhaseBias);
471  }
472
473  // Ionospheric Model
474  // -----------------
475  if (_vTEC.NumLayers > 0) {
476    _vTecMap[_lastTime]._time  = _lastTime;
477    _vTecMap[_lastTime]._updateInt =  _vTEC.UpdateInterval;
478    _vTecMap[_lastTime]._staID = _staID.toStdString();
479    for (unsigned ii = 0; ii < _vTEC.NumLayers; ii++) {
480      const SsrCorr::VTEC::IonoLayers& ionoLayer = _vTEC.Layers[ii];
481      t_vTecLayer layer;
482      layer._height = ionoLayer.Height;
483      layer._C.ReSize(ionoLayer.Degree+1, ionoLayer.Order+1);
484      layer._S.ReSize(ionoLayer.Degree+1, ionoLayer.Order+1);
485      for (unsigned iDeg = 0; iDeg <= ionoLayer.Degree; iDeg++) {
486        for (unsigned iOrd = 0; iOrd <= ionoLayer.Order; iOrd++) {
487          layer._C[iDeg][iOrd] = ionoLayer.Cosinus[iDeg][iOrd];
488          layer._S[iDeg][iOrd] = ionoLayer.Sinus[iDeg][iOrd];
489        }
490      }
491      _vTecMap[_lastTime]._layers.push_back(layer);
492    }
493  }
494
495  // Dump all older epochs
496  // ---------------------
497  QMutableMapIterator<bncTime, QList<t_orbCorr> > itOrb(_orbCorrections);
498  while (itOrb.hasNext()) {
499    itOrb.next();
500    if (itOrb.key() < _lastTime) {
501      emit newOrbCorrections(itOrb.value());
502      t_orbCorr::writeEpoch(_out, itOrb.value());
503      itOrb.remove();
504    }
505  }
506  QMutableMapIterator<bncTime, QList<t_clkCorr> > itClk(_clkCorrections);
507  while (itClk.hasNext()) {
508    itClk.next();
509    if (itClk.key() < _lastTime) {
510      emit newClkCorrections(itClk.value());
511      t_clkCorr::writeEpoch(_out, itClk.value());
512      itClk.remove();
513    }
514  }
515  QMutableMapIterator<bncTime, QList<t_satCodeBias> > itCB(_codeBiases);
516  while (itCB.hasNext()) {
517    itCB.next();
518    if (itCB.key() < _lastTime) {
519      emit newCodeBiases(itCB.value());
520      t_satCodeBias::writeEpoch(_out, itCB.value());
521      itCB.remove();
522    }
523  }
524  QMutableMapIterator<bncTime, QList<t_satPhaseBias> > itPB(_phaseBiases);
525  while (itPB.hasNext()) {
526    itPB.next();
527    if (itPB.key() < _lastTime) {
528      emit newPhaseBiases(itPB.value());
529      t_satPhaseBias::writeEpoch(_out, itPB.value());
530      itPB.remove();
531    }
532  }
533  QMutableMapIterator<bncTime, t_vTec> itTec(_vTecMap);
534  while (itTec.hasNext()) {
535    itTec.next();
536    if (itTec.key() < _lastTime) {
537      emit newTec(itTec.value());
538      t_vTec::write(_out, itTec.value());
539      itTec.remove();
540    }
541  }
542}
543
544//
545////////////////////////////////////////////////////////////////////////////
546void RTCM3coDecoder::checkProviderID() {
547
548  if (_clkOrb.SSRProviderID == 0 && _clkOrb.SSRSolutionID == 0 && _clkOrb.SSRIOD == 0) {
549    return;
550  }
551
552  int newProviderID[3];
553  newProviderID[0] = _clkOrb.SSRProviderID;
554  newProviderID[1] = _clkOrb.SSRSolutionID;
555  newProviderID[2] = _clkOrb.SSRIOD;
556
557  bool alreadySet = false;
558  bool different  = false;
559
560  for (unsigned ii = 0; ii < 3; ii++) {
561    if (_providerID[ii] != -1) {
562      alreadySet = true;
563    }
564    if (_providerID[ii] != newProviderID[ii]) {
565      different = true;
566    }
567    _providerID[ii] = newProviderID[ii];
568  }
569
570  if (alreadySet && different) {
571    emit newMessage("RTCM3coDecoder: Provider Changed: " + _staID.toLatin1(), true);
572    emit providerIDChanged(_staID);
573  }
574}
575
576//
577////////////////////////////////////////////////////////////////////////////
578void RTCM3coDecoder::setEpochTime() {
579
580  _lastTime.reset();
581
582  double epoSecGPS  = -1.0;
583  double epoSecGlo  = -1.0;
584  double epoSecGal  = -1.0;
585  double epoSecQzss = -1.0;
586  double epoSecSbas = -1.0;
587  double epoSecBds  = -1.0;
588  if      (_clkOrb.NumberOfSat[CLOCKORBIT_SATGPS] > 0) {
589    epoSecGPS = _clkOrb.EpochTime[CLOCKORBIT_SATGPS];        // 0 .. 604799 s
590  }
591  else if (_codeBias.NumberOfSat[CLOCKORBIT_SATGPS] > 0) {
592    epoSecGPS = _codeBias.EpochTime[CLOCKORBIT_SATGPS];      // 0 .. 604799 s
593  }
594  else if (_phaseBias.NumberOfSat[CLOCKORBIT_SATGPS] > 0) {
595    epoSecGPS = _phaseBias.EpochTime[CLOCKORBIT_SATGPS];     // 0 .. 604799 s
596  }
597  else if (_vTEC.NumLayers > 0) {
598    epoSecGPS = _vTEC.EpochTime;                             // 0 .. 604799 s
599  }
600  else if (_clkOrb.NumberOfSat[CLOCKORBIT_SATGLONASS] > 0) {
601    epoSecGlo = _clkOrb.EpochTime[CLOCKORBIT_SATGLONASS];    // 0 .. 86399 s
602  }
603  else if (_codeBias.NumberOfSat[CLOCKORBIT_SATGLONASS] > 0) {
604    epoSecGlo = _codeBias.EpochTime[CLOCKORBIT_SATGLONASS];  // 0 .. 86399 s
605  }
606  else if (_phaseBias.NumberOfSat[CLOCKORBIT_SATGLONASS] > 0) {
607    epoSecGlo = _phaseBias.EpochTime[CLOCKORBIT_SATGLONASS]; // 0 .. 86399 s
608  }
609  else if (_clkOrb.NumberOfSat[CLOCKORBIT_SATGALILEO] > 0) {
610    epoSecGal = _clkOrb.EpochTime[CLOCKORBIT_SATGALILEO];
611  }
612  else if (_codeBias.NumberOfSat[CLOCKORBIT_SATGALILEO] > 0) {
613    epoSecGal = _codeBias.EpochTime[CLOCKORBIT_SATGALILEO];
614  }
615  else if (_phaseBias.NumberOfSat[CLOCKORBIT_SATGALILEO] > 0) {
616    epoSecGal = _phaseBias.EpochTime[CLOCKORBIT_SATGALILEO];
617  }
618  else if (_clkOrb.NumberOfSat[CLOCKORBIT_SATQZSS] > 0) {
619    epoSecQzss = _clkOrb.EpochTime[CLOCKORBIT_SATQZSS];
620  }
621  else if (_codeBias.NumberOfSat[CLOCKORBIT_SATQZSS] > 0) {
622    epoSecQzss = _codeBias.EpochTime[CLOCKORBIT_SATQZSS];
623  }
624  else if (_phaseBias.NumberOfSat[CLOCKORBIT_SATQZSS] > 0) {
625    epoSecQzss = _phaseBias.EpochTime[CLOCKORBIT_SATQZSS];
626  }
627  else if (_clkOrb.NumberOfSat[CLOCKORBIT_SATSBAS] > 0) {
628    epoSecSbas = _clkOrb.EpochTime[CLOCKORBIT_SATSBAS];
629  }
630  else if (_codeBias.NumberOfSat[CLOCKORBIT_SATSBAS] > 0) {
631    epoSecSbas = _codeBias.EpochTime[CLOCKORBIT_SATSBAS];
632  }
633  else if (_phaseBias.NumberOfSat[CLOCKORBIT_SATSBAS] > 0) {
634    epoSecSbas = _phaseBias.EpochTime[CLOCKORBIT_SATSBAS];
635  }
636  else if (_clkOrb.NumberOfSat[CLOCKORBIT_SATBDS] > 0) {
637    epoSecBds = _clkOrb.EpochTime[CLOCKORBIT_SATBDS];
638  }
639  else if (_codeBias.NumberOfSat[CLOCKORBIT_SATBDS] > 0) {
640    epoSecBds = _codeBias.EpochTime[CLOCKORBIT_SATBDS];
641  }
642  else if (_phaseBias.NumberOfSat[CLOCKORBIT_SATBDS] > 0) {
643    epoSecBds = _phaseBias.EpochTime[CLOCKORBIT_SATBDS];
644  }
645
646  // Retrieve current time
647  // ---------------------
648  int    currentWeek = 0;
649  double currentSec  = 0.0;
650  currentGPSWeeks(currentWeek, currentSec);
651  bncTime currentTime(currentWeek, currentSec);
652
653  // Set _lastTime close to currentTime
654  // ----------------------------------
655  if      (epoSecGPS != -1) {
656    _lastTime.set(currentWeek, epoSecGPS);
657  }
658  else if (epoSecGlo != -1) {
659    if (_type == e_type::RTCMssr) {
660      QDate date = dateAndTimeFromGPSweek(currentTime.gpsw(), currentTime.gpssec()).date();
661      epoSecGlo = epoSecGlo - 3 * 3600 + gnumleap(date.year(), date.month(), date.day());
662    }
663    _lastTime.set(currentWeek, epoSecGlo);
664  }
665  else if (epoSecGal != -1) {
666    _lastTime.set(currentWeek, epoSecGal);
667  }
668  else if (epoSecQzss != -1) {
669    _lastTime.set(currentWeek, epoSecQzss);
670  }
671  else if (epoSecSbas != -1) {
672    _lastTime.set(currentWeek, epoSecSbas);
673  }
674  else if (epoSecBds != -1) {
675    if (_type == e_type::RTCMssr) {
676      epoSecBds += 14.0;
677      if (epoSecBds > 604800.0) {
678        epoSecBds -= 7.0*24.0*60.0*60.0;
679      }
680    }
681    _lastTime.set(currentWeek, epoSecBds);
682  }
683
684  if (_lastTime.valid()) {
685    double maxDiff = 12 * 3600.0;
686    while (_lastTime < currentTime - maxDiff) {
687      _lastTime = _lastTime + maxDiff;
688    }
689    while (_lastTime > currentTime + maxDiff) {
690      _lastTime = _lastTime - maxDiff;
691    }
692  }
693}
Note: See TracBrowser for help on using the repository browser.