00001 #pragma ident "$Id: TabularEphemerisStore.cpp 2741 2011-06-22 16:37:02Z nwu $"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00047 #include "TabularEphemerisStore.hpp"
00048 #include "MiscMath.hpp"
00049 #include "ECEF.hpp"
00050 #include "icd_200_constants.hpp"
00051
00052 using namespace gpstk::StringUtils;
00053
00054 namespace gpstk
00055 {
00056
00057
00058
00059
00060
00061
00062
00063
00064 void TabularEphemerisStore::dump( std::ostream& s,
00065 short detail )
00066 const throw()
00067 {
00068
00069 s << "Dump of TabularEphemerisStore:" << std::endl;
00070
00071 if(detail >= 0)
00072 {
00073
00074 EphMap::const_iterator it;
00075
00076 s << " Data stored for " << pe.size() << " satellites, over time span "
00077 << initialTime << " to " << finalTime << "." << std::endl;
00078
00079 if(detail == 0) return;
00080
00081 for(it=pe.begin(); it!=pe.end(); it++)
00082 {
00083
00084 s << " PRN " << it->first << " : "
00085 << it->second.size() << " records.";
00086 if(detail == 1) { s << std::endl; continue; }
00087 s << " Data:" << std::endl;
00088 SvEphMap::const_iterator jt;
00089
00090 for(jt=it->second.begin(); jt!=it->second.end(); jt++)
00091 {
00092 s << " " << jt->first << " P "
00093 << std::fixed << std::setprecision(6)
00094 << std::setw(13) << jt->second.x[0] << " "
00095 << std::setw(13) << jt->second.x[1] << " "
00096 << std::setw(13) << jt->second.x[2] << " "
00097 << std::setw(13) << jt->second.dtime
00098 << " V "
00099 << std::setw(13) << jt->second.v[0] << " "
00100 << std::setw(13) << jt->second.v[1] << " "
00101 << std::setw(13) << jt->second.v[2] << " "
00102 << std::setw(13) << jt->second.ddtime
00103 << std::endl;
00104 }
00105
00106 }
00107
00108 }
00109
00110 }
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 void TabularEphemerisStore::edit( const DayTime& tmin,
00121 const DayTime& tmax )
00122 throw()
00123 {
00124
00125 EphMap::iterator kt;
00126
00127 for(kt=pe.begin(); kt!=pe.end(); kt++)
00128 {
00129
00130 SvEphMap::reverse_iterator jt=(kt->second).rbegin();
00131
00132 while(jt != (kt->second).rend())
00133 {
00134
00135 if(jt->first < tmin || jt->first > tmax)
00136 {
00137 (kt->second).erase(jt->first);
00138 }
00139
00140 jt ++;
00141
00142 }
00143
00144 }
00145
00146 initialTime = tmin;
00147 finalTime = tmax;
00148
00149 }
00150
00151
00152
00153
00154 void TabularEphemerisStore::clear()
00155 throw()
00156 {
00157
00158 pe.clear();
00159 initialTime = DayTime::END_OF_TIME;
00160 finalTime = DayTime::BEGINNING_OF_TIME;
00161
00162 }
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 Xvt TabularEphemerisStore::getXvt( const SatID sat,
00179 const DayTime& t )
00180 const throw(InvalidRequest)
00181 {
00182
00183 EphMap::const_iterator svmap = pe.find(sat);
00184 if (svmap==pe.end()) {
00185 InvalidRequest e("Ephemeris for satellite " + asString(sat)
00186 + " not found.");
00187 GPSTK_THROW(e);
00188 }
00189
00190 const SvEphMap& sem=svmap->second;
00191 SvEphMap::const_iterator i=sem.find(t);
00192 Xvt sv;
00193 if (i!= sem.end() && haveVelocity) {
00194 sv = i->second;
00195 sv.x[0] *= 1.e3;
00196 sv.x[1] *= 1.e3;
00197 sv.x[2] *= 1.e3;
00198 sv.dtime *= 1.e-6;
00199 sv.v[0] *= 1.e-1;
00200 sv.v[1] *= 1.e-1;
00201 sv.v[2] *= 1.e-1;
00202 sv.ddtime *= 1.e-10;
00203
00204 sv.dtime += -2*(sv.x[0]/C_GPS_M)*(sv.v[0]/C_GPS_M)
00205 -2*(sv.x[1]/C_GPS_M)*(sv.v[1]/C_GPS_M)
00206 -2*(sv.x[2]/C_GPS_M)*(sv.v[2]/C_GPS_M);
00207 return sv;
00208 }
00209
00210
00211
00212 const int half=5;
00213
00214
00215 i = sem.lower_bound(t);
00216
00217 SvEphMap::const_iterator j=i;
00218
00219 if(i == sem.begin() || --i == sem.begin()) {
00220 InvalidRequest e("Inadequate data before requested time, satellite "
00221 + asString(sat));
00222 GPSTK_THROW(e);
00223 }
00224 if(j == sem.end()) {
00225 InvalidRequest e("Inadequate data after requested time, satellite "
00226 + asString(sat));
00227 GPSTK_THROW(e);
00228 }
00229
00230
00231
00232 if ( checkDataGap &&
00233 ( std::abs( t - i->first ) > gapInterval ) &&
00234 ( std::abs( j->first - t ) > gapInterval ) )
00235 {
00236
00237 InvalidRequest e( "Data gap too wide detected for satellite "
00238 + asString(sat) );
00239 GPSTK_THROW(e);
00240 }
00241
00242 for(int k=0; k<half-1; k++)
00243 {
00244
00245 i--;
00246
00247
00248 if(i == sem.begin() && k<half-2)
00249 {
00250 InvalidRequest e("Inadequate data before requested time, satellite "
00251 + asString(sat));
00252 GPSTK_THROW(e);
00253 }
00254 j++;
00255 if(j == sem.end() && k<half-2) {
00256 InvalidRequest e("Inadequate data after requested time, satellite "
00257 + asString(sat));
00258 GPSTK_THROW(e);
00259 }
00260 }
00261
00262
00263
00264
00265 if ( checkInterval &&
00266 ( std::abs( j->first - i->first ) > maxInterval ) )
00267 {
00268
00269 InvalidRequest e( "Interpolation interval too wide detected for SV "
00270 + asString(sat) );
00271 GPSTK_THROW(e);
00272 }
00273
00274
00275
00276 SvEphMap::const_iterator itr;
00277 DayTime t0=i->first;
00278 double dt=t-t0,err;
00279 std::vector<double> times,X,Y,Z,T,VX,VY,VZ,F;
00280
00281 for (itr=i; itr!=sem.end(); itr++)
00282 {
00283 times.push_back(itr->first - t0);
00284 X.push_back(itr->second.x[0]);
00285 Y.push_back(itr->second.x[1]);
00286 Z.push_back(itr->second.x[2]);
00287 T.push_back(itr->second.dtime);
00288 VX.push_back(itr->second.v[0]);
00289 VY.push_back(itr->second.v[1]);
00290 VZ.push_back(itr->second.v[2]);
00291 F.push_back(itr->second.ddtime);
00292 if(itr == j) break;
00293 }
00294
00295 if (haveVelocity)
00296 {
00297 sv.x[0] = LagrangeInterpolation(times,X,dt,err);
00298 sv.x[1] = LagrangeInterpolation(times,Y,dt,err);
00299 sv.x[2] = LagrangeInterpolation(times,Z,dt,err);
00300 sv.dtime = LagrangeInterpolation(times,T,dt,err);
00301 sv.v[0] = LagrangeInterpolation(times,VX,dt,err);
00302 sv.v[1] = LagrangeInterpolation(times,VY,dt,err);
00303 sv.v[2] = LagrangeInterpolation(times,VZ,dt,err);
00304 sv.ddtime = LagrangeInterpolation(times,F,dt,err);
00305 }
00306 else {
00307 LagrangeInterpolation(times,X,dt,sv.x[0],sv.v[0]);
00308 LagrangeInterpolation(times,Y,dt,sv.x[1],sv.v[1]);
00309 LagrangeInterpolation(times,Z,dt,sv.x[2],sv.v[2]);
00310 LagrangeInterpolation(times,T,dt,sv.dtime,sv.ddtime);
00311 sv.v[0] *= 1.e4;
00312 sv.v[1] *= 1.e4;
00313 sv.v[2] *= 1.e4;
00314 sv.ddtime *= 1.e4;
00315 }
00316
00317 sv.x[0] *= 1.e3;
00318 sv.x[1] *= 1.e3;
00319 sv.x[2] *= 1.e3;
00320 sv.dtime *= 1.e-6;
00321 sv.v[0] *= 1.e-1;
00322 sv.v[1] *= 1.e-1;
00323 sv.v[2] *= 1.e-1;
00324 sv.ddtime *= 1.e-10;
00325
00326
00327
00328
00329
00330 sv.dtime += -2*(sv.x[0]/C_GPS_M)*(sv.v[0]/C_GPS_M)
00331 -2*(sv.x[1]/C_GPS_M)*(sv.v[1]/C_GPS_M)
00332 -2*(sv.x[2]/C_GPS_M)*(sv.v[2]/C_GPS_M);
00333
00334 return sv;
00335
00336 }
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353 Triple TabularEphemerisStore::getAccel( const SatID sat,
00354 const DayTime& t )
00355 const throw(InvalidRequest)
00356 {
00357
00358 EphMap::const_iterator svmap = pe.find(sat);
00359 if (svmap==pe.end()) {
00360 InvalidRequest e("Ephemeris for satellite " + asString(sat)
00361 + " not found.");
00362 GPSTK_THROW(e);
00363 }
00364
00365 const SvEphMap& sem=svmap->second;
00366
00367 SvEphMap::const_iterator i=sem.find(t);
00368
00369
00370
00371 const int half=5;
00372
00373
00374 i = sem.lower_bound(t);
00375
00376 SvEphMap::const_iterator j=i;
00377
00378 if(i == sem.begin() || --i == sem.begin()) {
00379 InvalidRequest e("Inadequate data before requested time, satellite "
00380 + asString(sat));
00381 GPSTK_THROW(e);
00382 }
00383 if(j == sem.end()) {
00384 InvalidRequest e("Inadequate data after requested time, satellite "
00385 + asString(sat));
00386 GPSTK_THROW(e);
00387 }
00388
00389
00390
00391 if ( checkDataGap &&
00392 ( std::abs( t - i->first ) > gapInterval ) &&
00393 ( std::abs( j->first - t ) > gapInterval ) )
00394 {
00395
00396 InvalidRequest e( "Data gap too wide detected for satellite "
00397 + asString(sat) );
00398 GPSTK_THROW(e);
00399 }
00400
00401 for(int k=0; k<half-1; k++)
00402 {
00403
00404 i--;
00405
00406
00407 if(i == sem.begin() && k<half-2)
00408 {
00409 InvalidRequest e("Inadequate data before requested time, satellite "
00410 + asString(sat));
00411 GPSTK_THROW(e);
00412 }
00413 j++;
00414 if(j == sem.end() && k<half-2) {
00415 InvalidRequest e("Inadequate data after requested time, satellite "
00416 + asString(sat));
00417 GPSTK_THROW(e);
00418 }
00419 }
00420
00421
00422
00423
00424 if ( checkInterval &&
00425 ( std::abs( j->first - i->first ) > maxInterval ) )
00426 {
00427
00428 InvalidRequest e( "Interpolation interval too wide detected for SV "
00429 + asString(sat) );
00430 GPSTK_THROW(e);
00431 }
00432
00433
00434
00435 SvEphMap::const_iterator itr;
00436 DayTime t0(i->first);
00437 double dt(t-t0);
00438 std::vector<double> times,X,Y,Z;
00439
00440 for (itr=i; itr!=sem.end(); itr++)
00441 {
00442 times.push_back(itr->first - t0);
00443 X.push_back(itr->second.x[0]);
00444 Y.push_back(itr->second.x[1]);
00445 Z.push_back(itr->second.x[2]);
00446 if(itr == j) break;
00447 }
00448
00449 Triple accel;
00450
00451
00452 accel[0] = LagrangeInterpolating2ndDerivative(times,X,dt);
00453 accel[1] = LagrangeInterpolating2ndDerivative(times,Y,dt);
00454 accel[2] = LagrangeInterpolating2ndDerivative(times,Z,dt);
00455
00456 accel[0] *= 1.e3;
00457 accel[1] *= 1.e3;
00458 accel[2] *= 1.e3;
00459
00460 return accel;
00461
00462 }
00463
00464
00465
00466
00467
00468
00469
00470 void TabularEphemerisStore::addEphemeris(const SP3Data& data)
00471 throw()
00472 {
00473 DayTime t = data.time;
00474 SatID sat = data.sat;
00475 Xvt& xvt = pe[sat][t];
00476
00477 if (data.flag=='P')
00478 {
00479 xvt.x = ECEF(data.x[0], data.x[1], data.x[2]);
00480 xvt.dtime = data.clk;
00481 haveVelocity=false;
00482 }
00483 else if (data.flag=='V')
00484 {
00485 xvt.v = Triple(data.x[0],data.x[1],data.x[2]);
00486 xvt.ddtime = data.clk;
00487 haveVelocity=true;
00488 }
00489
00490 if (t<initialTime)
00491 initialTime = t;
00492 else if (t>finalTime)
00493 finalTime = t;
00494 }
00495
00496 }