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

Last change on this file since 2675 was 2561, checked in by mervart, 14 years ago
File size: 8.6 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
[2222]16//
17////////////////////////////////////////////////////////////////////////////
[1025]18bool t_eph::isNewerThan(const t_eph* eph) const {
19 if (_GPSweek > eph->_GPSweek ||
20 (_GPSweek == eph->_GPSweek && _GPSweeks > eph->_GPSweeks)) {
21 return true;
22 }
23 else {
24 return false;
25 }
26}
27
[2222]28// Set GPS Satellite Position
29////////////////////////////////////////////////////////////////////////////
[1025]30void t_ephGPS::set(const gpsephemeris* ee) {
31 ostringstream prn;
32 prn << 'G' << setfill('0') << setw(2) << ee->satellite;
33
34 _prn = prn.str();
35
36 // TODO: check if following two lines are correct
37 _GPSweek = ee->GPSweek;
38 _GPSweeks = ee->TOE;
39
40 _TOW = ee->TOW;
41 _TOC = ee->TOC;
42 _TOE = ee->TOE;
43 _IODE = ee->IODE;
44 _IODC = ee->IODC;
45
46 _clock_bias = ee->clock_bias ;
47 _clock_drift = ee->clock_drift ;
48 _clock_driftrate = ee->clock_driftrate;
49
50 _Crs = ee->Crs;
51 _Delta_n = ee->Delta_n;
52 _M0 = ee->M0;
53 _Cuc = ee->Cuc;
54 _e = ee->e;
55 _Cus = ee->Cus;
56 _sqrt_A = ee->sqrt_A;
57 _Cic = ee->Cic;
58 _OMEGA0 = ee->OMEGA0;
59 _Cis = ee->Cis;
60 _i0 = ee->i0;
61 _Crc = ee->Crc;
62 _omega = ee->omega;
63 _OMEGADOT = ee->OMEGADOT;
64 _IDOT = ee->IDOT;
65
66 _TGD = ee->TGD;
67}
68
[2222]69// Compute GPS Satellite Position (virtual)
[1025]70////////////////////////////////////////////////////////////////////////////
71void t_ephGPS::position(int GPSweek, double GPSweeks,
72 double* xc,
73 double* vv) const {
74
[1098]75 static const double secPerWeek = 7 * 86400.0;
76 static const double omegaEarth = 7292115.1467e-11;
77 static const double gmWGS = 398.6005e12;
[1025]78
79 memset(xc, 0, 4*sizeof(double));
80 memset(vv, 0, 3*sizeof(double));
81
82 double a0 = _sqrt_A * _sqrt_A;
83 if (a0 == 0) {
84 return;
85 }
86
87 double n0 = sqrt(gmWGS/(a0*a0*a0));
88 double tk = GPSweeks - _TOE;
89 if (GPSweek != _GPSweek) {
90 tk += (GPSweek - _GPSweek) * secPerWeek;
91 }
92 double n = n0 + _Delta_n;
93 double M = _M0 + n*tk;
94 double E = M;
95 double E_last;
96 do {
97 E_last = E;
98 E = M + _e*sin(E);
99 } while ( fabs(E-E_last)*a0 > 0.001 );
100 double v = 2.0*atan( sqrt( (1.0 + _e)/(1.0 - _e) )*tan( E/2 ) );
101 double u0 = v + _omega;
102 double sin2u0 = sin(2*u0);
103 double cos2u0 = cos(2*u0);
104 double r = a0*(1 - _e*cos(E)) + _Crc*cos2u0 + _Crs*sin2u0;
105 double i = _i0 + _IDOT*tk + _Cic*cos2u0 + _Cis*sin2u0;
106 double u = u0 + _Cuc*cos2u0 + _Cus*sin2u0;
107 double xp = r*cos(u);
108 double yp = r*sin(u);
109 double OM = _OMEGA0 + (_OMEGADOT - omegaEarth)*tk -
110 omegaEarth*_TOE;
111
112 double sinom = sin(OM);
113 double cosom = cos(OM);
114 double sini = sin(i);
115 double cosi = cos(i);
116 xc[0] = xp*cosom - yp*cosi*sinom;
117 xc[1] = xp*sinom + yp*cosi*cosom;
118 xc[2] = yp*sini;
119
120 double tc = GPSweeks - _TOC;
121 if (GPSweek != _GPSweek) {
122 tc += (GPSweek - _GPSweek) * secPerWeek;
123 }
[2429]124 xc[3] = _clock_bias + _clock_drift*tc + _clock_driftrate*tc*tc;
[1025]125
126 // Velocity
127 // --------
128 double tanv2 = tan(v/2);
129 double dEdM = 1 / (1 - _e*cos(E));
130 double dotv = sqrt((1.0 + _e)/(1.0 - _e)) / cos(E/2)/cos(E/2) / (1 + tanv2*tanv2)
131 * dEdM * n;
132 double dotu = dotv + (-_Cuc*sin2u0 + _Cus*cos2u0)*2*dotv;
133 double dotom = _OMEGADOT - omegaEarth;
134 double doti = _IDOT + (-_Cic*sin2u0 + _Cis*cos2u0)*2*dotv;
135 double dotr = a0 * _e*sin(E) * dEdM * n
136 + (-_Crc*sin2u0 + _Crs*cos2u0)*2*dotv;
137 double dotx = dotr*cos(u) - r*sin(u)*dotu;
138 double doty = dotr*sin(u) + r*cos(u)*dotu;
139
140 vv[0] = cosom *dotx - cosi*sinom *doty // dX / dr
141 - xp*sinom*dotom - yp*cosi*cosom*dotom // dX / dOMEGA
142 + yp*sini*sinom*doti; // dX / di
143
144 vv[1] = sinom *dotx + cosi*cosom *doty
145 + xp*cosom*dotom - yp*cosi*sinom*dotom
146 - yp*sini*cosom*doti;
147
148 vv[2] = sini *doty + yp*cosi *doti;
[2429]149
150 // Relativistic Correction
151 // -----------------------
152 // xc(4) -= 4.442807633e-10 * _e * sqrt(a0) *sin(E);
153 xc[3] -= 2.0 * (xc[0]*vv[0] + xc[1]*vv[1] + xc[2]*vv[2]) / t_CST::c / t_CST::c;
[1025]154}
155
156
[2221]157// Derivative of the state vector using a simple force model (static)
158////////////////////////////////////////////////////////////////////////////
[2556]159ColumnVector t_ephGlo::glo_deriv(double /* tt */, const ColumnVector& xv,
160 double* acc) {
[2221]161
162 // State vector components
163 // -----------------------
164 ColumnVector rr = xv.rows(1,3);
165 ColumnVector vv = xv.rows(4,6);
166
167 // Acceleration
168 // ------------
169 static const double GM = 398.60044e12;
170 static const double AE = 6378136.0;
171 static const double OMEGA = 7292115.e-11;
[2561]172 static const double C20 = -1082.6257e-6;
[2221]173
174 double rho = rr.norm_Frobenius();
175 double t1 = -GM/(rho*rho*rho);
176 double t2 = 3.0/2.0 * C20 * (GM*AE*AE) / (rho*rho*rho*rho*rho);
177 double t3 = OMEGA * OMEGA;
178 double t4 = 2.0 * OMEGA;
179 double z2 = rr(3) * rr(3);
180
181 // Vector of derivatives
182 // ---------------------
183 ColumnVector va(6);
184 va(1) = vv(1);
185 va(2) = vv(2);
186 va(3) = vv(3);
[2556]187 va(4) = (t1 + t2*(1.0-5.0*z2/(rho*rho)) + t3) * rr(1) + t4*vv(2) + acc[0];
188 va(5) = (t1 + t2*(1.0-5.0*z2/(rho*rho)) + t3) * rr(2) - t4*vv(1) + acc[1];
189 va(6) = (t1 + t2*(3.0-5.0*z2/(rho*rho)) ) * rr(3) + acc[2];
[2221]190
191 return va;
192}
193
194// Compute Glonass Satellite Position (virtual)
195////////////////////////////////////////////////////////////////////////////
196void t_ephGlo::position(int GPSweek, double GPSweeks,
197 double* xc, double* vv) const {
198
199 static const double secPerWeek = 7 * 86400.0;
200 static const double nominalStep = 10.0;
201
202 memset(xc, 0, 4*sizeof(double));
203 memset(vv, 0, 3*sizeof(double));
204
205 double dtPos = GPSweeks - _tt;
206 if (GPSweek != _GPSweek) {
207 dtPos += (GPSweek - _GPSweek) * secPerWeek;
208 }
209
210 int nSteps = int(fabs(dtPos) / nominalStep) + 1;
211 double step = dtPos / nSteps;
212
[2556]213 double acc[3];
[2557]214 acc[0] = _x_acceleration * 1.e3;
[2560]215 acc[1] = _y_acceleration * 1.e3;
216 acc[2] = _z_acceleration * 1.e3;
[2221]217 for (int ii = 1; ii <= nSteps; ii++) {
[2556]218 _xv = rungeKutta4(_tt, _xv, step, acc, glo_deriv);
[2221]219 _tt += step;
220 }
221
222 // Position and Velocity
223 // ---------------------
224 xc[0] = _xv(1);
225 xc[1] = _xv(2);
226 xc[2] = _xv(3);
227
228 vv[0] = _xv(4);
229 vv[1] = _xv(5);
230 vv[2] = _xv(6);
231
232 // Clock Correction
233 // ----------------
234 double dtClk = GPSweeks - _GPSweeks;
235 if (GPSweek != _GPSweek) {
236 dtClk += (GPSweek - _GPSweek) * secPerWeek;
237 }
238 xc[3] = -_tau + _gamma * dtClk;
239}
240
241// IOD of Glonass Ephemeris (virtual)
242////////////////////////////////////////////////////////////////////////////
243int t_ephGlo::IOD() const {
244
[2285]245 bool old = false;
[2221]246
247 if (old) { // 5 LSBs of iod are equal to 5 LSBs of tb
248 unsigned int tb = int(fmod(_GPSweeks,86400.0)); //sec of day
249 const int shift = sizeof(tb) * 8 - 5;
250 unsigned int iod = tb << shift;
251 return (iod >> shift);
252 }
253 else {
[2285]254 bncTime tGPS(_GPSweek, _GPSweeks);
255 int hlpWeek = _GPSweek;
256 int hlpSec = int(_GPSweeks);
257 int hlpMsec = int(_GPSweeks * 1000);
258 updatetime(&hlpWeek, &hlpSec, hlpMsec, 0);
259 bncTime tHlp(hlpWeek, hlpSec);
260 double diffSec = tGPS - tHlp;
261 bncTime tMoscow = tGPS + diffSec;
262 return int(tMoscow.daysec() / 900);
[2221]263 }
264}
265
266// Set Glonass Ephemeris
267////////////////////////////////////////////////////////////////////////////
268void t_ephGlo::set(const glonassephemeris* ee) {
269
[2223]270 ostringstream prn;
271 prn << 'R' << setfill('0') << setw(2) << ee->almanac_number;
272 _prn = prn.str();
273
[2234]274 int ww = ee->GPSWeek;
275 int tow = ee->GPSTOW;
[2257]276 updatetime(&ww, &tow, ee->tb*1000, 0); // Moscow -> GPS
[2223]277
[2234]278 _GPSweek = ww;
279 _GPSweeks = tow;
[2223]280 _E = ee->E;
281 _tau = ee->tau;
282 _gamma = ee->gamma;
283 _x_pos = ee->x_pos;
284 _x_velocity = ee->x_velocity;
285 _x_acceleration = ee->x_acceleration;
286 _y_pos = ee->y_pos;
287 _y_velocity = ee->y_velocity;
288 _y_acceleration = ee->y_acceleration;
289 _z_pos = ee->z_pos;
290 _z_velocity = ee->z_velocity;
291 _z_acceleration = ee->z_acceleration;
292 _health = 0;
293 _frequency_number = ee->frequency_number;
[2257]294 _tki = ee->tk-3*60*60; if (_tki < 0) _tki += 86400;
[2223]295
296 // Initialize status vector
297 // ------------------------
298 _tt = _GPSweeks;
299
300 _xv(1) = _x_pos * 1.e3;
301 _xv(2) = _y_pos * 1.e3;
302 _xv(3) = _z_pos * 1.e3;
303 _xv(4) = _x_velocity * 1.e3;
304 _xv(5) = _y_velocity * 1.e3;
305 _xv(6) = _z_velocity * 1.e3;
[2221]306}
Note: See TracBrowser for help on using the repository browser.