source: ntrip/trunk/BNC/src/PPP/pppParlist.cpp@ 7973

Last change on this file since 7973 was 7973, checked in by stuerze, 8 years ago

minor changes

  • Property svn:keywords set to Author Date Id Rev URL;svn:eol-style=native
  • Property svn:mime-type set to text/plain
File size: 10.9 KB
Line 
1/* -------------------------------------------------------------------------
2 * BKG NTRIP Client
3 * -------------------------------------------------------------------------
4 *
5 * Class: t_pppParlist
6 *
7 * Purpose: List of estimated parameters
8 *
9 * Author: L. Mervart
10 *
11 * Created: 29-Jul-2014
12 *
13 * Changes:
14 *
15 * -----------------------------------------------------------------------*/
16
17#include <cmath>
18#include <iostream>
19#include <sstream>
20#include <iomanip>
21#include <algorithm>
22#include <newmatio.h>
23
24#include "pppParlist.h"
25#include "pppSatObs.h"
26#include "pppStation.h"
27#include "bncutils.h"
28#include "bncconst.h"
29#include "pppClient.h"
30
31using namespace BNC_PPP;
32using namespace std;
33
34// Constructor
35////////////////////////////////////////////////////////////////////////////
36t_pppParam::t_pppParam(e_type type, const t_prn& prn, t_lc::type tLC,
37 const vector<t_pppSatObs*>* obsVector) {
38
39 _type = type;
40 _prn = prn;
41 _tLC = tLC;
42 _x0 = 0.0;
43 _indexOld = -1;
44 _indexNew = -1;
45 _noise = 0.0;
46 _ambInfo = 0;
47
48 switch (_type) {
49 case crdX:
50 _epoSpec = false;
51 _sigma0 = OPT->_aprSigCrd[0];
52 _noise = OPT->_noiseCrd[0];
53 break;
54 case crdY:
55 _epoSpec = false;
56 _sigma0 = OPT->_aprSigCrd[1];
57 _noise = OPT->_noiseCrd[1];
58 break;
59 case crdZ:
60 _epoSpec = false;
61 _sigma0 = OPT->_aprSigCrd[2];
62 _noise = OPT->_noiseCrd[2];
63 break;
64 case clkR:
65 _epoSpec = true;
66 _sigma0 = OPT->_noiseClk;
67 break;
68 case amb:
69 _epoSpec = false;
70 _sigma0 = OPT->_aprSigAmb;
71 _ambInfo = new t_ambInfo();
72 if (obsVector) {
73 for (unsigned ii = 0; ii < obsVector->size(); ii++) {
74 const t_pppSatObs* obs = obsVector->at(ii);
75 if (obs->prn() == _prn) {
76 double offGG = 0;
77 if (_prn.system() == 'R' && tLC != t_lc::MW) {
78 offGG = PPP_CLIENT->offGG();
79 }
80 _x0 = floor((obs->obsValue(tLC) - offGG - obs->cmpValue(tLC)) / obs->lambda(tLC) + 0.5);
81 break;
82 }
83 }
84 }
85 break;
86 case offGG:
87 _epoSpec = true;
88 _sigma0 = 1000.0;
89 _x0 = PPP_CLIENT->offGG();
90 break;
91 case trp:
92 _epoSpec = false;
93 _sigma0 = OPT->_aprSigTrp;
94 _noise = OPT->_noiseTrp;
95 break;
96 }
97}
98
99// Destructor
100////////////////////////////////////////////////////////////////////////////
101t_pppParam::~t_pppParam() {
102 delete _ambInfo;
103}
104
105//
106////////////////////////////////////////////////////////////////////////////
107double t_pppParam::partial(const bncTime& /* epoTime */, const t_pppSatObs* obs,
108 const t_lc::type& tLC) const {
109
110 // Special Case - Melbourne-Wuebbena
111 // ---------------------------------
112 if (tLC == t_lc::MW && _type != amb) {
113 return 0.0;
114 }
115
116 const t_pppStation* sta = PPP_CLIENT->staRover();
117 ColumnVector rhoV = sta->xyzApr() - obs->xc().Rows(1,3);
118
119 switch (_type) {
120 case crdX:
121 return (sta->xyzApr()[0] - obs->xc()[0]) / rhoV.norm_Frobenius();
122 case crdY:
123 return (sta->xyzApr()[1] - obs->xc()[1]) / rhoV.norm_Frobenius();
124 case crdZ:
125 return (sta->xyzApr()[2] - obs->xc()[2]) / rhoV.norm_Frobenius();
126 case clkR:
127 return 1.0;
128 case offGG:
129 return (obs->prn().system() == 'R') ? 1.0 : 0.0;
130 case amb:
131 if (obs->prn() == _prn) {
132 if (tLC == _tLC) {
133 return (obs->lambda(tLC));
134 }
135 else if (tLC == t_lc::lIF && _tLC == t_lc::MW) {
136 return obs->lambda(t_lc::lIF) * obs->lambda(t_lc::MW) / obs->lambda(t_lc::l2);
137 }
138 else {
139 map<t_frequency::type, double> codeCoeff;
140 map<t_frequency::type, double> phaseCoeff;
141 obs->lcCoeff(tLC, codeCoeff, phaseCoeff);
142 if (_tLC == t_lc::l1) {
143 return obs->lambda(t_lc::l1) * phaseCoeff[t_lc::toFreq(obs->prn().system(),t_lc::l1)];
144 }
145 else if (_tLC == t_lc::l2) {
146 return obs->lambda(t_lc::l2) * phaseCoeff[t_lc::toFreq(obs->prn().system(),t_lc::l2)];
147 }
148 }
149 }
150 return 0.0;
151 case trp:
152 return 1.0 / sin(obs->eleSat());
153 }
154
155 return 0.0;
156}
157
158//
159////////////////////////////////////////////////////////////////////////////
160string t_pppParam::toString() const {
161 stringstream ss;
162 switch (_type) {
163 case crdX:
164 ss << "CRD_X";
165 break;
166 case crdY:
167 ss << "CRD_Y";
168 break;
169 case crdZ:
170 ss << "CRD_Z";
171 break;
172 case clkR:
173 ss << "CLK ";
174 break;
175 case amb:
176 ss << "AMB " << left << setw(3) << t_lc::toString(_tLC) << right << ' ' << _prn.toString();
177 break;
178 case offGG:
179 ss << "OGG ";
180 break;
181 case trp:
182 ss << "TRP ";
183 break;
184 }
185 return ss.str();
186}
187
188// Constructor
189////////////////////////////////////////////////////////////////////////////
190t_pppParlist::t_pppParlist() {
191}
192
193// Destructor
194////////////////////////////////////////////////////////////////////////////
195t_pppParlist::~t_pppParlist() {
196 for (unsigned ii = 0; ii < _params.size(); ii++) {
197 delete _params[ii];
198 }
199}
200
201//
202////////////////////////////////////////////////////////////////////////////
203t_irc t_pppParlist::set(const bncTime& epoTime, const std::vector<t_pppSatObs*>& obsVector) {
204
205 // Remove some Parameters
206 // ----------------------
207 vector<t_pppParam*>::iterator it = _params.begin();
208 while (it != _params.end()) {
209 t_pppParam* par = *it;
210
211 bool remove = false;
212
213 if (par->epoSpec()) {
214 remove = true;
215 }
216
217 else if (par->type() == t_pppParam::amb) {
218 if (par->lastObsTime().valid() && (epoTime - par->lastObsTime() > 60.0)) {
219 remove = true;
220 }
221 }
222
223 if (remove) {
224 delete par;
225 it = _params.erase(it);
226 }
227 else {
228 ++it;
229 }
230 }
231
232 // Check whether parameters have observations
233 // ------------------------------------------
234 for (unsigned ii = 0; ii < _params.size(); ii++) {
235 t_pppParam* par = _params[ii];
236 if (par->prn() == 0) {
237 par->setLastObsTime(epoTime);
238 if (par->firstObsTime().undef()) {
239 par->setFirstObsTime(epoTime);
240 }
241 }
242 else {
243 for (unsigned jj = 0; jj < obsVector.size(); jj++) {
244 const t_pppSatObs* satObs = obsVector[jj];
245 if (satObs->prn() == par->prn()) {
246 par->setLastObsTime(epoTime);
247 if (par->firstObsTime().undef()) {
248 par->setFirstObsTime(epoTime);
249 }
250 break;
251 }
252 }
253 }
254 }
255
256 // Required Set of Parameters
257 // --------------------------
258 vector<t_pppParam*> required;
259
260 // Coordinates
261 // -----------
262 required.push_back(new t_pppParam(t_pppParam::crdX, t_prn(), t_lc::dummy));
263 required.push_back(new t_pppParam(t_pppParam::crdY, t_prn(), t_lc::dummy));
264 required.push_back(new t_pppParam(t_pppParam::crdZ, t_prn(), t_lc::dummy));
265
266 // Receiver Clock
267 // --------------
268 required.push_back(new t_pppParam(t_pppParam::clkR, t_prn(), t_lc::dummy));
269
270 // GPS-Glonass Clock Offset
271 // ------------------------
272 if (OPT->useSystem('R')) {
273 required.push_back(new t_pppParam(t_pppParam::offGG, t_prn(), t_lc::dummy));
274 }
275
276 // Troposphere
277 // -----------
278 if (OPT->estTrp()) {
279 required.push_back(new t_pppParam(t_pppParam::trp, t_prn(), t_lc::dummy));
280 }
281
282 // Ambiguities
283 // -----------
284 for (unsigned jj = 0; jj < obsVector.size(); jj++) {
285 const t_pppSatObs* satObs = obsVector[jj];
286 const vector<t_lc::type>& ambLCs = OPT->ambLCs(satObs->prn().system());
287 for (unsigned ii = 0; ii < ambLCs.size(); ii++) {
288 required.push_back(new t_pppParam(t_pppParam::amb, satObs->prn(), ambLCs[ii], &obsVector));
289 }
290 }
291
292 // Check if all required parameters are present
293 // --------------------------------------------
294 for (unsigned ii = 0; ii < required.size(); ii++) {
295 t_pppParam* parReq = required[ii];
296
297 bool found = false;
298 for (unsigned jj = 0; jj < _params.size(); jj++) {
299 t_pppParam* parOld = _params[jj];
300 if (parOld->isEqual(parReq)) {
301 found = true;
302 break;
303 }
304 }
305 if (found) {
306 delete parReq;
307 }
308 else {
309 _params.push_back(parReq);
310 }
311 }
312
313 // Set Parameter Indices
314 // ---------------------
315 sort(_params.begin(), _params.end(), t_pppParam::sortFunction);
316
317 for (unsigned ii = 0; ii < _params.size(); ii++) {
318 t_pppParam* par = _params[ii];
319 par->setIndex(ii);
320 for (unsigned jj = 0; jj < obsVector.size(); jj++) {
321 const t_pppSatObs* satObs = obsVector[jj];
322 if (satObs->prn() == par->prn()) {
323 par->setAmbEleSat(satObs->eleSat());
324 par->stepAmbNumEpo();
325 }
326 }
327 }
328
329 return success;
330}
331
332//
333////////////////////////////////////////////////////////////////////////////
334void t_pppParlist::printResult(const bncTime& epoTime, const SymmetricMatrix& QQ,
335 const ColumnVector& xx) const {
336
337 string epoTimeStr = string(epoTime);
338 const t_pppStation* sta = PPP_CLIENT->staRover();
339
340 LOG << endl;
341
342 t_pppParam* parX = 0;
343 t_pppParam* parY = 0;
344 t_pppParam* parZ = 0;
345 for (unsigned ii = 0; ii < _params.size(); ii++) {
346 t_pppParam* par = _params[ii];
347 if (par->type() == t_pppParam::crdX) {
348 parX = par;
349 }
350 else if (par->type() == t_pppParam::crdY) {
351 parY = par;
352 }
353 else if (par->type() == t_pppParam::crdZ) {
354 parZ = par;
355 }
356 else {
357 int ind = par->indexNew();
358 double apr = (par->type() == t_pppParam::trp) ?
359 t_tropo::delay_saast(sta->xyzApr(), M_PI/2.0) : par->x0();
360 LOG << epoTimeStr << ' ' << par->toString() << ' '
361 << setw(10) << setprecision(4) << apr << ' '
362 << showpos << setw(10) << setprecision(4) << xx[ind] << noshowpos << " +- "
363 << setw(8) << setprecision(4) << sqrt(QQ[ind][ind]);
364 if (par->type() == t_pppParam::amb) {
365 LOG << " el = " << setw(6) << setprecision(2) << par->ambEleSat() * 180.0 / M_PI
366 << " epo = " << setw(4) << par->ambNumEpo();
367 }
368 LOG << endl;
369 }
370 }
371
372 if (parX && parY && parZ) {
373
374 ColumnVector xyz(3);
375 xyz[0] = xx[parX->indexNew()];
376 xyz[1] = xx[parY->indexNew()];
377 xyz[2] = xx[parZ->indexNew()];
378
379 ColumnVector neu(3);
380 xyz2neu(sta->ellApr().data(), xyz.data(), neu.data());
381
382 SymmetricMatrix QQxyz = QQ.SymSubMatrix(1,3);
383
384 SymmetricMatrix QQneu(3);
385 covariXYZ_NEU(QQxyz, sta->ellApr().data(), QQneu);
386
387 LOG << epoTimeStr << ' ' << sta->name()
388 << " X = " << setprecision(4) << sta->xyzApr()[0] + xyz[0] << " +- "
389 << setprecision(4) << sqrt(QQxyz[0][0])
390
391 << " Y = " << setprecision(4) << sta->xyzApr()[1] + xyz[1] << " +- "
392 << setprecision(4) << sqrt(QQxyz[1][1])
393
394 << " Z = " << setprecision(4) << sta->xyzApr()[2] + xyz[2] << " +- "
395 << setprecision(4) << sqrt(QQxyz[2][2])
396
397 << " dN = " << setprecision(4) << neu[0] << " +- "
398 << setprecision(4) << sqrt(QQneu[0][0])
399
400 << " dE = " << setprecision(4) << neu[1] << " +- "
401 << setprecision(4) << sqrt(QQneu[1][1])
402
403 << " dU = " << setprecision(4) << neu[2] << " +- "
404 << setprecision(4) << sqrt(QQneu[2][2])
405
406 << endl;
407 }
408}
409
Note: See TracBrowser for help on using the repository browser.