source: ntrip/trunk/BNC/RTCM3/ephemeris.cpp@ 3267

Last change on this file since 3267 was 3267, checked in by mervart, 13 years ago
File size: 21.7 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"
[1025]11#include "timeutils.h"
[2285]12#include "bnctime.h"
[1025]13
14using namespace std;
15
[3255]16#define PI 3.1415926535898
17// Returns nearest integer value
18////////////////////////////////////////////////////////////////////////////
19static double NearestInt(double fl, double * remain)
20{
21 bool isneg = fl < 0.0;
22 double intval;
23 if(isneg) fl *= -1.0;
24 intval = (double)((unsigned long)(fl+0.5));
25 if(isneg) {fl *= -1.0; intval *= -1.0;}
26 if(remain)
27 *remain = fl-intval;
28 return intval;
29} /* NearestInt() */
30
31// Returns CRC24
32////////////////////////////////////////////////////////////////////////////
33static unsigned long CRC24(long size, const unsigned char *buf)
34{
35 unsigned long crc = 0;
36 int i;
37
38 while(size--)
39 {
40 crc ^= (*buf++) << (16);
41 for(i = 0; i < 8; i++)
42 {
43 crc <<= 1;
44 if(crc & 0x1000000)
45 crc ^= 0x01864cfb;
46 }
47 }
48 return crc;
49} /* CRC24 */
50
[2222]51//
52////////////////////////////////////////////////////////////////////////////
[1025]53bool t_eph::isNewerThan(const t_eph* eph) const {
54 if (_GPSweek > eph->_GPSweek ||
55 (_GPSweek == eph->_GPSweek && _GPSweeks > eph->_GPSweeks)) {
56 return true;
57 }
58 else {
59 return false;
60 }
61}
62
[2222]63// Set GPS Satellite Position
64////////////////////////////////////////////////////////////////////////////
[1025]65void t_ephGPS::set(const gpsephemeris* ee) {
66
[3255]67 _prn = QString("G%1").arg(ee->satellite, 2, 10, QChar('0'));
[1025]68
69 // TODO: check if following two lines are correct
70 _GPSweek = ee->GPSweek;
71 _GPSweeks = ee->TOE;
72
73 _TOW = ee->TOW;
74 _TOC = ee->TOC;
75 _TOE = ee->TOE;
76 _IODE = ee->IODE;
77 _IODC = ee->IODC;
78
79 _clock_bias = ee->clock_bias ;
80 _clock_drift = ee->clock_drift ;
81 _clock_driftrate = ee->clock_driftrate;
82
83 _Crs = ee->Crs;
84 _Delta_n = ee->Delta_n;
85 _M0 = ee->M0;
86 _Cuc = ee->Cuc;
87 _e = ee->e;
88 _Cus = ee->Cus;
89 _sqrt_A = ee->sqrt_A;
90 _Cic = ee->Cic;
91 _OMEGA0 = ee->OMEGA0;
92 _Cis = ee->Cis;
93 _i0 = ee->i0;
94 _Crc = ee->Crc;
95 _omega = ee->omega;
96 _OMEGADOT = ee->OMEGADOT;
97 _IDOT = ee->IDOT;
98
99 _TGD = ee->TGD;
100}
101
[2222]102// Compute GPS Satellite Position (virtual)
[1025]103////////////////////////////////////////////////////////////////////////////
104void t_ephGPS::position(int GPSweek, double GPSweeks,
105 double* xc,
106 double* vv) const {
107
[1098]108 static const double secPerWeek = 7 * 86400.0;
109 static const double omegaEarth = 7292115.1467e-11;
110 static const double gmWGS = 398.6005e12;
[1025]111
112 memset(xc, 0, 4*sizeof(double));
113 memset(vv, 0, 3*sizeof(double));
114
115 double a0 = _sqrt_A * _sqrt_A;
116 if (a0 == 0) {
117 return;
118 }
119
120 double n0 = sqrt(gmWGS/(a0*a0*a0));
121 double tk = GPSweeks - _TOE;
122 if (GPSweek != _GPSweek) {
123 tk += (GPSweek - _GPSweek) * secPerWeek;
124 }
125 double n = n0 + _Delta_n;
126 double M = _M0 + n*tk;
127 double E = M;
128 double E_last;
129 do {
130 E_last = E;
131 E = M + _e*sin(E);
132 } while ( fabs(E-E_last)*a0 > 0.001 );
133 double v = 2.0*atan( sqrt( (1.0 + _e)/(1.0 - _e) )*tan( E/2 ) );
134 double u0 = v + _omega;
135 double sin2u0 = sin(2*u0);
136 double cos2u0 = cos(2*u0);
137 double r = a0*(1 - _e*cos(E)) + _Crc*cos2u0 + _Crs*sin2u0;
138 double i = _i0 + _IDOT*tk + _Cic*cos2u0 + _Cis*sin2u0;
139 double u = u0 + _Cuc*cos2u0 + _Cus*sin2u0;
140 double xp = r*cos(u);
141 double yp = r*sin(u);
142 double OM = _OMEGA0 + (_OMEGADOT - omegaEarth)*tk -
143 omegaEarth*_TOE;
144
145 double sinom = sin(OM);
146 double cosom = cos(OM);
147 double sini = sin(i);
148 double cosi = cos(i);
149 xc[0] = xp*cosom - yp*cosi*sinom;
150 xc[1] = xp*sinom + yp*cosi*cosom;
151 xc[2] = yp*sini;
152
153 double tc = GPSweeks - _TOC;
154 if (GPSweek != _GPSweek) {
155 tc += (GPSweek - _GPSweek) * secPerWeek;
156 }
[2429]157 xc[3] = _clock_bias + _clock_drift*tc + _clock_driftrate*tc*tc;
[1025]158
159 // Velocity
160 // --------
161 double tanv2 = tan(v/2);
162 double dEdM = 1 / (1 - _e*cos(E));
163 double dotv = sqrt((1.0 + _e)/(1.0 - _e)) / cos(E/2)/cos(E/2) / (1 + tanv2*tanv2)
164 * dEdM * n;
165 double dotu = dotv + (-_Cuc*sin2u0 + _Cus*cos2u0)*2*dotv;
166 double dotom = _OMEGADOT - omegaEarth;
167 double doti = _IDOT + (-_Cic*sin2u0 + _Cis*cos2u0)*2*dotv;
168 double dotr = a0 * _e*sin(E) * dEdM * n
169 + (-_Crc*sin2u0 + _Crs*cos2u0)*2*dotv;
170 double dotx = dotr*cos(u) - r*sin(u)*dotu;
171 double doty = dotr*sin(u) + r*cos(u)*dotu;
172
173 vv[0] = cosom *dotx - cosi*sinom *doty // dX / dr
174 - xp*sinom*dotom - yp*cosi*cosom*dotom // dX / dOMEGA
175 + yp*sini*sinom*doti; // dX / di
176
177 vv[1] = sinom *dotx + cosi*cosom *doty
178 + xp*cosom*dotom - yp*cosi*sinom*dotom
179 - yp*sini*cosom*doti;
180
181 vv[2] = sini *doty + yp*cosi *doti;
[2429]182
183 // Relativistic Correction
184 // -----------------------
185 // xc(4) -= 4.442807633e-10 * _e * sqrt(a0) *sin(E);
186 xc[3] -= 2.0 * (xc[0]*vv[0] + xc[1]*vv[1] + xc[2]*vv[2]) / t_CST::c / t_CST::c;
[1025]187}
188
[3255]189// build up RTCM3 for GPS
190////////////////////////////////////////////////////////////////////////////
191#define GPSTOINT(type, value) static_cast<type>(NearestInt(value,0))
[1025]192
[3255]193#define GPSADDBITS(a, b) {bitbuffer = (bitbuffer<<(a)) \
194 |(GPSTOINT(long long,b)&((1ULL<<a)-1)); \
195 numbits += (a); \
196 while(numbits >= 8) { \
197 buffer[size++] = bitbuffer>>(numbits-8);numbits -= 8;}}
198#define GPSADDBITSFLOAT(a,b,c) {long long i = GPSTOINT(long long,(b)/(c)); \
199 GPSADDBITS(a,i)};
200
201int t_ephGPS::RTCM3(unsigned char *buffer)
202{
203
204 unsigned char *startbuffer = buffer;
205 buffer= buffer+3;
206 int size = 0;
207 int numbits = 0;
208 unsigned long long bitbuffer = 0;
209 if (_ura <= 2.40){
210 _ura = 0;
211 }
212 else if (_ura <= 3.40){
213 _ura = 1;
214 }
215 else if (_ura <= 6.85){
216 _ura = 2;
217 }
218 else if (_ura <= 9.65){
219 _ura = 3;
220 }
221 else if (_ura <= 13.65){
222 _ura = 4;
223 }
224 else if (_ura <= 24.00){
225 _ura = 5;
226 }
227 else if (_ura <= 48.00){
228 _ura = 6;
229 }
230 else if (_ura <= 96.00){
231 _ura = 7;
232 }
233 else if (_ura <= 192.00){
234 _ura = 8;
235 }
236 else if (_ura <= 384.00){
237 _ura = 9;
238 }
239 else if (_ura <= 768.00){
240 _ura = 10;
241 }
242 else if (_ura <= 1536.00){
243 _ura = 11;
244 }
245 else if (_ura <= 1536.00){
246 _ura = 12;
247 }
248 else if (_ura <= 2072.00){
249 _ura = 13;
250 }
251 else if (_ura <= 6144.00){
252 _ura = 14;
253 }
254 else{
255 _ura = 15;
256 }
257
258 GPSADDBITS(12, 1019)
259 GPSADDBITS(6,_prn.right((_prn.length()-1)).toInt())
260 GPSADDBITS(10, _GPSweek)
261 GPSADDBITS(4, _ura)
262 GPSADDBITS(2,_L2Codes)
263 GPSADDBITSFLOAT(14, _IDOT, PI/static_cast<double>(1<<30)
264 /static_cast<double>(1<<13))
265 GPSADDBITS(8, _IODE)
266 GPSADDBITS(16, static_cast<int>(_TOC)>>4)
267 GPSADDBITSFLOAT(8, _clock_driftrate, 1.0/static_cast<double>(1<<30)
268 /static_cast<double>(1<<25))
269 GPSADDBITSFLOAT(16, _clock_drift, 1.0/static_cast<double>(1<<30)
270 /static_cast<double>(1<<13))
271 GPSADDBITSFLOAT(22, _clock_bias, 1.0/static_cast<double>(1<<30)
272 /static_cast<double>(1<<1))
273 GPSADDBITS(10, _IODC)
274 GPSADDBITSFLOAT(16, _Crs, 1.0/static_cast<double>(1<<5))
275 GPSADDBITSFLOAT(16, _Delta_n, PI/static_cast<double>(1<<30)
276 /static_cast<double>(1<<13))
277 GPSADDBITSFLOAT(32, _M0, PI/static_cast<double>(1<<30)/static_cast<double>(1<<1))
278 GPSADDBITSFLOAT(16, _Cuc, 1.0/static_cast<double>(1<<29))
279 GPSADDBITSFLOAT(32, _e, 1.0/static_cast<double>(1<<30)/static_cast<double>(1<<3))
280 GPSADDBITSFLOAT(16, _Cus, 1.0/static_cast<double>(1<<29))
281 GPSADDBITSFLOAT(32, _sqrt_A, 1.0/static_cast<double>(1<<19))
282 GPSADDBITS(16, static_cast<int>(_TOE)>>4)
283 GPSADDBITSFLOAT(16, _Cic, 1.0/static_cast<double>(1<<29))
284 GPSADDBITSFLOAT(32, _OMEGA0, PI/static_cast<double>(1<<30)
285 /static_cast<double>(1<<1))
286 GPSADDBITSFLOAT(16, _Cis, 1.0/static_cast<double>(1<<29))
287 GPSADDBITSFLOAT(32, _i0, PI/static_cast<double>(1<<30)/static_cast<double>(1<<1))
288 GPSADDBITSFLOAT(16, _Crc, 1.0/static_cast<double>(1<<5))
289 GPSADDBITSFLOAT(32, _omega, PI/static_cast<double>(1<<30)
290 /static_cast<double>(1<<1))
291 GPSADDBITSFLOAT(24, _OMEGADOT, PI/static_cast<double>(1<<30)
292 /static_cast<double>(1<<13))
293 GPSADDBITSFLOAT(8, _TGD, 1.0/static_cast<double>(1<<30)/static_cast<double>(1<<1))
294 GPSADDBITS(6, _health)
295 GPSADDBITS(1, _L2PFlag)
296 GPSADDBITS(1, 0) /* GPS fit interval */
297
298 startbuffer[0]=0xD3;
299 startbuffer[1]=(size >> 8);
300 startbuffer[2]=size;
301 unsigned long i = CRC24(size+3, startbuffer);
302 buffer[size++] = i >> 16;
303 buffer[size++] = i >> 8;
304 buffer[size++] = i;
305 size += 3;
306 return size;
307}
308
[2221]309// Derivative of the state vector using a simple force model (static)
310////////////////////////////////////////////////////////////////////////////
[2556]311ColumnVector t_ephGlo::glo_deriv(double /* tt */, const ColumnVector& xv,
312 double* acc) {
[2221]313
314 // State vector components
315 // -----------------------
316 ColumnVector rr = xv.rows(1,3);
317 ColumnVector vv = xv.rows(4,6);
318
319 // Acceleration
320 // ------------
321 static const double GM = 398.60044e12;
322 static const double AE = 6378136.0;
323 static const double OMEGA = 7292115.e-11;
[2561]324 static const double C20 = -1082.6257e-6;
[2221]325
326 double rho = rr.norm_Frobenius();
327 double t1 = -GM/(rho*rho*rho);
328 double t2 = 3.0/2.0 * C20 * (GM*AE*AE) / (rho*rho*rho*rho*rho);
329 double t3 = OMEGA * OMEGA;
330 double t4 = 2.0 * OMEGA;
331 double z2 = rr(3) * rr(3);
332
333 // Vector of derivatives
334 // ---------------------
335 ColumnVector va(6);
336 va(1) = vv(1);
337 va(2) = vv(2);
338 va(3) = vv(3);
[2556]339 va(4) = (t1 + t2*(1.0-5.0*z2/(rho*rho)) + t3) * rr(1) + t4*vv(2) + acc[0];
340 va(5) = (t1 + t2*(1.0-5.0*z2/(rho*rho)) + t3) * rr(2) - t4*vv(1) + acc[1];
341 va(6) = (t1 + t2*(3.0-5.0*z2/(rho*rho)) ) * rr(3) + acc[2];
[2221]342
343 return va;
344}
345
346// Compute Glonass Satellite Position (virtual)
347////////////////////////////////////////////////////////////////////////////
348void t_ephGlo::position(int GPSweek, double GPSweeks,
349 double* xc, double* vv) const {
350
351 static const double secPerWeek = 7 * 86400.0;
352 static const double nominalStep = 10.0;
353
354 memset(xc, 0, 4*sizeof(double));
355 memset(vv, 0, 3*sizeof(double));
356
357 double dtPos = GPSweeks - _tt;
358 if (GPSweek != _GPSweek) {
359 dtPos += (GPSweek - _GPSweek) * secPerWeek;
360 }
361
362 int nSteps = int(fabs(dtPos) / nominalStep) + 1;
363 double step = dtPos / nSteps;
364
[2556]365 double acc[3];
[2557]366 acc[0] = _x_acceleration * 1.e3;
[2560]367 acc[1] = _y_acceleration * 1.e3;
368 acc[2] = _z_acceleration * 1.e3;
[2221]369 for (int ii = 1; ii <= nSteps; ii++) {
[2556]370 _xv = rungeKutta4(_tt, _xv, step, acc, glo_deriv);
[2221]371 _tt += step;
372 }
373
374 // Position and Velocity
375 // ---------------------
376 xc[0] = _xv(1);
377 xc[1] = _xv(2);
378 xc[2] = _xv(3);
379
380 vv[0] = _xv(4);
381 vv[1] = _xv(5);
382 vv[2] = _xv(6);
383
384 // Clock Correction
385 // ----------------
386 double dtClk = GPSweeks - _GPSweeks;
387 if (GPSweek != _GPSweek) {
388 dtClk += (GPSweek - _GPSweek) * secPerWeek;
389 }
390 xc[3] = -_tau + _gamma * dtClk;
391}
392
393// IOD of Glonass Ephemeris (virtual)
394////////////////////////////////////////////////////////////////////////////
395int t_ephGlo::IOD() const {
396
[2285]397 bool old = false;
[2221]398
399 if (old) { // 5 LSBs of iod are equal to 5 LSBs of tb
400 unsigned int tb = int(fmod(_GPSweeks,86400.0)); //sec of day
401 const int shift = sizeof(tb) * 8 - 5;
402 unsigned int iod = tb << shift;
403 return (iod >> shift);
404 }
405 else {
[2285]406 bncTime tGPS(_GPSweek, _GPSweeks);
407 int hlpWeek = _GPSweek;
408 int hlpSec = int(_GPSweeks);
409 int hlpMsec = int(_GPSweeks * 1000);
410 updatetime(&hlpWeek, &hlpSec, hlpMsec, 0);
411 bncTime tHlp(hlpWeek, hlpSec);
412 double diffSec = tGPS - tHlp;
413 bncTime tMoscow = tGPS + diffSec;
414 return int(tMoscow.daysec() / 900);
[2221]415 }
416}
417
418// Set Glonass Ephemeris
419////////////////////////////////////////////////////////////////////////////
420void t_ephGlo::set(const glonassephemeris* ee) {
421
[3255]422 _prn = QString("R%1").arg(ee->almanac_number, 2, 10, QChar('0'));
[2223]423
[2234]424 int ww = ee->GPSWeek;
425 int tow = ee->GPSTOW;
[2257]426 updatetime(&ww, &tow, ee->tb*1000, 0); // Moscow -> GPS
[2223]427
[3264]428 // Check the day once more
429 // -----------------------
430 {
[3266]431 int ww_old = ww;
432 int tow_old = tow;
[3264]433 int currentWeek;
434 double currentSec;
435 currentGPSWeeks(currentWeek, currentSec);
436 bncTime currentTime(currentWeek, currentSec);
437 bncTime hTime(ww, (double) tow);
[3267]438 bncTime oldHTime = hTime;
[3264]439
440 bool changed = false;
441 if (hTime - currentTime > 12 * 3600.0) {
442 changed = true;
443 hTime = hTime - 24 * 3600.0;
444 ww = hTime.gpsw();
[3265]445 tow = (int) hTime.gpssec();
446 updatetime(&ww, &tow, ee->tb*1000, 0); // Moscow -> GPS
[3264]447 }
448 else if (hTime - currentTime < 12 * 3600.0) {
449 changed = true;
450 hTime = hTime + 24 * 3600.0;
451 ww = hTime.gpsw();
[3265]452 tow = (int) hTime.gpssec();
453 updatetime(&ww, &tow, ee->tb*1000, 0); // Moscow -> GPS
[3264]454 }
455
456 if (changed) {
[3265]457 bncTime newHTime(ww, (double) tow);
[3266]458 cout << "GLONASS Time Changed at "
459 << currentTime.datestr() << " " << currentTime.timestr()
460 << endl
[3267]461 << "old: " << oldHTime.datestr() << " " << oldHTime.timestr()
[3266]462 << endl
463 << "new: " << newHTime.datestr() << " " << newHTime.timestr()
464 << endl
465 << "eph: " << ee->GPSWeek << " " << ee->GPSTOW << " " << ee->tb
466 << endl
467 << "ww, tow (old): " << ww_old << " " << tow_old
468 << endl
469 << "ww, tow (new): " << ww << " " << tow
[3267]470 << endl << endl;
[3264]471 }
472 }
473
[3263]474 bncTime hlpTime(ww, (double) tow);
[3255]475 unsigned year, month, day;
476 hlpTime.civil_date(year, month, day);
477 _gps_utc = gnumleap(year, month, day);
478
[2234]479 _GPSweek = ww;
480 _GPSweeks = tow;
[2223]481 _E = ee->E;
482 _tau = ee->tau;
483 _gamma = ee->gamma;
484 _x_pos = ee->x_pos;
485 _x_velocity = ee->x_velocity;
486 _x_acceleration = ee->x_acceleration;
487 _y_pos = ee->y_pos;
488 _y_velocity = ee->y_velocity;
489 _y_acceleration = ee->y_acceleration;
490 _z_pos = ee->z_pos;
491 _z_velocity = ee->z_velocity;
492 _z_acceleration = ee->z_acceleration;
493 _health = 0;
494 _frequency_number = ee->frequency_number;
[2257]495 _tki = ee->tk-3*60*60; if (_tki < 0) _tki += 86400;
[2223]496
497 // Initialize status vector
498 // ------------------------
499 _tt = _GPSweeks;
500
501 _xv(1) = _x_pos * 1.e3;
502 _xv(2) = _y_pos * 1.e3;
503 _xv(3) = _z_pos * 1.e3;
504 _xv(4) = _x_velocity * 1.e3;
505 _xv(5) = _y_velocity * 1.e3;
506 _xv(6) = _z_velocity * 1.e3;
[2221]507}
[2771]508
[3255]509// build up RTCM3 for GLONASS
510////////////////////////////////////////////////////////////////////////////
511#define GLONASSTOINT(type, value) static_cast<type>(NearestInt(value,0))
512
513#define GLONASSADDBITS(a, b) {bitbuffer = (bitbuffer<<(a)) \
514 |(GLONASSTOINT(long long,b)&((1ULL<<(a))-1)); \
515 numbits += (a); \
516 while(numbits >= 8) { \
517 buffer[size++] = bitbuffer>>(numbits-8);numbits -= 8;}}
518#define GLONASSADDBITSFLOATM(a,b,c) {int s; long long i; \
519 if(b < 0.0) \
520 { \
521 s = 1; \
522 i = GLONASSTOINT(long long,(-b)/(c)); \
523 if(!i) s = 0; \
524 } \
525 else \
526 { \
527 s = 0; \
528 i = GLONASSTOINT(long long,(b)/(c)); \
529 } \
530 GLONASSADDBITS(1,s) \
531 GLONASSADDBITS(a-1,i)}
532
533int t_ephGlo::RTCM3(unsigned char *buffer)
534{
535
536 int size = 0;
537 int numbits = 0;
538 long long bitbuffer = 0;
539 unsigned char *startbuffer = buffer;
540 buffer= buffer+3;
541
542 GLONASSADDBITS(12, 1020)
543 GLONASSADDBITS(6, _prn.right((_prn.length()-1)).toInt())
544 GLONASSADDBITS(5, 7+_frequency_number)
545 GLONASSADDBITS(1, 0)
546 GLONASSADDBITS(1, 0)
547 GLONASSADDBITS(2, 0)
548 _tki=_tki+3*60*60;
549 GLONASSADDBITS(5, static_cast<int>(_tki)/(60*60))
550 GLONASSADDBITS(6, (static_cast<int>(_tki)/60)%60)
551 GLONASSADDBITS(1, (static_cast<int>(_tki)/30)%30)
552 GLONASSADDBITS(1, _health)
553 GLONASSADDBITS(1, 0)
554 unsigned long long timeofday = (static_cast<int>(_tt+3*60*60-_gps_utc)%86400);
555 GLONASSADDBITS(7, timeofday/60/15)
556 GLONASSADDBITSFLOATM(24, _x_velocity*1000, 1000.0/static_cast<double>(1<<20))
557 GLONASSADDBITSFLOATM(27, _x_pos*1000, 1000.0/static_cast<double>(1<<11))
558 GLONASSADDBITSFLOATM(5, _x_acceleration*1000, 1000.0/static_cast<double>(1<<30))
559 GLONASSADDBITSFLOATM(24, _y_velocity*1000, 1000.0/static_cast<double>(1<<20))
560 GLONASSADDBITSFLOATM(27, _y_pos*1000, 1000.0/static_cast<double>(1<<11))
561 GLONASSADDBITSFLOATM(5, _y_acceleration*1000, 1000.0/static_cast<double>(1<<30))
562 GLONASSADDBITSFLOATM(24, _z_velocity*1000, 1000.0/static_cast<double>(1<<20))
563 GLONASSADDBITSFLOATM(27,_z_pos*1000, 1000.0/static_cast<double>(1<<11))
564 GLONASSADDBITSFLOATM(5, _z_acceleration*1000, 1000.0/static_cast<double>(1<<30))
565 GLONASSADDBITS(1, 0)
566 GLONASSADDBITSFLOATM(11, _gamma, 1.0/static_cast<double>(1<<30)
567 /static_cast<double>(1<<10))
568 GLONASSADDBITS(2, 0) /* GLONASS-M P */
569 GLONASSADDBITS(1, 0) /* GLONASS-M ln(3) */
570 GLONASSADDBITSFLOATM(22, _tau, 1.0/static_cast<double>(1<<30))
571 GLONASSADDBITS(5, 0) /* GLONASS-M delta tau */
572 GLONASSADDBITS(5, _E)
573 GLONASSADDBITS(1, 0) /* GLONASS-M P4 */
574 GLONASSADDBITS(4, 0) /* GLONASS-M FT */
575 GLONASSADDBITS(11, 0) /* GLONASS-M NT */
576 GLONASSADDBITS(2, 0) /* GLONASS-M active? */
577 GLONASSADDBITS(1, 0) /* GLONASS additional data */
578 GLONASSADDBITS(11, 0) /* GLONASS NA */
579 GLONASSADDBITS(32, 0) /* GLONASS tau C */
580 GLONASSADDBITS(5, 0) /* GLONASS-M N4 */
581 GLONASSADDBITS(22, 0) /* GLONASS-M tau GPS */
582 GLONASSADDBITS(1, 0) /* GLONASS-M ln(5) */
583 GLONASSADDBITS(7, 0) /* Reserved */
584
585 startbuffer[0]=0xD3;
586 startbuffer[1]=(size >> 8);
587 startbuffer[2]=size;
588 unsigned long i = CRC24(size+3, startbuffer);
589 buffer[size++] = i >> 16;
590 buffer[size++] = i >> 8;
591 buffer[size++] = i;
592 size += 3;
593 return size;
594}
595
[2771]596// Set Galileo Satellite Position
597////////////////////////////////////////////////////////////////////////////
598void t_ephGal::set(const galileoephemeris* ee) {
599
[3255]600 _prn = QString("E%1").arg(ee->satellite, 2, 10, QChar('0'));
[2771]601
602 _GPSweek = ee->Week;
603 _GPSweeks = ee->TOE;
604
605 _TOC = ee->TOC;
606 _TOE = ee->TOE;
607 _IODnav = ee->IODnav;
608
609 _clock_bias = ee->clock_bias ;
610 _clock_drift = ee->clock_drift ;
611 _clock_driftrate = ee->clock_driftrate;
612
613 _Crs = ee->Crs;
614 _Delta_n = ee->Delta_n;
615 _M0 = ee->M0;
616 _Cuc = ee->Cuc;
617 _e = ee->e;
618 _Cus = ee->Cus;
619 _sqrt_A = ee->sqrt_A;
620 _Cic = ee->Cic;
621 _OMEGA0 = ee->OMEGA0;
622 _Cis = ee->Cis;
623 _i0 = ee->i0;
624 _Crc = ee->Crc;
625 _omega = ee->omega;
626 _OMEGADOT = ee->OMEGADOT;
627 _IDOT = ee->IDOT;
628}
629
630// Compute Galileo Satellite Position (virtual)
631////////////////////////////////////////////////////////////////////////////
632void t_ephGal::position(int GPSweek, double GPSweeks,
633 double* xc,
634 double* vv) const {
635
636 static const double secPerWeek = 7 * 86400.0;
637 static const double omegaEarth = 7292115.1467e-11;
638 static const double gmWGS = 398.6005e12;
639
640 memset(xc, 0, 4*sizeof(double));
641 memset(vv, 0, 3*sizeof(double));
642
643 double a0 = _sqrt_A * _sqrt_A;
644 if (a0 == 0) {
645 return;
646 }
647
648 double n0 = sqrt(gmWGS/(a0*a0*a0));
649 double tk = GPSweeks - _TOE;
650 if (GPSweek != _GPSweek) {
651 tk += (GPSweek - _GPSweek) * secPerWeek;
652 }
653 double n = n0 + _Delta_n;
654 double M = _M0 + n*tk;
655 double E = M;
656 double E_last;
657 do {
658 E_last = E;
659 E = M + _e*sin(E);
660 } while ( fabs(E-E_last)*a0 > 0.001 );
661 double v = 2.0*atan( sqrt( (1.0 + _e)/(1.0 - _e) )*tan( E/2 ) );
662 double u0 = v + _omega;
663 double sin2u0 = sin(2*u0);
664 double cos2u0 = cos(2*u0);
665 double r = a0*(1 - _e*cos(E)) + _Crc*cos2u0 + _Crs*sin2u0;
666 double i = _i0 + _IDOT*tk + _Cic*cos2u0 + _Cis*sin2u0;
667 double u = u0 + _Cuc*cos2u0 + _Cus*sin2u0;
668 double xp = r*cos(u);
669 double yp = r*sin(u);
670 double OM = _OMEGA0 + (_OMEGADOT - omegaEarth)*tk -
671 omegaEarth*_TOE;
672
673 double sinom = sin(OM);
674 double cosom = cos(OM);
675 double sini = sin(i);
676 double cosi = cos(i);
677 xc[0] = xp*cosom - yp*cosi*sinom;
678 xc[1] = xp*sinom + yp*cosi*cosom;
679 xc[2] = yp*sini;
680
681 double tc = GPSweeks - _TOC;
682 if (GPSweek != _GPSweek) {
683 tc += (GPSweek - _GPSweek) * secPerWeek;
684 }
685 xc[3] = _clock_bias + _clock_drift*tc + _clock_driftrate*tc*tc;
686
687 // Velocity
688 // --------
689 double tanv2 = tan(v/2);
690 double dEdM = 1 / (1 - _e*cos(E));
691 double dotv = sqrt((1.0 + _e)/(1.0 - _e)) / cos(E/2)/cos(E/2) / (1 + tanv2*tanv2)
692 * dEdM * n;
693 double dotu = dotv + (-_Cuc*sin2u0 + _Cus*cos2u0)*2*dotv;
694 double dotom = _OMEGADOT - omegaEarth;
695 double doti = _IDOT + (-_Cic*sin2u0 + _Cis*cos2u0)*2*dotv;
696 double dotr = a0 * _e*sin(E) * dEdM * n
697 + (-_Crc*sin2u0 + _Crs*cos2u0)*2*dotv;
698 double dotx = dotr*cos(u) - r*sin(u)*dotu;
699 double doty = dotr*sin(u) + r*cos(u)*dotu;
700
701 vv[0] = cosom *dotx - cosi*sinom *doty // dX / dr
702 - xp*sinom*dotom - yp*cosi*cosom*dotom // dX / dOMEGA
703 + yp*sini*sinom*doti; // dX / di
704
705 vv[1] = sinom *dotx + cosi*cosom *doty
706 + xp*cosom*dotom - yp*cosi*sinom*dotom
707 - yp*sini*cosom*doti;
708
709 vv[2] = sini *doty + yp*cosi *doti;
710
711 // Relativistic Correction
712 // -----------------------
713 // xc(4) -= 4.442807633e-10 * _e * sqrt(a0) *sin(E);
714 xc[3] -= 2.0 * (xc[0]*vv[0] + xc[1]*vv[1] + xc[2]*vv[2]) / t_CST::c / t_CST::c;
715}
716
[3255]717// build up RTCM3 for Galileo
718////////////////////////////////////////////////////////////////////////////
719int t_ephGal::RTCM3(unsigned char *buffer) {
720
721 return 0;
722}
Note: See TracBrowser for help on using the repository browser.