source: ntrip/branches/BNC_2.12/src/upload/bncrtnetuploadcaster.cpp@ 9081

Last change on this file since 9081 was 9081, checked in by stuerze, 4 years ago

minor changes

File size: 37.1 KB
RevLine 
[3222]1/* -------------------------------------------------------------------------
2 * BKG NTRIP Server
3 * -------------------------------------------------------------------------
4 *
[3224]5 * Class: bncRtnetUploadCaster
[3222]6 *
7 * Purpose: Connection to NTRIP Caster
8 *
9 * Author: L. Mervart
10 *
11 * Created: 29-Mar-2011
12 *
[5662]13 * Changes:
[3222]14 *
15 * -----------------------------------------------------------------------*/
16
17#include <math.h>
[5662]18#include "bncrtnetuploadcaster.h"
[3222]19#include "bncsettings.h"
[3224]20#include "bncephuser.h"
[3222]21#include "bncclockrinex.h"
22#include "bncsp3.h"
[6812]23#include "gnss.h"
[3222]24
25using namespace std;
26
27// Constructor
28////////////////////////////////////////////////////////////////////////////
[3224]29bncRtnetUploadCaster::bncRtnetUploadCaster(const QString& mountpoint,
[9036]30 const QString& outHost, int outPort,
31 const QString& password,
32 const QString& crdTrafo, const QString& ssrFormat, bool CoM, const QString& sp3FileName,
[6877]33 const QString& rnxFileName, int PID, int SID, int IOD, int iRow) :
34 bncUploadCaster(mountpoint, outHost, outPort, password, iRow, 0) {
[3224]35
[8362]36 if (!mountpoint.isEmpty()) {
37 _casterID += mountpoint;
38 }
[5130]39 if (!outHost.isEmpty()) {
[8362]40 _casterID += " " + outHost;
41 if (outPort) {
42 _casterID += ":" + QString("%1").arg(outPort, 10);
43 }
[5130]44 }
45 if (!crdTrafo.isEmpty()) {
46 _casterID += " " + crdTrafo;
47 }
48 if (!sp3FileName.isEmpty()) {
49 _casterID += " " + sp3FileName;
50 }
51 if (!rnxFileName.isEmpty()) {
52 _casterID += " " + rnxFileName;
53 }
54
[6877]55 _crdTrafo = crdTrafo;
[9036]56
57 _ssrFormat = ssrFormat;
58 _ssrCorr = 0;
[9081]59 if (_ssrFormat == "IGS-SSR") {
[9036]60 _ssrCorr = new SsrCorrIgs();
61 }
[9081]62 else if (_ssrFormat == "RTCM-SSR") {
[9036]63 _ssrCorr = new SsrCorrRtcm();
64 }
65
[6877]66 _CoM = CoM;
67 _PID = PID;
68 _SID = SID;
69 _IOD = IOD;
[3222]70
[3224]71 // Member that receives the ephemeris
72 // ----------------------------------
[6441]73 _ephUser = new bncEphUser(true);
[3222]74
[3272]75 bncSettings settings;
[6877]76 QString intr = settings.value("uploadIntr").toString();
[7297]77 QStringList hlp = settings.value("cmbStreams").toStringList();
[6559]78 _samplRtcmEphCorr = settings.value("uploadSamplRtcmEphCorr").toDouble();
79 if (hlp.size() > 1) { // combination stream upload
[6877]80 _samplRtcmClkCorr = settings.value("cmbSampl").toInt();
[6557]81 }
[6877]82 else { // single stream upload or sp3 file generation
83 _samplRtcmClkCorr = 5; // default
84 }
85 int samplClkRnx = settings.value("uploadSamplClkRnx").toInt();
86 int samplSp3 = settings.value("uploadSamplSp3").toInt() * 60;
[4174]87
88 if (_samplRtcmEphCorr == 0.0) {
[3753]89 _usedEph = 0;
90 }
91 else {
[6442]92 _usedEph = new QMap<QString, const t_eph*>;
[3753]93 }
[3272]94
[3222]95 // RINEX writer
96 // ------------
97 if (!rnxFileName.isEmpty()) {
[4174]98 _rnx = new bncClockRinex(rnxFileName, intr, samplClkRnx);
[3222]99 }
100 else {
101 _rnx = 0;
102 }
103
104 // SP3 writer
105 // ----------
106 if (!sp3FileName.isEmpty()) {
[4174]107 _sp3 = new bncSP3(sp3FileName, intr, samplSp3);
[3222]108 }
109 else {
110 _sp3 = 0;
111 }
112
113 // Set Transformation Parameters
114 // -----------------------------
[8411]115 // Transformation Parameters from ITRF2014 to ETRF2000
[8712]116 // EUREF Technical Note 1 Relationship and Transformation between the ITRF and ETRF
117 // Zuheir Altamimi, June 28, 2018
[6877]118 if (_crdTrafo == "ETRF2000") {
[8712]119 _dx = 0.0547;
120 _dy = 0.0522;
121 _dz = -0.0741;
[8710]122
[8101]123 _dxr = 0.0001;
124 _dyr = 0.0001;
[8411]125 _dzr = -0.0019;
[8710]126
[8712]127 _ox = 0.001701;
128 _oy = 0.010290;
129 _oz = -0.016632;
[8710]130
[8712]131 _oxr = 0.000081;
132 _oyr = 0.000490;
133 _ozr = -0.000729;
[8710]134
[8712]135 _sc = 2.12;
136 _scr = 0.11;
[8710]137
[8712]138 _t0 = 2010.0;
[3222]139 }
[8101]140 // Transformation Parameters from ITRF2014 to GDA2020 (Ryan Ruddick, GA)
141 else if (_crdTrafo == "GDA2020") {
142 _dx = 0.0;
143 _dy = 0.0;
144 _dz = 0.0;
[8710]145
[8101]146 _dxr = 0.0;
147 _dyr = 0.0;
148 _dzr = 0.0;
[8710]149
[8101]150 _ox = 0.0;
151 _oy = 0.0;
152 _oz = 0.0;
[8710]153
[8101]154 _oxr = 0.00150379;
155 _oyr = 0.00118346;
156 _ozr = 0.00120716;
[8710]157
[8101]158 _sc = 0.0;
159 _scr = 0.0;
[8710]160
[8101]161 _t0 = 2020.0;
[3222]162 }
[8987]163 // Transformation Parameters from IGb14 to SIRGAS2000 (Thanks to Sonia Costa, BRA)
164 // June 29 2020: TX:-0.0027 m TY:-0.0025 m TZ:-0.0042 m SCL:1.20 (ppb) no rotations and no rates.*/
[8101]165 else if (_crdTrafo == "SIRGAS2000") {
[8987]166 _dx = -0.0027;
167 _dy = -0.0025;
168 _dz = -0.0042;
[8710]169
[8101]170 _dxr = 0.0000;
171 _dyr = 0.0000;
172 _dzr = 0.0000;
[8710]173
174 _ox = 0.000000;
175 _oy = 0.000000;
176 _oz = 0.000000;
177
[8101]178 _oxr = 0.000000;
179 _oyr = 0.000000;
180 _ozr = 0.000000;
[8710]181
[8987]182 _sc = 1.20000;
[8710]183 _scr = 0.00000;
184 _t0 = 2000.0;
[3222]185 }
[8411]186 // Transformation Parameters from ITRF2014 to DREF91
[5347]187 else if (_crdTrafo == "DREF91") {
[8719]188 _dx = 0.0547;
189 _dy = 0.0522;
190 _dz = -0.0741;
[8710]191
[8101]192 _dxr = 0.0001;
193 _dyr = 0.0001;
[8411]194 _dzr = -0.0019;
[8719]195 // ERTF200 + rotation parameters (ETRF200 => DREF91)
196 _ox = 0.001701 + 0.000658;
197 _oy = 0.010290 - 0.000208;
198 _oz = -0.016632 + 0.000755;
[8710]199
[8719]200 _oxr = 0.000081;
201 _oyr = 0.000490;
202 _ozr = -0.000729;
[8710]203
[8719]204 _sc = 2.12;
205 _scr = 0.11;
[8710]206
[8719]207 _t0 = 2010.0;
[5340]208 }
[3222]209 else if (_crdTrafo == "Custom") {
[6877]210 _dx = settings.value("trafo_dx").toDouble();
211 _dy = settings.value("trafo_dy").toDouble();
212 _dz = settings.value("trafo_dz").toDouble();
[3222]213 _dxr = settings.value("trafo_dxr").toDouble();
214 _dyr = settings.value("trafo_dyr").toDouble();
215 _dzr = settings.value("trafo_dzr").toDouble();
[6877]216 _ox = settings.value("trafo_ox").toDouble();
217 _oy = settings.value("trafo_oy").toDouble();
218 _oz = settings.value("trafo_oz").toDouble();
[3222]219 _oxr = settings.value("trafo_oxr").toDouble();
220 _oyr = settings.value("trafo_oyr").toDouble();
221 _ozr = settings.value("trafo_ozr").toDouble();
[6877]222 _sc = settings.value("trafo_sc").toDouble();
[3222]223 _scr = settings.value("trafo_scr").toDouble();
[6877]224 _t0 = settings.value("trafo_t0").toDouble();
[3222]225 }
226}
227
228// Destructor
229////////////////////////////////////////////////////////////////////////////
[3224]230bncRtnetUploadCaster::~bncRtnetUploadCaster() {
[3222]231 if (isRunning()) {
232 wait();
233 }
234 delete _rnx;
235 delete _sp3;
236 delete _ephUser;
[3753]237 delete _usedEph;
[9036]238 delete _ssrCorr;
[3222]239}
240
[5662]241//
[3222]242////////////////////////////////////////////////////////////////////////////
[3224]243void bncRtnetUploadCaster::decodeRtnetStream(char* buffer, int bufLen) {
[5662]244
[3222]245 QMutexLocker locker(&_mutex);
246
[3230]247 // Append to internal buffer
248 // -------------------------
[3222]249 _rtnetStreamBuffer.append(QByteArray(buffer, bufLen));
[3230]250
251 // Select buffer part that contains last epoch
252 // -------------------------------------------
253 QStringList lines;
254 int iEpoBeg = _rtnetStreamBuffer.lastIndexOf('*'); // begin of last epoch
255 if (iEpoBeg == -1) {
[3226]256 _rtnetStreamBuffer.clear();
257 return;
[3222]258 }
[8753]259 int iEpoBegEarlier = _rtnetStreamBuffer.indexOf('*');
260 if (iEpoBegEarlier != -1 && iEpoBegEarlier < iEpoBeg) { // are there two epoch lines in buffer?
261 _rtnetStreamBuffer = _rtnetStreamBuffer.mid(iEpoBegEarlier);
262 }
263 else {
[6896]264 _rtnetStreamBuffer = _rtnetStreamBuffer.mid(iEpoBeg);
265 }
[8753]266 int iEpoEnd = _rtnetStreamBuffer.lastIndexOf("EOE"); // end of last epoch
[3230]267 if (iEpoEnd == -1) {
268 return;
269 }
[8753]270
271 while (_rtnetStreamBuffer.count('*') > 1) { // is there more than 1 epoch line in buffer?
272 QString rtnetStreamBuffer = _rtnetStreamBuffer.mid(1);
273 int nextEpoch = rtnetStreamBuffer.indexOf('*');
[8759]274 if (nextEpoch != -1 && nextEpoch < iEpoEnd) {
[8753]275 _rtnetStreamBuffer = _rtnetStreamBuffer.mid(nextEpoch);
276 }
[8759]277 else if (nextEpoch != -1 && nextEpoch >= iEpoEnd) {
278 break;
279 }
[3226]280 }
[3222]281
[8759]282 lines = _rtnetStreamBuffer.left(iEpoEnd).split('\n',
[8753]283 QString::SkipEmptyParts);
284 _rtnetStreamBuffer = _rtnetStreamBuffer.mid(iEpoEnd + 3);
285
[3226]286 if (lines.size() < 2) {
[3222]287 return;
288 }
289
[3226]290 // Read first line (with epoch time)
291 // ---------------------------------
292 QTextStream in(lines[0].toAscii());
293 QString hlp;
[6877]294 int year, month, day, hour, min;
295 double sec;
[3226]296 in >> hlp >> year >> month >> day >> hour >> min >> sec;
[6877]297 bncTime epoTime;
298 epoTime.set(year, month, day, hour, min, sec);
[3226]299
[6877]300 emit(newMessage(
301 "bncRtnetUploadCaster: decode " + QByteArray(epoTime.datestr().c_str())
302 + " " + QByteArray(epoTime.timestr().c_str()) + " "
303 + _casterID.toAscii(), false));
[4808]304
[9036]305 struct SsrCorr::ClockOrbit co;
[3222]306 memset(&co, 0, sizeof(co));
[5672]307 co.EpochTime[CLOCKORBIT_SATGPS] = static_cast<int>(epoTime.gpssec());
[9036]308 if (_ssrFormat == "RTCM-SSR") {
309 double gt = epoTime.gpssec() + 3 * 3600 - gnumleap(year, month, day);
310 co.EpochTime[CLOCKORBIT_SATGLONASS] = static_cast<int>(fmod(gt, 86400.0));
311 }
312 else if (_ssrFormat == "IGS-SSR") {
313 co.EpochTime[CLOCKORBIT_SATGLONASS] = static_cast<int>(epoTime.gpssec());
314 }
[6846]315 co.EpochTime[CLOCKORBIT_SATGALILEO] = static_cast<int>(epoTime.gpssec());
[9036]316 co.EpochTime[CLOCKORBIT_SATQZSS] = static_cast<int>(epoTime.gpssec());
317 co.EpochTime[CLOCKORBIT_SATSBAS] = static_cast<int>(epoTime.gpssec());
318 if (_ssrFormat == "RTCM-SSR") {
319 co.EpochTime[CLOCKORBIT_SATBDS] = static_cast<int>(epoTime.bdssec());
320 }
321 else if (_ssrFormat == "IGS-SSR") {
322 co.EpochTime[CLOCKORBIT_SATBDS] = static_cast<int>(epoTime.gpssec());
323 }
324 co.Supplied[_ssrCorr->COBOFS_CLOCK] = 1;
325 co.Supplied[_ssrCorr->COBOFS_ORBIT] = 1;
326 co.SatRefDatum = _ssrCorr->DATUM_ITRF;
327 co.SSRIOD = _IOD;
[6850]328 co.SSRProviderID = _PID; // 256 .. BKG, 257 ... EUREF
329 co.SSRSolutionID = _SID;
[5662]330
[9036]331 struct SsrCorr::CodeBias bias;
[3222]332 memset(&bias, 0, sizeof(bias));
[9036]333 bias.EpochTime[CLOCKORBIT_SATGPS] = co.EpochTime[CLOCKORBIT_SATGPS];
[5666]334 bias.EpochTime[CLOCKORBIT_SATGLONASS] = co.EpochTime[CLOCKORBIT_SATGLONASS];
[6846]335 bias.EpochTime[CLOCKORBIT_SATGALILEO] = co.EpochTime[CLOCKORBIT_SATGALILEO];
[9036]336 bias.EpochTime[CLOCKORBIT_SATQZSS] = co.EpochTime[CLOCKORBIT_SATQZSS];
337 bias.EpochTime[CLOCKORBIT_SATSBAS] = co.EpochTime[CLOCKORBIT_SATSBAS];
338 bias.EpochTime[CLOCKORBIT_SATBDS] = co.EpochTime[CLOCKORBIT_SATBDS];
339 bias.SSRIOD = _IOD;
[6850]340 bias.SSRProviderID = _PID;
341 bias.SSRSolutionID = _SID;
[5662]342
[9036]343 struct SsrCorr::PhaseBias phasebias;
[6850]344 memset(&phasebias, 0, sizeof(phasebias));
[8018]345 unsigned int dispersiveBiasConsistenyIndicator = 0;
346 unsigned int mwConsistencyIndicator = 0;
[9036]347 phasebias.EpochTime[CLOCKORBIT_SATGPS] = co.EpochTime[CLOCKORBIT_SATGPS];
[6850]348 phasebias.EpochTime[CLOCKORBIT_SATGLONASS] = co.EpochTime[CLOCKORBIT_SATGLONASS];
349 phasebias.EpochTime[CLOCKORBIT_SATGALILEO] = co.EpochTime[CLOCKORBIT_SATGALILEO];
[9036]350 phasebias.EpochTime[CLOCKORBIT_SATQZSS] = co.EpochTime[CLOCKORBIT_SATQZSS];
351 phasebias.EpochTime[CLOCKORBIT_SATSBAS] = co.EpochTime[CLOCKORBIT_SATSBAS];
352 phasebias.EpochTime[CLOCKORBIT_SATBDS] = co.EpochTime[CLOCKORBIT_SATBDS];
353 phasebias.SSRIOD = _IOD;
[6850]354 phasebias.SSRProviderID = _PID;
355 phasebias.SSRSolutionID = _SID;
356
[9036]357 struct SsrCorr::VTEC vtec;
[6860]358 memset(&vtec, 0, sizeof(vtec));
359 vtec.EpochTime = static_cast<int>(epoTime.gpssec());
[9036]360 vtec.SSRIOD = _IOD;
[6860]361 vtec.SSRProviderID = _PID;
362 vtec.SSRSolutionID = _SID;
363
[4753]364 // Default Update Interval
365 // -----------------------
[4754]366 int clkUpdInd = 2; // 5 sec
367 int ephUpdInd = clkUpdInd; // default
[6557]368
[6559]369 if (_samplRtcmClkCorr > 5.0 && _samplRtcmEphCorr <= 5.0) { // combined orb and clock
370 ephUpdInd = determineUpdateInd(_samplRtcmClkCorr);
[4754]371 }
[6559]372 if (_samplRtcmClkCorr > 5.0) {
[6557]373 clkUpdInd = determineUpdateInd(_samplRtcmClkCorr);
[4754]374 }
[6559]375 if (_samplRtcmEphCorr > 5.0) {
376 ephUpdInd = determineUpdateInd(_samplRtcmEphCorr);
377 }
[4753]378
[6877]379 co.UpdateInterval = clkUpdInd;
[4754]380 bias.UpdateInterval = clkUpdInd;
[6850]381 phasebias.UpdateInterval = clkUpdInd;
[4753]382
[8754]383 for (int ii = 1; ii < lines.size(); ii++) {
[6877]384 QString key; // prn or key VTEC, IND (phase bias indicators)
[8570]385 double rtnUra = 0.0; // [m]
386 ColumnVector rtnAPC; rtnAPC.ReSize(3); rtnAPC = 0.0; // [m, m, m]
[8680]387 ColumnVector rtnVel; rtnVel.ReSize(3); rtnVel = 0.0; // [m/s, m/s, m/s]
[8570]388 ColumnVector rtnCoM; rtnCoM.ReSize(3); rtnCoM = 0.0; // [m, m, m]
389 ColumnVector rtnClk; rtnClk.ReSize(3); rtnClk = 0.0; // [m, m/s, m/s²]
390 ColumnVector rtnClkSig; rtnClkSig.ReSize(3); rtnClkSig = 0.0; // [m, m/s, m/s²]
[6877]391 t_prn prn;
[8543]392
[3222]393 QTextStream in(lines[ii].toAscii());
[6876]394 in >> key;
[3222]395
[6860]396 // non-satellite specific parameters
[6877]397 if (key.contains("IND", Qt::CaseSensitive)) {
[8018]398 in >> dispersiveBiasConsistenyIndicator >> mwConsistencyIndicator;
[6860]399 continue;
400 }
[6893]401 // non-satellite specific parameters
[6876]402 if (key.contains("VTEC", Qt::CaseSensitive)) {
[6897]403 double ui;
404 in >> ui >> vtec.NumLayers;
405 vtec.UpdateInterval = (unsigned int) determineUpdateInd(ui);
[6860]406 for (unsigned ll = 0; ll < vtec.NumLayers; ll++) {
407 int dummy;
408 in >> dummy >> vtec.Layers[ll].Degree >> vtec.Layers[ll].Order
[6877]409 >> vtec.Layers[ll].Height;
[6879]410 for (unsigned iDeg = 0; iDeg <= vtec.Layers[ll].Degree; iDeg++) {
411 for (unsigned iOrd = 0; iOrd <= vtec.Layers[ll].Order; iOrd++) {
[6860]412 in >> vtec.Layers[ll].Cosinus[iDeg][iOrd];
413 }
414 }
[6879]415 for (unsigned iDeg = 0; iDeg <= vtec.Layers[ll].Degree; iDeg++) {
416 for (unsigned iOrd = 0; iOrd <= vtec.Layers[ll].Order; iOrd++) {
[6860]417 in >> vtec.Layers[ll].Sinus[iDeg][iOrd];
418 }
419 }
420 }
421 continue;
422 }
[6877]423 // satellite specific parameters
424 char sys = key.mid(0, 1).at(0).toAscii();
425 int number = key.mid(1, 2).toInt();
426 int flags = 0;
427 if (sys == 'E') { // I/NAV
428 flags = 1;
429 }
[6876]430 prn.set(sys, number, flags);
431 QString prnInternalStr = QString::fromStdString(prn.toInternalString());
[6877]432 QString prnStr = QString::fromStdString(prn.toString());
433
[6876]434 const t_eph* ephLast = _ephUser->ephLast(prnInternalStr);
435 const t_eph* ephPrev = _ephUser->ephPrev(prnInternalStr);
[6877]436 const t_eph* eph = ephLast;
[6442]437 if (eph) {
[3754]438
[4098]439 // Use previous ephemeris if the last one is too recent
440 // ----------------------------------------------------
441 const int MINAGE = 60; // seconds
[6877]442 if (ephPrev && eph->receptDateTime().isValid()
443 && eph->receptDateTime().secsTo(currentDateAndTimeGPS()) < MINAGE) {
[6442]444 eph = ephPrev;
[4098]445 }
[3754]446
[3753]447 // Make sure the clock messages refer to same IOD as orbit messages
448 // ----------------------------------------------------------------
449 if (_usedEph) {
[4174]450 if (fmod(epoTime.gpssec(), _samplRtcmEphCorr) == 0.0) {
[6876]451 (*_usedEph)[prnInternalStr] = eph;
[3753]452 }
453 else {
454 eph = 0;
[6876]455 if (_usedEph->contains(prnInternalStr)) {
456 const t_eph* usedEph = _usedEph->value(prnInternalStr);
[6877]457 if (usedEph == ephLast) {
[6442]458 eph = ephLast;
[3753]459 }
[6442]460 else if (usedEph == ephPrev) {
461 eph = ephPrev;
[3753]462 }
463 }
464 }
465 }
466 }
467
[8582]468 if (eph &&
469 eph->checkState() != t_eph::bad &&
[8648]470 eph->checkState() != t_eph::unhealthy &&
471 eph->checkState() != t_eph::outdated) {
[5503]472 QMap<QString, double> codeBiases;
[6851]473 QList<phaseBiasSignal> phaseBiasList;
474 phaseBiasesSat pbSat;
[5503]475
[4991]476 while (true) {
477 QString key;
[6877]478 int numVal = 0;
[6850]479 in >> key;
[4991]480 if (in.status() != QTextStream::Ok) {
481 break;
482 }
[6877]483 if (key == "APC") {
[6850]484 in >> numVal;
[8570]485 rtnAPC.ReSize(3); rtnAPC = 0.0;
[6850]486 for (int ii = 0; ii < numVal; ii++) {
487 in >> rtnAPC[ii];
488 }
[4991]489 }
[8484]490 else if (key == "Ura") {
[6850]491 in >> numVal;
[6877]492 if (numVal == 1)
[8484]493 in >> rtnUra;
[4991]494 }
[8484]495 else if (key == "Clk") {
496 in >> numVal;
[8570]497 rtnClk.ReSize(3); rtnClk = 0.0;
[8484]498 for (int ii = 0; ii < numVal; ii++) {
499 in >> rtnClk[ii];
500 }
501 }
502 else if (key == "ClkSig") {
503 in >> numVal;
[8570]504 rtnClkSig.ReSize(3); rtnClkSig = 0.0;
[8484]505 for (int ii = 0; ii < numVal; ii++) {
506 in >> rtnClkSig[ii];
507 }
508 }
[4991]509 else if (key == "Vel") {
[6850]510 in >> numVal;
[8570]511 rtnVel.ReSize(3); rtnVel = 0.0;
[6850]512 for (int ii = 0; ii < numVal; ii++) {
513 in >> rtnVel[ii];
514 }
[4991]515 }
516 else if (key == "CoM") {
[6850]517 in >> numVal;
[8570]518 rtnCoM.ReSize(3); rtnCoM = 0.0;
[6850]519 for (int ii = 0; ii < numVal; ii++) {
520 in >> rtnCoM[ii];
521 }
[4991]522 }
[5503]523 else if (key == "CodeBias") {
[6850]524 in >> numVal;
[5503]525 for (int ii = 0; ii < numVal; ii++) {
526 QString type;
[6877]527 double value;
[5503]528 in >> type >> value;
529 codeBiases[type] = value;
530 }
531 }
[6857]532 else if (key == "YawAngle") {
[8018]533 in >> numVal >> pbSat.yawAngle;
534 if (pbSat.yawAngle < 0.0) {
535 pbSat.yawAngle += (2*M_PI);
[6975]536 }
[8018]537 else if (pbSat.yawAngle > 2*M_PI) {
538 pbSat.yawAngle -= (2*M_PI);
[6975]539 }
[6851]540 }
[6857]541 else if (key == "YawRate") {
[8018]542 in >> numVal >> pbSat.yawRate;
[6851]543 }
[6850]544 else if (key == "PhaseBias") {
545 in >> numVal;
546 for (int ii = 0; ii < numVal; ii++) {
[6851]547 phaseBiasSignal pb;
[8018]548 in >> pb.type >> pb.bias >> pb.integerIndicator
549 >> pb.wlIndicator >> pb.discontinuityCounter;
[6851]550 phaseBiasList.append(pb);
[6850]551 }
552 }
[4991]553 else {
[8686]554 in >> numVal;
555 for (int ii = 0; ii < numVal; ii++) {
556 double dummy;
557 in >> dummy;
558 }
[8541]559 emit(newMessage(" RTNET format error: "
560 + lines[ii].toAscii(), false));
[4991]561 }
[5662]562 }
[6850]563
[9036]564 struct SsrCorr::ClockOrbit::SatData* sd = 0;
[8649]565 if (prn.system() == 'G') {
566 sd = co.Sat + co.NumberOfSat[CLOCKORBIT_SATGPS];
567 ++co.NumberOfSat[CLOCKORBIT_SATGPS];
568 }
569 else if (prn.system() == 'R') {
570 sd = co.Sat + CLOCKORBIT_NUMGPS + co.NumberOfSat[CLOCKORBIT_SATGLONASS];
571 ++co.NumberOfSat[CLOCKORBIT_SATGLONASS];
572 }
573 else if (prn.system() == 'E') {
574 sd = co.Sat + CLOCKORBIT_NUMGPS + CLOCKORBIT_NUMGLONASS
[8987]575 + co.NumberOfSat[CLOCKORBIT_SATGALILEO];
[8649]576 ++co.NumberOfSat[CLOCKORBIT_SATGALILEO];
577 }
578 else if (prn.system() == 'J') {
579 sd = co.Sat + CLOCKORBIT_NUMGPS + CLOCKORBIT_NUMGLONASS
[8987]580 + CLOCKORBIT_NUMGALILEO
581 + co.NumberOfSat[CLOCKORBIT_SATQZSS];
[8649]582 ++co.NumberOfSat[CLOCKORBIT_SATQZSS];
583 }
584 else if (prn.system() == 'S') {
585 sd = co.Sat + CLOCKORBIT_NUMGPS + CLOCKORBIT_NUMGLONASS
586 + CLOCKORBIT_NUMGALILEO + CLOCKORBIT_NUMQZSS
587 + co.NumberOfSat[CLOCKORBIT_SATSBAS];
588 ++co.NumberOfSat[CLOCKORBIT_SATSBAS];
589 }
590 else if (prn.system() == 'C') {
591 sd = co.Sat + CLOCKORBIT_NUMGPS + CLOCKORBIT_NUMGLONASS
[8987]592 + CLOCKORBIT_NUMGALILEO + CLOCKORBIT_NUMQZSS
593 + CLOCKORBIT_NUMSBAS
[8649]594 + co.NumberOfSat[CLOCKORBIT_SATBDS];
595 ++co.NumberOfSat[CLOCKORBIT_SATBDS];
596 }
597 if (sd) {
598 QString outLine;
599 t_irc irc = processSatellite(eph, epoTime.gpsw(), epoTime.gpssec(), prnStr, rtnAPC,
600 rtnUra, rtnClk, rtnVel, rtnCoM, rtnClkSig, sd, outLine);
601 if (irc != success) {
602 // very few cases: check states bad and unhealthy are excluded earlier
603 sd->ID = prnStr.mid(1).toInt(); // to prevent G00, R00 entries
604 sd->IOD = eph->IOD();
605 }
606 }
607
[6850]608 // Code Biases
609 // -----------
[9036]610 struct SsrCorr::CodeBias::BiasSat* biasSat = 0;
[6877]611 if (!codeBiases.isEmpty()) {
612 if (prn.system() == 'G') {
613 biasSat = bias.Sat + bias.NumberOfSat[CLOCKORBIT_SATGPS];
614 ++bias.NumberOfSat[CLOCKORBIT_SATGPS];
615 }
616 else if (prn.system() == 'R') {
617 biasSat = bias.Sat + CLOCKORBIT_NUMGPS
[8987]618 + bias.NumberOfSat[CLOCKORBIT_SATGLONASS];
[6877]619 ++bias.NumberOfSat[CLOCKORBIT_SATGLONASS];
620 }
621 else if (prn.system() == 'E') {
622 biasSat = bias.Sat + CLOCKORBIT_NUMGPS + CLOCKORBIT_NUMGLONASS
[8987]623 + bias.NumberOfSat[CLOCKORBIT_SATGALILEO];
[6877]624 ++bias.NumberOfSat[CLOCKORBIT_SATGALILEO];
625 }
626 else if (prn.system() == 'J') {
627 biasSat = bias.Sat + CLOCKORBIT_NUMGPS + CLOCKORBIT_NUMGLONASS
[8987]628 + CLOCKORBIT_NUMGALILEO
629 + bias.NumberOfSat[CLOCKORBIT_SATQZSS];
[6877]630 ++bias.NumberOfSat[CLOCKORBIT_SATQZSS];
631 }
632 else if (prn.system() == 'S') {
633 biasSat = bias.Sat + CLOCKORBIT_NUMGPS + CLOCKORBIT_NUMGLONASS
[8987]634 + CLOCKORBIT_NUMGALILEO + CLOCKORBIT_NUMQZSS
635 + bias.NumberOfSat[CLOCKORBIT_SATSBAS];
[6877]636 ++bias.NumberOfSat[CLOCKORBIT_SATSBAS];
637 }
638 else if (prn.system() == 'C') {
639 biasSat = bias.Sat + CLOCKORBIT_NUMGPS + CLOCKORBIT_NUMGLONASS
[8987]640 + CLOCKORBIT_NUMGALILEO + CLOCKORBIT_NUMQZSS
641 + CLOCKORBIT_NUMSBAS
642 + bias.NumberOfSat[CLOCKORBIT_SATBDS];
[6877]643 ++bias.NumberOfSat[CLOCKORBIT_SATBDS];
644 }
[3222]645 }
[5662]646
[3222]647 if (biasSat) {
[6876]648 biasSat->ID = prn.number();
[5503]649 biasSat->NumberOfCodeBiases = 0;
[9036]650 QMapIterator<QString, double> it(codeBiases);
651 while (it.hasNext()) {
652 it.next();
653 int ii = biasSat->NumberOfCodeBiases;
654 if (ii >= CLOCKORBIT_NUMBIAS)
655 break;
656 SsrCorr::CodeType type = _ssrCorr->rnxTypeToCodeType(prn.system(), it.key().toStdString());
657 if (type != _ssrCorr->RESERVED) {
658 biasSat->NumberOfCodeBiases += 1;
659 biasSat->Biases[ii].Type = type;
660 biasSat->Biases[ii].Bias = it.value();
[5503]661 }
[3222]662 }
663 }
[9036]664
[6850]665 // Phase Biases
666 // ------------
[9036]667 struct SsrCorr::PhaseBias::PhaseBiasSat* phasebiasSat = 0;
[8987]668 if (prn.system() == 'G') {
669 phasebiasSat = phasebias.Sat
670 + phasebias.NumberOfSat[CLOCKORBIT_SATGPS];
671 ++phasebias.NumberOfSat[CLOCKORBIT_SATGPS];
672 }
673 else if (prn.system() == 'R') {
674 phasebiasSat = phasebias.Sat + CLOCKORBIT_NUMGPS
675 + phasebias.NumberOfSat[CLOCKORBIT_SATGLONASS];
676 ++phasebias.NumberOfSat[CLOCKORBIT_SATGLONASS];
677 }
678 else if (prn.system() == 'E') {
679 phasebiasSat = phasebias.Sat + CLOCKORBIT_NUMGPS + CLOCKORBIT_NUMGLONASS
680 + phasebias.NumberOfSat[CLOCKORBIT_SATGALILEO];
681 ++phasebias.NumberOfSat[CLOCKORBIT_SATGALILEO];
682 }
683 else if (prn.system() == 'J') {
684 phasebiasSat = phasebias.Sat + CLOCKORBIT_NUMGPS + CLOCKORBIT_NUMGLONASS
685 + CLOCKORBIT_NUMGALILEO
686 + phasebias.NumberOfSat[CLOCKORBIT_SATQZSS];
687 ++phasebias.NumberOfSat[CLOCKORBIT_SATQZSS];
688 }
689 else if (prn.system() == 'S') {
690 phasebiasSat = phasebias.Sat + CLOCKORBIT_NUMGPS + CLOCKORBIT_NUMGLONASS
691 + CLOCKORBIT_NUMGALILEO + CLOCKORBIT_NUMQZSS
692 + phasebias.NumberOfSat[CLOCKORBIT_SATSBAS];
693 ++phasebias.NumberOfSat[CLOCKORBIT_SATSBAS];
694 }
695 else if (prn.system() == 'C') {
696 phasebiasSat = phasebias.Sat + CLOCKORBIT_NUMGPS + CLOCKORBIT_NUMGLONASS
697 + CLOCKORBIT_NUMGALILEO + CLOCKORBIT_NUMQZSS
698 + CLOCKORBIT_NUMSBAS
699 + phasebias.NumberOfSat[CLOCKORBIT_SATBDS];
700 ++phasebias.NumberOfSat[CLOCKORBIT_SATBDS];
701 }
[6850]702
703 if (phasebiasSat) {
[8018]704 phasebias.DispersiveBiasConsistencyIndicator = dispersiveBiasConsistenyIndicator;
705 phasebias.MWConsistencyIndicator = mwConsistencyIndicator;
[6876]706 phasebiasSat->ID = prn.number();
[6850]707 phasebiasSat->NumberOfPhaseBiases = 0;
[8018]708 phasebiasSat->YawAngle = pbSat.yawAngle;
709 phasebiasSat->YawRate = pbSat.yawRate;
[9036]710 QListIterator<phaseBiasSignal> it(phaseBiasList);
711 while (it.hasNext()) {
712 const phaseBiasSignal &pbSig = it.next();
713 int ii = phasebiasSat->NumberOfPhaseBiases;
714 if (ii >= CLOCKORBIT_NUMBIAS)
715 break;
716 SsrCorr::CodeType type = _ssrCorr->rnxTypeToCodeType(prn.system(), pbSig.type.toStdString());
717 if (type != _ssrCorr->RESERVED) {
718 phasebiasSat->NumberOfPhaseBiases += 1;
719 phasebiasSat->Biases[ii].Type = type;
720 phasebiasSat->Biases[ii].Bias = pbSig.bias;
721 phasebiasSat->Biases[ii].SignalIntegerIndicator = pbSig.integerIndicator;
722 phasebiasSat->Biases[ii].SignalsWideLaneIntegerIndicator = pbSig.wlIndicator;
723 phasebiasSat->Biases[ii].SignalDiscontinuityCounter = pbSig.discontinuityCounter;
[6850]724 }
725 }
726 }
[3222]727 }
728 }
[3227]729
[5662]730 QByteArray hlpBufferCo;
[3493]731
732 // Orbit and Clock Corrections together
733 // ------------------------------------
[4174]734 if (_samplRtcmEphCorr == 0.0) {
[6877]735 if (co.NumberOfSat[CLOCKORBIT_SATGPS] > 0
736 || co.NumberOfSat[CLOCKORBIT_SATGLONASS] > 0
737 || co.NumberOfSat[CLOCKORBIT_SATGALILEO] > 0
738 || co.NumberOfSat[CLOCKORBIT_SATQZSS] > 0
739 || co.NumberOfSat[CLOCKORBIT_SATSBAS] > 0
740 || co.NumberOfSat[CLOCKORBIT_SATBDS] > 0) {
[3493]741 char obuffer[CLOCKORBIT_BUFFERSIZE];
[9036]742 int len = _ssrCorr->MakeClockOrbit(&co, _ssrCorr->COTYPE_AUTO, 0, obuffer, sizeof(obuffer));
[3493]743 if (len > 0) {
744 hlpBufferCo = QByteArray(obuffer, len);
745 }
[3222]746 }
747 }
[3493]748
749 // Orbit and Clock Corrections separately
750 // --------------------------------------
751 else {
[5666]752 if (co.NumberOfSat[CLOCKORBIT_SATGPS] > 0) {
[3493]753 char obuffer[CLOCKORBIT_BUFFERSIZE];
[4174]754 if (fmod(epoTime.gpssec(), _samplRtcmEphCorr) == 0.0) {
[4754]755 co.UpdateInterval = ephUpdInd;
[9036]756 int len1 = _ssrCorr->MakeClockOrbit(&co, _ssrCorr->COTYPE_GPSORBIT, 1, obuffer,
[6877]757 sizeof(obuffer));
[4754]758 co.UpdateInterval = clkUpdInd;
[3493]759 if (len1 > 0) {
760 hlpBufferCo += QByteArray(obuffer, len1);
761 }
762 }
[8807]763 int mmsg = (co.NumberOfSat[CLOCKORBIT_SATGLONASS] > 0 ||
764 co.NumberOfSat[CLOCKORBIT_SATGALILEO] > 0 ||
765 co.NumberOfSat[CLOCKORBIT_SATQZSS] > 0 ||
766 co.NumberOfSat[CLOCKORBIT_SATSBAS] > 0 ||
767 co.NumberOfSat[CLOCKORBIT_SATBDS] > 0 ) ? 1 : 0;
[9036]768 int len2 = _ssrCorr->MakeClockOrbit(&co, _ssrCorr->COTYPE_GPSCLOCK, mmsg, obuffer,
[6877]769 sizeof(obuffer));
[3493]770 if (len2 > 0) {
771 hlpBufferCo += QByteArray(obuffer, len2);
772 }
773 }
[5666]774 if (co.NumberOfSat[CLOCKORBIT_SATGLONASS] > 0) {
[3493]775 char obuffer[CLOCKORBIT_BUFFERSIZE];
[4174]776 if (fmod(epoTime.gpssec(), _samplRtcmEphCorr) == 0.0) {
[4754]777 co.UpdateInterval = ephUpdInd;
[9036]778 int len1 = _ssrCorr->MakeClockOrbit(&co, _ssrCorr->COTYPE_GLONASSORBIT, 1, obuffer,
[6877]779 sizeof(obuffer));
[4754]780 co.UpdateInterval = clkUpdInd;
[3493]781 if (len1 > 0) {
782 hlpBufferCo += QByteArray(obuffer, len1);
783 }
784 }
[8807]785 int mmsg = (co.NumberOfSat[CLOCKORBIT_SATGALILEO] > 0 ||
786 co.NumberOfSat[CLOCKORBIT_SATQZSS] > 0 ||
787 co.NumberOfSat[CLOCKORBIT_SATSBAS] > 0 ||
788 co.NumberOfSat[CLOCKORBIT_SATBDS] > 0 ) ? 1 : 0;
[9036]789 int len2 = _ssrCorr->MakeClockOrbit(&co, _ssrCorr->COTYPE_GLONASSCLOCK, mmsg, obuffer,
[6877]790 sizeof(obuffer));
[3493]791 if (len2 > 0) {
792 hlpBufferCo += QByteArray(obuffer, len2);
793 }
794 }
[6844]795 if (co.NumberOfSat[CLOCKORBIT_SATGALILEO] > 0) {
796 char obuffer[CLOCKORBIT_BUFFERSIZE];
797 if (fmod(epoTime.gpssec(), _samplRtcmEphCorr) == 0.0) {
798 co.UpdateInterval = ephUpdInd;
[9036]799 int len1 = _ssrCorr->MakeClockOrbit(&co, _ssrCorr->COTYPE_GALILEOORBIT, 1, obuffer,
[6877]800 sizeof(obuffer));
[6844]801 co.UpdateInterval = clkUpdInd;
802 if (len1 > 0) {
803 hlpBufferCo += QByteArray(obuffer, len1);
804 }
805 }
[8807]806 int mmsg = (co.NumberOfSat[CLOCKORBIT_SATQZSS] > 0 ||
807 co.NumberOfSat[CLOCKORBIT_SATSBAS] > 0 ||
808 co.NumberOfSat[CLOCKORBIT_SATBDS] > 0 ) ? 1 : 0;
[9036]809 int len2 = _ssrCorr->MakeClockOrbit(&co, _ssrCorr->COTYPE_GALILEOCLOCK, mmsg, obuffer,
[6877]810 sizeof(obuffer));
[6844]811 if (len2 > 0) {
812 hlpBufferCo += QByteArray(obuffer, len2);
813 }
814 }
815 if (co.NumberOfSat[CLOCKORBIT_SATQZSS] > 0) {
816 char obuffer[CLOCKORBIT_BUFFERSIZE];
817 if (fmod(epoTime.gpssec(), _samplRtcmEphCorr) == 0.0) {
818 co.UpdateInterval = ephUpdInd;
[9036]819 int len1 = _ssrCorr->MakeClockOrbit(&co, _ssrCorr->COTYPE_QZSSORBIT, 1, obuffer,
[6877]820 sizeof(obuffer));
[6844]821 co.UpdateInterval = clkUpdInd;
822 if (len1 > 0) {
823 hlpBufferCo += QByteArray(obuffer, len1);
824 }
825 }
[8807]826 int mmsg = (co.NumberOfSat[CLOCKORBIT_SATSBAS] > 0 ||
827 co.NumberOfSat[CLOCKORBIT_SATBDS] > 0 ) ? 1 : 0;
[9036]828 int len2 = _ssrCorr->MakeClockOrbit(&co, _ssrCorr->COTYPE_QZSSCLOCK, mmsg, obuffer,
[6877]829 sizeof(obuffer));
[6844]830 if (len2 > 0) {
831 hlpBufferCo += QByteArray(obuffer, len2);
832 }
833 }
834 if (co.NumberOfSat[CLOCKORBIT_SATSBAS] > 0) {
835 char obuffer[CLOCKORBIT_BUFFERSIZE];
836 if (fmod(epoTime.gpssec(), _samplRtcmEphCorr) == 0.0) {
837 co.UpdateInterval = ephUpdInd;
[9036]838 int len1 = _ssrCorr->MakeClockOrbit(&co, _ssrCorr->COTYPE_SBASORBIT, 1, obuffer,
[6877]839 sizeof(obuffer));
[6844]840 co.UpdateInterval = clkUpdInd;
841 if (len1 > 0) {
842 hlpBufferCo += QByteArray(obuffer, len1);
843 }
844 }
845 int mmsg = (co.NumberOfSat[CLOCKORBIT_SATBDS] > 0) ? 1 : 0;
[9036]846 int len2 = _ssrCorr->MakeClockOrbit(&co, _ssrCorr->COTYPE_SBASCLOCK, mmsg, obuffer,
[6877]847 sizeof(obuffer));
[6844]848 if (len2 > 0) {
849 hlpBufferCo += QByteArray(obuffer, len2);
850 }
851 }
852 if (co.NumberOfSat[CLOCKORBIT_SATBDS] > 0) {
853 char obuffer[CLOCKORBIT_BUFFERSIZE];
854 if (fmod(epoTime.gpssec(), _samplRtcmEphCorr) == 0.0) {
855 co.UpdateInterval = ephUpdInd;
[9036]856 int len1 = _ssrCorr->MakeClockOrbit(&co, _ssrCorr->COTYPE_BDSORBIT, 1, obuffer,
[6877]857 sizeof(obuffer));
[6844]858 co.UpdateInterval = clkUpdInd;
859 if (len1 > 0) {
860 hlpBufferCo += QByteArray(obuffer, len1);
861 }
862 }
[8807]863 int mmsg = 0;
[9036]864 int len2 = _ssrCorr->MakeClockOrbit(&co, _ssrCorr->COTYPE_BDSCLOCK, mmsg, obuffer,
[6877]865 sizeof(obuffer));
[6844]866 if (len2 > 0) {
867 hlpBufferCo += QByteArray(obuffer, len2);
868 }
869 }
[3493]870 }
[5662]871
[6850]872 // Code Biases
873 // -----------
[5662]874 QByteArray hlpBufferBias;
[6877]875 if (bias.NumberOfSat[CLOCKORBIT_SATGPS] > 0
876 || bias.NumberOfSat[CLOCKORBIT_SATGLONASS] > 0
877 || bias.NumberOfSat[CLOCKORBIT_SATGALILEO] > 0
878 || bias.NumberOfSat[CLOCKORBIT_SATQZSS] > 0
879 || bias.NumberOfSat[CLOCKORBIT_SATSBAS] > 0
880 || bias.NumberOfSat[CLOCKORBIT_SATBDS] > 0) {
[3222]881 char obuffer[CLOCKORBIT_BUFFERSIZE];
[9036]882 int len = _ssrCorr->MakeCodeBias(&bias, _ssrCorr->CBTYPE_AUTO, 0, obuffer, sizeof(obuffer));
[3222]883 if (len > 0) {
[3227]884 hlpBufferBias = QByteArray(obuffer, len);
[3222]885 }
886 }
[3227]887
[6850]888 // Phase Biases
889 // ------------
890 QByteArray hlpBufferPhaseBias;
[6877]891 if (phasebias.NumberOfSat[CLOCKORBIT_SATGPS] > 0
892 || phasebias.NumberOfSat[CLOCKORBIT_SATGLONASS] > 0
893 || phasebias.NumberOfSat[CLOCKORBIT_SATGALILEO] > 0
894 || phasebias.NumberOfSat[CLOCKORBIT_SATQZSS] > 0
895 || phasebias.NumberOfSat[CLOCKORBIT_SATSBAS] > 0
896 || phasebias.NumberOfSat[CLOCKORBIT_SATBDS] > 0) {
[6850]897 char obuffer[CLOCKORBIT_BUFFERSIZE];
[9036]898 int len = _ssrCorr->MakePhaseBias(&phasebias, _ssrCorr->PBTYPE_AUTO, 0, obuffer,
[6877]899 sizeof(obuffer));
[6850]900 if (len > 0) {
901 hlpBufferPhaseBias = QByteArray(obuffer, len);
902 }
903 }
904
905 // VTEC
906 // ----
907 QByteArray hlpBufferVtec;
[6860]908 if (vtec.NumLayers > 0) {
909 char obuffer[CLOCKORBIT_BUFFERSIZE];
[9036]910 int len = _ssrCorr->MakeVTEC(&vtec, 0, obuffer, sizeof(obuffer));
[6860]911 if (len > 0) {
912 hlpBufferVtec = QByteArray(obuffer, len);
913 }
914 }
[6850]915
[6877]916 _outBuffer += hlpBufferCo + hlpBufferBias + hlpBufferPhaseBias
917 + hlpBufferVtec;
[3222]918}
919
[5662]920//
[3222]921////////////////////////////////////////////////////////////////////////////
[8541]922t_irc bncRtnetUploadCaster::processSatellite(const t_eph* eph, int GPSweek,
[6877]923 double GPSweeks, const QString& prn, const ColumnVector& rtnAPC,
[8484]924 double rtnUra, const ColumnVector& rtnClk, const ColumnVector& rtnVel,
925 const ColumnVector& rtnCoM, const ColumnVector& rtnClkSig,
[9036]926 struct SsrCorr::ClockOrbit::SatData* sd, QString& outLine) {
[3222]927
[4930]928 // Broadcast Position and Velocity
929 // -------------------------------
[8541]930 ColumnVector xB(6);
[4930]931 ColumnVector vB(3);
[8541]932 t_irc irc = eph->getCrd(bncTime(GPSweek, GPSweeks), xB, vB, false);
[5662]933
[8541]934 if (irc != success) {
935 return irc;
936 }
937
[4991]938 // Precise Position
939 // ----------------
940 ColumnVector xP = _CoM ? rtnCoM : rtnAPC;
[3222]941
[8541]942 if (xP.size() == 0) {
943 return failure;
944 }
945
[5662]946 double dc = 0.0;
[8411]947 if (_crdTrafo != "IGS14") {
[8146]948 crdTrafo(GPSweek, xP, dc);
[8101]949 }
[5662]950
[4930]951 // Difference in xyz
952 // -----------------
[6877]953 ColumnVector dx = xB.Rows(1, 3) - xP;
954 ColumnVector dv = vB - rtnVel;
[5662]955
[4930]956 // Difference in RSW
957 // -----------------
[3222]958 ColumnVector rsw(3);
[6877]959 XYZ_to_RSW(xB.Rows(1, 3), vB, dx, rsw);
[3222]960
[4930]961 ColumnVector dotRsw(3);
[6877]962 XYZ_to_RSW(xB.Rows(1, 3), vB, dv, dotRsw);
[3222]963
[4930]964 // Clock Correction
965 // ----------------
[8498]966 double dClkA0 = rtnClk(1) - (xB(4) - dc) * t_CST::c;
[8570]967 double dClkA1 = 0.0;
968 if (rtnClk(2)) {
969 dClkA1 = rtnClk(2) - xB(5) * t_CST::c;
970 }
971 double dClkA2 = 0.0;
972 if (rtnClk(3)) {
973 dClkA2 = rtnClk(3) - xB(6) * t_CST::c;
974 }
[3222]975
976 if (sd) {
[6877]977 sd->ID = prn.mid(1).toInt();
978 sd->IOD = eph->IOD();
[8484]979 sd->Clock.DeltaA0 = dClkA0;
980 sd->Clock.DeltaA1 = dClkA1;
981 sd->Clock.DeltaA2 = dClkA2;
982 sd->UserRangeAccuracy = rtnUra;
983 sd->Orbit.DeltaRadial = rsw(1);
[6877]984 sd->Orbit.DeltaAlongTrack = rsw(2);
985 sd->Orbit.DeltaCrossTrack = rsw(3);
[8484]986 sd->Orbit.DotDeltaRadial = dotRsw(1);
[4930]987 sd->Orbit.DotDeltaAlongTrack = dotRsw(2);
988 sd->Orbit.DotDeltaCrossTrack = dotRsw(3);
[3222]989 }
990
[8484]991 outLine.sprintf("%d %.1f %s %u %10.3f %8.3f %8.3f %8.3f %8.3f %8.3f\n", GPSweek,
992 GPSweeks, eph->prn().toString().c_str(), eph->IOD(), dClkA0, dClkA1, dClkA2,
993 rsw(1), rsw(2), rsw(3));
[3222]994
[8498]995 // RTNET full clock for RINEX and SP3 file
996 // ---------------------------------------
[4991]997 double relativity = -2.0 * DotProduct(xP, rtnVel) / t_CST::c;
[8498]998 double clkRnx = (rtnClk[0] - relativity) / t_CST::c; // [s]
[8484]999 double clkRnxRate = rtnClk[1] / t_CST::c; // [s/s = -]
1000 double clkRnxAcc = rtnClk[2] / t_CST::c; // [s/s² ) -/s]
[4991]1001
[3222]1002 if (_rnx) {
[8509]1003 double clkRnxSig, clkRnxRateSig, clkRnxAccSig;
1004 int s = rtnClkSig.size();
1005 switch (s) {
1006 case 1:
1007 clkRnxSig = rtnClkSig[0] / t_CST::c; // [s]
1008 clkRnxRateSig = 0.0; // [s/s = -]
1009 clkRnxAccSig = 0.0; // [s/s² ) -/s]
1010 break;
1011 case 2:
1012 clkRnxSig = rtnClkSig[0] / t_CST::c; // [s]
1013 clkRnxRateSig = rtnClkSig[1] / t_CST::c; // [s/s = -]
1014 clkRnxAccSig = 0.0; // [s/s² ) -/s]
1015 break;
1016 case 3:
1017 clkRnxSig = rtnClkSig[0] / t_CST::c; // [s]
1018 clkRnxRateSig = rtnClkSig[1] / t_CST::c; // [s/s = -]
1019 clkRnxAccSig = rtnClkSig[2] / t_CST::c; // [s/s² ) -/s]
1020 break;
1021 }
[8484]1022 _rnx->write(GPSweek, GPSweeks, prn, clkRnx, clkRnxRate, clkRnxAcc,
1023 clkRnxSig, clkRnxRateSig, clkRnxAccSig);
[3222]1024 }
1025 if (_sp3) {
[8484]1026 _sp3->write(GPSweek, GPSweeks, prn, rtnCoM, clkRnx, rtnVel, clkRnxRate);
[3222]1027 }
[8541]1028 return success;
[3222]1029}
1030
1031// Transform Coordinates
1032////////////////////////////////////////////////////////////////////////////
[5662]1033void bncRtnetUploadCaster::crdTrafo(int GPSWeek, ColumnVector& xyz,
[6877]1034 double& dc) {
[3222]1035
1036 // Current epoch minus 2000.0 in years
1037 // ------------------------------------
[6877]1038 double dt = (GPSWeek - (1042.0 + 6.0 / 7.0)) / 365.2422 * 7.0 + 2000.0 - _t0;
[3222]1039
1040 ColumnVector dx(3);
1041
1042 dx(1) = _dx + dt * _dxr;
1043 dx(2) = _dy + dt * _dyr;
1044 dx(3) = _dz + dt * _dzr;
1045
1046 static const double arcSec = 180.0 * 3600.0 / M_PI;
1047
1048 double ox = (_ox + dt * _oxr) / arcSec;
1049 double oy = (_oy + dt * _oyr) / arcSec;
1050 double oz = (_oz + dt * _ozr) / arcSec;
1051
[8712]1052 double sc = 1.0 + _sc * 1e-9 + dt * _scr * 1e-9;
[3222]1053
[4912]1054 // Specify approximate center of area
1055 // ----------------------------------
1056 ColumnVector meanSta(3);
1057
[6877]1058 if (_crdTrafo == "ETRF2000") {
1059 meanSta(1) = 3661090.0;
1060 meanSta(2) = 845230.0;
1061 meanSta(3) = 5136850.0;
[4908]1062 }
[8101]1063 else if (_crdTrafo == "GDA2020") {
[4973]1064 meanSta(1) = -4052050.0;
[6877]1065 meanSta(2) = 4212840.0;
[4973]1066 meanSta(3) = -2545110.0;
[4912]1067 }
1068 else if (_crdTrafo == "SIRGAS2000") {
[6877]1069 meanSta(1) = 3740860.0;
[4973]1070 meanSta(2) = -4964290.0;
1071 meanSta(3) = -1425420.0;
[4912]1072 }
[5343]1073 else if (_crdTrafo == "DREF91") {
[6877]1074 meanSta(1) = 3959579.0;
1075 meanSta(2) = 721719.0;
1076 meanSta(3) = 4931539.0;
[5343]1077 }
[4912]1078 else if (_crdTrafo == "Custom") {
[6877]1079 meanSta(1) = 0.0; // TODO
1080 meanSta(2) = 0.0; // TODO
1081 meanSta(3) = 0.0; // TODO
[4912]1082 }
[8484]1083
[4912]1084 // Clock correction proportional to topocentric distance to satellites
1085 // -------------------------------------------------------------------
1086 double rho = (xyz - meanSta).norm_Frobenius();
[4913]1087 dc = rho * (sc - 1.0) / sc / t_CST::c;
[4908]1088
[6877]1089 Matrix rMat(3, 3);
1090 rMat(1, 1) = 1.0;
1091 rMat(1, 2) = -oz;
1092 rMat(1, 3) = oy;
1093 rMat(2, 1) = oz;
1094 rMat(2, 2) = 1.0;
1095 rMat(2, 3) = -ox;
1096 rMat(3, 1) = -oy;
1097 rMat(3, 2) = ox;
1098 rMat(3, 3) = 1.0;
[3222]1099
1100 xyz = sc * rMat * xyz + dx;
1101}
1102
[6557]1103int bncRtnetUploadCaster::determineUpdateInd(double samplingRate) {
1104
1105 if (samplingRate == 10.0) {
1106 return 3;
1107 }
1108 else if (samplingRate == 15.0) {
1109 return 4;
1110 }
1111 else if (samplingRate == 30.0) {
1112 return 5;
1113 }
1114 else if (samplingRate == 60.0) {
1115 return 6;
1116 }
1117 else if (samplingRate == 120.0) {
1118 return 7;
1119 }
1120 else if (samplingRate == 240.0) {
1121 return 8;
1122 }
1123 else if (samplingRate == 300.0) {
1124 return 9;
1125 }
1126 else if (samplingRate == 600.0) {
1127 return 10;
1128 }
1129 else if (samplingRate == 900.0) {
1130 return 11;
1131 }
1132 else if (samplingRate == 1800.0) {
1133 return 12;
1134 }
1135 else if (samplingRate == 3600.0) {
1136 return 13;
1137 }
1138 else if (samplingRate == 7200.0) {
1139 return 14;
1140 }
1141 else if (samplingRate == 10800.0) {
1142 return 15;
1143 }
[6877]1144 return 2; // default
[6557]1145}
Note: See TracBrowser for help on using the repository browser.