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

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