source: ntrip/trunk/BNC/src/PPP/pppClient.cpp@ 11095

Last change on this file since 11095 was 11095, checked in by stuerze, 7 days ago

updates regarding new RTCMSSR usage in PPP mode

  • Property svn:keywords set to Author Date Id Rev URL;svn:eol-style=native
  • Property svn:mime-type set to text/plain
File size: 22.9 KB
Line 
1/* -------------------------------------------------------------------------
2 * BKG NTRIP Client
3 * -------------------------------------------------------------------------
4 *
5 * Class: t_pppClient
6 *
7 * Purpose: PPP Client processing starts here
8 *
9 * Author: L. Mervart
10 *
11 * Created: 29-Jul-2014
12 *
13 * Changes:
14 *
15 * -----------------------------------------------------------------------*/
16
17#include <QThreadStorage>
18
19#include <iostream>
20#include <iomanip>
21#include <cmath>
22#include <stdlib.h>
23#include <string.h>
24#include <stdexcept>
25
26#include "pppClient.h"
27#include "pppEphPool.h"
28#include "pppObsPool.h"
29#include "bncconst.h"
30#include "bncutils.h"
31#include "pppStation.h"
32#include "bncantex.h"
33#include "pppFilter.h"
34
35using namespace BNC_PPP;
36using namespace std;
37
38// Global variable holding thread-specific pointers
39//////////////////////////////////////////////////////////////////////////////
40QThreadStorage<t_pppClient*> CLIENTS;
41
42// Static function returning thread-specific pointer
43//////////////////////////////////////////////////////////////////////////////
44t_pppClient* t_pppClient::instance() {
45 return CLIENTS.localData();
46}
47
48// Constructor
49//////////////////////////////////////////////////////////////////////////////
50t_pppClient::t_pppClient(const t_pppOptions* opt) {
51 _running = true;
52 _output = 0;
53 _opt = new t_pppOptions(*opt);
54 _log = new ostringstream();
55 _ephPool = new t_pppEphPool();
56 _obsPool = new t_pppObsPool();
57 _staRover = new t_pppStation();
58 _filter = new t_pppFilter();
59 _tides = new t_tides();
60 _antex = 0;
61 _ssrFormat = ssrUnknown;
62 if (!_opt->_antexFileName.empty()) {
63 _antex = new bncAntex(_opt->_antexFileName.c_str());
64 *_log << _antex->info().toStdString() << endl;
65 }
66 if (!_opt->_blqFileName.empty()) {
67 if (_tides->readBlqFile(_opt->_blqFileName.c_str()) == success) {
68 //_tides->printAllBlqSets();
69 }
70 }
71 CLIENTS.setLocalData(this); // CLIENTS takes ownership over "this"
72}
73
74// Destructor
75//////////////////////////////////////////////////////////////////////////////
76t_pppClient::~t_pppClient() {
77 _running = false;
78 delete _log;
79 delete _opt;
80 delete _ephPool;
81 delete _obsPool;
82 delete _staRover;
83 if (_antex) {
84 delete _antex;
85 }
86 delete _filter;
87 delete _tides;
88 clearObs();
89}
90
91//
92//////////////////////////////////////////////////////////////////////////////
93void t_pppClient::putEphemeris(const t_eph* eph) {
94 const t_ephGPS* ephGPS = dynamic_cast<const t_ephGPS*>(eph);
95 const t_ephGlo* ephGlo = dynamic_cast<const t_ephGlo*>(eph);
96 const t_ephGal* ephGal = dynamic_cast<const t_ephGal*>(eph);
97 const t_ephBDS* ephBDS = dynamic_cast<const t_ephBDS*>(eph);
98 if (ephGPS) {
99 _ephPool->putEphemeris(new t_ephGPS(*ephGPS));
100 }
101 else if (ephGlo) {
102 _ephPool->putEphemeris(new t_ephGlo(*ephGlo));
103 }
104 else if (ephGal) {
105 // SSR corrections of all formats refer to Galileo I/NAV. The pool matches
106 // corrections by IOD only and keeps one ephemeris per TOC, so an F/NAV set
107 // with the same IODnav (different clock parameters) must not get in.
108 if (ephGal->type() == t_eph::INAV) {
109 _ephPool->putEphemeris(new t_ephGal(*ephGal));
110 }
111 }
112 else if (ephBDS) {
113 _ephPool->putEphemeris(new t_ephBDS(*ephBDS));
114 }
115}
116
117//
118//////////////////////////////////////////////////////////////////////////////
119void t_pppClient::putTec(const t_vTec* vTec) {
120 _obsPool->putTec(new t_vTec(*vTec));
121}
122
123//
124//////////////////////////////////////////////////////////////////////////////
125void t_pppClient::putMetaData(const t_metaData* metaData) {
126 _obsPool->putMetaData(new t_metaData(*metaData));
127}
128
129//
130//////////////////////////////////////////////////////////////////////////////
131void t_pppClient::putOrbCorrections(const vector<t_orbCorr*>& corr) {
132 if (OPT->_logMode == t_pppOptions::normal && corr.size() > 0) {
133 LOG << "orbCorrections " << string(corr[0]->_time) << ' ' << corr.size() << endl;
134 }
135 for (unsigned ii = 0; ii < corr.size(); ii++) {
136 _ssrFormat = corr[ii]->_ssrFormat;
137 _ephPool->putOrbCorrection(new t_orbCorr(*corr[ii]));
138 }
139}
140
141//
142//////////////////////////////////////////////////////////////////////////////
143void t_pppClient::putClkCorrections(const vector<t_clkCorr*>& corr) {
144 if (OPT->_logMode == t_pppOptions::normal && corr.size() > 0) {
145 LOG << "clkCorrections " << string(corr[0]->_time) << ' ' << corr.size() << endl;
146 }
147 for (unsigned ii = 0; ii < corr.size(); ii++) {
148 _ephPool->putClkCorrection(new t_clkCorr(*corr[ii]));
149 }
150}
151
152//
153//////////////////////////////////////////////////////////////////////////////
154void t_pppClient::putCodeBiases(const vector<t_satCodeBias*>& biases) {
155 if (OPT->_logMode == t_pppOptions::normal && biases.size() > 0) {
156 LOG << "codeBiases " << string(biases[0]->_time) << ' ' << biases.size() << endl;
157 }
158 set<char> systems;
159 for (unsigned ii = 0; ii < biases.size(); ii++) {
160 t_satCodeBias* newBias = new t_satCodeBias(*biases[ii]);
161 char sys = newBias->_prn.system();
162 if (systems.find(sys) == systems.end()) {
163 _obsPool->clearCodeBiases(sys);
164 systems.insert(sys);
165 }
166 _obsPool->putCodeBias(newBias);
167 }
168}
169
170//
171//////////////////////////////////////////////////////////////////////////////
172void t_pppClient::putSatAntennas(const vector<t_satAntenna*>& satAntennas) {
173 if (OPT->_logMode == t_pppOptions::normal && satAntennas.size() > 0) {
174 LOG << "satAntennas " << string(satAntennas[0]->_time) << ' ' << satAntennas.size() << endl;
175 }
176 for (unsigned ii = 0; ii < satAntennas.size(); ii++) {
177 _obsPool->putSatAntenna(new t_satAntenna(*satAntennas[ii]));
178 }
179}
180
181//
182//////////////////////////////////////////////////////////////////////////////
183void t_pppClient::putPhaseBiases(const vector<t_satPhaseBias*>& biases) {
184 if (OPT->_logMode == t_pppOptions::normal && biases.size() > 0) {
185 LOG << "phaseBiases " << string(biases[0]->_time) << ' ' << biases.size() << endl;
186 }
187 set<char> systems;
188 for (unsigned ii = 0; ii < biases.size(); ii++) {
189 t_satPhaseBias* newBias = new t_satPhaseBias(*biases[ii]);
190 char sys = newBias->_prn.system();
191 if (systems.find(sys) == systems.end()) {
192 _obsPool->clearPhaseBiases(sys);
193 systems.insert(sys);
194 }
195 _obsPool->putPhaseBias(newBias);
196 }
197}
198
199//
200//////////////////////////////////////////////////////////////////////////////
201t_irc t_pppClient::prepareObs(const vector<t_satObs*>& satObs,
202 vector<t_pppSatObs*>& obsVector, bncTime& epoTime) {
203
204 // Default
205 // -------
206 epoTime.reset();
207 clearObs();
208
209 // Create vector of valid observations
210 // -----------------------------------
211 for (unsigned ii = 0; ii < satObs.size(); ii++) {
212 char sys = satObs[ii]->_prn.system();
213 if (_opt->useSystem(sys)) {
214 t_pppSatObs* pppSatObs = new t_pppSatObs(*satObs[ii]);
215 if (pppSatObs->isValid()) {
216 obsVector.push_back(pppSatObs);
217 }
218 else {
219 delete pppSatObs;
220 }
221 }
222 }
223
224 // Check whether data are synchronized, compute epoTime
225 // ----------------------------------------------------
226 const double MAXSYNC = 0.05; // synchronization limit
227 double meanDt = 0.0;
228 for (unsigned ii = 0; ii < obsVector.size(); ii++) {
229 const t_pppSatObs* satObs = obsVector.at(ii);
230 if (epoTime.undef()) {
231 epoTime = satObs->time();
232 }
233 else {
234 double dt = satObs->time() - epoTime;
235 if (fabs(dt) > MAXSYNC) {
236 LOG << "t_pppClient::prepareObs asynchronous observations" << endl;
237 return failure;
238 }
239 meanDt += dt;
240 }
241 }
242
243 if (obsVector.size() > 0) {
244 epoTime += meanDt / obsVector.size();
245 }
246
247 return success;
248}
249
250//
251//////////////////////////////////////////////////////////////////////////////
252bool t_pppClient::preparePseudoObs(std::vector<t_pppSatObs*>& obsVector) {
253
254 bool pseudoObsIono = false;
255
256 if (_opt->_pseudoObsIono) {
257
258 // Select reference satellite per system: keep the current one if still
259 // visible; only switch to highest elevation when the current one disappears
260 // -------------------------------------------------------------------------
261 map<char, t_pppSatObs*> refSatMap;
262 map<char, t_pppSatObs*> bestEleMap;
263 for (t_pppSatObs* satObs : obsVector) {
264 satObs->resetReference();
265 double stec = satObs->getIonoCodeDelay(t_frequency::G1);
266 if (stec == 0.0) continue;
267 char sys = satObs->prn().system();
268 if (!bestEleMap.count(sys) || satObs->eleSat() > bestEleMap[sys]->eleSat()) {
269 bestEleMap[sys] = satObs;
270 }
271 if (_refPrnMap.count(sys) && satObs->prn() == _refPrnMap[sys]) {
272 refSatMap[sys] = satObs;
273 }
274 }
275 for (auto& kv : bestEleMap) {
276 if (!refSatMap.count(kv.first)) {
277 refSatMap[kv.first] = kv.second;
278 }
279 }
280 for (auto& kv : refSatMap) {
281 _refPrnMap[kv.first] = kv.second->prn();
282 kv.second->setAsReference();
283 }
284
285 if (bestEleMap.empty()) {
286 LOG << "GIM pseudo-obs unavailable: no valid STEC (vTec data missing?)" << endl;
287 }
288
289 // Set STEC pseudo-observations (single-differenced vs reference satellite)
290 // -------------------------------------------------------------------------
291 int nGIM = 0;
292 for (t_pppSatObs* satObs : obsVector) {
293 char sys = satObs->prn().system();
294 double stecRefSat = refSatMap.count(sys)
295 ? refSatMap[sys]->getIonoCodeDelay(t_frequency::G1)
296 : 0.0;
297 if (satObs->setPseudoObsIono(t_frequency::G1, stecRefSat)) {
298 pseudoObsIono = true;
299 nGIM++;
300 }
301 }
302 if (nGIM > 0) {
303 LOG << "GIM pseudo-obs: " << nGIM << " satellites, ref:";
304 for (auto& kv : refSatMap) {
305 LOG << ' ' << kv.second->prn().toString();
306 }
307 LOG << endl;
308 }
309 }
310
311 if (OPT->_logMode == t_pppOptions::all) {
312 vector<t_pppSatObs*>::iterator it = obsVector.begin();
313 while (it != obsVector.end()) {
314 t_pppSatObs* satObs = *it;
315 satObs->printObsMinusComputed();
316 it++;
317 }
318 }
319 return pseudoObsIono;
320}
321
322// Compute the Bancroft position, check for blunders
323//////////////////////////////////////////////////////////////////////////////
324t_irc t_pppClient::cmpBancroft(const bncTime& epoTime,
325 vector<t_pppSatObs*>& obsVector,
326 ColumnVector& xyzc, bool print) {
327
328 int numBancroft = obsVector.size();
329
330 while (_running) {
331 Matrix BB(numBancroft, 4);
332 int iObs = -1;
333 for (unsigned ii = 0; ii < obsVector.size(); ii++) {
334 const t_pppSatObs* satObs = obsVector.at(ii);
335 t_lc LC = satObs->rangeLC();
336 if ( satObs->isValid(LC) &&
337 (!satObs->modelSet() || satObs->eleSat() >= _opt->_minEle) ) {
338 ++iObs;
339 BB[iObs][0] = satObs->xc()[0];
340 BB[iObs][1] = satObs->xc()[1];
341 BB[iObs][2] = satObs->xc()[2];
342 BB[iObs][3] = satObs->obsValue(LC) - satObs->cmpValueForBanc(LC);
343 }
344 }
345 if (iObs + 1 < _opt->_minObs) {
346 LOG << "t_pppClient::cmpBancroft not enough observations: " << iObs + 1 << endl;
347 return failure;
348 }
349 BB = BB.Rows(1,iObs+1);
350 if (bancroft(BB, xyzc) != success) {
351 return failure;
352 }
353
354 xyzc[3] /= t_CST::c;
355
356 // Check Blunders
357 // --------------
358 const double BLUNDER = 1500.0;
359 double maxRes = 0.0;
360 unsigned maxResIndex = 0;
361 for (unsigned ii = 0; ii < obsVector.size(); ii++) {
362 const t_pppSatObs* satObs = obsVector.at(ii);
363 t_lc LC = satObs->rangeLC();
364 if (satObs->isValid(LC) &&
365 (!satObs->modelSet() || satObs->eleSat() >= _opt->_minEle) ) {
366 ColumnVector rr = satObs->xc().Rows(1,3) - xyzc.Rows(1,3);
367 double res = rr.NormFrobenius() - satObs->obsValue(LC)
368 - (satObs->xc()[3] - xyzc[3]) * t_CST::c;
369 if (fabs(res) > maxRes) {
370 maxRes = fabs(res);
371 maxResIndex = ii;
372 }
373 }
374 }
375 if (maxRes < BLUNDER) {
376 if (print) {
377 LOG.setf(ios::fixed);
378 LOG << "\nPPP of Epoch ";
379 if (!_epoTimeRover.undef()) LOG << string(_epoTimeRover);
380 LOG << " using " << _opt->_corrMount;
381 LOG << "\n---------------------------------------------------------------\n";
382 LOG << string(epoTime) << " BANCROFT: "
383 << setw(14) << setprecision(3) << xyzc[0] << ' '
384 << setw(14) << setprecision(3) << xyzc[1] << ' '
385 << setw(14) << setprecision(3) << xyzc[2] << ' '
386 << setw(14) << setprecision(3) << xyzc[3] * t_CST::c << endl << endl;
387 }
388 break;
389 }
390 else {
391 t_pppSatObs* satObs = obsVector.at(maxResIndex);
392 LOG << "t_pppClient::cmpBancroft Outlier " << satObs->prn().toString()
393 << " " << maxRes << endl;
394 delete satObs;
395 obsVector.erase(obsVector.begin() + maxResIndex);
396 }
397 }
398
399 return success;
400}
401
402//
403//////////////////////////////////////////////////////////////////////////////
404void t_pppClient::initOutput(t_output* output) {
405 _output = output;
406 _output->_numSat = 0;
407 _output->_hDop = 0.0;
408 _output->_error = false;
409}
410
411//
412//////////////////////////////////////////////////////////////////////////////
413void t_pppClient::clearObs() {
414 for (unsigned ii = 0; ii < _obsRover.size(); ii++) {
415 delete _obsRover.at(ii);
416 }
417 _obsRover.clear();
418}
419
420//
421//////////////////////////////////////////////////////////////////////////////
422void t_pppClient::finish(t_irc irc, int ind) {
423#ifdef BNC_DEBUG_PPP
424 LOG << "t_pppClient::finish(" << ind << "): " << irc << endl;
425#endif
426
427 clearObs();
428
429 _output->_epoTime = _epoTimeRover;
430
431 if (irc == success) {
432 _output->_xyzRover[0] = _staRover->xyzApr()[0] + _filter->x()[0];
433 _output->_xyzRover[1] = _staRover->xyzApr()[1] + _filter->x()[1];
434 _output->_xyzRover[2] = _staRover->xyzApr()[2] + _filter->x()[2];
435
436 xyz2neu(_staRover->ellApr().data(), _filter->x().data(), _output->_neu);
437
438 copy(&_filter->Q().data()[0], &_filter->Q().data()[6], _output->_covMatrix);
439
440 _output->_trp0 = t_tropo::delay_saast(_staRover->xyzApr(), M_PI/2.0);
441 _output->_trp = _filter->trp();
442 _output->_trpStdev = _filter->trpStdev();
443
444 _output->_fixRatio = _filter->fixRatio();
445
446 _output->_numSat = _filter->numSat();
447 _output->_hDop = _filter->HDOP();
448 _output->_error = false;
449 }
450 else {
451 _output->_error = true;
452 }
453
454 _output->_log = _log->str();
455 delete _log; _log = new ostringstream();
456
457 return;
458}
459
460//
461//////////////////////////////////////////////////////////////////////////////
462t_irc t_pppClient::cmpModel(t_pppStation* station, const ColumnVector& xyzc,
463 vector<t_pppSatObs*>& obsVector) {
464 bncTime time;
465 time = _epoTimeRover;
466 station->setName(_opt->_roverName);
467 station->setAntName(_opt->_antNameRover);
468 station->setEpochTime(time);
469
470 if (_opt->xyzAprRoverSet()) {
471 if (_opt->_refEpochRover != 0.0) {
472 double dt = decimalYear(time) - _opt->_refEpochRover;
473 station->setXyzApr(_opt->_xyzAprRover + dt * _opt->_velRover);
474 }
475 else {
476 station->setXyzApr(_opt->_xyzAprRover);
477 }
478 }
479 else {
480 station->setXyzApr(xyzc.Rows(1,3));
481 }
482 station->setNeuEcc(_opt->_neuEccRover);
483
484 // Receiver Clock
485 // --------------
486 station->setDClk(xyzc[3]);
487
488 // Tides
489 // -----
490 // RTCM-SSR Metadata (model correction type 3 = solid earth tides) tells us
491 // whether - and with which model - the correction stream's generation
492 // system already accounted for solid earth tides. To stay consistent with
493 // the orbit/clock corrections, mirror that choice here: skip our own
494 // correction if the provider applied none, apply our default model if the
495 // provider used its own default, and fall back to our default (with a
496 // warning) if the provider used some other, unsupported model - we have no
497 // way to reproduce an unknown model exactly. Absent any Metadata message
498 // (e.g. RTNET or older streams), keep today's unconditional behavior.
499 bool applyEarthTide = true;
500 const t_metaData* metaData = _obsPool->metaData();
501 if (metaData) {
502 for (unsigned ii = 0; ii < metaData->_entries.size(); ii++) {
503 const t_metaDataEntry& entry = metaData->_entries[ii];
504 if (entry._typeIndicator == 3) { // solid earth tides
505 if (!entry._applicationIndicator) {
506 applyEarthTide = false;
507 }
508 else if (entry._nonDefaultIndicator) {
509 LOG << "WARNING: SSR Metadata signals a non-default solid earth "
510 << "tide model (identifier " << entry._nonDefaultIdentifier
511 << "); applying BNC's default model anyway, results may be "
512 << "inconsistent" << endl;
513 }
514 break;
515 }
516 }
517 }
518 if (applyEarthTide) {
519 station->setTideDsplEarth(_tides->earth(time, station->xyzApr()));
520 }
521 else {
522 ColumnVector tideDsplEarth(3); tideDsplEarth = 0.0;
523 station->setTideDsplEarth(tideDsplEarth);
524 }
525 station->setTideDsplOcean(_tides->ocean(time, station->xyzApr(), station->name()));
526
527 // Observation model
528 // -----------------
529 vector<t_pppSatObs*>::iterator it = obsVector.begin();
530 while (it != obsVector.end()) {
531 t_pppSatObs* satObs = *it;
532 t_irc modelSetup;
533 if (satObs->isValid()) {
534 modelSetup = satObs->cmpModel(station);
535 }
536 if (satObs->isValid() &&
537 satObs->eleSat() >= _opt->_minEle &&
538 modelSetup == success) {
539 ++it;
540 }
541 else {
542 delete satObs;
543 it = obsVector.erase(it);
544 }
545 }
546
547 return success;
548}
549
550//
551//////////////////////////////////////////////////////////////////////////////
552void t_pppClient::processEpoch(const vector<t_satObs*>& satObs, t_output* output) {
553
554 try {
555 initOutput(output);
556
557 // Prepare Observations of the Rover
558 // ---------------------------------
559 if (prepareObs(satObs, _obsRover, _epoTimeRover) != success) {
560 return finish(failure, 1);
561 }
562
563 for (int iter = 1; iter <= 2; iter++) {
564 ColumnVector xyzc(4); xyzc = 0.0;
565 bool print = (iter == 2);
566 if (cmpBancroft(_epoTimeRover, _obsRover, xyzc, print) != success) {
567 return finish(failure, 2);
568 }
569 if (cmpModel(_staRover, xyzc, _obsRover) != success) {
570 return finish(failure, 3);
571 }
572 }
573
574 // Use observations only if satellite code biases are available
575 // ------------------------------------------------------------
576 if (_opt->ambRes()) {
577 useObsWithBiasesOnly(_obsRover);
578 }
579
580 if (int(_obsRover.size()) < _opt->_minObs) {
581 LOG << "t_pppClient::processEpoch not enough observations" << endl;
582 return finish(failure, 4);
583 }
584
585 // Prepare Pseudo Observations of the Rover
586 // ----------------------------------------
587 _pseudoObsIono = preparePseudoObs(_obsRover);
588
589 // Store last epoch of data
590 // ------------------------
591 _obsPool->putEpoch(_epoTimeRover, _obsRover, _pseudoObsIono);
592
593 // Process Epoch in Filter
594 // -----------------------
595 if (_filter->processEpoch(_obsPool) != success) {
596 LOG << "t_pppFilter::processEpoch() != success" << endl;
597 return finish(failure, 5);
598 }
599 }
600 catch (Exception& exc) {
601 LOG << exc.what() << endl;
602 // A failed Kalman update (e.g. non-positive-definite covariance) leaves
603 // the filter state unusable and would be carried into every subsequent
604 // epoch => restart the filter, keeping ephemerides and corrections
605 // ----------------------------------------------------------------------
606 LOG << string(_epoTimeRover) << " pppClient: filter reset after exception" << endl;
607 delete _filter;
608 _filter = new t_pppFilter();
609 return finish(failure, 6);
610 }
611 catch (t_except msg) {
612 LOG << msg.what() << endl;
613 return finish(failure, 7);
614 }
615 catch (const char* msg) {
616 LOG << msg << endl;
617 return finish(failure, 8);
618 }
619 catch (...) {
620 LOG << "unknown exception" << endl;
621 return finish(failure, 9);
622 }
623 return finish(success, 0);
624}
625
626//
627////////////////////////////////////////////////////////////////////////////
628double lorentz(const ColumnVector& aa, const ColumnVector& bb) {
629 return aa[0]*bb[0] + aa[1]*bb[1] + aa[2]*bb[2] - aa[3]*bb[3];
630}
631
632//
633////////////////////////////////////////////////////////////////////////////
634t_irc t_pppClient::bancroft(const Matrix& BBpass, ColumnVector& pos) {
635
636 if (pos.Nrows() != 4) {
637 pos.ReSize(4);
638 }
639 pos = 0.0;
640
641 for (int iter = 1; iter <= 2; iter++) {
642 Matrix BB = BBpass;
643 int mm = BB.Nrows();
644 for (int ii = 1; ii <= mm; ii++) {
645 double xx = BB(ii,1);
646 double yy = BB(ii,2);
647 double traveltime = 0.072;
648 if (iter > 1) {
649 double zz = BB(ii,3);
650 double rho = sqrt( (xx-pos(1)) * (xx-pos(1)) +
651 (yy-pos(2)) * (yy-pos(2)) +
652 (zz-pos(3)) * (zz-pos(3)) );
653 traveltime = rho / t_CST::c;
654 }
655 double angle = traveltime * t_CST::omega;
656 double cosa = cos(angle);
657 double sina = sin(angle);
658 BB(ii,1) = cosa * xx + sina * yy;
659 BB(ii,2) = -sina * xx + cosa * yy;
660 }
661
662 Matrix BBB;
663 if (mm > 4) {
664 SymmetricMatrix hlp; hlp << BB.t() * BB;
665 BBB = hlp.i() * BB.t();
666 }
667 else {
668 BBB = BB.i();
669 }
670 ColumnVector ee(mm); ee = 1.0;
671 ColumnVector alpha(mm); alpha = 0.0;
672 for (int ii = 1; ii <= mm; ii++) {
673 alpha(ii) = lorentz(BB.Row(ii).t(),BB.Row(ii).t())/2.0;
674 }
675 ColumnVector BBBe = BBB * ee;
676 ColumnVector BBBalpha = BBB * alpha;
677 double aa = lorentz(BBBe, BBBe);
678 double bb = lorentz(BBBe, BBBalpha)-1;
679 double cc = lorentz(BBBalpha, BBBalpha);
680 double root = sqrt(bb*bb-aa*cc);
681
682 Matrix hlpPos(4,2);
683 hlpPos.Column(1) = (-bb-root)/aa * BBBe + BBBalpha;
684 hlpPos.Column(2) = (-bb+root)/aa * BBBe + BBBalpha;
685
686 ColumnVector omc(2);
687 for (int pp = 1; pp <= 2; pp++) {
688 hlpPos(4,pp) = -hlpPos(4,pp);
689 omc(pp) = BB(1,4) -
690 sqrt( (BB(1,1)-hlpPos(1,pp)) * (BB(1,1)-hlpPos(1,pp)) +
691 (BB(1,2)-hlpPos(2,pp)) * (BB(1,2)-hlpPos(2,pp)) +
692 (BB(1,3)-hlpPos(3,pp)) * (BB(1,3)-hlpPos(3,pp)) ) -
693 hlpPos(4,pp);
694 }
695 if ( fabs(omc(1)) > fabs(omc(2)) ) {
696 pos = hlpPos.Column(2);
697 }
698 else {
699 pos = hlpPos.Column(1);
700 }
701 }
702 if (pos.size() != 4 ||
703 std::isnan(pos(1)) ||
704 std::isnan(pos(2)) ||
705 std::isnan(pos(3)) ||
706 std::isnan(pos(4))) {
707 return failure;
708 }
709
710 return success;
711}
712
713//
714//////////////////////////////////////////////////////////////////////////////
715void t_pppClient::reset() {
716
717 LOG << "pppClient: reset" << endl;
718 _refPrnMap.clear();
719 // to delete old orbit and clock corrections
720 delete _ephPool;
721 _ephPool = new t_pppEphPool();
722
723 // to delete old biases
724 delete _obsPool;
725 _obsPool = new t_pppObsPool();
726
727 // to delete all parameters
728 delete _filter;
729 _filter = new t_pppFilter();
730
731}
732
733//
734//////////////////////////////////////////////////////////////////////////////
735void t_pppClient::useObsWithBiasesOnly(vector<t_pppSatObs*>& obsVector) const {
736 vector<t_pppSatObs*>::iterator it = obsVector.begin();
737 while (it != obsVector.end()) {
738 t_pppSatObs* pppSatObs = *it;
739 if (pppSatObs->hasBiases()) {
740 ++it;
741 }
742 else {
743 LOG << "t_pppClient::useObsWithBiasesOnly: no biases: " << pppSatObs->prn().toString().c_str() << endl;
744 it = obsVector.erase(it);
745 delete pppSatObs;
746 }
747 }
748}
Note: See TracBrowser for help on using the repository browser.