00001 #pragma ident "$Id: IERSConventions.cpp 3203 2012-07-15 10:38:44Z yanweignss $"
00002
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "IERSConventions.hpp"
00032
00033 #include "CommonTime.hpp"
00034 #include "YDSTime.hpp"
00035 #include "MJD.hpp"
00036 #include "CivilTime.hpp"
00037
00038 namespace gpstk
00039 {
00040 using namespace std;
00041
00042
00043 const CommonTime J2000(CivilTime(2000,1,1,12,0,0.0));
00044
00045 const double PI = std::atan(1.0)*4.0;
00046
00047 const double D2PI = PI+PI;
00048
00049
00050 const double DJC = 36525.0;
00051
00052
00053 const double DAS2R = PI/180.0/3600.0;
00054
00055
00056 const double DS2R = PI/43200.0;
00057
00058
00059
00060
00061
00062 class TAImUTCData : public map<CommonTime,int>
00063 {
00064 public:
00065 void leapHistory(int year, int month, int day,int leap)
00066 { (*this)[ CivilTime(year,month,day,0,0,0.0) ] = leap; }
00067
00068 TAImUTCData()
00069 {
00070 leapHistory( 1972, 1, 1, 10 );
00071 leapHistory( 1972, 7, 1, 11 );
00072 leapHistory( 1973, 1, 1, 12 );
00073 leapHistory( 1974, 1, 1, 13 );
00074 leapHistory( 1975, 1, 1, 14 );
00075 leapHistory( 1976, 1, 1, 15 );
00076 leapHistory( 1977, 1, 1, 16 );
00077 leapHistory( 1978, 1, 1, 17 );
00078 leapHistory( 1979, 1, 1, 18 );
00079 leapHistory( 1980, 1, 1, 19 );
00080 leapHistory( 1981, 7, 1, 20 );
00081 leapHistory( 1982, 7, 1, 21 );
00082 leapHistory( 1983, 7, 1, 22 );
00083 leapHistory( 1985, 7, 1, 23 );
00084 leapHistory( 1988, 1, 1, 24 );
00085 leapHistory( 1990, 1, 1, 25 );
00086 leapHistory( 1991, 1, 1, 26 );
00087 leapHistory( 1992, 7, 1, 27 );
00088 leapHistory( 1993, 7, 1, 28 );
00089 leapHistory( 1994, 7, 1, 29 );
00090 leapHistory( 1996, 1, 1, 30 );
00091 leapHistory( 1997, 7, 1, 31 );
00092 leapHistory( 1999, 1, 1, 32 );
00093 leapHistory( 2006, 1, 1, 33 );
00094 leapHistory( 2009, 1, 1, 34 );
00095
00096
00097
00098 }
00099 };
00100
00101 static const TAImUTCData lsDataTable;
00102
00103 int TAImUTC(const CommonTime& UTC)
00104 throw(InvalidRequest)
00105 {
00106 if( UTC < CivilTime(1972,1,1,0,0,0.0) )
00107 {
00108 GPSTK_THROW(
00109 InvalidRequest( "There are no leap second data for the epoch"
00110 +UTC.asString()) );
00111 }
00112
00113
00114 TAImUTCData::const_iterator it = lsDataTable.lower_bound(UTC);
00115
00116 if( (it == lsDataTable.end()) || (it->first != UTC) )
00117 {
00118 it--;
00119 return it->second;
00120 }
00121 else if( it->first == UTC )
00122 {
00123 return it->second;
00124 }
00125
00126
00127 GPSTK_THROW(Exception("My God, it should never go here!"));
00128
00129 }
00130
00131 double TTmTAI(){ return 32.184; }
00132
00133 double TAImGPST(){ return 19.0; }
00134
00135
00136 static EOPDataStore eopDataTable;
00137
00138
00139 void LoadIERSFile(const std::string& fileName)
00140 {
00141 eopDataTable.clear();
00142 try { eopDataTable.loadIERSFile(fileName); }
00143 catch(...)
00144 {
00145 GPSTK_THROW(Exception("Failed to load the IERS ERP File "+fileName));
00146 }
00147 }
00148
00149
00150 void LoadIGSFile(const std::string& fileName)
00151 {
00152 eopDataTable.clear();
00153 try { eopDataTable.loadIGSFile(fileName); }
00154 catch(...)
00155 {
00156 GPSTK_THROW(Exception("Failed to load the IGS ERP File "+fileName));
00157 }
00158 }
00159
00160
00161 void LoadSTKFile(const std::string& fileName)
00162 {
00163 eopDataTable.clear();
00164 try { eopDataTable.loadSTKFile(fileName); }
00165 catch(...)
00166 {
00167 GPSTK_THROW(Exception("Failed to load the STK ERP File "+fileName));
00168 }
00169 }
00170
00171
00172
00173 EOPDataStore::EOPData EOPData(const CommonTime& UTC)
00174 throw(InvalidRequest)
00175 {
00176 return eopDataTable.getEOPData(UTC);
00177 }
00178
00179
00180 double PolarMotionX(const CommonTime& UTC)
00181 {
00182 try { return EOPData(UTC).xp; }
00183 catch(...)
00184 {
00185 GPSTK_THROW(Exception("Failed to get EOP data on" + CivilTime(UTC).asString()));
00186
00187 return 0.0;
00188 }
00189 }
00190
00191
00192 double PolarMotionY(const CommonTime& UTC)
00193 {
00194 try { return EOPData(UTC).yp; }
00195 catch(...)
00196 {
00197 GPSTK_THROW(Exception("Failed to get EOP data on " + CivilTime(UTC).asString()));
00198
00199 return 0.0;
00200 }
00201 }
00202
00203
00204 double UT1mUTC(const CommonTime& UTC)
00205 {
00206 try { return EOPData(UTC).UT1mUTC; }
00207 catch(...)
00208 {
00209 GPSTK_THROW(Exception("Failed to get EOP data on " + CivilTime(UTC).asString()));
00210
00211 return 0.0;
00212 }
00213 }
00214
00215
00216 double NutationDPsi(const CommonTime& UTC)
00217 {
00218 try { return EOPData(UTC).dPsi; }
00219 catch(...)
00220 {
00221 GPSTK_THROW(Exception("Failed to get EOP data on "+CivilTime(UTC).asString()));
00222
00223 return 0.0;
00224 }
00225 }
00226
00227
00228 double NutationDEps(const CommonTime& UTC)
00229 {
00230 try { return EOPData(UTC).dEps; }
00231 catch(...)
00232 {
00233 GPSTK_THROW(Exception("Failed to get EOP data on "+CivilTime(UTC).asString()));
00234
00235 return 0.0;
00236 }
00237 }
00238
00239
00240
00241
00242 CommonTime ConvertTimeSystem(const CommonTime& time, TimeSystemEnum from, TimeSystemEnum to)
00243 {
00244 if(from==to) return time;
00245
00246 static std::map<TimeSystemEnum,std::string> mapTSName;
00247 if(mapTSName.size()==0)
00248 {
00249 mapTSName[TS_UTC] = "UTC";
00250 mapTSName[TS_UT1] = "UT1";
00251 mapTSName[TS_GPST]= "GPST";
00252 mapTSName[TS_TAI] = "TAI";
00253 mapTSName[TS_TT] = "TT";
00254 }
00255
00256 std::map<TimeSystemEnum,std::string>::const_iterator itf,itt,ite;
00257 itf = mapTSName.find(from);
00258 itt = mapTSName.find(to);
00259 ite = mapTSName.end();
00260
00261 if( (itf==ite) || (itt==ite) )
00262 {
00263 Exception e("Can't convert the Time System from "
00264 + ((itf==ite)?"Unknown":itf->second) + std::string(" to")
00265 + ((itt==ite)?"Unknown":itt->second) + std::string("."));
00266
00267 GPSTK_THROW(e);
00268 }
00269
00270 typedef CommonTime (*ConvertFunPtr)(const CommonTime&);
00271
00272 ConvertFunPtr funPtr1(0);
00273 if( itf->first == TS_UT1) funPtr1 = UT12UTC;
00274 if( itf->first == TS_GPST)funPtr1 = GPST2UTC;
00275 if( itf->first == TS_TAI) funPtr1 = TAI2UTC;
00276 if( itf->first == TS_TT) funPtr1 = TT2UTC;
00277
00278 CommonTime utc = funPtr1 ? funPtr1(time) : time;
00279
00280 ConvertFunPtr funPtr2(0);
00281 if( itt->first == TS_UT1) funPtr2 = UTC2UT1;
00282 if( itt->first == TS_GPST)funPtr2 = UTC2GPST;
00283 if( itt->first == TS_TAI) funPtr2 = UTC2TAI;
00284 if( itt->first == TS_TT) funPtr2 = UTC2TT;
00285
00286 CommonTime dest = funPtr2 ? funPtr2(utc) : utc;
00287
00288 return dest;
00289 }
00290
00291 CommonTime GPST2UTC(const CommonTime& GPST)
00292 {
00293
00294 int leapSec = TAImUTC(GPST);
00295 CommonTime UTC = GPST;
00296 UTC += (19.0 - double(leapSec));
00297
00298 leapSec = TAImUTC(UTC);
00299 UTC = GPST;
00300 UTC += (19.0 - double(leapSec));
00301
00302 return UTC;
00303 }
00304 CommonTime UTC2GPST(const CommonTime& UTC)
00305 {
00306 CommonTime GPST(UTC);
00307 GPST += TAImUTC(UTC);
00308 GPST +=-TAImGPST();
00309 return GPST;
00310 }
00311
00312 CommonTime UT12UTC(const CommonTime& UT1)
00313 {
00314 CommonTime UTC(UT1);
00315 UTC -= UT1mUTC(UT1);
00316
00317 CommonTime T(UT1);
00318 T -= UT1mUTC(UTC);
00319
00320 UTC = UT1;
00321 UTC -= UT1mUTC(T);
00322
00323 return UTC;
00324 }
00325 CommonTime UTC2UT1(const CommonTime& UTC)
00326 {
00327 CommonTime UT1(UTC);
00328 UT1 += UT1mUTC(UTC);
00329
00330 return UT1;
00331 }
00332
00333 CommonTime UT12UTC(const CommonTime& UT1,double ut1mutc)
00334 {
00335 CommonTime UTC(UT1);
00336 UTC -= ut1mutc;
00337
00338 return UTC;
00339 }
00340 CommonTime UTC2UT1(const CommonTime& UTC,double ut1mutc)
00341 {
00342 CommonTime UT1(UTC);
00343 UT1 += ut1mutc;
00344
00345 return UT1;
00346 }
00347
00348 CommonTime TT2UTC(const CommonTime& TT)
00349 {
00350 CommonTime TAI = TT;
00351 TAI -= TTmTAI();
00352
00353 CommonTime UTC = TAI;
00354 UTC -= TAImUTC(TAI);
00355
00356 CommonTime UTC2(UTC);
00357
00358 UTC = TAI;
00359 UTC -= TAImUTC(UTC2);
00360
00361 UTC2 = UTC;
00362
00363 UTC = TAI;
00364 UTC -= TAImUTC(UTC2);
00365
00366 return UTC;
00367 }
00368 CommonTime UTC2TT(const CommonTime& UTC)
00369 {
00370 CommonTime TAI(UTC);
00371 TAI += TAImUTC(UTC);
00372
00373 CommonTime TT(TAI);
00374 TT += TTmTAI();
00375
00376 return TT;
00377 }
00378
00379 CommonTime TAI2UTC(const CommonTime& TAI)
00380 {
00381 CommonTime UTC(TAI);
00382 UTC -= TAImUTC(TAI);
00383
00384 CommonTime UTC2 = TAI;
00385 UTC2 -= TAImUTC(UTC);
00386
00387 UTC = TAI;
00388 UTC -= TAImUTC(UTC2);
00389
00390 return UTC;
00391 }
00392 CommonTime UTC2TAI(const CommonTime& UTC)
00393 {
00394 CommonTime TAI(UTC);
00395 TAI += TAImUTC(UTC);
00396
00397 return TAI;
00398 }
00399
00400 CommonTime BDT2UTC(const CommonTime& BDT)
00401 {
00402 CommonTime GPST(BDT);
00403 GPST += 14.0;
00404
00405 return GPST2UTC(GPST);
00406 }
00407 CommonTime UTC2BDT(const CommonTime& UTC)
00408 {
00409 CommonTime BDT = UTC2GPST(UTC);
00410 BDT -= 14.0;
00411
00412 return BDT;
00413 }
00414
00415
00416
00417
00418 Triple J2kPosToECEF(const Triple& j2kPos, const CommonTime& time, TimeSystemEnum sys)
00419 {
00420 Vector<double> j2kR(3,0.0);
00421 j2kR[0] = j2kPos[0];
00422 j2kR[1] = j2kPos[1];
00423 j2kR[2] = j2kPos[2];
00424
00425 CommonTime UTC = ConvertTimeSystem(time, sys, TS_UTC);
00426 Vector<double> ecefR = J2kPosToECEF(UTC,j2kR);
00427
00428 return Triple(ecefR[0], ecefR[1], ecefR[2]);
00429 }
00430
00431 Triple ECEFPosToJ2k(const Triple& ecefPos, const CommonTime& time, TimeSystemEnum sys)
00432 {
00433 Vector<double> ecefR(3,0.0);
00434 ecefR[0] = ecefPos[0];
00435 ecefR[1] = ecefPos[1];
00436 ecefR[2] = ecefPos[2];
00437
00438 CommonTime UTC = ConvertTimeSystem(time, sys, TS_UTC);
00439 Vector<double> j2kR = ECEFPosToJ2k(UTC,ecefR);
00440
00441 return Triple(j2kR[0], j2kR[1], j2kR[2]);
00442 }
00443
00444
00445 double iauNut80Args(const CommonTime& TT,double& eps, double& dpsi,double& deps)
00446 throw(Exception)
00447 {
00448 static const double nut[106][10]={
00449 { 0, 0, 0, 0, 1, -6798.4, -171996, -174.2, 92025, 8.9},
00450 { 0, 0, 2, -2, 2, 182.6, -13187, -1.6, 5736, -3.1},
00451 { 0, 0, 2, 0, 2, 13.7, -2274, -0.2, 977, -0.5},
00452 { 0, 0, 0, 0, 2, -3399.2, 2062, 0.2, -895, 0.5},
00453 { 0, -1, 0, 0, 0, -365.3, -1426, 3.4, 54, -0.1},
00454 { 1, 0, 0, 0, 0, 27.6, 712, 0.1, -7, 0.0},
00455 { 0, 1, 2, -2, 2, 121.7, -517, 1.2, 224, -0.6},
00456 { 0, 0, 2, 0, 1, 13.6, -386, -0.4, 200, 0.0},
00457 { 1, 0, 2, 0, 2, 9.1, -301, 0.0, 129, -0.1},
00458 { 0, -1, 2, -2, 2, 365.2, 217, -0.5, -95, 0.3},
00459 { -1, 0, 0, 2, 0, 31.8, 158, 0.0, -1, 0.0},
00460 { 0, 0, 2, -2, 1, 177.8, 129, 0.1, -70, 0.0},
00461 { -1, 0, 2, 0, 2, 27.1, 123, 0.0, -53, 0.0},
00462 { 1, 0, 0, 0, 1, 27.7, 63, 0.1, -33, 0.0},
00463 { 0, 0, 0, 2, 0, 14.8, 63, 0.0, -2, 0.0},
00464 { -1, 0, 2, 2, 2, 9.6, -59, 0.0, 26, 0.0},
00465 { -1, 0, 0, 0, 1, -27.4, -58, -0.1, 32, 0.0},
00466 { 1, 0, 2, 0, 1, 9.1, -51, 0.0, 27, 0.0},
00467 { -2, 0, 0, 2, 0, -205.9, -48, 0.0, 1, 0.0},
00468 { -2, 0, 2, 0, 1, 1305.5, 46, 0.0, -24, 0.0},
00469 { 0, 0, 2, 2, 2, 7.1, -38, 0.0, 16, 0.0},
00470 { 2, 0, 2, 0, 2, 6.9, -31, 0.0, 13, 0.0},
00471 { 2, 0, 0, 0, 0, 13.8, 29, 0.0, -1, 0.0},
00472 { 1, 0, 2, -2, 2, 23.9, 29, 0.0, -12, 0.0},
00473 { 0, 0, 2, 0, 0, 13.6, 26, 0.0, -1, 0.0},
00474 { 0, 0, 2, -2, 0, 173.3, -22, 0.0, 0, 0.0},
00475 { -1, 0, 2, 0, 1, 27.0, 21, 0.0, -10, 0.0},
00476 { 0, 2, 0, 0, 0, 182.6, 17, -0.1, 0, 0.0},
00477 { 0, 2, 2, -2, 2, 91.3, -16, 0.1, 7, 0.0},
00478 { -1, 0, 0, 2, 1, 32.0, 16, 0.0, -8, 0.0},
00479 { 0, 1, 0, 0, 1, 386.0, -15, 0.0, 9, 0.0},
00480 { 1, 0, 0, -2, 1, -31.7, -13, 0.0, 7, 0.0},
00481 { 0, -1, 0, 0, 1, -346.6, -12, 0.0, 6, 0.0},
00482 { 2, 0, -2, 0, 0, -1095.2, 11, 0.0, 0, 0.0},
00483 { -1, 0, 2, 2, 1, 9.5, -10, 0.0, 5, 0.0},
00484 { 1, 0, 2, 2, 2, 5.6, -8, 0.0, 3, 0.0},
00485 { 0, -1, 2, 0, 2, 14.2, -7, 0.0, 3, 0.0},
00486 { 0, 0, 2, 2, 1, 7.1, -7, 0.0, 3, 0.0},
00487 { 1, 1, 0, -2, 0, -34.8, -7, 0.0, 0, 0.0},
00488 { 0, 1, 2, 0, 2, 13.2, 7, 0.0, -3, 0.0},
00489 { -2, 0, 0, 2, 1, -199.8, -6, 0.0, 3, 0.0},
00490 { 0, 0, 0, 2, 1, 14.8, -6, 0.0, 3, 0.0},
00491 { 2, 0, 2, -2, 2, 12.8, 6, 0.0, -3, 0.0},
00492 { 1, 0, 0, 2, 0, 9.6, 6, 0.0, 0, 0.0},
00493 { 1, 0, 2, -2, 1, 23.9, 6, 0.0, -3, 0.0},
00494 { 0, 0, 0, -2, 1, -14.7, -5, 0.0, 3, 0.0},
00495 { 0, -1, 2, -2, 1, 346.6, -5, 0.0, 3, 0.0},
00496 { 2, 0, 2, 0, 1, 6.9, -5, 0.0, 3, 0.0},
00497 { 1, -1, 0, 0, 0, 29.8, 5, 0.0, 0, 0.0},
00498 { 1, 0, 0, -1, 0, 411.8, -4, 0.0, 0, 0.0},
00499 { 0, 0, 0, 1, 0, 29.5, -4, 0.0, 0, 0.0},
00500 { 0, 1, 0, -2, 0, -15.4, -4, 0.0, 0, 0.0},
00501 { 1, 0, -2, 0, 0, -26.9, 4, 0.0, 0, 0.0},
00502 { 2, 0, 0, -2, 1, 212.3, 4, 0.0, -2, 0.0},
00503 { 0, 1, 2, -2, 1, 119.6, 4, 0.0, -2, 0.0},
00504 { 1, 1, 0, 0, 0, 25.6, -3, 0.0, 0, 0.0},
00505 { 1, -1, 0, -1, 0, -3232.9, -3, 0.0, 0, 0.0},
00506 { -1, -1, 2, 2, 2, 9.8, -3, 0.0, 1, 0.0},
00507 { 0, -1, 2, 2, 2, 7.2, -3, 0.0, 1, 0.0},
00508 { 1, -1, 2, 0, 2, 9.4, -3, 0.0, 1, 0.0},
00509 { 3, 0, 2, 0, 2, 5.5, -3, 0.0, 1, 0.0},
00510 { -2, 0, 2, 0, 2, 1615.7, -3, 0.0, 1, 0.0},
00511 { 1, 0, 2, 0, 0, 9.1, 3, 0.0, 0, 0.0},
00512 { -1, 0, 2, 4, 2, 5.8, -2, 0.0, 1, 0.0},
00513 { 1, 0, 0, 0, 2, 27.8, -2, 0.0, 1, 0.0},
00514 { -1, 0, 2, -2, 1, -32.6, -2, 0.0, 1, 0.0},
00515 { 0, -2, 2, -2, 1, 6786.3, -2, 0.0, 1, 0.0},
00516 { -2, 0, 0, 0, 1, -13.7, -2, 0.0, 1, 0.0},
00517 { 2, 0, 0, 0, 1, 13.8, 2, 0.0, -1, 0.0},
00518 { 3, 0, 0, 0, 0, 9.2, 2, 0.0, 0, 0.0},
00519 { 1, 1, 2, 0, 2, 8.9, 2, 0.0, -1, 0.0},
00520 { 0, 0, 2, 1, 2, 9.3, 2, 0.0, -1, 0.0},
00521 { 1, 0, 0, 2, 1, 9.6, -1, 0.0, 0, 0.0},
00522 { 1, 0, 2, 2, 1, 5.6, -1, 0.0, 1, 0.0},
00523 { 1, 1, 0, -2, 1, -34.7, -1, 0.0, 0, 0.0},
00524 { 0, 1, 0, 2, 0, 14.2, -1, 0.0, 0, 0.0},
00525 { 0, 1, 2, -2, 0, 117.5, -1, 0.0, 0, 0.0},
00526 { 0, 1, -2, 2, 0, -329.8, -1, 0.0, 0, 0.0},
00527 { 1, 0, -2, 2, 0, 23.8, -1, 0.0, 0, 0.0},
00528 { 1, 0, -2, -2, 0, -9.5, -1, 0.0, 0, 0.0},
00529 { 1, 0, 2, -2, 0, 32.8, -1, 0.0, 0, 0.0},
00530 { 1, 0, 0, -4, 0, -10.1, -1, 0.0, 0, 0.0},
00531 { 2, 0, 0, -4, 0, -15.9, -1, 0.0, 0, 0.0},
00532 { 0, 0, 2, 4, 2, 4.8, -1, 0.0, 0, 0.0},
00533 { 0, 0, 2, -1, 2, 25.4, -1, 0.0, 0, 0.0},
00534 { -2, 0, 2, 4, 2, 7.3, -1, 0.0, 1, 0.0},
00535 { 2, 0, 2, 2, 2, 4.7, -1, 0.0, 0, 0.0},
00536 { 0, -1, 2, 0, 1, 14.2, -1, 0.0, 0, 0.0},
00537 { 0, 0, -2, 0, 1, -13.6, -1, 0.0, 0, 0.0},
00538 { 0, 0, 4, -2, 2, 12.7, 1, 0.0, 0, 0.0},
00539 { 0, 1, 0, 0, 2, 409.2, 1, 0.0, 0, 0.0},
00540 { 1, 1, 2, -2, 2, 22.5, 1, 0.0, -1, 0.0},
00541 { 3, 0, 2, -2, 2, 8.7, 1, 0.0, 0, 0.0},
00542 { -2, 0, 2, 2, 2, 14.6, 1, 0.0, -1, 0.0},
00543 { -1, 0, 0, 0, 2, -27.3, 1, 0.0, -1, 0.0},
00544 { 0, 0, -2, 2, 1, -169.0, 1, 0.0, 0, 0.0},
00545 { 0, 1, 2, 0, 1, 13.1, 1, 0.0, 0, 0.0},
00546 { -1, 0, 4, 0, 2, 9.1, 1, 0.0, 0, 0.0},
00547 { 2, 1, 0, -2, 0, 131.7, 1, 0.0, 0, 0.0},
00548 { 2, 0, 0, 2, 0, 7.1, 1, 0.0, 0, 0.0},
00549 { 2, 0, 2, -2, 1, 12.8, 1, 0.0, -1, 0.0},
00550 { 2, 0, -2, 0, 1, -943.2, 1, 0.0, 0, 0.0},
00551 { 1, -1, 0, -2, 0, -29.3, 1, 0.0, 0, 0.0},
00552 { -1, 0, 0, 1, 1, -388.3, 1, 0.0, 0, 0.0},
00553 { -1, -1, 0, 2, 1, 35.0, 1, 0.0, 0, 0.0},
00554 { 0, 1, 0, 1, 0, 27.3, 1, 0.0, 0, 0.0}
00555 };
00556
00557 static const double fc[][5]={
00558 { 134.96340251, 1717915923.2178, 31.8792, 0.051635, -0.00024470},
00559 { 357.52910918, 129596581.0481, -0.5532, 0.000136, -0.00001149},
00560 { 93.27209062, 1739527262.8478, -12.7512, -0.001037, 0.00000417},
00561 { 297.85019547, 1602961601.2090, -6.3706, 0.006593, -0.00003169},
00562 { 125.04455501, -6962890.2665, 7.4722, 0.007702 -0.00005939}
00563 };
00564
00565 eps = 0.0;
00566 dpsi = 0.0;
00567 deps = 0.0;
00568
00569
00570 const double T = (TT-J2000)/86400.0/36525.0;
00571
00572 eps = (84381.448-46.8150*T-0.00059*T*T+0.001813*T*T*T)*DAS2R;
00573
00574 double f[5]={0.0};
00575 {
00576 double tt[4]={0.0}; tt[0] = T;
00577 for ( int i=1; i<4; i++) tt[i]=tt[i-1]*T;
00578 for (int i=0; i<5; i++)
00579 {
00580 f[i]=fc[i][0]*3600.0;
00581 for (int j=0; j<4; j++) f[i]+=fc[i][j+1]*tt[j];
00582 f[i]=fmod(f[i]*DAS2R, 2.0*PI);
00583 }
00584 }
00585
00586 for(int i = 0; i < 106; i++)
00587 {
00588 double ang(0.0);
00589 for(int j=0; j<5; j++) ang+=nut[i][j]*f[j];
00590
00591 dpsi+=(nut[i][6]+nut[i][7]*T)*std::sin(ang);
00592 deps+=(nut[i][8]+nut[i][9]*T)*std::cos(ang);
00593 }
00594
00595 dpsi *= 1E-4*DAS2R;
00596 deps *= 1E-4*DAS2R;
00597
00598 return f[4];
00599
00600 }
00601
00602
00603 void J2kToECEFMatrix(const CommonTime& UTC,
00604 const EOPDataStore::EOPData& ERP,
00605 Matrix<double>& POM,
00606 Matrix<double>& Theta,
00607 Matrix<double>& NP)
00608 throw(Exception)
00609 {
00610 double xp = ERP.xp * DAS2R;
00611 double yp = ERP.yp * DAS2R;
00612 double ut1_utc = ERP.UT1mUTC;
00613 double ddeps = ERP.dEps * DAS2R;
00614 double ddpsi = ERP.dPsi * DAS2R;
00615
00616 CommonTime TT = UTC2TT(UTC);
00617 CommonTime UT1 = UTC2UT1(UTC,ut1_utc);
00618
00619
00620 Matrix<double> P = iauPmat76(TT);
00621
00622
00623 double eps(0.0),dpsi(0.0),deps(0.0);
00624 double f = iauNut80Args(TT,eps,dpsi,deps);
00625
00626 Matrix<double> N = iauNmat(eps, dpsi + ddpsi, deps + ddeps);
00627
00628 NP = N * P;
00629
00630 YDSTime ut1_yds(UT1);
00631 double ut1_sec = ut1_yds.sod;
00632 ut1_yds.sod = 0.0;
00633 CommonTime ut1_day(ut1_yds);
00634 const double t = (ut1_day-J2000) / 86400.0 / DJC;
00635
00636 double temp = 24110.54841+8640184.812866*t+0.093104*(t*t)-6.2E-6*(t*t*t)
00637 +1.002737909350795*ut1_sec;
00638 double gmst = fmod(temp,86400.0)*DS2R;
00639 double ee = dpsi * std::cos(eps)
00640 + (0.00264 * std::sin(f) + 0.000063 * std::sin(f+f))*DAS2R;
00641 double gast = normalizeAngle(gmst + ee);
00642
00643 Theta = Rz(gast);
00644
00645
00646 POM = Ry(-xp) * Rx(-yp);
00647
00648
00649 }
00650
00651
00652 Matrix<double> J2kToECEFMatrix(const CommonTime& UTC,const EOPDataStore::EOPData& ERP)
00653 {
00654 Matrix<double> POM, Theta, NP;
00655 J2kToECEFMatrix(UTC,ERP,POM,Theta,NP);
00656
00657 return (POM * Theta * NP);
00658 }
00659
00660
00661 Vector<double> J2kPosToECEF(const CommonTime& UTC, const Vector<double>& j2kPos)
00662 throw(Exception)
00663 {
00664 EOPDataStore::EOPData ERP = EOPData(UTC);
00665 Matrix<double> c2tMat = J2kToECEFMatrix(UTC,ERP);
00666 return c2tMat * j2kPos;
00667 }
00668
00669
00670
00671 Vector<double> ECEFPosToJ2k(const CommonTime& UTC, const Vector<double>& ecefPos)
00672 throw(Exception)
00673 {
00674 EOPDataStore::EOPData ERP = EOPData(UTC);
00675 Matrix<double> c2tMat = J2kToECEFMatrix(UTC,ERP);
00676 return transpose(c2tMat) * ecefPos;
00677 }
00678
00679
00680 Vector<double> J2kPosVelToECEF(const CommonTime& UTC, const Vector<double>& j2kPosVel)
00681 throw(Exception)
00682 {
00683 EOPDataStore::EOPData ERP = EOPData(UTC);
00684
00685 Matrix<double> POM, Theta, NP;
00686 J2kToECEFMatrix(UTC,ERP,POM,Theta,NP);
00687
00688 const double dera = earthRotationAngleRate1( UTC2TT(UTC) );
00689
00690
00691 Matrix<double> S(3,3,0.0);
00692 S(0,1) = 1.0; S(1,0) = -1.0;
00693
00694 Matrix<double> dTheta = dera * S * Theta;
00695
00696 Matrix<double> c2t = POM * Theta * NP;
00697 Matrix<double> dc2t = POM * dTheta * NP;
00698
00699 Vector<double> j2kPos(3, 0.0), j2kVel(3, 0.0);
00700 for(int i=0; i<3; i++)
00701 {
00702 j2kPos(i) = j2kPosVel(i);
00703 j2kVel(i) = j2kPosVel(i+3);
00704 }
00705
00706 Vector<double> ecefPos = c2t * j2kPos;
00707 Vector<double> ecefVel = c2t * j2kVel + dc2t * j2kPos;
00708
00709 Vector<double> ecefPosVel(6,0.0);
00710 for(int i=0; i<3; i++)
00711 {
00712 ecefPosVel(i) = ecefPos(i);
00713 ecefPosVel(i+3) = ecefVel(i);
00714 }
00715
00716 return ecefPosVel;
00717 }
00718
00719
00720 Vector<double> ECEFPosVelToJ2k(const CommonTime& UTC, const Vector<double>& ecefPosVel)
00721 throw(Exception)
00722 {
00723 EOPDataStore::EOPData ERP = EOPData(UTC);
00724
00725 Matrix<double> POM, Theta, NP;
00726 J2kToECEFMatrix(UTC,ERP,POM,Theta,NP);
00727
00728 const double dera = earthRotationAngleRate1( UTC2TT(UTC) );
00729
00730
00731 Matrix<double> S(3,3,0.0);
00732 S(0,1) = 1.0; S(1,0) = -1.0;
00733
00734 Matrix<double> dTheta = dera * S * Theta;
00735
00736 Matrix<double> c2t = POM * Theta * NP;
00737 Matrix<double> dc2t = POM * dTheta * NP;
00738
00739 Vector<double> ecefPos(3, 0.0), ecefVel(3, 0.0);
00740 for(int i=0; i<3; i++)
00741 {
00742 ecefPos(i) = ecefPosVel(i);
00743 ecefVel(i) = ecefPosVel(i+3);
00744 }
00745
00746 Vector<double> j2kPos = transpose(c2t) * ecefPos;
00747 Vector<double> j2kVel = transpose(c2t) * ecefVel
00748 +transpose(dc2t)* ecefPos;
00749
00750 Vector<double> j2kPosVel(6,0.0);
00751 for(int i=0; i<3; i++)
00752 {
00753 j2kPosVel(i) = j2kPos(i);
00754 j2kPosVel(i+3) = j2kVel(i);
00755 }
00756
00757 return j2kPosVel;
00758 }
00759
00760
00761 Vector<double> sunJ2kPosition(const CommonTime& TT)
00762 {
00763
00764
00765
00766 const double eps = 23.43929111 * PI / 180.0;
00767
00768
00769 const double T = (TT-J2000)/86400.0/36525.0;
00770
00771
00772 double M = std::fmod(0.9931267 + 99.9973583*T,1.0)*D2PI;
00773
00774
00775 double L = std::fmod( 0.7859444 + M/D2PI
00776 +(6892.0*std::sin(M)+72.0*std::sin(2.0*M))/1296.0e3
00777 ,1.0)*D2PI;
00778
00779
00780 double r = 149.619e9-2.499e9*std::cos(M)-0.021e9*std::cos(2.0*M);
00781
00782
00783 return Triple(r*std::cos(L),r*std::sin(L),0.0).R1(-eps*180.0/PI).toVector();
00784 }
00785
00786 Vector<double> moonJ2kPosition(const CommonTime& TT)
00787 {
00788
00789 const double eps = 23.43929111 * PI / 180.0;
00790 const double Arcs = 3600.0*180.0/PI;
00791
00792
00793 const double T = (TT-J2000)/86400.0/36525.0;
00794
00795
00796
00797
00798 double L0 = std::fmod(0.606433 + 1336.851344*T, 1.0);
00799 double l = std::fmod( 0.374897 + 1325.552410*T,1.0)*D2PI;
00800 double lp = std::fmod( 0.993133 + 99.997361*T,1.0)*D2PI;
00801 double F = std::fmod( 0.259086 + 1342.227825*T,1.0)*D2PI;
00802 double D = std::fmod( 0.827361 + 1236.853086*T,1.0)*D2PI;
00803
00804
00805
00806
00807 double dL = +22640.0*std::sin(l)-4586.0*std::sin(l-2*D)+2370.0*std::sin(2*D)
00808 +769.0*std::sin(2.0*l)-668.0*std::sin(lp)-412.0*std::sin(2.0*F)
00809 -212.0*std::sin(2.0*l-2.0*D)-206.0*std::sin(l+lp-2.0*D)
00810 +192.0*std::sin(l+2.0*D)-165.0*std::sin(lp-2.0*D)-125.0*std::sin(D)
00811 -110.0*std::sin(l+lp)+148.0*std::sin(l-lp)-55.0*std::sin(2.0*F-2.0*D);
00812
00813 double L = std::fmod( L0 + dL/1296.0e3, 1.0)*D2PI;
00814
00815
00816
00817
00818 double S = F + (dL+412.0*std::sin(2.0*F)+541.0*std::sin(lp)) / Arcs;
00819 double h = F-2.0*D;
00820 double N =-526.0*std::sin(h) + 44.0*std::sin(l+h)-31.0*std::sin(-l+h)-23.0*std::sin(lp+h)
00821 +11.0*std::sin(-lp+h)-25.0*std::sin(-2.0*l+F)+21.0*std::sin(-l+F);
00822
00823 double B = (18520.0*std::sin(S)+N) / Arcs;
00824
00825
00826
00827 double R = 385000e3-20905e3*std::cos(l)-3699e3*std::cos(2.0*D-l)
00828 -2956e3*std::cos(2.0*D)-570e3*std::cos(2.0*l)+246e3*std::cos(2.0*l-2.0*D)
00829 -205e3*std::cos(lp-2.0*D)-171e3*std::cos(l+2.0*D)-152e3*std::cos(l+lp-2.0*D);
00830
00831
00832 Triple rMoon(R*std::cos(L)*std::cos(B),
00833 R*std::sin(L)*std::cos(B),
00834 R*std::sin(B));
00835
00836 return rMoon.R1(-eps*180.0/PI).toVector();
00837 }
00838
00839
00841
00842
00843 double normalizeAngle(double a)
00844 {
00845 double w = fmod(a, D2PI);
00846 if (fabs(w) >= (D2PI*0.5))
00847 {
00848 w-= ((a<0.0)?-D2PI:D2PI);
00849 }
00850
00851 return w;
00852 }
00853
00854
00855
00856 Matrix<double> Rx(const double& angle)
00857 {
00858 const double s = std::sin(angle);
00859 const double c = std::cos(angle);
00860
00861 const double a[9] = { 1, 0, 0, 0, c, s, 0,-s, c };
00862
00863 Matrix<double> r(3,3,0.0);
00864 r = a;
00865
00866 return r;
00867 }
00868
00869
00870 Matrix<double> Ry(const double& angle)
00871 {
00872 const double s = std::sin(angle);
00873 const double c = std::cos(angle);
00874
00875 const double a[9] = { c, 0,-s, 0, 1, 0, s, 0, c };
00876
00877 Matrix<double> r(3,3,0.0);
00878 r = a;
00879
00880 return r;
00881 }
00882
00883
00884 Matrix<double> Rz(const double& angle)
00885 {
00886 const double s = std::sin(angle);
00887 const double c = std::cos(angle);
00888
00889 const double a[9] = { c, s, 0,-s, c, 0, 0, 0, 1 };
00890
00891 Matrix<double> r(3,3,0.0);
00892 r = a;
00893
00894 return r;
00895 }
00896
00897 Matrix<double> iauPmat76(const CommonTime& TT)
00898 {
00899
00900 const double t0 = 0.0;
00901
00902
00903 const double t = ( TT - J2000 ) / 86400.0 / DJC;
00904
00905
00906 const double tas2r = t * DAS2R;
00907 const double w = 2306.2181 + (1.39656 - 0.000139 * t0) * t0;
00908
00909 double zeta = (w + ((0.30188 - 0.000344 * t0) + 0.017998 * t) * t) * tas2r;
00910
00911 double z = (w + ((1.09468 + 0.000066 * t0) + 0.018203 * t) * t) * tas2r;
00912
00913 double theta = ((2004.3109 + (-0.85330 - 0.000217 * t0) * t0)
00914 + ((-0.42665 - 0.000217 * t0) - 0.041833 * t) * t) * tas2r;
00915
00916 return ( Rz(-z) * Ry(theta) * Rz(-zeta) );
00917
00918 }
00919
00920
00921 void nutationAngles(const CommonTime& TT, double& dpsi, double& deps)
00922 {
00923
00924 const double U2R = DAS2R / 1e4;
00925
00926
00927
00928
00929
00930
00931
00932 static const struct
00933 {
00934 int nl,nlp,nf,nd,nom;
00935 double sp,spt;
00936 double ce,cet;
00937 } x[] = {
00938
00939
00940 { 0, 0, 0, 0, 1, -171996.0, -174.2, 92025.0, 8.9 },
00941 { 0, 0, 0, 0, 2, 2062.0, 0.2, -895.0, 0.5 },
00942 { -2, 0, 2, 0, 1, 46.0, 0.0, -24.0, 0.0 },
00943 { 2, 0, -2, 0, 0, 11.0, 0.0, 0.0, 0.0 },
00944 { -2, 0, 2, 0, 2, -3.0, 0.0, 1.0, 0.0 },
00945 { 1, -1, 0, -1, 0, -3.0, 0.0, 0.0, 0.0 },
00946 { 0, -2, 2, -2, 1, -2.0, 0.0, 1.0, 0.0 },
00947 { 2, 0, -2, 0, 1, 1.0, 0.0, 0.0, 0.0 },
00948 { 0, 0, 2, -2, 2, -13187.0, -1.6, 5736.0, -3.1 },
00949 { 0, 1, 0, 0, 0, 1426.0, -3.4, 54.0, -0.1 },
00950
00951
00952 { 0, 1, 2, -2, 2, -517.0, 1.2, 224.0, -0.6 },
00953 { 0, -1, 2, -2, 2, 217.0, -0.5, -95.0, 0.3 },
00954 { 0, 0, 2, -2, 1, 129.0, 0.1, -70.0, 0.0 },
00955 { 2, 0, 0, -2, 0, 48.0, 0.0, 1.0, 0.0 },
00956 { 0, 0, 2, -2, 0, -22.0, 0.0, 0.0, 0.0 },
00957 { 0, 2, 0, 0, 0, 17.0, -0.1, 0.0, 0.0 },
00958 { 0, 1, 0, 0, 1, -15.0, 0.0, 9.0, 0.0 },
00959 { 0, 2, 2, -2, 2, -16.0, 0.1, 7.0, 0.0 },
00960 { 0, -1, 0, 0, 1, -12.0, 0.0, 6.0, 0.0 },
00961 { -2, 0, 0, 2, 1, -6.0, 0.0, 3.0, 0.0 },
00962
00963
00964 { 0, -1, 2, -2, 1, -5.0, 0.0, 3.0, 0.0 },
00965 { 2, 0, 0, -2, 1, 4.0, 0.0, -2.0, 0.0 },
00966 { 0, 1, 2, -2, 1, 4.0, 0.0, -2.0, 0.0 },
00967 { 1, 0, 0, -1, 0, -4.0, 0.0, 0.0, 0.0 },
00968 { 2, 1, 0, -2, 0, 1.0, 0.0, 0.0, 0.0 },
00969 { 0, 0, -2, 2, 1, 1.0, 0.0, 0.0, 0.0 },
00970 { 0, 1, -2, 2, 0, -1.0, 0.0, 0.0, 0.0 },
00971 { 0, 1, 0, 0, 2, 1.0, 0.0, 0.0, 0.0 },
00972 { -1, 0, 0, 1, 1, 1.0, 0.0, 0.0, 0.0 },
00973 { 0, 1, 2, -2, 0, -1.0, 0.0, 0.0, 0.0 },
00974
00975
00976 { 0, 0, 2, 0, 2, -2274.0, -0.2, 977.0, -0.5 },
00977 { 1, 0, 0, 0, 0, 712.0, 0.1, -7.0, 0.0 },
00978 { 0, 0, 2, 0, 1, -386.0, -0.4, 200.0, 0.0 },
00979 { 1, 0, 2, 0, 2, -301.0, 0.0, 129.0, -0.1 },
00980 { 1, 0, 0, -2, 0, -158.0, 0.0, -1.0, 0.0 },
00981 { -1, 0, 2, 0, 2, 123.0, 0.0, -53.0, 0.0 },
00982 { 0, 0, 0, 2, 0, 63.0, 0.0, -2.0, 0.0 },
00983 { 1, 0, 0, 0, 1, 63.0, 0.1, -33.0, 0.0 },
00984 { -1, 0, 0, 0, 1, -58.0, -0.1, 32.0, 0.0 },
00985 { -1, 0, 2, 2, 2, -59.0, 0.0, 26.0, 0.0 },
00986
00987
00988 { 1, 0, 2, 0, 1, -51.0, 0.0, 27.0, 0.0 },
00989 { 0, 0, 2, 2, 2, -38.0, 0.0, 16.0, 0.0 },
00990 { 2, 0, 0, 0, 0, 29.0, 0.0, -1.0, 0.0 },
00991 { 1, 0, 2, -2, 2, 29.0, 0.0, -12.0, 0.0 },
00992 { 2, 0, 2, 0, 2, -31.0, 0.0, 13.0, 0.0 },
00993 { 0, 0, 2, 0, 0, 26.0, 0.0, -1.0, 0.0 },
00994 { -1, 0, 2, 0, 1, 21.0, 0.0, -10.0, 0.0 },
00995 { -1, 0, 0, 2, 1, 16.0, 0.0, -8.0, 0.0 },
00996 { 1, 0, 0, -2, 1, -13.0, 0.0, 7.0, 0.0 },
00997 { -1, 0, 2, 2, 1, -10.0, 0.0, 5.0, 0.0 },
00998
00999
01000 { 1, 1, 0, -2, 0, -7.0, 0.0, 0.0, 0.0 },
01001 { 0, 1, 2, 0, 2, 7.0, 0.0, -3.0, 0.0 },
01002 { 0, -1, 2, 0, 2, -7.0, 0.0, 3.0, 0.0 },
01003 { 1, 0, 2, 2, 2, -8.0, 0.0, 3.0, 0.0 },
01004 { 1, 0, 0, 2, 0, 6.0, 0.0, 0.0, 0.0 },
01005 { 2, 0, 2, -2, 2, 6.0, 0.0, -3.0, 0.0 },
01006 { 0, 0, 0, 2, 1, -6.0, 0.0, 3.0, 0.0 },
01007 { 0, 0, 2, 2, 1, -7.0, 0.0, 3.0, 0.0 },
01008 { 1, 0, 2, -2, 1, 6.0, 0.0, -3.0, 0.0 },
01009 { 0, 0, 0, -2, 1, -5.0, 0.0, 3.0, 0.0 },
01010
01011
01012 { 1, -1, 0, 0, 0, 5.0, 0.0, 0.0, 0.0 },
01013 { 2, 0, 2, 0, 1, -5.0, 0.0, 3.0, 0.0 },
01014 { 0, 1, 0, -2, 0, -4.0, 0.0, 0.0, 0.0 },
01015 { 1, 0, -2, 0, 0, 4.0, 0.0, 0.0, 0.0 },
01016 { 0, 0, 0, 1, 0, -4.0, 0.0, 0.0, 0.0 },
01017 { 1, 1, 0, 0, 0, -3.0, 0.0, 0.0, 0.0 },
01018 { 1, 0, 2, 0, 0, 3.0, 0.0, 0.0, 0.0 },
01019 { 1, -1, 2, 0, 2, -3.0, 0.0, 1.0, 0.0 },
01020 { -1, -1, 2, 2, 2, -3.0, 0.0, 1.0, 0.0 },
01021 { -2, 0, 0, 0, 1, -2.0, 0.0, 1.0, 0.0 },
01022
01023
01024 { 3, 0, 2, 0, 2, -3.0, 0.0, 1.0, 0.0 },
01025 { 0, -1, 2, 2, 2, -3.0, 0.0, 1.0, 0.0 },
01026 { 1, 1, 2, 0, 2, 2.0, 0.0, -1.0, 0.0 },
01027 { -1, 0, 2, -2, 1, -2.0, 0.0, 1.0, 0.0 },
01028 { 2, 0, 0, 0, 1, 2.0, 0.0, -1.0, 0.0 },
01029 { 1, 0, 0, 0, 2, -2.0, 0.0, 1.0, 0.0 },
01030 { 3, 0, 0, 0, 0, 2.0, 0.0, 0.0, 0.0 },
01031 { 0, 0, 2, 1, 2, 2.0, 0.0, -1.0, 0.0 },
01032 { -1, 0, 0, 0, 2, 1.0, 0.0, -1.0, 0.0 },
01033 { 1, 0, 0, -4, 0, -1.0, 0.0, 0.0, 0.0 },
01034
01035
01036 { -2, 0, 2, 2, 2, 1.0, 0.0, -1.0, 0.0 },
01037 { -1, 0, 2, 4, 2, -2.0, 0.0, 1.0, 0.0 },
01038 { 2, 0, 0, -4, 0, -1.0, 0.0, 0.0, 0.0 },
01039 { 1, 1, 2, -2, 2, 1.0, 0.0, -1.0, 0.0 },
01040 { 1, 0, 2, 2, 1, -1.0, 0.0, 1.0, 0.0 },
01041 { -2, 0, 2, 4, 2, -1.0, 0.0, 1.0, 0.0 },
01042 { -1, 0, 4, 0, 2, 1.0, 0.0, 0.0, 0.0 },
01043 { 1, -1, 0, -2, 0, 1.0, 0.0, 0.0, 0.0 },
01044 { 2, 0, 2, -2, 1, 1.0, 0.0, -1.0, 0.0 },
01045 { 2, 0, 2, 2, 2, -1.0, 0.0, 0.0, 0.0 },
01046
01047
01048 { 1, 0, 0, 2, 1, -1.0, 0.0, 0.0, 0.0 },
01049 { 0, 0, 4, -2, 2, 1.0, 0.0, 0.0, 0.0 },
01050 { 3, 0, 2, -2, 2, 1.0, 0.0, 0.0, 0.0 },
01051 { 1, 0, 2, -2, 0, -1.0, 0.0, 0.0, 0.0 },
01052 { 0, 1, 2, 0, 1, 1.0, 0.0, 0.0, 0.0 },
01053 { -1, -1, 0, 2, 1, 1.0, 0.0, 0.0, 0.0 },
01054 { 0, 0, -2, 0, 1, -1.0, 0.0, 0.0, 0.0 },
01055 { 0, 0, 2, -1, 2, -1.0, 0.0, 0.0, 0.0 },
01056 { 0, 1, 0, 2, 0, -1.0, 0.0, 0.0, 0.0 },
01057 { 1, 0, -2, -2, 0, -1.0, 0.0, 0.0, 0.0 },
01058
01059
01060 { 0, -1, 2, 0, 1, -1.0, 0.0, 0.0, 0.0 },
01061 { 1, 1, 0, -2, 1, -1.0, 0.0, 0.0, 0.0 },
01062 { 1, 0, -2, 2, 0, -1.0, 0.0, 0.0, 0.0 },
01063 { 2, 0, 0, 2, 0, 1.0, 0.0, 0.0, 0.0 },
01064 { 0, 0, 2, 4, 2, -1.0, 0.0, 0.0, 0.0 },
01065 { 0, 1, 0, 1, 0, 1.0, 0.0, 0.0, 0.0 }
01066 };
01067
01068
01069 const int NT = (int) (sizeof x / sizeof x[0]);
01070
01071
01072
01073 const double t = ( TT - J2000 ) / 86400.0 / DJC;
01074
01075
01076
01077
01078
01079 double el = normalizeAngle(
01080 (485866.733 + (715922.633 + (31.310 + 0.064 * t) * t) * t)
01081 * DAS2R + fmod(1325.0 * t, 1.0) * D2PI);
01082
01083
01084 double elp = normalizeAngle(
01085 (1287099.804 + (1292581.224 + (-0.577 - 0.012 * t) * t) * t)
01086 * DAS2R + fmod(99.0 * t, 1.0) * D2PI);
01087
01088
01089 double f = normalizeAngle(
01090 (335778.877 + (295263.137 + (-13.257 + 0.011 * t) * t) * t)
01091 * DAS2R + fmod(1342.0 * t, 1.0) * D2PI);
01092
01093
01094 double d = normalizeAngle(
01095 (1072261.307 + (1105601.328 + (-6.891 + 0.019 * t) * t) * t)
01096 * DAS2R + fmod(1236.0 * t, 1.0) * D2PI);
01097
01098
01099
01100 double om = normalizeAngle(
01101 (450160.280 + (-482890.539 + (7.455 + 0.008 * t) * t) * t)
01102 * DAS2R + fmod(-5.0 * t, 1.0) * D2PI);
01103
01104
01105
01106
01107
01108
01109 double dp = 0.0;
01110 double de = 0.0;
01111
01112
01113 for (int j = NT-1; j >= 0; j--)
01114 {
01115
01116
01117 double arg = (double)x[j].nl * el
01118 + (double)x[j].nlp * elp
01119 + (double)x[j].nf * f
01120 + (double)x[j].nd * d
01121 + (double)x[j].nom * om;
01122
01123
01124 double s = x[j].sp + x[j].spt * t;
01125 double c = x[j].ce + x[j].cet * t;
01126 if (s != 0.0) dp += s * std::sin(arg);
01127 if (c != 0.0) de += c * std::cos(arg);
01128 }
01129
01130
01131 dpsi = dp * U2R;
01132 deps = de * U2R;
01133
01134 }
01135
01136
01137 double meanObliquity(const CommonTime& TT)
01138 {
01139
01140 const double t = ( TT - J2000 ) / 86400.0 / DJC;
01141 const double t2 = t*t;
01142 const double t3 = t2*t;
01143
01144 return (84381.448-46.8150*t-0.00059*t2+0.001813*t3)*DAS2R;
01145 }
01146
01147 double iauEqeq94(const CommonTime& TT,double eps,double dPsi)
01148 {
01149
01150 double t = ( TT - J2000 ) / 86400.0 / DJC;
01151
01152
01153
01154 double om = normalizeAngle((450160.280 + (-482890.539
01155 + (7.455 + 0.008 * t) * t) * t) * DAS2R
01156 + fmod(-5.0 * t, 1.0) * D2PI);
01157
01158
01159
01160
01161
01162
01163
01164
01165 double ee = dPsi * std::cos(eps)
01166 + DAS2R*(0.00264 * std::sin(om) + 0.000063 * std::sin(om + om));
01167
01168 return ee;
01169 }
01170
01171 double iauGmst82(const CommonTime& UT1)
01172 {
01173
01174 const double A = 24110.54841 - 86400.0 / 2.0;
01175 const double B = 8640184.812866;
01176 const double C = 0.093104;
01177 const double D = -6.2e-6;
01178
01179
01180
01181
01182
01183
01184 double d2 = MJD_TO_JD;
01185 double d1 = MJD(UT1).mjd;
01186 double t = ( MJD(UT1).mjd - MJD(J2000).mjd ) / DJC;
01187
01188
01189 double f = 86400.0 * (fmod(d1, 1.0) + fmod(d2, 1.0));
01190
01191
01192 double gmst = normalizeAngle(
01193 DS2R * ((A + (B + (C + D * t) * t) * t) + f));
01194
01195 return gmst;
01196
01197 }
01198
01199
01200 double iauGmst00(const CommonTime& UT1,CommonTime TT)
01201 {
01202
01203
01204 double t = ( TT - J2000 ) / 86400.0 / DJC;
01205
01206
01207 double gmst = normalizeAngle(earthRotationAngle(UT1) +
01208 ( 0.014506 +
01209 ( 4612.15739966 +
01210 ( 1.39667721 +
01211 ( -0.00009344 +
01212 ( 0.00001882 )
01213 * t) * t) * t) * t) * DAS2R);
01214
01215 return gmst;
01216
01217 }
01218
01219
01220
01221 Matrix<double> iauNmat(const double& eps, const double& dpsi, const double& deps)
01222 {
01223 return ( Rx(-(eps+deps)) * Rz(-dpsi) * Rx(eps) );
01224 }
01225
01226
01227
01228 double earthRotationAngle(const CommonTime& UT1)
01229 {
01230
01231 double t = (UT1 - J2000)/86400.0;
01232 double f = ( fmod(static_cast<double>(MJD(UT1).mjd), 1.0) +
01233 fmod(static_cast<double>(MJD_TO_JD), 1.0) );
01234
01235 double era = normalizeAngle(D2PI*(f+0.7790572732640+0.00273781191135448*t));
01236
01237 return era;
01238 }
01239
01240
01241
01242
01243
01244 double earthRotationAngleRate1(const CommonTime& TT)
01245 {
01246 double T = ( TT - J2000 )/86400.0/36525.0;
01247 double dera = (1.002737909350795 + 5.9006e-11 * T - 5.9e-15 * T * T )
01248 * D2PI / 86400.0;
01249
01250 return dera;
01251 }
01252
01253
01254
01255
01256 }