source: ntrip/branches/BNC_2.12/src/RTCM3/RTCM3coDecoder.cpp @ 9307

Last change on this file since 9307 was 9307, checked in by stuerze, 4 months ago

bug fixed

File size: 23.3 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.toAscii().data(), ios_base::out | ios_base::app );
152    }
153    else {
154      _out = new ofstream( _fileName.toAscii().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
182    GCOB_RETURN irc = _ssrCorr->GetSSR(&_clkOrb, &_codeBias, &_vTEC, &_phaseBias,
183                             _buffer.data(), _buffer.size(), &bytesused);
184
185    if      (irc <= -30) { // not enough data - restore state and exit loop
186      memcpy(&_clkOrb,    &clkOrbSav,    sizeof(clkOrbSav));
187      memcpy(&_codeBias,  &codeBiasSav,  sizeof(codeBiasSav));
188      memcpy(&_phaseBias, &phaseBiasSav, sizeof(phaseBiasSav));
189      memcpy(&_vTEC,      &vTECSav,      sizeof(vTECSav));
190      break;
191    }
192
193    else if (irc < 0) {    // error  - skip 1 byte and retry
194      reset();
195      _buffer = _buffer.mid(bytesused ? bytesused : 1);
196    }
197
198    else {                 // OK or MESSAGEFOLLOWS
199      _buffer = _buffer.mid(bytesused);
200
201      if (irc == GCOBR_OK || irc == GCOBR_MESSAGEFOLLOWS ) {
202
203        setEpochTime(); // sets _lastTime
204
205        if (_lastTime.valid()) {
206          reopen();
207          checkProviderID();
208          sendResults();
209          retCode = success;
210        }
211        else {
212          retCode = failure;
213        }
214
215        reset();
216      }
217    }
218  }
219
220  return retCode;
221}
222
223//
224////////////////////////////////////////////////////////////////////////////
225void RTCM3coDecoder::sendResults() {
226
227  // Orbit and clock corrections of all satellites
228  // ---------------------------------------------
229  for (unsigned ii = 0; ii <  CLOCKORBIT_NUMGPS
230                            + CLOCKORBIT_NUMGLONASS
231                            + CLOCKORBIT_NUMGALILEO
232                            + CLOCKORBIT_NUMQZSS
233                            + CLOCKORBIT_NUMSBAS
234                            + _clkOrb.NumberOfSat[CLOCKORBIT_SATBDS];
235    ii++) {
236    char sysCh = ' ';
237    int flag = 0;
238    if      (ii < _clkOrb.NumberOfSat[CLOCKORBIT_SATGPS]) {
239      sysCh = 'G';
240    }
241    else if (ii >= CLOCKORBIT_OFFSETGLONASS &&
242        ii < CLOCKORBIT_OFFSETGLONASS + _clkOrb.NumberOfSat[CLOCKORBIT_SATGLONASS]) {
243      sysCh = 'R';
244    }
245    else if (ii >= CLOCKORBIT_OFFSETGALILEO &&
246        ii < CLOCKORBIT_OFFSETGALILEO + _clkOrb.NumberOfSat[CLOCKORBIT_SATGALILEO]) {
247      sysCh = 'E';
248      flag = 1; // I/NAV clock has been chosen as reference clock for Galileo SSR corrections
249    }
250    else if (ii >= CLOCKORBIT_OFFSETQZSS &&
251        ii < CLOCKORBIT_OFFSETQZSS + _clkOrb.NumberOfSat[CLOCKORBIT_SATQZSS]) {
252      sysCh = 'J';
253    }
254    else if (ii >= CLOCKORBIT_OFFSETSBAS &&
255        ii < CLOCKORBIT_OFFSETSBAS + _clkOrb.NumberOfSat[CLOCKORBIT_SATSBAS]) {
256      sysCh = 'S';
257    }
258    else if (ii >= CLOCKORBIT_OFFSETBDS &&
259        ii < CLOCKORBIT_OFFSETBDS + _clkOrb.NumberOfSat[CLOCKORBIT_SATBDS]) {
260      sysCh = 'C';
261    }
262    else {
263      continue;
264    }
265
266    // Orbit correction
267    // ----------------
268    if ( _clkOrb.messageType == _ssrCorr->COTYPE_GPSCOMBINED     ||
269         _clkOrb.messageType == _ssrCorr->COTYPE_GLONASSCOMBINED ||
270         _clkOrb.messageType == _ssrCorr->COTYPE_GALILEOCOMBINED ||
271         _clkOrb.messageType == _ssrCorr->COTYPE_QZSSCOMBINED ||
272         _clkOrb.messageType == _ssrCorr->COTYPE_SBASCOMBINED ||
273         _clkOrb.messageType == _ssrCorr->COTYPE_BDSCOMBINED ||
274         _clkOrb.messageType == _ssrCorr->COTYPE_GPSORBIT ||
275         _clkOrb.messageType == _ssrCorr->COTYPE_GLONASSORBIT ||
276         _clkOrb.messageType == _ssrCorr->COTYPE_GALILEOORBIT ||
277         _clkOrb.messageType == _ssrCorr->COTYPE_QZSSORBIT ||
278         _clkOrb.messageType == _ssrCorr->COTYPE_SBASORBIT ||
279         _clkOrb.messageType == _ssrCorr->COTYPE_BDSORBIT ) {
280
281      t_orbCorr orbCorr;
282      orbCorr._prn.set(sysCh, _clkOrb.Sat[ii].ID, flag);
283      orbCorr._staID     = _staID.toStdString();
284      orbCorr._iod       = _clkOrb.Sat[ii].IOD;
285      orbCorr._time      = _lastTime;
286      orbCorr._updateInt = _clkOrb.UpdateInterval;
287      orbCorr._system    = sysCh;
288      orbCorr._xr[0]     = _clkOrb.Sat[ii].Orbit.DeltaRadial;
289      orbCorr._xr[1]     = _clkOrb.Sat[ii].Orbit.DeltaAlongTrack;
290      orbCorr._xr[2]     = _clkOrb.Sat[ii].Orbit.DeltaCrossTrack;
291      orbCorr._dotXr[0]  = _clkOrb.Sat[ii].Orbit.DotDeltaRadial;
292      orbCorr._dotXr[1]  = _clkOrb.Sat[ii].Orbit.DotDeltaAlongTrack;
293      orbCorr._dotXr[2]  = _clkOrb.Sat[ii].Orbit.DotDeltaCrossTrack;
294
295      _orbCorrections[_lastTime].append(orbCorr);
296
297      _IODs[orbCorr._prn] = _clkOrb.Sat[ii].IOD;
298    }
299
300    // Clock Corrections
301    // -----------------
302    if ( _clkOrb.messageType == _ssrCorr->COTYPE_GPSCOMBINED     ||
303         _clkOrb.messageType == _ssrCorr->COTYPE_GLONASSCOMBINED ||
304         _clkOrb.messageType == _ssrCorr->COTYPE_GALILEOCOMBINED ||
305         _clkOrb.messageType == _ssrCorr->COTYPE_QZSSCOMBINED ||
306         _clkOrb.messageType == _ssrCorr->COTYPE_SBASCOMBINED ||
307         _clkOrb.messageType == _ssrCorr->COTYPE_BDSCOMBINED ||
308         _clkOrb.messageType == _ssrCorr->COTYPE_GPSCLOCK ||
309         _clkOrb.messageType == _ssrCorr->COTYPE_GLONASSCLOCK ||
310         _clkOrb.messageType == _ssrCorr->COTYPE_GALILEOCLOCK ||
311         _clkOrb.messageType == _ssrCorr->COTYPE_QZSSCLOCK ||
312         _clkOrb.messageType == _ssrCorr->COTYPE_SBASCLOCK ||
313         _clkOrb.messageType == _ssrCorr->COTYPE_BDSCLOCK) {
314
315      t_clkCorr clkCorr;
316      clkCorr._prn.set(sysCh, _clkOrb.Sat[ii].ID, flag);
317      clkCorr._staID      = _staID.toStdString();
318      clkCorr._time       = _lastTime;
319      clkCorr._updateInt  = _clkOrb.UpdateInterval;
320      clkCorr._dClk       = _clkOrb.Sat[ii].Clock.DeltaA0 / t_CST::c;
321      clkCorr._dotDClk    = _clkOrb.Sat[ii].Clock.DeltaA1 / t_CST::c;
322      clkCorr._dotDotDClk = _clkOrb.Sat[ii].Clock.DeltaA2 / t_CST::c;
323
324      _lastClkCorrections[clkCorr._prn] = clkCorr;
325
326      if (_IODs.contains(clkCorr._prn)) {
327        clkCorr._iod = _IODs[clkCorr._prn];
328        _clkCorrections[_lastTime].append(clkCorr);
329      }
330    }
331
332    // High-Resolution Clocks
333    // ----------------------
334    if ( _clkOrb.messageType == _ssrCorr->COTYPE_GPSHR     ||
335         _clkOrb.messageType == _ssrCorr->COTYPE_GLONASSHR ||
336         _clkOrb.messageType == _ssrCorr->COTYPE_GALILEOHR ||
337         _clkOrb.messageType == _ssrCorr->COTYPE_QZSSHR ||
338         _clkOrb.messageType == _ssrCorr->COTYPE_SBASHR ||
339         _clkOrb.messageType == _ssrCorr->COTYPE_BDSHR) {
340      t_prn prn(sysCh, _clkOrb.Sat[ii].ID, flag);
341      if (_lastClkCorrections.contains(prn)) {
342        t_clkCorr clkCorr;
343        clkCorr            = _lastClkCorrections[prn];
344        clkCorr._time      = _lastTime;
345        clkCorr._updateInt = _clkOrb.UpdateInterval;
346        clkCorr._dClk     += _clkOrb.Sat[ii].hrclock / t_CST::c;
347        if (_IODs.contains(clkCorr._prn)) {
348          clkCorr._iod = _IODs[clkCorr._prn];
349          _clkCorrections[_lastTime].push_back(clkCorr);
350        }
351      }
352    }
353  }
354
355  // Code Biases
356  // -----------
357  for (unsigned ii = 0; ii <  CLOCKORBIT_NUMGPS
358                            + CLOCKORBIT_NUMGLONASS
359                            + CLOCKORBIT_NUMGALILEO
360                            + CLOCKORBIT_NUMQZSS
361                            + CLOCKORBIT_NUMSBAS
362                            + _codeBias.NumberOfSat[CLOCKORBIT_SATBDS];
363    ii++) {
364    char sysCh = ' ';
365    if      (ii < _codeBias.NumberOfSat[CLOCKORBIT_SATGPS]) {
366      sysCh = 'G';
367    }
368    else if (ii >= CLOCKORBIT_OFFSETGLONASS &&
369        ii < CLOCKORBIT_OFFSETGLONASS + _codeBias.NumberOfSat[CLOCKORBIT_SATGLONASS]) {
370      sysCh = 'R';
371    }
372    else if (ii >= CLOCKORBIT_OFFSETGALILEO &&
373        ii < CLOCKORBIT_OFFSETGALILEO + _codeBias.NumberOfSat[CLOCKORBIT_SATGALILEO]) {
374      sysCh = 'E';
375    }
376    else if (ii >= CLOCKORBIT_OFFSETQZSS &&
377        ii < CLOCKORBIT_OFFSETQZSS + _codeBias.NumberOfSat[CLOCKORBIT_SATQZSS]) {
378      sysCh = 'J';
379    }
380    else if (ii >= CLOCKORBIT_OFFSETSBAS &&
381        ii < CLOCKORBIT_OFFSETSBAS + _codeBias.NumberOfSat[CLOCKORBIT_SATSBAS]) {
382      sysCh = 'S';
383    }
384    else if (ii >= CLOCKORBIT_OFFSETBDS &&
385        ii < CLOCKORBIT_OFFSETBDS + _codeBias.NumberOfSat[CLOCKORBIT_SATBDS]) {
386      sysCh = 'C';
387    }
388    else {
389      continue;
390    }
391    t_satCodeBias satCodeBias;
392    satCodeBias._prn.set(sysCh, _codeBias.Sat[ii].ID);
393    satCodeBias._staID     = _staID.toStdString();
394    satCodeBias._time      = _lastTime;
395    satCodeBias._updateInt = _codeBias.UpdateInterval;
396    for (unsigned jj = 0; jj < _codeBias.Sat[ii].NumberOfCodeBiases; jj++) {
397      const SsrCorr::CodeBias::BiasSat::CodeBiasEntry& biasEntry = _codeBias.Sat[ii].Biases[jj];
398      t_frqCodeBias frqCodeBias;
399      frqCodeBias._rnxType2ch.assign(_ssrCorr->codeTypeToRnxType(sysCh, biasEntry.Type));
400      frqCodeBias._value      = biasEntry.Bias;
401      if (!frqCodeBias._rnxType2ch.empty()) {
402        satCodeBias._bias.push_back(frqCodeBias);
403      }
404    }
405    _codeBiases[_lastTime].append(satCodeBias);
406  }
407
408  // Phase Biases
409  // -----------
410  for (unsigned ii = 0; ii <  CLOCKORBIT_NUMGPS
411                            + CLOCKORBIT_NUMGLONASS
412                            + CLOCKORBIT_NUMGALILEO
413                            + CLOCKORBIT_NUMQZSS
414                            + CLOCKORBIT_NUMSBAS
415                            + _phaseBias.NumberOfSat[CLOCKORBIT_SATBDS];
416    ii++) {
417    char sysCh = ' ';
418    if      (ii < _phaseBias.NumberOfSat[CLOCKORBIT_SATGPS]) {
419      sysCh = 'G';
420    }
421    else if (ii >= CLOCKORBIT_OFFSETGLONASS &&
422        ii < CLOCKORBIT_OFFSETGLONASS + _phaseBias.NumberOfSat[CLOCKORBIT_SATGLONASS]) {
423      sysCh = 'R';
424    }
425    else if (ii >= CLOCKORBIT_OFFSETGALILEO &&
426        ii < CLOCKORBIT_OFFSETGALILEO + _phaseBias.NumberOfSat[CLOCKORBIT_SATGALILEO]) {
427      sysCh = 'E';
428    }
429    else if (ii >= CLOCKORBIT_OFFSETQZSS &&
430        ii < CLOCKORBIT_OFFSETQZSS + _phaseBias.NumberOfSat[CLOCKORBIT_SATQZSS]) {
431      sysCh = 'J';
432    }
433    else if (ii >= CLOCKORBIT_OFFSETSBAS &&
434        ii < CLOCKORBIT_OFFSETSBAS + _phaseBias.NumberOfSat[CLOCKORBIT_SATSBAS]) {
435      sysCh = 'S';
436    }
437    else if (ii >= CLOCKORBIT_OFFSETBDS &&
438        ii < CLOCKORBIT_OFFSETBDS + _phaseBias.NumberOfSat[CLOCKORBIT_SATBDS]) {
439      sysCh = 'C';
440    }
441    else {
442      continue;
443    }
444    t_satPhaseBias satPhaseBias;
445    satPhaseBias._prn.set(sysCh, _phaseBias.Sat[ii].ID);
446    satPhaseBias._staID      = _staID.toStdString();
447    satPhaseBias._time       = _lastTime;
448    satPhaseBias._updateInt  = _phaseBias.UpdateInterval;
449    satPhaseBias._dispBiasConstistInd = _phaseBias.DispersiveBiasConsistencyIndicator;
450    satPhaseBias._MWConsistInd        = _phaseBias.MWConsistencyIndicator;
451    satPhaseBias._yawDeg     = _phaseBias.Sat[ii].YawAngle * 180.0 / M_PI;
452    satPhaseBias._yawDegRate = _phaseBias.Sat[ii].YawRate * 180.0 / M_PI;
453    for (unsigned jj = 0; jj < _phaseBias.Sat[ii].NumberOfPhaseBiases; jj++) {
454      const SsrCorr::PhaseBias::PhaseBiasSat::PhaseBiasEntry& biasEntry = _phaseBias.Sat[ii].Biases[jj];
455      t_frqPhaseBias frqPhaseBias;
456      frqPhaseBias._rnxType2ch.assign(_ssrCorr->codeTypeToRnxType(sysCh, biasEntry.Type));
457      frqPhaseBias._value                = biasEntry.Bias;
458      frqPhaseBias._fixIndicator         = biasEntry.SignalIntegerIndicator;
459      frqPhaseBias._fixWideLaneIndicator = biasEntry.SignalsWideLaneIntegerIndicator;
460      frqPhaseBias._jumpCounter          = biasEntry.SignalDiscontinuityCounter;
461      if (!frqPhaseBias._rnxType2ch.empty()) {
462        satPhaseBias._bias.push_back(frqPhaseBias);
463      }
464    }
465    _phaseBiases[_lastTime].append(satPhaseBias);
466  }
467
468  // Ionospheric Model
469  // -----------------
470  if (_vTEC.NumLayers > 0) {
471    _vTecMap[_lastTime]._time  = _lastTime;
472    _vTecMap[_lastTime]._updateInt =  _vTEC.UpdateInterval;
473    _vTecMap[_lastTime]._staID = _staID.toStdString();
474    for (unsigned ii = 0; ii < _vTEC.NumLayers; ii++) {
475      const SsrCorr::VTEC::IonoLayers& ionoLayer = _vTEC.Layers[ii];
476      t_vTecLayer layer;
477      layer._height = ionoLayer.Height;
478      layer._C.ReSize(ionoLayer.Degree+1, ionoLayer.Order+1);
479      layer._S.ReSize(ionoLayer.Degree+1, ionoLayer.Order+1);
480      for (unsigned iDeg = 0; iDeg <= ionoLayer.Degree; iDeg++) {
481        for (unsigned iOrd = 0; iOrd <= ionoLayer.Order; iOrd++) {
482          layer._C[iDeg][iOrd] = ionoLayer.Cosinus[iDeg][iOrd];
483          layer._S[iDeg][iOrd] = ionoLayer.Sinus[iDeg][iOrd];
484        }
485      }
486      _vTecMap[_lastTime]._layers.push_back(layer);
487    }
488  }
489
490  // Dump all older epochs
491  // ---------------------
492  QMutableMapIterator<bncTime, QList<t_orbCorr> > itOrb(_orbCorrections);
493  while (itOrb.hasNext()) {
494    itOrb.next();
495    if (itOrb.key() < _lastTime) {
496      emit newOrbCorrections(itOrb.value());
497      t_orbCorr::writeEpoch(_out, itOrb.value());
498      itOrb.remove();
499    }
500  }
501  QMutableMapIterator<bncTime, QList<t_clkCorr> > itClk(_clkCorrections);
502  while (itClk.hasNext()) {
503    itClk.next();
504    if (itClk.key() < _lastTime) {
505      emit newClkCorrections(itClk.value());
506      t_clkCorr::writeEpoch(_out, itClk.value());
507      itClk.remove();
508    }
509  }
510  QMutableMapIterator<bncTime, QList<t_satCodeBias> > itCB(_codeBiases);
511  while (itCB.hasNext()) {
512    itCB.next();
513    if (itCB.key() < _lastTime) {
514      emit newCodeBiases(itCB.value());
515      t_satCodeBias::writeEpoch(_out, itCB.value());
516      itCB.remove();
517    }
518  }
519  QMutableMapIterator<bncTime, QList<t_satPhaseBias> > itPB(_phaseBiases);
520  while (itPB.hasNext()) {
521    itPB.next();
522    if (itPB.key() < _lastTime) {
523      emit newPhaseBiases(itPB.value());
524      t_satPhaseBias::writeEpoch(_out, itPB.value());
525      itPB.remove();
526    }
527  }
528  QMutableMapIterator<bncTime, t_vTec> itTec(_vTecMap);
529  while (itTec.hasNext()) {
530    itTec.next();
531    if (itTec.key() < _lastTime) {
532      emit newTec(itTec.value());
533      t_vTec::write(_out, itTec.value());
534      itTec.remove();
535    }
536  }
537}
538
539//
540////////////////////////////////////////////////////////////////////////////
541void RTCM3coDecoder::checkProviderID() {
542
543  if (_clkOrb.SSRProviderID == 0 && _clkOrb.SSRSolutionID == 0 && _clkOrb.SSRIOD == 0) {
544    return;
545  }
546
547  int newProviderID[3];
548  newProviderID[0] = _clkOrb.SSRProviderID;
549  newProviderID[1] = _clkOrb.SSRSolutionID;
550  newProviderID[2] = _clkOrb.SSRIOD;
551
552  bool alreadySet = false;
553  bool different  = false;
554
555  for (unsigned ii = 0; ii < 3; ii++) {
556    if (_providerID[ii] != -1) {
557      alreadySet = true;
558    }
559    if (_providerID[ii] != newProviderID[ii]) {
560      different = true;
561    }
562    _providerID[ii] = newProviderID[ii];
563  }
564
565  if (alreadySet && different) {
566    emit newMessage("RTCM3coDecoder: Provider Changed: " + _staID.toAscii(), true);
567    emit providerIDChanged(_staID);
568  }
569}
570
571//
572////////////////////////////////////////////////////////////////////////////
573void RTCM3coDecoder::setEpochTime() {
574
575  _lastTime.reset();
576
577  double epoSecGPS  = -1.0;
578  double epoSecGlo  = -1.0;
579  double epoSecGal  = -1.0;
580  double epoSecQzss = -1.0;
581  double epoSecSbas = -1.0;
582  double epoSecBds  = -1.0;
583  if      (_clkOrb.NumberOfSat[CLOCKORBIT_SATGPS] > 0) {
584    epoSecGPS = _clkOrb.EpochTime[CLOCKORBIT_SATGPS];        // 0 .. 604799 s
585  }
586  else if (_codeBias.NumberOfSat[CLOCKORBIT_SATGPS] > 0) {
587    epoSecGPS = _codeBias.EpochTime[CLOCKORBIT_SATGPS];      // 0 .. 604799 s
588  }
589  else if (_phaseBias.NumberOfSat[CLOCKORBIT_SATGPS] > 0) {
590    epoSecGPS = _phaseBias.EpochTime[CLOCKORBIT_SATGPS];     // 0 .. 604799 s
591  }
592  else if (_vTEC.NumLayers > 0) {
593    epoSecGPS = _vTEC.EpochTime;                             // 0 .. 604799 s
594  }
595  else if (_clkOrb.NumberOfSat[CLOCKORBIT_SATGLONASS] > 0) {
596    epoSecGlo = _clkOrb.EpochTime[CLOCKORBIT_SATGLONASS];    // 0 .. 86399 s
597  }
598  else if (_codeBias.NumberOfSat[CLOCKORBIT_SATGLONASS] > 0) {
599    epoSecGlo = _codeBias.EpochTime[CLOCKORBIT_SATGLONASS];  // 0 .. 86399 s
600  }
601  else if (_phaseBias.NumberOfSat[CLOCKORBIT_SATGLONASS] > 0) {
602    epoSecGlo = _phaseBias.EpochTime[CLOCKORBIT_SATGLONASS]; // 0 .. 86399 s
603  }
604  else if (_clkOrb.NumberOfSat[CLOCKORBIT_SATGALILEO] > 0) {
605    epoSecGal = _clkOrb.EpochTime[CLOCKORBIT_SATGALILEO];
606  }
607  else if (_codeBias.NumberOfSat[CLOCKORBIT_SATGALILEO] > 0) {
608    epoSecGal = _codeBias.EpochTime[CLOCKORBIT_SATGALILEO];
609  }
610  else if (_phaseBias.NumberOfSat[CLOCKORBIT_SATGALILEO] > 0) {
611    epoSecGal = _phaseBias.EpochTime[CLOCKORBIT_SATGALILEO];
612  }
613  else if (_clkOrb.NumberOfSat[CLOCKORBIT_SATQZSS] > 0) {
614    epoSecQzss = _clkOrb.EpochTime[CLOCKORBIT_SATQZSS];
615  }
616  else if (_codeBias.NumberOfSat[CLOCKORBIT_SATQZSS] > 0) {
617    epoSecQzss = _codeBias.EpochTime[CLOCKORBIT_SATQZSS];
618  }
619  else if (_phaseBias.NumberOfSat[CLOCKORBIT_SATQZSS] > 0) {
620    epoSecQzss = _phaseBias.EpochTime[CLOCKORBIT_SATQZSS];
621  }
622  else if (_clkOrb.NumberOfSat[CLOCKORBIT_SATSBAS] > 0) {
623    epoSecSbas = _clkOrb.EpochTime[CLOCKORBIT_SATSBAS];
624  }
625  else if (_codeBias.NumberOfSat[CLOCKORBIT_SATSBAS] > 0) {
626    epoSecSbas = _codeBias.EpochTime[CLOCKORBIT_SATSBAS];
627  }
628  else if (_phaseBias.NumberOfSat[CLOCKORBIT_SATSBAS] > 0) {
629    epoSecSbas = _phaseBias.EpochTime[CLOCKORBIT_SATSBAS];
630  }
631  else if (_clkOrb.NumberOfSat[CLOCKORBIT_SATBDS] > 0) {
632    epoSecBds = _clkOrb.EpochTime[CLOCKORBIT_SATBDS];
633  }
634  else if (_codeBias.NumberOfSat[CLOCKORBIT_SATBDS] > 0) {
635    epoSecBds = _codeBias.EpochTime[CLOCKORBIT_SATBDS];
636  }
637  else if (_phaseBias.NumberOfSat[CLOCKORBIT_SATBDS] > 0) {
638    epoSecBds = _phaseBias.EpochTime[CLOCKORBIT_SATBDS];
639  }
640
641  // Retrieve current time
642  // ---------------------
643  int    currentWeek = 0;
644  double currentSec  = 0.0;
645  currentGPSWeeks(currentWeek, currentSec);
646  bncTime currentTime(currentWeek, currentSec);
647
648  // Set _lastTime close to currentTime
649  // ----------------------------------
650  if      (epoSecGPS != -1) {
651    _lastTime.set(currentWeek, epoSecGPS);
652  }
653  else if (epoSecGlo != -1) {
654    if (_type == RTCMssr) {
655      QDate date = dateAndTimeFromGPSweek(currentTime.gpsw(), currentTime.gpssec()).date();
656      epoSecGlo = epoSecGlo - 3 * 3600 + gnumleap(date.year(), date.month(), date.day());
657    }
658    _lastTime.set(currentWeek, epoSecGlo);
659  }
660  else if (epoSecGal != -1) {
661    _lastTime.set(currentWeek, epoSecGal);
662  }
663  else if (epoSecQzss != -1) {
664    _lastTime.set(currentWeek, epoSecQzss);
665  }
666  else if (epoSecSbas != -1) {
667    _lastTime.set(currentWeek, epoSecSbas);
668  }
669  else if (epoSecBds != -1) {
670    if (_type == RTCMssr) {
671      epoSecBds += 14.0;
672      if (epoSecBds > 604800.0) {
673        epoSecBds -= 7.0*24.0*60.0*60.0;
674      }
675    }
676    _lastTime.set(currentWeek, epoSecBds);
677  }
678
679  if (_lastTime.valid()) {
680    double maxDiff = 12 * 3600.0;
681    while (_lastTime < currentTime - maxDiff) {
682      _lastTime = _lastTime + maxDiff;
683    }
684    while (_lastTime > currentTime + maxDiff) {
685      _lastTime = _lastTime - maxDiff;
686    }
687  }
688}
Note: See TracBrowser for help on using the repository browser.