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

Last change on this file since 8153 was 8028, checked in by stuerze, 10 years ago

number of allowed biases is enlarged and some future GLONASS signal and tracking mode identifier are added

File size: 27.1 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
100// Destructor
101////////////////////////////////////////////////////////////////////////////
102RTCM3coDecoder::~RTCM3coDecoder() {
103 delete _out;
104 _IODs.clear();
105 _orbCorrections.clear();
106 _clkCorrections.clear();
107 _lastClkCorrections.clear();
108 _codeBiases.clear();
109 _phaseBiases.clear();
110 _vTecMap.clear();
111}
112
113//
114////////////////////////////////////////////////////////////////////////////
115void RTCM3coDecoder::reset() {
116 memset(&_clkOrb, 0, sizeof(_clkOrb));
117 memset(&_codeBias, 0, sizeof(_codeBias));
118 memset(&_phaseBias, 0, sizeof(_phaseBias));
119 memset(&_vTEC, 0, sizeof(_vTEC));
120}
121
122// Reopen Output File
123////////////////////////////////////////////////////////////////////////
124void RTCM3coDecoder::reopen() {
125
126 if (!_fileNameSkl.isEmpty()) {
127
128 bncSettings settings;
129
130 QDateTime datTim = currentDateAndTimeGPS();
131
132 QString hlpStr = bncRinex::nextEpochStr(datTim,
133 settings.value("corrIntr").toString(), false);
134
135 QString fileNameHlp = _fileNameSkl
136 + QString("%1").arg(datTim.date().dayOfYear(), 3, 10, QChar('0'))
137 + hlpStr + datTim.toString(".yyC");
138
139 if (_fileName == fileNameHlp) {
140 return;
141 }
142 else {
143 _fileName = fileNameHlp;
144 }
145
146 delete _out;
147 if ( Qt::CheckState(settings.value("rnxAppend").toInt()) == Qt::Checked) {
148 _out = new ofstream( _fileName.toAscii().data(), ios_base::out | ios_base::app );
149 }
150 else {
151 _out = new ofstream( _fileName.toAscii().data() );
152 }
153 }
154}
155
156//
157////////////////////////////////////////////////////////////////////////////
158t_irc RTCM3coDecoder::Decode(char* buffer, int bufLen, vector<string>& errmsg) {
159
160 errmsg.clear();
161
162 _buffer.append(QByteArray(buffer,bufLen));
163
164 t_irc retCode = failure;
165
166 while(_buffer.size()) {
167
168 struct ClockOrbit clkOrbSav;
169 struct CodeBias codeBiasSav;
170 struct PhaseBias phaseBiasSav;
171 struct VTEC vTECSav;
172 memcpy(&clkOrbSav, &_clkOrb, sizeof(clkOrbSav)); // save state
173 memcpy(&codeBiasSav, &_codeBias, sizeof(codeBiasSav));
174 memcpy(&phaseBiasSav, &_phaseBias, sizeof(phaseBiasSav));
175 memcpy(&vTECSav, &_vTEC, sizeof(vTECSav));
176
177 int bytesused = 0;
178 GCOB_RETURN irc = GetSSR(&_clkOrb, &_codeBias, &_vTEC, &_phaseBias,
179 _buffer.data(), _buffer.size(), &bytesused);
180
181 if (irc <= -30) { // not enough data - restore state and exit loop
182 memcpy(&_clkOrb, &clkOrbSav, sizeof(clkOrbSav));
183 memcpy(&_codeBias, &codeBiasSav, sizeof(codeBiasSav));
184 memcpy(&_phaseBias, &phaseBiasSav, sizeof(phaseBiasSav));
185 memcpy(&_vTEC, &vTECSav, sizeof(vTECSav));
186 break;
187 }
188
189 else if (irc < 0) { // error - skip 1 byte and retry
190 reset();
191 _buffer = _buffer.mid(bytesused ? bytesused : 1);
192 }
193
194 else { // OK or MESSAGEFOLLOWS
195 _buffer = _buffer.mid(bytesused);
196
197 if (irc == GCOBR_OK || irc == GCOBR_MESSAGEFOLLOWS ) {
198
199 setEpochTime(); // sets _lastTime
200
201 if (_lastTime.valid()) {
202 reopen();
203 checkProviderID();
204 sendResults();
205 retCode = success;
206 }
207 else {
208 retCode = failure;
209 }
210
211 reset();
212 }
213 }
214 }
215
216 return retCode;
217}
218
219//
220////////////////////////////////////////////////////////////////////////////
221void RTCM3coDecoder::sendResults() {
222
223 // Orbit and clock corrections of all satellites
224 // ---------------------------------------------
225 for (unsigned ii = 0; ii < CLOCKORBIT_NUMGPS
226 + CLOCKORBIT_NUMGLONASS
227 + CLOCKORBIT_NUMGALILEO
228 + CLOCKORBIT_NUMQZSS
229 + CLOCKORBIT_NUMSBAS
230 + _clkOrb.NumberOfSat[CLOCKORBIT_SATBDS];
231 ii++) {
232 char sysCh = ' ';
233 int flag = 0;
234 if (ii < _clkOrb.NumberOfSat[CLOCKORBIT_SATGPS]) {
235 sysCh = 'G';
236 }
237 else if (ii >= CLOCKORBIT_OFFSETGLONASS &&
238 ii < CLOCKORBIT_OFFSETGLONASS + _clkOrb.NumberOfSat[CLOCKORBIT_SATGLONASS]) {
239 sysCh = 'R';
240 }
241 else if (ii >= CLOCKORBIT_OFFSETGALILEO &&
242 ii < CLOCKORBIT_OFFSETGALILEO + _clkOrb.NumberOfSat[CLOCKORBIT_SATGALILEO]) {
243 sysCh = 'E';
244 flag = 1; // I/NAV clock has been chosen as reference clock for Galileo SSR corrections
245 }
246 else if (ii >= CLOCKORBIT_OFFSETQZSS &&
247 ii < CLOCKORBIT_OFFSETQZSS + _clkOrb.NumberOfSat[CLOCKORBIT_SATQZSS]) {
248 sysCh = 'J';
249 }
250 else if (ii >= CLOCKORBIT_OFFSETSBAS &&
251 ii < CLOCKORBIT_OFFSETSBAS + _clkOrb.NumberOfSat[CLOCKORBIT_SATSBAS]) {
252 sysCh = 'S';
253 }
254 else if (ii >= CLOCKORBIT_OFFSETBDS &&
255 ii < CLOCKORBIT_OFFSETBDS + _clkOrb.NumberOfSat[CLOCKORBIT_SATBDS]) {
256 sysCh = 'C';
257 }
258 else {
259 continue;
260 }
261 // Orbit correction
262 // ----------------
263 if ( _clkOrb.messageType == COTYPE_GPSCOMBINED ||
264 _clkOrb.messageType == COTYPE_GLONASSCOMBINED ||
265 _clkOrb.messageType == COTYPE_GALILEOCOMBINED ||
266 _clkOrb.messageType == COTYPE_QZSSCOMBINED ||
267 _clkOrb.messageType == COTYPE_SBASCOMBINED ||
268 _clkOrb.messageType == COTYPE_BDSCOMBINED ||
269 _clkOrb.messageType == COTYPE_GPSORBIT ||
270 _clkOrb.messageType == COTYPE_GLONASSORBIT ||
271 _clkOrb.messageType == COTYPE_GALILEOORBIT ||
272 _clkOrb.messageType == COTYPE_QZSSORBIT ||
273 _clkOrb.messageType == COTYPE_SBASORBIT ||
274 _clkOrb.messageType == COTYPE_BDSORBIT ) {
275
276 t_orbCorr orbCorr;
277 orbCorr._prn.set(sysCh, _clkOrb.Sat[ii].ID, flag);
278 orbCorr._staID = _staID.toStdString();
279 orbCorr._iod = _clkOrb.Sat[ii].IOD;
280 orbCorr._time = _lastTime;
281 orbCorr._updateInt = _clkOrb.UpdateInterval;
282 orbCorr._system = sysCh;
283 orbCorr._xr[0] = _clkOrb.Sat[ii].Orbit.DeltaRadial;
284 orbCorr._xr[1] = _clkOrb.Sat[ii].Orbit.DeltaAlongTrack;
285 orbCorr._xr[2] = _clkOrb.Sat[ii].Orbit.DeltaCrossTrack;
286 orbCorr._dotXr[0] = _clkOrb.Sat[ii].Orbit.DotDeltaRadial;
287 orbCorr._dotXr[1] = _clkOrb.Sat[ii].Orbit.DotDeltaAlongTrack;
288 orbCorr._dotXr[2] = _clkOrb.Sat[ii].Orbit.DotDeltaCrossTrack;
289
290 _orbCorrections[_lastTime].append(orbCorr);
291
292 _IODs[orbCorr._prn] = _clkOrb.Sat[ii].IOD;
293 }
294
295 // Clock Corrections
296 // -----------------
297 if ( _clkOrb.messageType == COTYPE_GPSCOMBINED ||
298 _clkOrb.messageType == COTYPE_GLONASSCOMBINED ||
299 _clkOrb.messageType == COTYPE_GALILEOCOMBINED ||
300 _clkOrb.messageType == COTYPE_QZSSCOMBINED ||
301 _clkOrb.messageType == COTYPE_SBASCOMBINED ||
302 _clkOrb.messageType == COTYPE_BDSCOMBINED ||
303 _clkOrb.messageType == COTYPE_GPSCLOCK ||
304 _clkOrb.messageType == COTYPE_GLONASSCLOCK ||
305 _clkOrb.messageType == COTYPE_GALILEOCLOCK ||
306 _clkOrb.messageType == COTYPE_QZSSCLOCK ||
307 _clkOrb.messageType == COTYPE_SBASCLOCK ||
308 _clkOrb.messageType == COTYPE_BDSCLOCK) {
309
310 t_clkCorr clkCorr;
311 clkCorr._prn.set(sysCh, _clkOrb.Sat[ii].ID, flag);
312
313 clkCorr._staID = _staID.toStdString();
314 clkCorr._time = _lastTime;
315 clkCorr._updateInt = _clkOrb.UpdateInterval;
316 clkCorr._dClk = _clkOrb.Sat[ii].Clock.DeltaA0 / t_CST::c;
317 clkCorr._dotDClk = _clkOrb.Sat[ii].Clock.DeltaA1 / t_CST::c;
318 clkCorr._dotDotDClk = _clkOrb.Sat[ii].Clock.DeltaA2 / t_CST::c;
319
320 _lastClkCorrections[clkCorr._prn] = clkCorr;
321
322 if (_IODs.contains(clkCorr._prn)) {
323 clkCorr._iod = _IODs[clkCorr._prn];
324 _clkCorrections[_lastTime].append(clkCorr);
325 }
326 }
327
328 // High-Resolution Clocks
329 // ----------------------
330 if ( _clkOrb.messageType == COTYPE_GPSHR ||
331 _clkOrb.messageType == COTYPE_GLONASSHR ||
332 _clkOrb.messageType == COTYPE_GALILEOHR ||
333 _clkOrb.messageType == COTYPE_QZSSHR ||
334 _clkOrb.messageType == COTYPE_SBASHR ||
335 _clkOrb.messageType == COTYPE_BDSHR) {
336 t_prn prn(sysCh, _clkOrb.Sat[ii].ID, flag);
337 if (_lastClkCorrections.contains(prn)) {
338 t_clkCorr clkCorr;
339 clkCorr = _lastClkCorrections[prn];
340 clkCorr._time = _lastTime;
341 clkCorr._updateInt = _clkOrb.UpdateInterval;
342 clkCorr._dClk += _clkOrb.Sat[ii].hrclock / t_CST::c;
343 if (_IODs.contains(clkCorr._prn)) {
344 clkCorr._iod = _IODs[clkCorr._prn];
345 _clkCorrections[_lastTime].push_back(clkCorr);
346 }
347 }
348 }
349 }
350
351 // Code Biases
352 // -----------
353 for (unsigned ii = 0; ii < CLOCKORBIT_NUMGPS
354 + CLOCKORBIT_NUMGLONASS
355 + CLOCKORBIT_NUMGALILEO
356 + CLOCKORBIT_NUMQZSS
357 + CLOCKORBIT_NUMSBAS
358 + _codeBias.NumberOfSat[CLOCKORBIT_SATBDS];
359 ii++) {
360 char sysCh = ' ';
361 if (ii < _codeBias.NumberOfSat[CLOCKORBIT_SATGPS]) {
362 sysCh = 'G';
363 }
364 else if (ii >= CLOCKORBIT_OFFSETGLONASS &&
365 ii < CLOCKORBIT_OFFSETGLONASS + _codeBias.NumberOfSat[CLOCKORBIT_SATGLONASS]) {
366 sysCh = 'R';
367 }
368 else if (ii >= CLOCKORBIT_OFFSETGALILEO &&
369 ii < CLOCKORBIT_OFFSETGALILEO + _codeBias.NumberOfSat[CLOCKORBIT_SATGALILEO]) {
370 sysCh = 'E';
371 }
372 else if (ii >= CLOCKORBIT_OFFSETQZSS &&
373 ii < CLOCKORBIT_OFFSETQZSS + _codeBias.NumberOfSat[CLOCKORBIT_SATQZSS]) {
374 sysCh = 'J';
375 }
376 else if (ii >= CLOCKORBIT_OFFSETSBAS &&
377 ii < CLOCKORBIT_OFFSETSBAS + _codeBias.NumberOfSat[CLOCKORBIT_SATSBAS]) {
378 sysCh = 'S';
379 }
380 else if (ii >= CLOCKORBIT_OFFSETBDS &&
381 ii < CLOCKORBIT_OFFSETBDS + _codeBias.NumberOfSat[CLOCKORBIT_SATBDS]) {
382 sysCh = 'C';
383 }
384 else {
385 continue;
386 }
387 t_satCodeBias satCodeBias;
388 satCodeBias._prn.set(sysCh, _codeBias.Sat[ii].ID);
389 satCodeBias._staID = _staID.toStdString();
390 satCodeBias._time = _lastTime;
391 satCodeBias._updateInt = _codeBias.UpdateInterval;
392 for (unsigned jj = 0; jj < _codeBias.Sat[ii].NumberOfCodeBiases; jj++) {
393 const CodeBias::BiasSat::CodeBiasEntry& biasEntry = _codeBias.Sat[ii].Biases[jj];
394 t_frqCodeBias frqCodeBias;
395 frqCodeBias._rnxType2ch.assign(codeTypeToRnxType(sysCh, biasEntry.Type));
396 frqCodeBias._value = biasEntry.Bias;
397 if (!frqCodeBias._rnxType2ch.empty()) {
398 satCodeBias._bias.push_back(frqCodeBias);
399 }
400 }
401 _codeBiases[_lastTime].append(satCodeBias);
402 }
403
404 // Phase Biases
405 // -----------
406 for (unsigned ii = 0; ii < CLOCKORBIT_NUMGPS
407 + CLOCKORBIT_NUMGLONASS
408 + CLOCKORBIT_NUMGALILEO
409 + CLOCKORBIT_NUMQZSS
410 + CLOCKORBIT_NUMSBAS
411 + _phaseBias.NumberOfSat[CLOCKORBIT_SATBDS];
412 ii++) {
413 char sysCh = ' ';
414 if (ii < _phaseBias.NumberOfSat[CLOCKORBIT_SATGPS]) {
415 sysCh = 'G';
416 }
417 else if (ii >= CLOCKORBIT_OFFSETGLONASS &&
418 ii < CLOCKORBIT_OFFSETGLONASS + _phaseBias.NumberOfSat[CLOCKORBIT_SATGLONASS]) {
419 sysCh = 'R';
420 }
421 else if (ii >= CLOCKORBIT_OFFSETGALILEO &&
422 ii < CLOCKORBIT_OFFSETGALILEO + _phaseBias.NumberOfSat[CLOCKORBIT_SATGALILEO]) {
423 sysCh = 'E';
424 }
425 else if (ii >= CLOCKORBIT_OFFSETQZSS &&
426 ii < CLOCKORBIT_OFFSETQZSS + _phaseBias.NumberOfSat[CLOCKORBIT_SATQZSS]) {
427 sysCh = 'J';
428 }
429 else if (ii >= CLOCKORBIT_OFFSETSBAS &&
430 ii < CLOCKORBIT_OFFSETSBAS + _phaseBias.NumberOfSat[CLOCKORBIT_SATSBAS]) {
431 sysCh = 'S';
432 }
433 else if (ii >= CLOCKORBIT_OFFSETBDS &&
434 ii < CLOCKORBIT_OFFSETBDS + _phaseBias.NumberOfSat[CLOCKORBIT_SATBDS]) {
435 sysCh = 'C';
436 }
437 else {
438 continue;
439 }
440 t_satPhaseBias satPhaseBias;
441 satPhaseBias._prn.set(sysCh, _phaseBias.Sat[ii].ID);
442 satPhaseBias._staID = _staID.toStdString();
443 satPhaseBias._time = _lastTime;
444 satPhaseBias._updateInt = _phaseBias.UpdateInterval;
445 satPhaseBias._dispBiasConstistInd = _phaseBias.DispersiveBiasConsistencyIndicator;
446 satPhaseBias._MWConsistInd = _phaseBias.MWConsistencyIndicator;
447 satPhaseBias._yawDeg = _phaseBias.Sat[ii].YawAngle * 180.0 / M_PI;
448 satPhaseBias._yawDegRate = _phaseBias.Sat[ii].YawRate * 180.0 / M_PI;
449 for (unsigned jj = 0; jj < _phaseBias.Sat[ii].NumberOfPhaseBiases; jj++) {
450 const PhaseBias::PhaseBiasSat::PhaseBiasEntry& biasEntry = _phaseBias.Sat[ii].Biases[jj];
451 t_frqPhaseBias frqPhaseBias;
452 frqPhaseBias._rnxType2ch.assign(codeTypeToRnxType(sysCh, biasEntry.Type));
453 frqPhaseBias._value = biasEntry.Bias;
454 frqPhaseBias._fixIndicator = biasEntry.SignalIntegerIndicator;
455 frqPhaseBias._fixWideLaneIndicator = biasEntry.SignalsWideLaneIntegerIndicator;
456 frqPhaseBias._jumpCounter = biasEntry.SignalDiscontinuityCounter;
457 if (!frqPhaseBias._rnxType2ch.empty()) {
458 satPhaseBias._bias.push_back(frqPhaseBias);
459 }
460 }
461 _phaseBiases[_lastTime].append(satPhaseBias);
462 }
463
464 // Ionospheric Model
465 // -----------------
466 if (_vTEC.NumLayers > 0) {
467 _vTecMap[_lastTime]._time = _lastTime;
468 _vTecMap[_lastTime]._updateInt = _vTEC.UpdateInterval;
469 _vTecMap[_lastTime]._staID = _staID.toStdString();
470 for (unsigned ii = 0; ii < _vTEC.NumLayers; ii++) {
471 const VTEC::IonoLayers& ionoLayer = _vTEC.Layers[ii];
472 t_vTecLayer layer;
473 layer._height = ionoLayer.Height;
474 layer._C.ReSize(ionoLayer.Degree+1, ionoLayer.Order+1);
475 layer._S.ReSize(ionoLayer.Degree+1, ionoLayer.Order+1);
476 for (unsigned iDeg = 0; iDeg <= ionoLayer.Degree; iDeg++) {
477 for (unsigned iOrd = 0; iOrd <= ionoLayer.Order; iOrd++) {
478 layer._C[iDeg][iOrd] = ionoLayer.Cosinus[iDeg][iOrd];
479 layer._S[iDeg][iOrd] = ionoLayer.Sinus[iDeg][iOrd];
480 }
481 }
482 _vTecMap[_lastTime]._layers.push_back(layer);
483 }
484 }
485
486 // Dump all older epochs
487 // ---------------------
488 QMutableMapIterator<bncTime, QList<t_orbCorr> > itOrb(_orbCorrections);
489 while (itOrb.hasNext()) {
490 itOrb.next();
491 if (itOrb.key() < _lastTime) {
492 emit newOrbCorrections(itOrb.value());
493 t_orbCorr::writeEpoch(_out, itOrb.value());
494 itOrb.remove();
495 }
496 }
497 QMutableMapIterator<bncTime, QList<t_clkCorr> > itClk(_clkCorrections);
498 while (itClk.hasNext()) {
499 itClk.next();
500 if (itClk.key() < _lastTime) {
501 emit newClkCorrections(itClk.value());
502 t_clkCorr::writeEpoch(_out, itClk.value());
503 itClk.remove();
504 }
505 }
506 QMutableMapIterator<bncTime, QList<t_satCodeBias> > itCB(_codeBiases);
507 while (itCB.hasNext()) {
508 itCB.next();
509 if (itCB.key() < _lastTime) {
510 emit newCodeBiases(itCB.value());
511 t_satCodeBias::writeEpoch(_out, itCB.value());
512 itCB.remove();
513 }
514 }
515 QMutableMapIterator<bncTime, QList<t_satPhaseBias> > itPB(_phaseBiases);
516 while (itPB.hasNext()) {
517 itPB.next();
518 if (itPB.key() < _lastTime) {
519 emit newPhaseBiases(itPB.value());
520 t_satPhaseBias::writeEpoch(_out, itPB.value());
521 itPB.remove();
522 }
523 }
524 QMutableMapIterator<bncTime, t_vTec> itTec(_vTecMap);
525 while (itTec.hasNext()) {
526 itTec.next();
527 if (itTec.key() < _lastTime) {
528 emit newTec(itTec.value());
529 t_vTec::write(_out, itTec.value());
530 itTec.remove();
531 }
532 }
533}
534
535//
536////////////////////////////////////////////////////////////////////////////
537void RTCM3coDecoder::checkProviderID() {
538
539 if (_clkOrb.SSRProviderID == 0 && _clkOrb.SSRSolutionID == 0 && _clkOrb.SSRIOD == 0) {
540 return;
541 }
542
543 int newProviderID[3];
544 newProviderID[0] = _clkOrb.SSRProviderID;
545 newProviderID[1] = _clkOrb.SSRSolutionID;
546 newProviderID[2] = _clkOrb.SSRIOD;
547
548 bool alreadySet = false;
549 bool different = false;
550
551 for (unsigned ii = 0; ii < 3; ii++) {
552 if (_providerID[ii] != -1) {
553 alreadySet = true;
554 }
555 if (_providerID[ii] != newProviderID[ii]) {
556 different = true;
557 }
558 _providerID[ii] = newProviderID[ii];
559 }
560
561 if (alreadySet && different) {
562 emit newMessage("RTCM3coDecoder: Provider Changed: " + _staID.toAscii(), true);
563 emit providerIDChanged(_staID);
564 }
565}
566
567//
568////////////////////////////////////////////////////////////////////////////
569void RTCM3coDecoder::setEpochTime() {
570
571 _lastTime.reset();
572
573 double epoSecGPS = -1.0;
574 double epoSecGlo = -1.0;
575 double epoSecGal = -1.0;
576 double epoSecQzss = -1.0;
577 double epoSecSbas = -1.0;
578 double epoSecBds = -1.0;
579 if (_clkOrb.NumberOfSat[CLOCKORBIT_SATGPS] > 0) {
580 epoSecGPS = _clkOrb.EpochTime[CLOCKORBIT_SATGPS]; // 0 .. 604799 s
581 }
582 else if (_codeBias.NumberOfSat[CLOCKORBIT_SATGPS] > 0) {
583 epoSecGPS = _codeBias.EpochTime[CLOCKORBIT_SATGPS]; // 0 .. 604799 s
584 }
585 else if (_phaseBias.NumberOfSat[CLOCKORBIT_SATGPS] > 0) {
586 epoSecGPS = _phaseBias.EpochTime[CLOCKORBIT_SATGPS]; // 0 .. 604799 s
587 }
588 else if (_vTEC.NumLayers > 0) {
589 epoSecGPS = _vTEC.EpochTime; // 0 .. 604799 s
590 }
591 else if (_clkOrb.NumberOfSat[CLOCKORBIT_SATGLONASS] > 0) {
592 epoSecGlo = _clkOrb.EpochTime[CLOCKORBIT_SATGLONASS]; // 0 .. 86399 s
593 }
594 else if (_codeBias.NumberOfSat[CLOCKORBIT_SATGLONASS] > 0) {
595 epoSecGlo = _codeBias.EpochTime[CLOCKORBIT_SATGLONASS]; // 0 .. 86399 s
596 }
597 else if (_phaseBias.NumberOfSat[CLOCKORBIT_SATGLONASS] > 0) {
598 epoSecGlo = _phaseBias.EpochTime[CLOCKORBIT_SATGLONASS]; // 0 .. 86399 s
599 }
600 else if (_clkOrb.NumberOfSat[CLOCKORBIT_SATGALILEO] > 0) {
601 epoSecGal = _clkOrb.EpochTime[CLOCKORBIT_SATGALILEO];
602 }
603 else if (_codeBias.NumberOfSat[CLOCKORBIT_SATGALILEO] > 0) {
604 epoSecGal = _codeBias.EpochTime[CLOCKORBIT_SATGALILEO];
605 }
606 else if (_phaseBias.NumberOfSat[CLOCKORBIT_SATGALILEO] > 0) {
607 epoSecGal = _phaseBias.EpochTime[CLOCKORBIT_SATGALILEO];
608 }
609 else if (_clkOrb.NumberOfSat[CLOCKORBIT_SATQZSS] > 0) {
610 epoSecQzss = _clkOrb.EpochTime[CLOCKORBIT_SATQZSS];
611 }
612 else if (_codeBias.NumberOfSat[CLOCKORBIT_SATQZSS] > 0) {
613 epoSecQzss = _codeBias.EpochTime[CLOCKORBIT_SATQZSS];
614 }
615 else if (_phaseBias.NumberOfSat[CLOCKORBIT_SATQZSS] > 0) {
616 epoSecQzss = _phaseBias.EpochTime[CLOCKORBIT_SATQZSS];
617 }
618 else if (_clkOrb.NumberOfSat[CLOCKORBIT_SATSBAS] > 0) {
619 epoSecSbas = _clkOrb.EpochTime[CLOCKORBIT_SATSBAS];
620 }
621 else if (_codeBias.NumberOfSat[CLOCKORBIT_SATSBAS] > 0) {
622 epoSecSbas = _codeBias.EpochTime[CLOCKORBIT_SATSBAS];
623 }
624 else if (_phaseBias.NumberOfSat[CLOCKORBIT_SATSBAS] > 0) {
625 epoSecSbas = _phaseBias.EpochTime[CLOCKORBIT_SATSBAS];
626 }
627 else if (_clkOrb.NumberOfSat[CLOCKORBIT_SATBDS] > 0) {
628 epoSecBds = _clkOrb.EpochTime[CLOCKORBIT_SATBDS];
629 }
630 else if (_codeBias.NumberOfSat[CLOCKORBIT_SATBDS] > 0) {
631 epoSecBds = _codeBias.EpochTime[CLOCKORBIT_SATBDS];
632 }
633 else if (_phaseBias.NumberOfSat[CLOCKORBIT_SATBDS] > 0) {
634 epoSecBds = _phaseBias.EpochTime[CLOCKORBIT_SATBDS];
635 }
636
637 // Retrieve current time
638 // ---------------------
639 int currentWeek = 0;
640 double currentSec = 0.0;
641 currentGPSWeeks(currentWeek, currentSec);
642 bncTime currentTime(currentWeek, currentSec);
643
644 // Set _lastTime close to currentTime
645 // ----------------------------------
646 if (epoSecGPS != -1) {
647 _lastTime.set(currentWeek, epoSecGPS);
648 }
649 else if (epoSecGlo != -1) {
650 QDate date = dateAndTimeFromGPSweek(currentTime.gpsw(), currentTime.gpssec()).date();
651 epoSecGlo = epoSecGlo - 3 * 3600 + gnumleap(date.year(), date.month(), date.day());
652 _lastTime.set(currentWeek, epoSecGlo);
653 }
654 else if (epoSecGal != -1) {
655 _lastTime.set(currentWeek, epoSecGal);
656 }
657 else if (epoSecQzss != -1) {
658 _lastTime.set(currentWeek, epoSecQzss);
659 }
660 else if (epoSecSbas != -1) {
661 _lastTime.set(currentWeek, epoSecSbas);
662 }
663 else if (epoSecBds != -1) {
664 epoSecBds += 14.0;
665 if (epoSecBds > 604800.0) {
666 epoSecBds -= 7.0*24.0*60.0*60.0;
667 }
668 _lastTime.set(currentWeek, epoSecBds);
669 }
670
671 if (_lastTime.valid()) {
672 double maxDiff = 12 * 3600.0;
673 while (_lastTime < currentTime - maxDiff) {
674 _lastTime = _lastTime + maxDiff;
675 }
676 while (_lastTime > currentTime + maxDiff) {
677 _lastTime = _lastTime - maxDiff;
678 }
679 }
680}
681
682//
683////////////////////////////////////////////////////////////////////////////
684string RTCM3coDecoder::codeTypeToRnxType(char system, CodeType type) const {
685 if (system == 'G') {
686 switch (type) {
687 case CODETYPEGPS_L1_CA: return "1C";
688 case CODETYPEGPS_L1_P: return "1P";
689 case CODETYPEGPS_L1_Z: return "1W";
690 //case CODETYPEGPS_L1_Y: return "1Y";
691 //case CODETYPEGPS_L1_M: return "1M";
692 case CODETYPEGPS_L2_CA: return "2C";
693 case CODETYPEGPS_SEMI_CODELESS: return "2D";
694 case CODETYPEGPS_L2_CM: return "2S";
695 case CODETYPEGPS_L2_CL: return "2L";
696 case CODETYPEGPS_L2_CML: return "2X";
697 case CODETYPEGPS_L2_P: return "2P";
698 case CODETYPEGPS_L2_Z: return "2W";
699 //case CODETYPEGPS_L2_Y: return "2Y";
700 //case CODETYPEGPS_L2_M: return "2M";
701 case CODETYPEGPS_L5_I: return "5I";
702 case CODETYPEGPS_L5_Q: return "5Q";
703 case CODETYPEGPS_L5_IQ: return "5X";
704 case CODETYPEGPS_L1C_D: return "1S";
705 case CODETYPEGPS_L1C_P: return "1L";
706 case CODETYPEGPS_L1C_DP: return "1X";
707 default: return "";
708 }
709 }
710 else if (system == 'R') {
711 switch (type) {
712 case CODETYPEGLONASS_L1_CA: return "1C";
713 case CODETYPEGLONASS_L1_P: return "1P";
714 case CODETYPEGLONASS_L2_CA: return "2C";
715 case CODETYPEGLONASS_L2_P: return "2P";
716 case CODETYPEGLONASS_L3_I: return "3I";
717 case CODETYPEGLONASS_L3_Q: return "3Q";
718 case CODETYPEGLONASS_L3_IQ: return "3X";
719 default: return "";
720 }
721 }
722 else if (system == 'E') {
723 switch (type) {
724 case CODETYPEGALILEO_E1_A: return "1A";
725 case CODETYPEGALILEO_E1_B: return "1B";
726 case CODETYPEGALILEO_E1_C: return "1C";
727 case CODETYPEGALILEO_E1_BC: return "1X";
728 case CODETYPEGALILEO_E1_ABC: return "1Z";
729 case CODETYPEGALILEO_E5A_I: return "5I";
730 case CODETYPEGALILEO_E5A_Q: return "5Q";
731 case CODETYPEGALILEO_E5A_IQ: return "5X";
732 case CODETYPEGALILEO_E5B_I: return "7I";
733 case CODETYPEGALILEO_E5B_Q: return "7Q";
734 case CODETYPEGALILEO_E5B_IQ: return "7X";
735 case CODETYPEGALILEO_E5_I: return "8I";
736 case CODETYPEGALILEO_E5_Q: return "8Q";
737 case CODETYPEGALILEO_E5_IQ: return "8X";
738 case CODETYPEGALILEO_E6_A: return "6A";
739 case CODETYPEGALILEO_E6_B: return "6B";
740 case CODETYPEGALILEO_E6_C: return "6C";
741 case CODETYPEGALILEO_E6_BC: return "6X";
742 case CODETYPEGALILEO_E6_ABC: return "6Z";
743 default: return "";
744 }
745 }
746 else if (system == 'J') {
747 switch (type) {
748 case CODETYPEQZSS_L1_CA: return "1C";
749 case CODETYPEQZSS_L1C_D: return "1S";
750 case CODETYPEQZSS_L1C_P: return "1L";
751 case CODETYPEQZSS_L1C_DP: return "1X";
752 case CODETYPEQZSS_L2C_M: return "2S";
753 case CODETYPEQZSS_L2C_L: return "2L";
754 case CODETYPEQZSS_L2C_ML: return "2X";
755 case CODETYPEQZSS_L5_I: return "5I";
756 case CODETYPEQZSS_L5_Q: return "5Q";
757 case CODETYPEQZSS_L5_IQ: return "5X";
758 case CODETYPEQZSS_LEX_S: return "6S";
759 case CODETYPEQZSS_LEX_L: return "6L";
760 case CODETYPEQZSS_LEX_SL: return "6X";
761 default: return "";
762 }
763 }
764 else if (system == 'S') {
765 switch (type) {
766 case CODETYPE_SBAS_L1_CA: return "1C";
767 case CODETYPE_SBAS_L5_I: return "5I";
768 case CODETYPE_SBAS_L5_Q: return "5Q";
769 case CODETYPE_SBAS_L5_IQ: return "5X";
770 default: return "";
771 }
772 }
773 else if (system == 'C') {
774 switch (type) {
775 case CODETYPE_BDS_B1_I: return "2I";
776 case CODETYPE_BDS_B1_Q: return "2Q";
777 case CODETYPE_BDS_B1_IQ: return "2X";
778 case CODETYPE_BDS_B2_I: return "7I";
779 case CODETYPE_BDS_B2_Q: return "7Q";
780 case CODETYPE_BDS_B2_IQ: return "7X";
781 case CODETYPE_BDS_B3_I: return "6I";
782 case CODETYPE_BDS_B3_Q: return "6Q";
783 case CODETYPE_BDS_B3_IQ: return "6X";
784 default: return "";
785 }
786 }
787 return "";
788};
Note: See TracBrowser for help on using the repository browser.