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

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