source: ntrip/trunk/BNC/src/RTCM3/RTCM3coDecoder.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: 20.0 KB
RevLine 
[866]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 *
[6215]37 * Changes:
[866]38 *
39 * -----------------------------------------------------------------------*/
40
[868]41#include <stdio.h>
[920]42#include <math.h>
[868]43
[866]44#include "RTCM3coDecoder.h"
[918]45#include "bncutils.h"
[934]46#include "bncrinex.h"
[5070]47#include "bnccore.h"
[1535]48#include "bncsettings.h"
[4428]49#include "bnctime.h"
[866]50
51using namespace std;
52
53// Constructor
54////////////////////////////////////////////////////////////////////////////
[970]55RTCM3coDecoder::RTCM3coDecoder(const QString& staID) {
[934]56
[970]57 _staID = staID;
58
[934]59 // File Output
60 // -----------
[1535]61 bncSettings settings;
[934]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 }
[970]68 _fileNameSkl = path + staID;
[934]69 }
[6141]70 _out = 0;
[934]71
[6215]72 connect(this, SIGNAL(newOrbCorrections(QList<t_orbCorr>)),
[6141]73 BNC_CORE, SLOT(slotNewOrbCorrections(QList<t_orbCorr>)));
[1828]74
[6215]75 connect(this, SIGNAL(newClkCorrections(QList<t_clkCorr>)),
[6141]76 BNC_CORE, SLOT(slotNewClkCorrections(QList<t_clkCorr>)));
77
[6486]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
[6215]87 connect(this, SIGNAL(providerIDChanged(QString)),
[5577]88 BNC_CORE, SIGNAL(providerIDChanged(QString)));
89
[6215]90 connect(this, SIGNAL(newMessage(QByteArray,bool)),
[5068]91 BNC_CORE, SLOT(slotMessage(const QByteArray,bool)));
[4428]92
[6467]93 reset();
[5576]94
95 _providerID[0] = -1;
96 _providerID[1] = -1;
97 _providerID[2] = -1;
[866]98}
99
100// Destructor
101////////////////////////////////////////////////////////////////////////////
102RTCM3coDecoder::~RTCM3coDecoder() {
[935]103 delete _out;
[866]104}
105
[6467]106//
107////////////////////////////////////////////////////////////////////////////
108void RTCM3coDecoder::reset() {
109 memset(&_clkOrb, 0, sizeof(_clkOrb));
110 memset(&_codeBias, 0, sizeof(_codeBias));
111 memset(&_phaseBias, 0, sizeof(_phaseBias));
112 memset(&_vTEC, 0, sizeof(_vTEC));
113}
114
[934]115// Reopen Output File
[6215]116////////////////////////////////////////////////////////////////////////
[6141]117void RTCM3coDecoder::reopen() {
[934]118
[6141]119 if (!_fileNameSkl.isEmpty()) {
[934]120
[1535]121 bncSettings settings;
[934]122
[1154]123 QDateTime datTim = currentDateAndTimeGPS();
[934]124
125 QString hlpStr = bncRinex::nextEpochStr(datTim,
126 settings.value("corrIntr").toString());
127
[6215]128 QString fileNameHlp = _fileNameSkl
[934]129 + QString("%1").arg(datTim.date().dayOfYear(), 3, 10, QChar('0'))
[938]130 + hlpStr + datTim.toString(".yyC");
[934]131
[6141]132 if (_fileName == fileNameHlp) {
[934]133 return;
134 }
135 else {
[6141]136 _fileName = fileNameHlp;
[934]137 }
138
[6141]139 delete _out;
[1727]140 if ( Qt::CheckState(settings.value("rnxAppend").toInt()) == Qt::Checked) {
[6141]141 _out = new ofstream( _fileName.toAscii().data(), ios_base::out | ios_base::app );
[1727]142 }
143 else {
[6141]144 _out = new ofstream( _fileName.toAscii().data() );
[1727]145 }
[934]146 }
147}
148
[6215]149//
[866]150////////////////////////////////////////////////////////////////////////////
[1227]151t_irc RTCM3coDecoder::Decode(char* buffer, int bufLen, vector<string>& errmsg) {
[868]152
[1218]153 errmsg.clear();
154
[1227]155 _buffer.append(QByteArray(buffer,bufLen));
[868]156
[1023]157 t_irc retCode = failure;
158
[1832]159 while(_buffer.size()) {
160
[6454]161 struct ClockOrbit clkOrbSav;
162 struct CodeBias codeBiasSav;
163 struct PhaseBias phaseBiasSav;
164 struct VTEC vTECSav;
165 memcpy(&clkOrbSav, &_clkOrb, sizeof(clkOrbSav)); // save state
166 memcpy(&codeBiasSav, &_codeBias, sizeof(codeBiasSav));
167 memcpy(&phaseBiasSav, &_phaseBias, sizeof(phaseBiasSav));
168 memcpy(&vTECSav, &_vTEC, sizeof(vTECSav));
169
[879]170 int bytesused = 0;
[6454]171 GCOB_RETURN irc = GetSSR(&_clkOrb, &_codeBias, &_vTEC, &_phaseBias,
172 _buffer.data(), _buffer.size(), &bytesused);
[1829]173
[1833]174 if (irc <= -30) { // not enough data - restore state and exit loop
[6454]175 memcpy(&_clkOrb, &clkOrbSav, sizeof(clkOrbSav));
176 memcpy(&_codeBias, &codeBiasSav, sizeof(codeBiasSav));
177 memcpy(&_phaseBias, &phaseBiasSav, sizeof(phaseBiasSav));
178 memcpy(&_vTEC, &vTECSav, sizeof(vTECSav));
[1833]179 break;
[869]180 }
[1832]181
[1833]182 else if (irc < 0) { // error - skip 1 byte and retry
[6467]183 reset();
[1842]184 _buffer = _buffer.mid(bytesused ? bytesused : 1);
[1833]185 }
186
187 else { // OK or MESSAGEFOLLOWS
[1828]188 _buffer = _buffer.mid(bytesused);
189
[6467]190 if (irc == GCOBR_OK || irc == GCOBR_MESSAGEFOLLOWS ) {
[2435]191
[6556]192 setEpochTime(); // sets _lastTime
[6467]193
194 if (_lastTime.valid()) {
195 reopen();
196 checkProviderID();
197 sendResults();
198 retCode = success;
[919]199 }
[6467]200 else {
201 retCode = failure;
[1829]202 }
[918]203
[6467]204 reset();
[869]205 }
[1829]206 }
[1833]207 }
[1832]208
[1829]209 return retCode;
[866]210}
[934]211
[6215]212//
[934]213////////////////////////////////////////////////////////////////////////////
[6141]214void RTCM3coDecoder::sendResults() {
[934]215
[6455]216 // Orbit and clock corrections of all satellites
217 // ---------------------------------------------
[6454]218 for (unsigned ii = 0; ii < CLOCKORBIT_NUMGPS + _clkOrb.NumberOfSat[CLOCKORBIT_SATGLONASS]; ii++) {
[3022]219 char sysCh = ' ';
[6454]220 if (ii < _clkOrb.NumberOfSat[CLOCKORBIT_SATGPS]) {
[3022]221 sysCh = 'G';
222 }
223 else if (ii >= CLOCKORBIT_NUMGPS) {
224 sysCh = 'R';
225 }
[6141]226 else {
227 continue;
228 }
[3024]229
[6141]230 // Orbit correction
231 // ----------------
[6454]232 if ( _clkOrb.messageType == COTYPE_GPSCOMBINED ||
233 _clkOrb.messageType == COTYPE_GLONASSCOMBINED ||
234 _clkOrb.messageType == COTYPE_GPSORBIT ||
235 _clkOrb.messageType == COTYPE_GLONASSORBIT ) {
[3022]236
[6141]237 t_orbCorr orbCorr;
[6454]238 orbCorr._prn.set(sysCh, _clkOrb.Sat[ii].ID);
[6564]239 orbCorr._staID = _staID.toStdString();
[6556]240 orbCorr._iod = _clkOrb.Sat[ii].IOD;
241 orbCorr._time = _lastTime;
242 orbCorr._updateInt = _clkOrb.UpdateInterval;
243 orbCorr._system = 'R';
244 orbCorr._xr[0] = _clkOrb.Sat[ii].Orbit.DeltaRadial;
245 orbCorr._xr[1] = _clkOrb.Sat[ii].Orbit.DeltaAlongTrack;
246 orbCorr._xr[2] = _clkOrb.Sat[ii].Orbit.DeltaCrossTrack;
247 orbCorr._dotXr[0] = _clkOrb.Sat[ii].Orbit.DotDeltaRadial;
248 orbCorr._dotXr[1] = _clkOrb.Sat[ii].Orbit.DotDeltaAlongTrack;
249 orbCorr._dotXr[2] = _clkOrb.Sat[ii].Orbit.DotDeltaCrossTrack;
[3022]250
[6497]251 _orbCorrections[_lastTime].push_back(orbCorr);
[3022]252
[6471]253 _IODs[orbCorr._prn] = _clkOrb.Sat[ii].IOD;
[6141]254 }
[3022]255
[6455]256 // Clock Corrections
257 // -----------------
[6454]258 if ( _clkOrb.messageType == COTYPE_GPSCOMBINED ||
259 _clkOrb.messageType == COTYPE_GLONASSCOMBINED ||
260 _clkOrb.messageType == COTYPE_GPSCLOCK ||
261 _clkOrb.messageType == COTYPE_GLONASSCLOCK ) {
[3022]262
[6141]263 t_clkCorr clkCorr;
[6454]264 clkCorr._prn.set(sysCh, _clkOrb.Sat[ii].ID);
[6564]265 clkCorr._staID = _staID.toStdString();
[6141]266 clkCorr._time = _lastTime;
[6556]267 clkCorr._updateInt = _clkOrb.UpdateInterval;
[6454]268 clkCorr._dClk = _clkOrb.Sat[ii].Clock.DeltaA0 / t_CST::c;
269 clkCorr._dotDClk = _clkOrb.Sat[ii].Clock.DeltaA1 / t_CST::c;
270 clkCorr._dotDotDClk = _clkOrb.Sat[ii].Clock.DeltaA2 / t_CST::c;
[3022]271
[6471]272 _lastClkCorrections[clkCorr._prn] = clkCorr;
273
274 if (_IODs.contains(clkCorr._prn)) {
275 clkCorr._iod = _IODs[clkCorr._prn];
[6497]276 _clkCorrections[_lastTime].push_back(clkCorr);
[3022]277 }
278 }
[6141]279
280 // High-Resolution Clocks
281 // ----------------------
[6454]282 if ( _clkOrb.messageType == COTYPE_GPSHR ||
283 _clkOrb.messageType == COTYPE_GLONASSHR ) {
[6471]284
285 t_prn prn(sysCh, _clkOrb.Sat[ii].ID);
286 if (_lastClkCorrections.contains(prn)) {
287 t_clkCorr clkCorr;
[6556]288 clkCorr = _lastClkCorrections[prn];
289 clkCorr._time = _lastTime;
290 clkCorr._updateInt = _clkOrb.UpdateInterval;
291 clkCorr._dClk += _clkOrb.Sat[ii].hrclock / t_CST::c;
[6471]292 if (_IODs.contains(clkCorr._prn)) {
293 clkCorr._iod = _IODs[clkCorr._prn];
[6497]294 _clkCorrections[_lastTime].push_back(clkCorr);
[6471]295 }
296 }
[6141]297 }
[3022]298 }
299
[6455]300 // Code Biases
301 // -----------
[6454]302 for (unsigned ii = 0; ii < CLOCKORBIT_NUMGPS + _codeBias.NumberOfSat[CLOCKORBIT_SATGLONASS]; ii++) {
[6141]303 char sysCh = ' ';
[6454]304 if (ii < _codeBias.NumberOfSat[CLOCKORBIT_SATGPS]) {
[6141]305 sysCh = 'G';
[3022]306 }
[6141]307 else if (ii >= CLOCKORBIT_NUMGPS) {
308 sysCh = 'R';
[3022]309 }
[6141]310 else {
311 continue;
312 }
[6463]313 t_satCodeBias satCodeBias;
314 satCodeBias._prn.set(sysCh, _codeBias.Sat[ii].ID);
[6564]315 satCodeBias._staID = _staID.toStdString();
[6556]316 satCodeBias._time = _lastTime;
317 satCodeBias._updateInt = _codeBias.UpdateInterval;
[6454]318 for (unsigned jj = 0; jj < _codeBias.Sat[ii].NumberOfCodeBiases; jj++) {
[6472]319 const CodeBias::BiasSat::CodeBiasEntry& biasEntry = _codeBias.Sat[ii].Biases[jj];
320 t_frqCodeBias frqCodeBias;
321 frqCodeBias._rnxType2ch = codeTypeToRnxType(sysCh, biasEntry.Type);
322 frqCodeBias._value = biasEntry.Bias;
[6474]323 if (!frqCodeBias._rnxType2ch.empty()) {
324 satCodeBias._bias.push_back(frqCodeBias);
325 }
[6141]326 }
[6497]327 _codeBiases[_lastTime].push_back(satCodeBias);
[3022]328 }
329
[6487]330 // Phase Biases
331 // -----------
332 for (unsigned ii = 0; ii < CLOCKORBIT_NUMGPS + _phaseBias.NumberOfSat[CLOCKORBIT_SATGLONASS]; ii++) {
333 char sysCh = ' ';
334 if (ii < _phaseBias.NumberOfSat[CLOCKORBIT_SATGPS]) {
335 sysCh = 'G';
336 }
337 else if (ii >= CLOCKORBIT_NUMGPS) {
338 sysCh = 'R';
339 }
340 else {
341 continue;
342 }
343 t_satPhaseBias satPhaseBias;
344 satPhaseBias._prn.set(sysCh, _phaseBias.Sat[ii].ID);
[6564]345 satPhaseBias._staID = _staID.toStdString();
[6488]346 satPhaseBias._time = _lastTime;
[6556]347 satPhaseBias._updateInt = _phaseBias.UpdateInterval;
[6488]348 satPhaseBias._yawDeg = _phaseBias.Sat[ii].YawAngle * 180.0 / M_PI;
349 satPhaseBias._yawDegRate = _phaseBias.Sat[ii].YawRate * 180.0 / M_PI;
[6487]350 for (unsigned jj = 0; jj < _phaseBias.Sat[ii].NumberOfPhaseBiases; jj++) {
351 const PhaseBias::PhaseBiasSat::PhaseBiasEntry& biasEntry = _phaseBias.Sat[ii].Biases[jj];
352 t_frqPhaseBias frqPhaseBias;
[6488]353 frqPhaseBias._rnxType2ch = codeTypeToRnxType(sysCh, biasEntry.Type);
354 frqPhaseBias._value = biasEntry.Bias;
355 frqPhaseBias._fixIndicator = biasEntry.SignalIntegerIndicator;
356 frqPhaseBias._fixWideLaneIndicator = biasEntry.SignalsWideLaneIntegerIndicator;
357 frqPhaseBias._jumpCounter = biasEntry.SignalDiscontinuityCounter;
[6487]358 if (!frqPhaseBias._rnxType2ch.empty()) {
359 satPhaseBias._bias.push_back(frqPhaseBias);
360 }
361 }
[6497]362 _phaseBiases[_lastTime].push_back(satPhaseBias);
[6487]363 }
364
[6490]365 // Ionospheric Model
366 // -----------------
367 if (_vTEC.NumLayers > 0) {
[6497]368 _vTecMap[_lastTime]._time = _lastTime;
[6556]369 _vTecMap[_lastTime]._updateInt = _vTEC.UpdateInterval;
[6564]370 _vTecMap[_lastTime]._staID = _staID.toStdString();
[6491]371 for (unsigned ii = 0; ii < _vTEC.NumLayers; ii++) {
372 const VTEC::IonoLayers& ionoLayer = _vTEC.Layers[ii];
373 t_vTecLayer layer;
374 layer._height = ionoLayer.Height;
375 layer._C.ReSize(ionoLayer.Degree, ionoLayer.Order);
376 layer._S.ReSize(ionoLayer.Degree, ionoLayer.Order);
377 for (unsigned iDeg = 0; iDeg < ionoLayer.Degree; iDeg++) {
378 for (unsigned iOrd = 0; iOrd < ionoLayer.Order; iOrd++) {
379 layer._C[iDeg][iOrd] = ionoLayer.Cosinus[iDeg][iOrd];
380 layer._S[iDeg][iOrd] = ionoLayer.Sinus[iDeg][iOrd];
381 }
382 }
[6497]383 _vTecMap[_lastTime]._layers.push_back(layer);
[6491]384 }
[6490]385 }
386
[6455]387 // Dump all older epochs
388 // ---------------------
389 QMutableMapIterator<bncTime, QList<t_orbCorr> > itOrb(_orbCorrections);
390 while (itOrb.hasNext()) {
391 itOrb.next();
392 if (itOrb.key() < _lastTime) {
393 emit newOrbCorrections(itOrb.value());
[6456]394 t_orbCorr::writeEpoch(_out, itOrb.value());
[6455]395 itOrb.remove();
396 }
[6141]397 }
[6455]398 QMutableMapIterator<bncTime, QList<t_clkCorr> > itClk(_clkCorrections);
399 while (itClk.hasNext()) {
400 itClk.next();
401 if (itClk.key() < _lastTime) {
402 emit newClkCorrections(itClk.value());
[6456]403 t_clkCorr::writeEpoch(_out, itClk.value());
[6455]404 itClk.remove();
405 }
[6141]406 }
[6474]407 QMutableMapIterator<bncTime, QList<t_satCodeBias> > itCB(_codeBiases);
408 while (itCB.hasNext()) {
409 itCB.next();
410 if (itCB.key() < _lastTime) {
411 emit newCodeBiases(itCB.value());
[6475]412 t_satCodeBias::writeEpoch(_out, itCB.value());
[6474]413 itCB.remove();
414 }
415 }
[6487]416 QMutableMapIterator<bncTime, QList<t_satPhaseBias> > itPB(_phaseBiases);
417 while (itPB.hasNext()) {
418 itPB.next();
419 if (itPB.key() < _lastTime) {
420 emit newPhaseBiases(itPB.value());
421 t_satPhaseBias::writeEpoch(_out, itPB.value());
422 itPB.remove();
423 }
424 }
[6490]425 QMutableMapIterator<bncTime, t_vTec> itTec(_vTecMap);
426 while (itTec.hasNext()) {
427 itTec.next();
428 if (itTec.key() < _lastTime) {
429 emit newTec(itTec.value());
430 t_vTec::write(_out, itTec.value());
431 itTec.remove();
432 }
433 }
[3022]434}
[5576]435
[6215]436//
[5576]437////////////////////////////////////////////////////////////////////////////
438void RTCM3coDecoder::checkProviderID() {
439
[6454]440 if (_clkOrb.SSRProviderID == 0 && _clkOrb.SSRSolutionID == 0 && _clkOrb.SSRIOD == 0) {
[5576]441 return;
442 }
443
444 int newProviderID[3];
[6454]445 newProviderID[0] = _clkOrb.SSRProviderID;
446 newProviderID[1] = _clkOrb.SSRSolutionID;
447 newProviderID[2] = _clkOrb.SSRIOD;
[5576]448
449 bool alreadySet = false;
450 bool different = false;
451
452 for (unsigned ii = 0; ii < 3; ii++) {
453 if (_providerID[ii] != -1) {
454 alreadySet = true;
455 }
456 if (_providerID[ii] != newProviderID[ii]) {
457 different = true;
458 }
459 _providerID[ii] = newProviderID[ii];
460 }
[6215]461
[5576]462 if (alreadySet && different) {
[5580]463 emit newMessage("RTCM3coDecoder: Provider Changed " + _staID.toAscii() + "\n", true);
[5577]464 emit providerIDChanged(_staID);
[5576]465 }
466}
[6467]467
468//
469////////////////////////////////////////////////////////////////////////////
[6556]470void RTCM3coDecoder::setEpochTime() {
[6467]471
472 _lastTime.reset();
473
[6553]474 double epoSecGPS = -1.0;
475 double epoSecGlo = -1.0;
[6467]476 if (_clkOrb.NumberOfSat[CLOCKORBIT_SATGPS] > 0) {
[6553]477 epoSecGPS = _clkOrb.EpochTime[CLOCKORBIT_SATGPS]; // 0 .. 604799 s
[6467]478 }
479 else if (_codeBias.NumberOfSat[CLOCKORBIT_SATGPS] > 0) {
[6470]480 epoSecGPS = _codeBias.EpochTime[CLOCKORBIT_SATGPS]; // 0 .. 604799 s
[6467]481 }
[6470]482 else if (_phaseBias.NumberOfSat[CLOCKORBIT_SATGPS] > 0) {
483 epoSecGPS = _phaseBias.EpochTime[CLOCKORBIT_SATGPS]; // 0 .. 604799 s
484 }
485 else if (_vTEC.NumLayers > 0) {
486 epoSecGPS = _vTEC.EpochTime; // 0 .. 604799 s
487 }
[6467]488 else if (_clkOrb.NumberOfSat[CLOCKORBIT_SATGLONASS] > 0) {
[6470]489 epoSecGlo = _clkOrb.EpochTime[CLOCKORBIT_SATGLONASS]; // 0 .. 86399 s
[6467]490 }
491 else if (_codeBias.NumberOfSat[CLOCKORBIT_SATGLONASS] > 0) {
[6470]492 epoSecGlo = _codeBias.EpochTime[CLOCKORBIT_SATGLONASS]; // 0 .. 86399 s
[6467]493 }
[6470]494 else if (_phaseBias.NumberOfSat[CLOCKORBIT_SATGLONASS] > 0) {
495 epoSecGlo = _phaseBias.EpochTime[CLOCKORBIT_SATGLONASS]; // 0 .. 86399 s
496 }
[6467]497
498 // Retrieve current time
499 // ---------------------
500 int currentWeek = 0;
501 double currentSec = 0.0;
502 currentGPSWeeks(currentWeek, currentSec);
503 bncTime currentTime(currentWeek, currentSec);
504
505 // Set _lastTime close to currentTime
506 // ----------------------------------
507 if (epoSecGPS != -1) {
508 _lastTime.set(currentWeek, epoSecGPS);
509 }
510 else if (epoSecGlo != -1) {
511 QDate date = dateAndTimeFromGPSweek(currentTime.gpsw(), currentTime.gpssec()).date();
512 epoSecGlo = epoSecGlo - 3 * 3600 + gnumleap(date.year(), date.month(), date.day());
513 _lastTime.set(currentWeek, epoSecGlo);
[6468]514 }
515
516 if (_lastTime.valid()) {
[6469]517 double maxDiff = 12 * 3600.0;
518 while (_lastTime < currentTime - maxDiff) {
519 _lastTime = _lastTime + maxDiff;
[6467]520 }
[6469]521 while (_lastTime > currentTime + maxDiff) {
522 _lastTime = _lastTime - maxDiff;
[6467]523 }
524 }
525}
[6472]526
527//
528////////////////////////////////////////////////////////////////////////////
529string RTCM3coDecoder::codeTypeToRnxType(char system, CodeType type) const {
530 if (system == 'G') {
531 switch (type) {
[6473]532 case CODETYPEGPS_L1_CA: return "1C";
533 case CODETYPEGPS_L1_P: return "1P";
534 case CODETYPEGPS_L1_Z: return "1W";
535 case CODETYPEGPS_L2_CA: return "2C";
536 case CODETYPEGPS_SEMI_CODELESS: return "?N"; // which carrier ?
537 case CODETYPEGPS_L2_CM: return "2S";
538 case CODETYPEGPS_L2_CL: return "2L";
539 case CODETYPEGPS_L2_CML: return "2X";
540 case CODETYPEGPS_L2_P: return "2P";
541 case CODETYPEGPS_L2_Z: return "2W";
542 case CODETYPEGPS_L5_I: return "5I";
543 case CODETYPEGPS_L5_Q: return "5Q";
[6472]544 default: return "";
545 }
546 }
547 else if (system == 'R') {
548 switch (type) {
[6473]549 case CODETYPEGLONASS_L1_CA: return "1C";
550 case CODETYPEGLONASS_L1_P: return "1P";
551 case CODETYPEGLONASS_L2_CA: return "2C";
552 case CODETYPEGLONASS_L2_P: return "2P";
[6472]553 default: return "";
554 }
555 }
556 else if (system == 'E') {
557 switch (type) {
[6473]558 case CODETYPEGALILEO_E1_A: return "1A";
559 case CODETYPEGALILEO_E1_B: return "1B";
560 case CODETYPEGALILEO_E1_C: return "1C";
561 case CODETYPEGALILEO_E5A_I: return "5I";
562 case CODETYPEGALILEO_E5A_Q: return "5Q";
563 case CODETYPEGALILEO_E5B_I: return "7I";
564 case CODETYPEGALILEO_E5B_Q: return "7Q";
565 case CODETYPEGALILEO_E5_I: return "8I";
566 case CODETYPEGALILEO_E5_Q: return "8Q";
567 case CODETYPEGALILEO_E6_A: return "6A";
568 case CODETYPEGALILEO_E6_B: return "6B";
569 case CODETYPEGALILEO_E6_C: return "6C";
[6472]570 default: return "";
571 }
572 }
573 else if (system == 'J') {
574 switch (type) {
[6473]575 case CODETYPEQZSS_L1_CA: return "1C";
576 case CODETYPEQZSS_L1C_D: return "1S";
577 case CODETYPEQZSS_L1C_P: return "1L";
578 case CODETYPEQZSS_L1C_DP: return "1X";
579 case CODETYPEQZSS_L2_CM: return "2S";
580 case CODETYPEQZSS_L2_CL: return "2L";
581 case CODETYPEQZSS_L2_CML: return "2X";
582 case CODETYPEQZSS_L5_I: return "5I";
583 case CODETYPEQZSS_L5_Q: return "5Q";
584 case CODETYPEQZSS_L5_IQ: return "5X";
585 case CODETYPEQZSS_LEX_S: return "6S";
586 case CODETYPEQZSS_LEX_L: return "6L";
587 case CODETYPEQZSS_LEX_SL: return "6X";
[6472]588 default: return "";
589 }
590 }
591 else if (system == 'S') {
592 switch (type) {
[6473]593 case CODETYPE_SBAS_L1_CA: return "1C";
594 case CODETYPE_SBAS_L5_I: return "5I";
595 case CODETYPE_SBAS_L5_Q: return "5Q";
596 case CODETYPE_SBAS_L5_IQ: return "5X";
[6472]597 default: return "";
598 }
599 }
600 else if (system == 'C') {
601 switch (type) {
[6473]602 case CODETYPE_BDS_B1_I: return "1I";
603 case CODETYPE_BDS_B1_Q: return "1Q";
604 case CODETYPE_BDS_B1_IQ: return "1X";
605 case CODETYPE_BDS_B2_I: return "7I";
606 case CODETYPE_BDS_B2_Q: return "7Q";
607 case CODETYPE_BDS_B2_IQ: return "7X";
608 case CODETYPE_BDS_B3_I: return "6I";
609 case CODETYPE_BDS_B3_Q: return "6Q";
610 case CODETYPE_BDS_B3_IQ: return "6X";
[6472]611 default: return "";
612 }
613 }
614 return "";
615};
Note: See TracBrowser for help on using the repository browser.