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

Last change on this file since 2429 was 2429, checked in by mervart, 14 years ago

* empty log message *

File size: 8.4 KB
Line 
1#include <math.h>
2#include <sstream>
3#include <iostream>
4#include <iomanip>
5#include <cstring>
6
7#include <newmatio.h>
8
9#include "ephemeris.h"
10#include "bncutils.h"
11#include "timeutils.h"
12#include "bnctime.h"
13
14using namespace std;
15
16//
17////////////////////////////////////////////////////////////////////////////
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
28// Set GPS Satellite Position
29////////////////////////////////////////////////////////////////////////////
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
69// Compute GPS Satellite Position (virtual)
70////////////////////////////////////////////////////////////////////////////
71void t_ephGPS::position(int GPSweek, double GPSweeks,
72 double* xc,
73 double* vv) const {
74
75 static const double secPerWeek = 7 * 86400.0;
76 static const double omegaEarth = 7292115.1467e-11;
77 static const double gmWGS = 398.6005e12;
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 }
124 xc[3] = _clock_bias + _clock_drift*tc + _clock_driftrate*tc*tc;
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;
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;
154}
155
156
157// Derivative of the state vector using a simple force model (static)
158////////////////////////////////////////////////////////////////////////////
159ColumnVector t_ephGlo::glo_deriv(double /* tt */, const ColumnVector& xv) {
160
161 // State vector components
162 // -----------------------
163 ColumnVector rr = xv.rows(1,3);
164 ColumnVector vv = xv.rows(4,6);
165
166 // Acceleration
167 // ------------
168 static const double GM = 398.60044e12;
169 static const double AE = 6378136.0;
170 static const double OMEGA = 7292115.e-11;
171 static const double C20 = -1082.63e-6;
172
173 double rho = rr.norm_Frobenius();
174 double t1 = -GM/(rho*rho*rho);
175 double t2 = 3.0/2.0 * C20 * (GM*AE*AE) / (rho*rho*rho*rho*rho);
176 double t3 = OMEGA * OMEGA;
177 double t4 = 2.0 * OMEGA;
178 double z2 = rr(3) * rr(3);
179
180 // Vector of derivatives
181 // ---------------------
182 ColumnVector va(6);
183 va(1) = vv(1);
184 va(2) = vv(2);
185 va(3) = vv(3);
186 va(4) = (t1 + t2*(1.0-5.0*z2/(rho*rho)) + t3) * rr(1) + t4*vv(2);
187 va(5) = (t1 + t2*(1.0-5.0*z2/(rho*rho)) + t3) * rr(2) - t4*vv(1);
188 va(6) = (t1 + t2*(3.0-5.0*z2/(rho*rho)) ) * rr(3);
189
190 return va;
191}
192
193// Compute Glonass Satellite Position (virtual)
194////////////////////////////////////////////////////////////////////////////
195void t_ephGlo::position(int GPSweek, double GPSweeks,
196 double* xc, double* vv) const {
197
198 static const double secPerWeek = 7 * 86400.0;
199 static const double nominalStep = 10.0;
200
201 memset(xc, 0, 4*sizeof(double));
202 memset(vv, 0, 3*sizeof(double));
203
204 double dtPos = GPSweeks - _tt;
205 if (GPSweek != _GPSweek) {
206 dtPos += (GPSweek - _GPSweek) * secPerWeek;
207 }
208
209 int nSteps = int(fabs(dtPos) / nominalStep) + 1;
210 double step = dtPos / nSteps;
211
212 for (int ii = 1; ii <= nSteps; ii++) {
213 _xv = rungeKutta4(_tt, _xv, step, glo_deriv);
214 _tt += step;
215 }
216
217 // Position and Velocity
218 // ---------------------
219 xc[0] = _xv(1);
220 xc[1] = _xv(2);
221 xc[2] = _xv(3);
222
223 vv[0] = _xv(4);
224 vv[1] = _xv(5);
225 vv[2] = _xv(6);
226
227 // Clock Correction
228 // ----------------
229 double dtClk = GPSweeks - _GPSweeks;
230 if (GPSweek != _GPSweek) {
231 dtClk += (GPSweek - _GPSweek) * secPerWeek;
232 }
233 xc[3] = -_tau + _gamma * dtClk;
234}
235
236// IOD of Glonass Ephemeris (virtual)
237////////////////////////////////////////////////////////////////////////////
238int t_ephGlo::IOD() const {
239
240 bool old = false;
241
242 if (old) { // 5 LSBs of iod are equal to 5 LSBs of tb
243 unsigned int tb = int(fmod(_GPSweeks,86400.0)); //sec of day
244 const int shift = sizeof(tb) * 8 - 5;
245 unsigned int iod = tb << shift;
246 return (iod >> shift);
247 }
248 else {
249 bncTime tGPS(_GPSweek, _GPSweeks);
250 int hlpWeek = _GPSweek;
251 int hlpSec = int(_GPSweeks);
252 int hlpMsec = int(_GPSweeks * 1000);
253 updatetime(&hlpWeek, &hlpSec, hlpMsec, 0);
254 bncTime tHlp(hlpWeek, hlpSec);
255 double diffSec = tGPS - tHlp;
256 bncTime tMoscow = tGPS + diffSec;
257 return int(tMoscow.daysec() / 900);
258 }
259}
260
261// Set Glonass Ephemeris
262////////////////////////////////////////////////////////////////////////////
263void t_ephGlo::set(const glonassephemeris* ee) {
264
265 ostringstream prn;
266 prn << 'R' << setfill('0') << setw(2) << ee->almanac_number;
267 _prn = prn.str();
268
269 int ww = ee->GPSWeek;
270 int tow = ee->GPSTOW;
271 updatetime(&ww, &tow, ee->tb*1000, 0); // Moscow -> GPS
272
273 _GPSweek = ww;
274 _GPSweeks = tow;
275 _E = ee->E;
276 _tau = ee->tau;
277 _gamma = ee->gamma;
278 _x_pos = ee->x_pos;
279 _x_velocity = ee->x_velocity;
280 _x_acceleration = ee->x_acceleration;
281 _y_pos = ee->y_pos;
282 _y_velocity = ee->y_velocity;
283 _y_acceleration = ee->y_acceleration;
284 _z_pos = ee->z_pos;
285 _z_velocity = ee->z_velocity;
286 _z_acceleration = ee->z_acceleration;
287 _health = 0;
288 _frequency_number = ee->frequency_number;
289 _tki = ee->tk-3*60*60; if (_tki < 0) _tki += 86400;
290
291 // Initialize status vector
292 // ------------------------
293 _tt = _GPSweeks;
294
295 _xv(1) = _x_pos * 1.e3;
296 _xv(2) = _y_pos * 1.e3;
297 _xv(3) = _z_pos * 1.e3;
298 _xv(4) = _x_velocity * 1.e3;
299 _xv(5) = _y_velocity * 1.e3;
300 _xv(6) = _z_velocity * 1.e3;
301}
Note: See TracBrowser for help on using the repository browser.