source: ntrip/branches/BNC_2.12/src/PPP/pppParlist.cpp@ 8669

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

reset of coordinate parameter is added to consider gaps

  • Property svn:keywords set to Author Date Id Rev URL;svn:eol-style=native
  • Property svn:mime-type set to text/plain
File size: 11.0 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 par->type() == t_pppParam::crdX ||
219 par->type() == t_pppParam::crdY ||
220 par->type() == t_pppParam::crdZ) {
221 if (par->lastObsTime().valid() && (epoTime - par->lastObsTime() > 60.0)) {
222 remove = true;
223 }
224 }
225
226 if (remove) {
227 delete par;
228 it = _params.erase(it);
229 }
230 else {
231 ++it;
232 }
233 }
234
235 // Check whether parameters have observations
236 // ------------------------------------------
237 for (unsigned ii = 0; ii < _params.size(); ii++) {
238 t_pppParam* par = _params[ii];
239 if (par->prn() == 0) {
240 par->setLastObsTime(epoTime);
241 if (par->firstObsTime().undef()) {
242 par->setFirstObsTime(epoTime);
243 }
244 }
245 else {
246 for (unsigned jj = 0; jj < obsVector.size(); jj++) {
247 const t_pppSatObs* satObs = obsVector[jj];
248 if (satObs->prn() == par->prn()) {
249 par->setLastObsTime(epoTime);
250 if (par->firstObsTime().undef()) {
251 par->setFirstObsTime(epoTime);
252 }
253 break;
254 }
255 }
256 }
257 }
258
259 // Required Set of Parameters
260 // --------------------------
261 vector<t_pppParam*> required;
262
263 // Coordinates
264 // -----------
265 required.push_back(new t_pppParam(t_pppParam::crdX, t_prn(), t_lc::dummy));
266 required.push_back(new t_pppParam(t_pppParam::crdY, t_prn(), t_lc::dummy));
267 required.push_back(new t_pppParam(t_pppParam::crdZ, t_prn(), t_lc::dummy));
268
269 // Receiver Clock
270 // --------------
271 required.push_back(new t_pppParam(t_pppParam::clkR, t_prn(), t_lc::dummy));
272
273 // GPS-Glonass Clock Offset
274 // ------------------------
275 if (OPT->useSystem('R')) {
276 required.push_back(new t_pppParam(t_pppParam::offGG, t_prn(), t_lc::dummy));
277 }
278
279 // Troposphere
280 // -----------
281 if (OPT->estTrp()) {
282 required.push_back(new t_pppParam(t_pppParam::trp, t_prn(), t_lc::dummy));
283 }
284
285 // Ambiguities
286 // -----------
287 for (unsigned jj = 0; jj < obsVector.size(); jj++) {
288 const t_pppSatObs* satObs = obsVector[jj];
289 const vector<t_lc::type>& ambLCs = OPT->ambLCs(satObs->prn().system());
290 for (unsigned ii = 0; ii < ambLCs.size(); ii++) {
291 required.push_back(new t_pppParam(t_pppParam::amb, satObs->prn(), ambLCs[ii], &obsVector));
292 }
293 }
294
295 // Check if all required parameters are present
296 // --------------------------------------------
297 for (unsigned ii = 0; ii < required.size(); ii++) {
298 t_pppParam* parReq = required[ii];
299
300 bool found = false;
301 for (unsigned jj = 0; jj < _params.size(); jj++) {
302 t_pppParam* parOld = _params[jj];
303 if (parOld->isEqual(parReq)) {
304 found = true;
305 break;
306 }
307 }
308 if (found) {
309 delete parReq;
310 }
311 else {
312 _params.push_back(parReq);
313 }
314 }
315
316 // Set Parameter Indices
317 // ---------------------
318 sort(_params.begin(), _params.end(), t_pppParam::sortFunction);
319
320 for (unsigned ii = 0; ii < _params.size(); ii++) {
321 t_pppParam* par = _params[ii];
322 par->setIndex(ii);
323 for (unsigned jj = 0; jj < obsVector.size(); jj++) {
324 const t_pppSatObs* satObs = obsVector[jj];
325 if (satObs->prn() == par->prn()) {
326 par->setAmbEleSat(satObs->eleSat());
327 par->stepAmbNumEpo();
328 }
329 }
330 }
331
332 return success;
333}
334
335//
336////////////////////////////////////////////////////////////////////////////
337void t_pppParlist::printResult(const bncTime& epoTime, const SymmetricMatrix& QQ,
338 const ColumnVector& xx) const {
339
340 string epoTimeStr = string(epoTime);
341 const t_pppStation* sta = PPP_CLIENT->staRover();
342
343 LOG << endl;
344
345 t_pppParam* parX = 0;
346 t_pppParam* parY = 0;
347 t_pppParam* parZ = 0;
348 for (unsigned ii = 0; ii < _params.size(); ii++) {
349 t_pppParam* par = _params[ii];
350 if (par->type() == t_pppParam::crdX) {
351 parX = par;
352 }
353 else if (par->type() == t_pppParam::crdY) {
354 parY = par;
355 }
356 else if (par->type() == t_pppParam::crdZ) {
357 parZ = par;
358 }
359 else {
360 int ind = par->indexNew();
361 double apr = (par->type() == t_pppParam::trp) ?
362 t_tropo::delay_saast(sta->xyzApr(), M_PI/2.0) : par->x0();
363 LOG << epoTimeStr << ' ' << par->toString() << ' '
364 << setw(10) << setprecision(4) << apr << ' '
365 << showpos << setw(10) << setprecision(4) << xx[ind] << noshowpos << " +- "
366 << setw(8) << setprecision(4) << sqrt(QQ[ind][ind]);
367 if (par->type() == t_pppParam::amb) {
368 LOG << " el = " << setw(6) << setprecision(2) << par->ambEleSat() * 180.0 / M_PI
369 << " epo = " << setw(4) << par->ambNumEpo();
370 }
371 LOG << endl;
372 }
373 }
374
375 if (parX && parY && parZ) {
376
377 ColumnVector xyz(3);
378 xyz[0] = xx[parX->indexNew()];
379 xyz[1] = xx[parY->indexNew()];
380 xyz[2] = xx[parZ->indexNew()];
381
382 ColumnVector neu(3);
383 xyz2neu(sta->ellApr().data(), xyz.data(), neu.data());
384
385 SymmetricMatrix QQxyz = QQ.SymSubMatrix(1,3);
386
387 SymmetricMatrix QQneu(3);
388 covariXYZ_NEU(QQxyz, sta->ellApr().data(), QQneu);
389
390 LOG << epoTimeStr << ' ' << sta->name()
391 << " X = " << setprecision(4) << sta->xyzApr()[0] + xyz[0] << " +- "
392 << setprecision(4) << sqrt(QQxyz[0][0])
393
394 << " Y = " << setprecision(4) << sta->xyzApr()[1] + xyz[1] << " +- "
395 << setprecision(4) << sqrt(QQxyz[1][1])
396
397 << " Z = " << setprecision(4) << sta->xyzApr()[2] + xyz[2] << " +- "
398 << setprecision(4) << sqrt(QQxyz[2][2])
399
400 << " dN = " << setprecision(4) << neu[0] << " +- "
401 << setprecision(4) << sqrt(QQneu[0][0])
402
403 << " dE = " << setprecision(4) << neu[1] << " +- "
404 << setprecision(4) << sqrt(QQneu[1][1])
405
406 << " dU = " << setprecision(4) << neu[2] << " +- "
407 << setprecision(4) << sqrt(QQneu[2][2])
408
409 << endl;
410 }
411}
412
Note: See TracBrowser for help on using the repository browser.