source: ntrip/trunk/BNC/src/ephemeris.cpp@ 5852

Last change on this file since 5852 was 5852, checked in by mervart, 10 years ago
File size: 29.1 KB
Line 
1#include <math.h>
2#include <sstream>
3#include <iostream>
4#include <iomanip>
5#include <cstring>
6
7#include <newmatio.h>
8
9#include "ephemeris.h"
10#include "bncutils.h"
11#include "timeutils.h"
12#include "bnctime.h"
13#include "bnccore.h"
14#include "bncutils.h"
15#include "PPP/pppInclude.h"
16
17using namespace std;
18
19// Constructor
20////////////////////////////////////////////////////////////////////////////
21t_eph::t_eph() {
22 _ok = false;
23 _orbCorr = 0;
24 _clkCorr = 0;
25}
26
27//
28////////////////////////////////////////////////////////////////////////////
29void t_eph::setOrbCorr(const BNC_PPP::t_orbCorr* orbCorr) {
30 delete _orbCorr;
31 _orbCorr = new BNC_PPP::t_orbCorr(*orbCorr);
32}
33
34//
35////////////////////////////////////////////////////////////////////////////
36void t_eph::setClkCorr(const BNC_PPP::t_clkCorr* clkCorr) {
37 delete _clkCorr;
38 _clkCorr = new BNC_PPP::t_clkCorr(*clkCorr);
39}
40
41//
42////////////////////////////////////////////////////////////////////////////
43t_irc t_eph::getCrd(const bncTime& tt, ColumnVector& xc,
44 ColumnVector& vv, bool useCorr) const {
45 xc.ReSize(4);
46 vv.ReSize(3);
47 position(tt.gpsw(), tt.gpssec(), xc.data(), vv.data());
48 if (useCorr) {
49 if (_orbCorr && _clkCorr) {
50
51 double dtO = tt - _orbCorr->_time;
52 ColumnVector dx(3);
53 dx[0] = _orbCorr->_xr[0] + _orbCorr->_dotXr[0] * dtO;
54 dx[1] = _orbCorr->_xr[1] + _orbCorr->_dotXr[1] * dtO;
55 dx[2] = _orbCorr->_xr[2] + _orbCorr->_dotXr[2] * dtO;
56
57 if (_orbCorr->_system == 'R') {
58 RSW_to_XYZ(xc.Rows(1,3), vv.Rows(1,3), dx, dx);
59 }
60
61 xc[0] -= dx[0];
62 xc[1] -= dx[1];
63 xc[2] -= dx[2];
64
65 double dtC = tt - _clkCorr->_time;
66 cout << "AGE " << dtO << ' ' << dtC << endl;
67 xc[3] += _clkCorr->_dClk + _clkCorr->_dotDClk * dtC + _clkCorr->_dotDotDClk * dtC * dtC;
68 }
69 else {
70 return failure;
71 }
72 }
73 return success;
74}
75
76// Set GPS Satellite Position
77////////////////////////////////////////////////////////////////////////////
78void t_ephGPS::set(const gpsephemeris* ee) {
79
80 _receptDateTime = currentDateAndTimeGPS();
81
82 _prn.set('G', ee->satellite);
83
84 _TOC.set(ee->GPSweek, ee->TOC);
85 _clock_bias = ee->clock_bias;
86 _clock_drift = ee->clock_drift;
87 _clock_driftrate = ee->clock_driftrate;
88
89 _IODE = ee->IODE;
90 _Crs = ee->Crs;
91 _Delta_n = ee->Delta_n;
92 _M0 = ee->M0;
93
94 _Cuc = ee->Cuc;
95 _e = ee->e;
96 _Cus = ee->Cus;
97 _sqrt_A = ee->sqrt_A;
98
99 _TOEsec = ee->TOE;
100 _Cic = ee->Cic;
101 _OMEGA0 = ee->OMEGA0;
102 _Cis = ee->Cis;
103
104 _i0 = ee->i0;
105 _Crc = ee->Crc;
106 _omega = ee->omega;
107 _OMEGADOT = ee->OMEGADOT;
108
109 _IDOT = ee->IDOT;
110 _L2Codes = 0.0;
111 _TOEweek = ee->GPSweek;
112 _L2PFlag = 0.0;
113
114 if (ee->URAindex <= 6) {
115 _ura = ceil(10.0*pow(2.0, 1.0+((double)ee->URAindex)/2.0))/10.0;
116 }
117 else {
118 _ura = ceil(10.0*pow(2.0, ((double)ee->URAindex)/2.0))/10.0;
119 }
120 _health = ee->SVhealth;
121 _TGD = ee->TGD;
122 _IODC = ee->IODC;
123
124 _TOT = 0.9999e9;
125 _fitInterval = 0.0;
126
127 _ok = true;
128}
129
130// Compute GPS Satellite Position (virtual)
131////////////////////////////////////////////////////////////////////////////
132void t_ephGPS::position(int GPSweek, double GPSweeks,
133 double* xc,
134 double* vv) const {
135
136
137 static const double omegaEarth = 7292115.1467e-11;
138 static const double gmGRS = 398.6005e12;
139
140 memset(xc, 0, 4*sizeof(double));
141 memset(vv, 0, 3*sizeof(double));
142
143 double a0 = _sqrt_A * _sqrt_A;
144 if (a0 == 0) {
145 return;
146 }
147
148 double n0 = sqrt(gmGRS/(a0*a0*a0));
149
150 bncTime tt(GPSweek, GPSweeks);
151 double tk = tt - bncTime(int(_TOEweek), _TOEsec);
152
153 double n = n0 + _Delta_n;
154 double M = _M0 + n*tk;
155 double E = M;
156 double E_last;
157 do {
158 E_last = E;
159 E = M + _e*sin(E);
160 } while ( fabs(E-E_last)*a0 > 0.001 );
161 double v = 2.0*atan( sqrt( (1.0 + _e)/(1.0 - _e) )*tan( E/2 ) );
162 double u0 = v + _omega;
163 double sin2u0 = sin(2*u0);
164 double cos2u0 = cos(2*u0);
165 double r = a0*(1 - _e*cos(E)) + _Crc*cos2u0 + _Crs*sin2u0;
166 double i = _i0 + _IDOT*tk + _Cic*cos2u0 + _Cis*sin2u0;
167 double u = u0 + _Cuc*cos2u0 + _Cus*sin2u0;
168 double xp = r*cos(u);
169 double yp = r*sin(u);
170 double OM = _OMEGA0 + (_OMEGADOT - omegaEarth)*tk -
171 omegaEarth*_TOEsec;
172
173 double sinom = sin(OM);
174 double cosom = cos(OM);
175 double sini = sin(i);
176 double cosi = cos(i);
177 xc[0] = xp*cosom - yp*cosi*sinom;
178 xc[1] = xp*sinom + yp*cosi*cosom;
179 xc[2] = yp*sini;
180
181 double tc = tt - _TOC;
182 xc[3] = _clock_bias + _clock_drift*tc + _clock_driftrate*tc*tc;
183
184 // Velocity
185 // --------
186 double tanv2 = tan(v/2);
187 double dEdM = 1 / (1 - _e*cos(E));
188 double dotv = sqrt((1.0 + _e)/(1.0 - _e)) / cos(E/2)/cos(E/2) / (1 + tanv2*tanv2)
189 * dEdM * n;
190 double dotu = dotv + (-_Cuc*sin2u0 + _Cus*cos2u0)*2*dotv;
191 double dotom = _OMEGADOT - omegaEarth;
192 double doti = _IDOT + (-_Cic*sin2u0 + _Cis*cos2u0)*2*dotv;
193 double dotr = a0 * _e*sin(E) * dEdM * n
194 + (-_Crc*sin2u0 + _Crs*cos2u0)*2*dotv;
195 double dotx = dotr*cos(u) - r*sin(u)*dotu;
196 double doty = dotr*sin(u) + r*cos(u)*dotu;
197
198 vv[0] = cosom *dotx - cosi*sinom *doty // dX / dr
199 - xp*sinom*dotom - yp*cosi*cosom*dotom // dX / dOMEGA
200 + yp*sini*sinom*doti; // dX / di
201
202 vv[1] = sinom *dotx + cosi*cosom *doty
203 + xp*cosom*dotom - yp*cosi*sinom*dotom
204 - yp*sini*cosom*doti;
205
206 vv[2] = sini *doty + yp*cosi *doti;
207
208 // Relativistic Correction
209 // -----------------------
210 xc[3] -= 2.0 * (xc[0]*vv[0] + xc[1]*vv[1] + xc[2]*vv[2]) / t_CST::c / t_CST::c;
211}
212
213// Derivative of the state vector using a simple force model (static)
214////////////////////////////////////////////////////////////////////////////
215ColumnVector t_ephGlo::glo_deriv(double /* tt */, const ColumnVector& xv,
216 double* acc) {
217
218 // State vector components
219 // -----------------------
220 ColumnVector rr = xv.rows(1,3);
221 ColumnVector vv = xv.rows(4,6);
222
223 // Acceleration
224 // ------------
225 static const double gmWGS = 398.60044e12;
226 static const double AE = 6378136.0;
227 static const double OMEGA = 7292115.e-11;
228 static const double C20 = -1082.6257e-6;
229
230 double rho = rr.norm_Frobenius();
231 double t1 = -gmWGS/(rho*rho*rho);
232 double t2 = 3.0/2.0 * C20 * (gmWGS*AE*AE) / (rho*rho*rho*rho*rho);
233 double t3 = OMEGA * OMEGA;
234 double t4 = 2.0 * OMEGA;
235 double z2 = rr(3) * rr(3);
236
237 // Vector of derivatives
238 // ---------------------
239 ColumnVector va(6);
240 va(1) = vv(1);
241 va(2) = vv(2);
242 va(3) = vv(3);
243 va(4) = (t1 + t2*(1.0-5.0*z2/(rho*rho)) + t3) * rr(1) + t4*vv(2) + acc[0];
244 va(5) = (t1 + t2*(1.0-5.0*z2/(rho*rho)) + t3) * rr(2) - t4*vv(1) + acc[1];
245 va(6) = (t1 + t2*(3.0-5.0*z2/(rho*rho)) ) * rr(3) + acc[2];
246
247 return va;
248}
249
250// Compute Glonass Satellite Position (virtual)
251////////////////////////////////////////////////////////////////////////////
252void t_ephGlo::position(int GPSweek, double GPSweeks,
253 double* xc, double* vv) const {
254
255 static const double nominalStep = 10.0;
256
257 memset(xc, 0, 4*sizeof(double));
258 memset(vv, 0, 3*sizeof(double));
259
260 double dtPos = bncTime(GPSweek, GPSweeks) - _tt;
261
262 int nSteps = int(fabs(dtPos) / nominalStep) + 1;
263 double step = dtPos / nSteps;
264
265 double acc[3];
266 acc[0] = _x_acceleration * 1.e3;
267 acc[1] = _y_acceleration * 1.e3;
268 acc[2] = _z_acceleration * 1.e3;
269 for (int ii = 1; ii <= nSteps; ii++) {
270 _xv = rungeKutta4(_tt.gpssec(), _xv, step, acc, glo_deriv);
271 _tt = _tt + step;
272 }
273
274 // Position and Velocity
275 // ---------------------
276 xc[0] = _xv(1);
277 xc[1] = _xv(2);
278 xc[2] = _xv(3);
279
280 vv[0] = _xv(4);
281 vv[1] = _xv(5);
282 vv[2] = _xv(6);
283
284 // Clock Correction
285 // ----------------
286 double dtClk = bncTime(GPSweek, GPSweeks) - _TOC;
287 xc[3] = -_tau + _gamma * dtClk;
288}
289
290// IOD of Glonass Ephemeris (virtual)
291////////////////////////////////////////////////////////////////////////////
292int t_ephGlo::IOD() const {
293 bncTime tMoscow = _TOC - _gps_utc + 3 * 3600.0;
294 return int(tMoscow.daysec() / 900);
295}
296
297// Set Glonass Ephemeris
298////////////////////////////////////////////////////////////////////////////
299void t_ephGlo::set(const glonassephemeris* ee) {
300
301 _receptDateTime = currentDateAndTimeGPS();
302
303 _prn.set('R', ee->almanac_number);
304
305 int ww = ee->GPSWeek;
306 int tow = ee->GPSTOW;
307 updatetime(&ww, &tow, ee->tb*1000, 0); // Moscow -> GPS
308
309 // Check the day once more
310 // -----------------------
311 bool timeChanged = false;
312 {
313 const double secPerDay = 24 * 3600.0;
314 const double secPerWeek = 7 * secPerDay;
315 int ww_old = ww;
316 int tow_old = tow;
317 int currentWeek;
318 double currentSec;
319 currentGPSWeeks(currentWeek, currentSec);
320 bncTime currentTime(currentWeek, currentSec);
321 bncTime hTime(ww, (double) tow);
322
323 if (hTime - currentTime > secPerDay/2.0) {
324 timeChanged = true;
325 tow -= int(secPerDay);
326 if (tow < 0) {
327 tow += int(secPerWeek);
328 ww -= 1;
329 }
330 }
331 else if (hTime - currentTime < -secPerDay/2.0) {
332 timeChanged = true;
333 tow += int(secPerDay);
334 if (tow > secPerWeek) {
335 tow -= int(secPerWeek);
336 ww += 1;
337 }
338 }
339
340 if (false && timeChanged && BNC_CORE->mode() == t_bncCore::batchPostProcessing) {
341 bncTime newHTime(ww, (double) tow);
342 cout << "GLONASS " << ee->almanac_number << " Time Changed at "
343 << currentTime.datestr() << " " << currentTime.timestr()
344 << endl
345 << "old: " << hTime.datestr() << " " << hTime.timestr()
346 << endl
347 << "new: " << newHTime.datestr() << " " << newHTime.timestr()
348 << endl
349 << "eph: " << ee->GPSWeek << " " << ee->GPSTOW << " " << ee->tb
350 << endl
351 << "ww, tow (old): " << ww_old << " " << tow_old
352 << endl
353 << "ww, tow (new): " << ww << " " << tow
354 << endl << endl;
355 }
356 }
357
358 bncTime hlpTime(ww, (double) tow);
359 unsigned year, month, day;
360 hlpTime.civil_date(year, month, day);
361 _gps_utc = gnumleap(year, month, day);
362
363 _TOC.set(ww, tow);
364 _E = ee->E;
365 _tau = ee->tau;
366 _gamma = ee->gamma;
367 _x_pos = ee->x_pos;
368 _x_velocity = ee->x_velocity;
369 _x_acceleration = ee->x_acceleration;
370 _y_pos = ee->y_pos;
371 _y_velocity = ee->y_velocity;
372 _y_acceleration = ee->y_acceleration;
373 _z_pos = ee->z_pos;
374 _z_velocity = ee->z_velocity;
375 _z_acceleration = ee->z_acceleration;
376 _health = 0;
377 _frequency_number = ee->frequency_number;
378 _tki = ee->tk-3*60*60; if (_tki < 0) _tki += 86400;
379
380 // Initialize status vector
381 // ------------------------
382 _tt = _TOC;
383
384 _xv(1) = _x_pos * 1.e3;
385 _xv(2) = _y_pos * 1.e3;
386 _xv(3) = _z_pos * 1.e3;
387 _xv(4) = _x_velocity * 1.e3;
388 _xv(5) = _y_velocity * 1.e3;
389 _xv(6) = _z_velocity * 1.e3;
390
391 _ok = true;
392}
393
394// Set Galileo Satellite Position
395////////////////////////////////////////////////////////////////////////////
396void t_ephGal::set(const galileoephemeris* ee) {
397
398 _receptDateTime = currentDateAndTimeGPS();
399
400 _prn.set('E', ee->satellite);
401
402 _TOC.set(ee->Week, ee->TOC);
403 _clock_bias = ee->clock_bias;
404 _clock_drift = ee->clock_drift;
405 _clock_driftrate = ee->clock_driftrate;
406
407 _IODnav = ee->IODnav;
408 _Crs = ee->Crs;
409 _Delta_n = ee->Delta_n;
410 _M0 = ee->M0;
411
412 _Cuc = ee->Cuc;
413 _e = ee->e;
414 _Cus = ee->Cus;
415 _sqrt_A = ee->sqrt_A;
416
417 _TOEsec = _TOC.gpssec();
418 //// _TOEsec = ee->TOE; //// TODO:
419 _Cic = ee->Cic;
420 _OMEGA0 = ee->OMEGA0;
421 _Cis = ee->Cis;
422
423 _i0 = ee->i0;
424 _Crc = ee->Crc;
425 _omega = ee->omega;
426 _OMEGADOT = ee->OMEGADOT;
427
428 _IDOT = ee->IDOT;
429 _TOEweek = ee->Week;
430
431 _SISA = ee->SISA;
432 _E5aHS = ee->E5aHS;
433 _E5bHS = ee->E5bHS;
434 _BGD_1_5A = ee->BGD_1_5A;
435 _BGD_1_5B = ee->BGD_1_5B;
436
437 _TOT = 0.9999e9;
438
439 _flags = ee->flags;
440
441 _ok = true;
442}
443
444// Compute Galileo Satellite Position (virtual)
445////////////////////////////////////////////////////////////////////////////
446void t_ephGal::position(int GPSweek, double GPSweeks,
447 double* xc,
448 double* vv) const {
449
450 static const double omegaEarth = 7292115.1467e-11;
451 static const double gmWGS = 398.60044e12;
452
453 memset(xc, 0, 4*sizeof(double));
454 memset(vv, 0, 3*sizeof(double));
455
456 double a0 = _sqrt_A * _sqrt_A;
457 if (a0 == 0) {
458 return;
459 }
460
461 double n0 = sqrt(gmWGS/(a0*a0*a0));
462
463 bncTime tt(GPSweek, GPSweeks);
464 double tk = tt - bncTime(_TOC.gpsw(), _TOEsec);
465
466 double n = n0 + _Delta_n;
467 double M = _M0 + n*tk;
468 double E = M;
469 double E_last;
470 do {
471 E_last = E;
472 E = M + _e*sin(E);
473 } while ( fabs(E-E_last)*a0 > 0.001 );
474 double v = 2.0*atan( sqrt( (1.0 + _e)/(1.0 - _e) )*tan( E/2 ) );
475 double u0 = v + _omega;
476 double sin2u0 = sin(2*u0);
477 double cos2u0 = cos(2*u0);
478 double r = a0*(1 - _e*cos(E)) + _Crc*cos2u0 + _Crs*sin2u0;
479 double i = _i0 + _IDOT*tk + _Cic*cos2u0 + _Cis*sin2u0;
480 double u = u0 + _Cuc*cos2u0 + _Cus*sin2u0;
481 double xp = r*cos(u);
482 double yp = r*sin(u);
483 double OM = _OMEGA0 + (_OMEGADOT - omegaEarth)*tk -
484 omegaEarth*_TOEsec;
485
486 double sinom = sin(OM);
487 double cosom = cos(OM);
488 double sini = sin(i);
489 double cosi = cos(i);
490 xc[0] = xp*cosom - yp*cosi*sinom;
491 xc[1] = xp*sinom + yp*cosi*cosom;
492 xc[2] = yp*sini;
493
494 double tc = tt - _TOC;
495 xc[3] = _clock_bias + _clock_drift*tc + _clock_driftrate*tc*tc;
496
497 // Velocity
498 // --------
499 double tanv2 = tan(v/2);
500 double dEdM = 1 / (1 - _e*cos(E));
501 double dotv = sqrt((1.0 + _e)/(1.0 - _e)) / cos(E/2)/cos(E/2) / (1 + tanv2*tanv2)
502 * dEdM * n;
503 double dotu = dotv + (-_Cuc*sin2u0 + _Cus*cos2u0)*2*dotv;
504 double dotom = _OMEGADOT - omegaEarth;
505 double doti = _IDOT + (-_Cic*sin2u0 + _Cis*cos2u0)*2*dotv;
506 double dotr = a0 * _e*sin(E) * dEdM * n
507 + (-_Crc*sin2u0 + _Crs*cos2u0)*2*dotv;
508 double dotx = dotr*cos(u) - r*sin(u)*dotu;
509 double doty = dotr*sin(u) + r*cos(u)*dotu;
510
511 vv[0] = cosom *dotx - cosi*sinom *doty // dX / dr
512 - xp*sinom*dotom - yp*cosi*cosom*dotom // dX / dOMEGA
513 + yp*sini*sinom*doti; // dX / di
514
515 vv[1] = sinom *dotx + cosi*cosom *doty
516 + xp*cosom*dotom - yp*cosi*sinom*dotom
517 - yp*sini*cosom*doti;
518
519 vv[2] = sini *doty + yp*cosi *doti;
520
521 // Relativistic Correction
522 // -----------------------
523 // xc(4) -= 4.442807633e-10 * _e * sqrt(a0) *sin(E);
524 xc[3] -= 2.0 * (xc[0]*vv[0] + xc[1]*vv[1] + xc[2]*vv[2]) / t_CST::c / t_CST::c;
525}
526
527// Constructor
528//////////////////////////////////////////////////////////////////////////////
529t_ephGPS::t_ephGPS(float rnxVersion, const QStringList& lines) {
530
531 const int nLines = 8;
532
533 _ok = false;
534
535 if (lines.size() != nLines) {
536 return;
537 }
538
539 // RINEX Format
540 // ------------
541 int fieldLen = 19;
542
543 int pos[4];
544 pos[0] = (rnxVersion <= 2.12) ? 3 : 4;
545 pos[1] = pos[0] + fieldLen;
546 pos[2] = pos[1] + fieldLen;
547 pos[3] = pos[2] + fieldLen;
548
549 // Read eight lines
550 // ----------------
551 for (int iLine = 0; iLine < nLines; iLine++) {
552 QString line = lines[iLine];
553
554 if ( iLine == 0 ) {
555 QTextStream in(line.left(pos[1]).toAscii());
556
557 int year, month, day, hour, min;
558 double sec;
559
560 QString prnStr;
561 in >> prnStr >> year >> month >> day >> hour >> min >> sec;
562 if (prnStr.at(0) == 'G') {
563 _prn.set('G', prnStr.mid(1).toInt());
564 }
565 else {
566 _prn.set('G', prnStr.toInt());
567 }
568
569 if (year < 80) {
570 year += 2000;
571 }
572 else if (year < 100) {
573 year += 1900;
574 }
575
576 _TOC.set(year, month, day, hour, min, sec);
577
578 if ( readDbl(line, pos[1], fieldLen, _clock_bias ) ||
579 readDbl(line, pos[2], fieldLen, _clock_drift ) ||
580 readDbl(line, pos[3], fieldLen, _clock_driftrate) ) {
581 return;
582 }
583 }
584
585 else if ( iLine == 1 ) {
586 if ( readDbl(line, pos[0], fieldLen, _IODE ) ||
587 readDbl(line, pos[1], fieldLen, _Crs ) ||
588 readDbl(line, pos[2], fieldLen, _Delta_n) ||
589 readDbl(line, pos[3], fieldLen, _M0 ) ) {
590 return;
591 }
592 }
593
594 else if ( iLine == 2 ) {
595 if ( readDbl(line, pos[0], fieldLen, _Cuc ) ||
596 readDbl(line, pos[1], fieldLen, _e ) ||
597 readDbl(line, pos[2], fieldLen, _Cus ) ||
598 readDbl(line, pos[3], fieldLen, _sqrt_A) ) {
599 return;
600 }
601 }
602
603 else if ( iLine == 3 ) {
604 if ( readDbl(line, pos[0], fieldLen, _TOEsec) ||
605 readDbl(line, pos[1], fieldLen, _Cic ) ||
606 readDbl(line, pos[2], fieldLen, _OMEGA0) ||
607 readDbl(line, pos[3], fieldLen, _Cis ) ) {
608 return;
609 }
610 }
611
612 else if ( iLine == 4 ) {
613 if ( readDbl(line, pos[0], fieldLen, _i0 ) ||
614 readDbl(line, pos[1], fieldLen, _Crc ) ||
615 readDbl(line, pos[2], fieldLen, _omega ) ||
616 readDbl(line, pos[3], fieldLen, _OMEGADOT) ) {
617 return;
618 }
619 }
620
621 else if ( iLine == 5 ) {
622 if ( readDbl(line, pos[0], fieldLen, _IDOT ) ||
623 readDbl(line, pos[1], fieldLen, _L2Codes) ||
624 readDbl(line, pos[2], fieldLen, _TOEweek ) ||
625 readDbl(line, pos[3], fieldLen, _L2PFlag) ) {
626 return;
627 }
628 }
629
630 else if ( iLine == 6 ) {
631 if ( readDbl(line, pos[0], fieldLen, _ura ) ||
632 readDbl(line, pos[1], fieldLen, _health) ||
633 readDbl(line, pos[2], fieldLen, _TGD ) ||
634 readDbl(line, pos[3], fieldLen, _IODC ) ) {
635 return;
636 }
637 }
638
639 else if ( iLine == 7 ) {
640 if ( readDbl(line, pos[0], fieldLen, _TOT) ) {
641 return;
642 }
643 readDbl(line, pos[1], fieldLen, _fitInterval); // _fitInterval optional
644 }
645 }
646
647 _ok = true;
648}
649
650// Constructor
651//////////////////////////////////////////////////////////////////////////////
652t_ephGlo::t_ephGlo(float rnxVersion, const QStringList& lines) {
653
654 const int nLines = 4;
655
656 _ok = false;
657
658 if (lines.size() != nLines) {
659 return;
660 }
661
662 // RINEX Format
663 // ------------
664 int fieldLen = 19;
665
666 int pos[4];
667 pos[0] = (rnxVersion <= 2.12) ? 3 : 4;
668 pos[1] = pos[0] + fieldLen;
669 pos[2] = pos[1] + fieldLen;
670 pos[3] = pos[2] + fieldLen;
671
672 // Read four lines
673 // ---------------
674 for (int iLine = 0; iLine < nLines; iLine++) {
675 QString line = lines[iLine];
676
677 if ( iLine == 0 ) {
678 QTextStream in(line.left(pos[1]).toAscii());
679
680 int year, month, day, hour, min;
681 double sec;
682
683 QString prnStr;
684 in >> prnStr >> year >> month >> day >> hour >> min >> sec;
685 if (prnStr.at(0) == 'R') {
686 _prn.set('R', prnStr.mid(1).toInt());
687 }
688 else {
689 _prn.set('R', prnStr.toInt());
690 }
691
692 if (year < 80) {
693 year += 2000;
694 }
695 else if (year < 100) {
696 year += 1900;
697 }
698
699 _gps_utc = gnumleap(year, month, day);
700
701 _TOC.set(year, month, day, hour, min, sec);
702 _TOC = _TOC + _gps_utc;
703
704 if ( readDbl(line, pos[1], fieldLen, _tau ) ||
705 readDbl(line, pos[2], fieldLen, _gamma) ||
706 readDbl(line, pos[3], fieldLen, _tki ) ) {
707 return;
708 }
709
710 _tau = -_tau;
711 }
712
713 else if ( iLine == 1 ) {
714 if ( readDbl(line, pos[0], fieldLen, _x_pos ) ||
715 readDbl(line, pos[1], fieldLen, _x_velocity ) ||
716 readDbl(line, pos[2], fieldLen, _x_acceleration) ||
717 readDbl(line, pos[3], fieldLen, _health ) ) {
718 return;
719 }
720 }
721
722 else if ( iLine == 2 ) {
723 if ( readDbl(line, pos[0], fieldLen, _y_pos ) ||
724 readDbl(line, pos[1], fieldLen, _y_velocity ) ||
725 readDbl(line, pos[2], fieldLen, _y_acceleration ) ||
726 readDbl(line, pos[3], fieldLen, _frequency_number) ) {
727 return;
728 }
729 }
730
731 else if ( iLine == 3 ) {
732 if ( readDbl(line, pos[0], fieldLen, _z_pos ) ||
733 readDbl(line, pos[1], fieldLen, _z_velocity ) ||
734 readDbl(line, pos[2], fieldLen, _z_acceleration) ||
735 readDbl(line, pos[3], fieldLen, _E ) ) {
736 return;
737 }
738 }
739 }
740
741 // Initialize status vector
742 // ------------------------
743 _tt = _TOC;
744 _xv.ReSize(6);
745 _xv(1) = _x_pos * 1.e3;
746 _xv(2) = _y_pos * 1.e3;
747 _xv(3) = _z_pos * 1.e3;
748 _xv(4) = _x_velocity * 1.e3;
749 _xv(5) = _y_velocity * 1.e3;
750 _xv(6) = _z_velocity * 1.e3;
751
752 _ok = true;
753}
754
755// Constructor
756//////////////////////////////////////////////////////////////////////////////
757t_ephGal::t_ephGal(float rnxVersion, const QStringList& lines) {
758
759 const int nLines = 8;
760
761 _ok = false;
762
763 if (lines.size() != nLines) {
764 return;
765 }
766
767 // RINEX Format
768 // ------------
769 int fieldLen = 19;
770
771 int pos[4];
772 pos[0] = (rnxVersion <= 2.12) ? 3 : 4;
773 pos[1] = pos[0] + fieldLen;
774 pos[2] = pos[1] + fieldLen;
775 pos[3] = pos[2] + fieldLen;
776
777 // Read eight lines
778 // ----------------
779 for (int iLine = 0; iLine < nLines; iLine++) {
780 QString line = lines[iLine];
781
782 if ( iLine == 0 ) {
783 QTextStream in(line.left(pos[1]).toAscii());
784
785 int year, month, day, hour, min;
786 double sec;
787
788 QString prnStr;
789 in >> prnStr >> year >> month >> day >> hour >> min >> sec;
790 if (prnStr.at(0) == 'E') {
791 _prn.set('E', prnStr.mid(1).toInt());
792 }
793 else {
794 _prn.set('E', prnStr.toInt());
795 }
796
797 if (year < 80) {
798 year += 2000;
799 }
800 else if (year < 100) {
801 year += 1900;
802 }
803
804 _TOC.set(year, month, day, hour, min, sec);
805
806 if ( readDbl(line, pos[1], fieldLen, _clock_bias ) ||
807 readDbl(line, pos[2], fieldLen, _clock_drift ) ||
808 readDbl(line, pos[3], fieldLen, _clock_driftrate) ) {
809 return;
810 }
811 }
812
813 else if ( iLine == 1 ) {
814 if ( readDbl(line, pos[0], fieldLen, _IODnav ) ||
815 readDbl(line, pos[1], fieldLen, _Crs ) ||
816 readDbl(line, pos[2], fieldLen, _Delta_n) ||
817 readDbl(line, pos[3], fieldLen, _M0 ) ) {
818 return;
819 }
820 }
821
822 else if ( iLine == 2 ) {
823 if ( readDbl(line, pos[0], fieldLen, _Cuc ) ||
824 readDbl(line, pos[1], fieldLen, _e ) ||
825 readDbl(line, pos[2], fieldLen, _Cus ) ||
826 readDbl(line, pos[3], fieldLen, _sqrt_A) ) {
827 return;
828 }
829 }
830
831 else if ( iLine == 3 ) {
832 if ( readDbl(line, pos[0], fieldLen, _TOEsec) ||
833 readDbl(line, pos[1], fieldLen, _Cic ) ||
834 readDbl(line, pos[2], fieldLen, _OMEGA0) ||
835 readDbl(line, pos[3], fieldLen, _Cis ) ) {
836 return;
837 }
838 }
839
840 else if ( iLine == 4 ) {
841 if ( readDbl(line, pos[0], fieldLen, _i0 ) ||
842 readDbl(line, pos[1], fieldLen, _Crc ) ||
843 readDbl(line, pos[2], fieldLen, _omega ) ||
844 readDbl(line, pos[3], fieldLen, _OMEGADOT) ) {
845 return;
846 }
847 }
848
849 else if ( iLine == 5 ) {
850 if ( readDbl(line, pos[0], fieldLen, _IDOT ) ||
851 readDbl(line, pos[2], fieldLen, _TOEweek) ) {
852 return;
853 }
854 }
855
856 else if ( iLine == 6 ) {
857 if ( readDbl(line, pos[0], fieldLen, _SISA ) ||
858 readDbl(line, pos[1], fieldLen, _E5aHS ) ||
859 readDbl(line, pos[2], fieldLen, _BGD_1_5A) ||
860 readDbl(line, pos[3], fieldLen, _BGD_1_5B) ) {
861 return;
862 }
863 }
864
865 else if ( iLine == 7 ) {
866 if ( readDbl(line, pos[0], fieldLen, _TOT) ) {
867 return;
868 }
869 }
870 }
871
872 _ok = true;
873}
874
875//
876//////////////////////////////////////////////////////////////////////////////
877QString t_eph::rinexDateStr(const bncTime& tt, const t_prn& prn, double version) {
878 QString prnStr(prn.toString().c_str());
879 return rinexDateStr(tt, prnStr, version);
880}
881
882//
883//////////////////////////////////////////////////////////////////////////////
884QString t_eph::rinexDateStr(const bncTime& tt, const QString& prnStr, double version) {
885
886 QString datStr;
887
888 unsigned year, month, day, hour, min;
889 double sec;
890 tt.civil_date(year, month, day);
891 tt.civil_time(hour, min, sec);
892
893 QTextStream out(&datStr);
894
895 if (version < 3.0) {
896 QString prnHlp = prnStr.mid(1,2); if (prnHlp[0] == '0') prnHlp[0] = ' ';
897 out << prnHlp << QString(" %1 %2 %3 %4 %5%6")
898 .arg(year % 100, 2, 10, QChar('0'))
899 .arg(month, 2)
900 .arg(day, 2)
901 .arg(hour, 2)
902 .arg(min, 2)
903 .arg(sec, 5, 'f',1);
904 }
905 else {
906 out << prnStr << QString(" %1 %2 %3 %4 %5 %6")
907 .arg(year, 4)
908 .arg(month, 2, 10, QChar('0'))
909 .arg(day, 2, 10, QChar('0'))
910 .arg(hour, 2, 10, QChar('0'))
911 .arg(min, 2, 10, QChar('0'))
912 .arg(int(sec), 2, 10, QChar('0'));
913 }
914
915 return datStr;
916}
917
918// RINEX Format String
919//////////////////////////////////////////////////////////////////////////////
920QString t_ephGPS::toString(double version) const {
921
922 QString rnxStr = rinexDateStr(_TOC, _prn, version);
923
924 QTextStream out(&rnxStr);
925
926 out << QString("%1%2%3\n")
927 .arg(_clock_bias, 19, 'e', 12)
928 .arg(_clock_drift, 19, 'e', 12)
929 .arg(_clock_driftrate, 19, 'e', 12);
930
931 QString fmt = version < 3.0 ? " %1%2%3%4\n" : " %1%2%3%4\n";
932
933 out << QString(fmt)
934 .arg(_IODE, 19, 'e', 12)
935 .arg(_Crs, 19, 'e', 12)
936 .arg(_Delta_n, 19, 'e', 12)
937 .arg(_M0, 19, 'e', 12);
938
939 out << QString(fmt)
940 .arg(_Cuc, 19, 'e', 12)
941 .arg(_e, 19, 'e', 12)
942 .arg(_Cus, 19, 'e', 12)
943 .arg(_sqrt_A, 19, 'e', 12);
944
945 out << QString(fmt)
946 .arg(_TOEsec, 19, 'e', 12)
947 .arg(_Cic, 19, 'e', 12)
948 .arg(_OMEGA0, 19, 'e', 12)
949 .arg(_Cis, 19, 'e', 12);
950
951 out << QString(fmt)
952 .arg(_i0, 19, 'e', 12)
953 .arg(_Crc, 19, 'e', 12)
954 .arg(_omega, 19, 'e', 12)
955 .arg(_OMEGADOT, 19, 'e', 12);
956
957 out << QString(fmt)
958 .arg(_IDOT, 19, 'e', 12)
959 .arg(_L2Codes, 19, 'e', 12)
960 .arg(_TOEweek, 19, 'e', 12)
961 .arg(_L2PFlag, 19, 'e', 12);
962
963 out << QString(fmt)
964 .arg(_ura, 19, 'e', 12)
965 .arg(_health, 19, 'e', 12)
966 .arg(_TGD, 19, 'e', 12)
967 .arg(_IODC, 19, 'e', 12);
968
969 out << QString(fmt)
970 .arg(_TOT, 19, 'e', 12)
971 .arg(_fitInterval, 19, 'e', 12)
972 .arg("", 19, QChar(' '))
973 .arg("", 19, QChar(' '));
974
975 return rnxStr;
976}
977
978// RINEX Format String
979//////////////////////////////////////////////////////////////////////////////
980QString t_ephGlo::toString(double version) const {
981
982 QString rnxStr = rinexDateStr(_TOC-_gps_utc, _prn, version);
983
984 QTextStream out(&rnxStr);
985
986 out << QString("%1%2%3\n")
987 .arg(-_tau, 19, 'e', 12)
988 .arg(_gamma, 19, 'e', 12)
989 .arg(_tki, 19, 'e', 12);
990
991 QString fmt = version < 3.0 ? " %1%2%3%4\n" : " %1%2%3%4\n";
992
993 out << QString(fmt)
994 .arg(_x_pos, 19, 'e', 12)
995 .arg(_x_velocity, 19, 'e', 12)
996 .arg(_x_acceleration, 19, 'e', 12)
997 .arg(_health, 19, 'e', 12);
998
999 out << QString(fmt)
1000 .arg(_y_pos, 19, 'e', 12)
1001 .arg(_y_velocity, 19, 'e', 12)
1002 .arg(_y_acceleration, 19, 'e', 12)
1003 .arg(_frequency_number, 19, 'e', 12);
1004
1005 out << QString(fmt)
1006 .arg(_z_pos, 19, 'e', 12)
1007 .arg(_z_velocity, 19, 'e', 12)
1008 .arg(_z_acceleration, 19, 'e', 12)
1009 .arg(_E, 19, 'e', 12);
1010
1011 return rnxStr;
1012}
1013
1014// RINEX Format String
1015//////////////////////////////////////////////////////////////////////////////
1016QString t_ephGal::toString(double version) const {
1017
1018 QString rnxStr = rinexDateStr(_TOC, _prn, version);
1019
1020 QTextStream out(&rnxStr);
1021
1022 out << QString("%1%2%3\n")
1023 .arg(_clock_bias, 19, 'e', 12)
1024 .arg(_clock_drift, 19, 'e', 12)
1025 .arg(_clock_driftrate, 19, 'e', 12);
1026
1027 QString fmt = version < 3.0 ? " %1%2%3%4\n" : " %1%2%3%4\n";
1028
1029 out << QString(fmt)
1030 .arg(_IODnav, 19, 'e', 12)
1031 .arg(_Crs, 19, 'e', 12)
1032 .arg(_Delta_n, 19, 'e', 12)
1033 .arg(_M0, 19, 'e', 12);
1034
1035 out << QString(fmt)
1036 .arg(_Cuc, 19, 'e', 12)
1037 .arg(_e, 19, 'e', 12)
1038 .arg(_Cus, 19, 'e', 12)
1039 .arg(_sqrt_A, 19, 'e', 12);
1040
1041 out << QString(fmt)
1042 .arg(_TOEsec, 19, 'e', 12)
1043 .arg(_Cic, 19, 'e', 12)
1044 .arg(_OMEGA0, 19, 'e', 12)
1045 .arg(_Cis, 19, 'e', 12);
1046
1047 out << QString(fmt)
1048 .arg(_i0, 19, 'e', 12)
1049 .arg(_Crc, 19, 'e', 12)
1050 .arg(_omega, 19, 'e', 12)
1051 .arg(_OMEGADOT, 19, 'e', 12);
1052
1053 int dataSource = 0;
1054 double HS = 0.0;
1055 if ( (_flags & GALEPHF_INAV) == GALEPHF_INAV ) {
1056 dataSource |= (1<<0);
1057 dataSource |= (1<<9);
1058 HS = _E5bHS;
1059 }
1060 else if ( (_flags & GALEPHF_FNAV) == GALEPHF_FNAV ) {
1061 dataSource |= (1<<1);
1062 dataSource |= (1<<8);
1063 HS = _E5aHS;
1064 }
1065 out << QString(fmt)
1066 .arg(_IDOT, 19, 'e', 12)
1067 .arg(double(dataSource), 19, 'e', 12)
1068 .arg(_TOEweek, 19, 'e', 12)
1069 .arg(0.0, 19, 'e', 12);
1070
1071 out << QString(fmt)
1072 .arg(_SISA, 19, 'e', 12)
1073 .arg(HS, 19, 'e', 12)
1074 .arg(_BGD_1_5A, 19, 'e', 12)
1075 .arg(_BGD_1_5B, 19, 'e', 12);
1076
1077 out << QString(fmt)
1078 .arg(_TOT, 19, 'e', 12)
1079 .arg("", 19, QChar(' '))
1080 .arg("", 19, QChar(' '))
1081 .arg("", 19, QChar(' '));
1082
1083 return rnxStr;
1084}
1085
Note: See TracBrowser for help on using the repository browser.