//------------------------------------------------------------------------------ Rmatrix33 ITRFAxes::Skew(Rvector3 vec) { Rmatrix33 r; r.SetElement(0,0,0.0); r.SetElement(0,1,-vec.GetElement(2)); r.SetElement(0,2,vec.GetElement(1)); r.SetElement(1,0,vec.GetElement(2)); r.SetElement(1,1,0.0); r.SetElement(1,2,-vec.GetElement(0)); r.SetElement(2,0,-vec.GetElement(1)); r.SetElement(2,1,vec.GetElement(0)); r.SetElement(2,2,0.0); return r; }
//------------------------------------------------------------------------------ Rmatrix33 ITRFAxes::R3(Real angle) { Rmatrix33 r; Real c = cos(angle); Real s = sin(angle); r.SetElement(0,0,c); r.SetElement(0,1,s); r.SetElement(0,2,0.0); r.SetElement(1,0,-s); r.SetElement(1,1,c); r.SetElement(1,2,0.0); r.SetElement(2,0,0.0); r.SetElement(2,1,0.0); r.SetElement(2,2,1.0); return r; }
void CoordinateConverter::RotationMatrixFromICRFToFK5(const A1Mjd &atEpoch) { Real theEpoch = atEpoch.Get(); #ifdef DEBUG_ICRF_TOFK5 MessageInterface::ShowMessage( "Enter CoordinateConverter::RotationMatrixFromICRFToFK5 at epoch %18.12lf; \n\n", theEpoch); #endif // Specify Euler rotation vector for theEpoch: Real vec[3]; ICRFFile* icrfFile = ICRFFile::Instance(); icrfFile->Initialize(); icrfFile->GetICRFRotationVector(theEpoch, &vec[0], 3, 9); // Calculate rotation matrix based on Euler rotation vector: Real angle = GmatMathUtil::Sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]); Real a[3]; a[0] = vec[0]/angle; a[1] = vec[1]/angle; a[2] = vec[2]/angle; Real c = GmatMathUtil::Cos(angle); Real s = GmatMathUtil::Sin(angle); // rotation matrix from FK5 to ICRF: Rmatrix33 rotM; rotM.SetElement(0,0, c+a[0]*a[0]*(1-c)); rotM.SetElement(0,1, a[0]*a[1]*(1-c)+a[2]*s); rotM.SetElement(0,2, a[0]*a[2]*(1-c)-a[1]*s); rotM.SetElement(1,0, a[0]*a[1]*(1-c)-a[2]*s); rotM.SetElement(1,1, c+a[1]*a[1]*(1-c)); rotM.SetElement(1,2, a[1]*a[2]*(1-c)+a[0]*s); rotM.SetElement(2,0, a[0]*a[2]*(1-c)+a[1]*s); rotM.SetElement(2,1, a[1]*a[2]*(1-c)-a[0]*s); rotM.SetElement(2,2, c+a[2]*a[2]*(1-c)); // rotation matrix from ICRF to FK5: icrfToFK5 = rotM.Transpose(); // rotation dot matrix from ICRF to FK5: icrfToFK5Dot.Set(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); #ifdef DEBUG_ICRF_TOFK5 MessageInterface::ShowMessage("theEpoch = %18.12lf\n",theEpoch); MessageInterface::ShowMessage("rotation vector = %18.12e %18.12e %18.12e\n", vec[0], vec[1], vec[2]); MessageInterface::ShowMessage("R(0,0)=%18.12e, R(0,1)=%18.12e, R(0,2)=%18.12e\n",icrfToFK5(0,0),icrfToFK5(0,1),icrfToFK5(0,2)); MessageInterface::ShowMessage("R(1,0)=%18.12e, R(1,1)=%18.12e, R(1,2)=%18.12e\n",icrfToFK5(1,0),icrfToFK5(1,1),icrfToFK5(1,2)); MessageInterface::ShowMessage("R(2,0)=%18.12e, R(2,1)=%18.12e, R(2,2)=%18.12e\n",icrfToFK5(2,0),icrfToFK5(2,1),icrfToFK5(2,2)); MessageInterface::ShowMessage("Rdot(0,0)=%18.12e, Rdot(0,1)=%18.12e, Rdot(0,2)=%18.12e\n",icrfToFK5Dot(0,0),icrfToFK5Dot(0,1),icrfToFK5Dot(0,2)); MessageInterface::ShowMessage("Rdot(1,0)=%18.12e, Rdot(1,1)=%18.12e, Rdot(1,2)=%18.12e\n",icrfToFK5Dot(1,0),icrfToFK5Dot(1,1),icrfToFK5Dot(1,2)); MessageInterface::ShowMessage("Rdot(2,0)=%18.12e, Rdot(2,1)=%18.12e, Rdot(2,2)=%18.12e\n\n\n",icrfToFK5Dot(2,0),icrfToFK5Dot(2,1),icrfToFK5Dot(2,2)); #endif #ifdef DEBUG_ICRF_TOFK5 MessageInterface::ShowMessage("NOW exiting CoordinateConverter::RotationMatrixFromICRFToFK5 ...\n\n"); #endif }
//------------------------------------------------------------------------------ void ITRFAxes::CalculateRotationMatrix(const A1Mjd &atEpoch, bool forceComputation) { #ifdef DEBUG_FIRST_CALL if (!firstCallFired) MessageInterface::ShowMessage( "Calling ITRF::CalculateRotationMatrix at epoch %18.12lf; \n", atEpoch.Get()); #endif Real theEpoch = atEpoch.Get(); // Perform time computations and read EOP file Real sec2rad = GmatMathConstants::RAD_PER_DEG/3600; Real a1MJD = theEpoch; Real utcMJD = TimeConverterUtil::Convert(a1MJD, TimeConverterUtil::A1MJD, TimeConverterUtil::UTCMJD, JD_JAN_5_1941); Real offset = JD_JAN_5_1941 - JD_NOV_17_1858; Real xp,yp,LOD,dUT1; dUT1 = eop->GetUt1UtcOffset(utcMJD + offset); eop->GetPolarMotionAndLod(utcMJD + offset, xp, yp, LOD); xp = xp*sec2rad; yp = yp*sec2rad; Real ut1MJD = TimeConverterUtil::Convert(a1MJD, TimeConverterUtil::A1MJD, TimeConverterUtil::UT1, JD_JAN_5_1941); // Compute elapsed Julian centuries (UT1) Real tDiff = JD_JAN_5_1941 - JD_OF_J2000; Real jdUT1 = ut1MJD + JD_JAN_5_1941; // convert input A1 MJD to TT MJD (for most calculations) Real ttMJD = TimeConverterUtil::Convert(a1MJD, TimeConverterUtil::A1MJD, TimeConverterUtil::TTMJD, JD_JAN_5_1941); Real jdTT = ttMJD + JD_JAN_5_1941; // right? // Compute Julian centuries of TDB from the base epoch (J2000) // NOTE - this is really TT, an approximation of TDB ********* Real T_TT = (ttMJD + tDiff) / DAYS_PER_JULIAN_CENTURY; // Compute the Polar Motion Matrix, W, and Earth Rotation Angle, theta Real sPrime = -0.000047*sec2rad*T_TT; Rmatrix33 W = R3(-sPrime)*R2(xp)*R1(yp); Real theta = fmod(GmatMathConstants::TWO_PI*(0.7790572732640 + 1.00273781191135448*(jdUT1 - 2451545.0)),GmatMathConstants::TWO_PI); // Compute the precession-nutation matrix // . interpolate the XYs data file Real data[3]; if (iauFile == NULL) { throw CoordinateSystemException("Error: IAUFile object is NULL. GMAT cannot get IAU data.\n"); } iauFile->GetIAUData(jdTT,data,3,9); Real X = data[0]*sec2rad; Real Y = data[1]*sec2rad; Real s = data[2]*sec2rad; // . construct the Precession Nutation matrix Real b = 1/(1 + sqrt(1- X*X - Y*Y)); Rmatrix33 CT; CT.SetElement(0,0, 1-b*X*X); CT.SetElement(0,1, -b*X*Y ); CT.SetElement(0,2,X); CT.SetElement(1,0, -b*X*Y); CT.SetElement(1,1, 1-b*Y*Y); CT.SetElement(1,2,Y); CT.SetElement(2,0, -X); CT.SetElement(2,1, -Y); CT.SetElement(2,2,(1 - b*(X*X + Y*Y))); CT = CT*R3(s); // Form the complete rotation matrix from ITRF to GCRF Rmatrix33 R = CT*R3(-theta)*W; Real omegaEarth = 7.292115146706979e-5*(1 - LOD/86400); Rvector3 vec(0.0, 0.0, omegaEarth); Rmatrix33 Rdot = CT*R3(-theta)*Skew(vec)*W; rotMatrix = R; rotDotMatrix = Rdot; #ifdef DEBUG_ITRF_ROT_MATRIX MessageInterface::ShowMessage("a1MJD = %18.10lf\n",a1MJD); MessageInterface::ShowMessage("utcMJD = %18.10lf\n",utcMJD); MessageInterface::ShowMessage("dUT1=%18.10e, xp=%18.10e, yp=%18.10e, LOD=%18.10e\n",dUT1,xp,yp,LOD); MessageInterface::ShowMessage("ut1MJD = %18.10lf\n",ut1MJD); MessageInterface::ShowMessage("ttMJD = %18.10lf\n",ttMJD); MessageInterface::ShowMessage("jdTT = %18.10lf\n",jdTT); MessageInterface::ShowMessage("jdUT1 = %18.10lf\n",jdUT1); MessageInterface::ShowMessage("T_TT = %18.10lf\n\n",T_TT); MessageInterface::ShowMessage("sPrime = %18.10lf, theta = %18.10lf\n",sPrime, theta); MessageInterface::ShowMessage("W(0,0)=%18.10lf, W(0,1)=%18.10lf, W(0,2)=%18.10lf\n",W.GetElement(0,0),W.GetElement(0,1),W.GetElement(0,2)); MessageInterface::ShowMessage("W(1,0)=%18.10lf, W(1,1)=%18.10lf, W(1,2)=%18.10lf\n",W.GetElement(1,0),W.GetElement(1,1),W.GetElement(1,2)); MessageInterface::ShowMessage("W(2,0)=%18.10lf, W(2,1)=%18.10lf, W(2,2)=%18.10lf\n",W.GetElement(2,0),W.GetElement(2,1),W.GetElement(2,2)); MessageInterface::ShowMessage("X = %18.10lf, Y = %18.10lf, s = %18.10lf\n", X, Y, s); MessageInterface::ShowMessage("CT(0,0)=%18.10lf, CT(0,1)=%18.10lf, CT(0,2)=%18.10lf\n",CT.GetElement(0,0),CT.GetElement(0,1),CT.GetElement(0,2)); MessageInterface::ShowMessage("CT(1,0)=%18.10lf, CT(1,1)=%18.10lf, CT(1,2)=%18.10lf\n",CT.GetElement(1,0),CT.GetElement(1,1),CT.GetElement(1,2)); MessageInterface::ShowMessage("CT(2,0)=%18.10lf, CT(2,1)=%18.10lf, CT(2,2)=%18.10lf\n",CT.GetElement(2,0),CT.GetElement(2,1),CT.GetElement(2,2)); MessageInterface::ShowMessage("R(0,0)=%18.10lf, R(0,1)=%18.10lf, R(0,2)=%18.10lf\n",R.GetElement(0,0),R.GetElement(0,1),R.GetElement(0,2)); MessageInterface::ShowMessage("R(1,0)=%18.10lf, R(1,1)=%18.10lf, R(1,2)=%18.10lf\n",R.GetElement(1,0),R.GetElement(1,1),R.GetElement(1,2)); MessageInterface::ShowMessage("R(2,0)=%18.10lf, R(2,1)=%18.10lf, R(2,2)=%18.10lf\n",R.GetElement(2,0),R.GetElement(2,1),R.GetElement(2,2)); MessageInterface::ShowMessage("Rdot(0,0)=%18.10lf, Rdot(0,1)=%18.10lf, Rdot(0,2)=%18.10lf\n",Rdot.GetElement(0,0),Rdot.GetElement(0,1),Rdot.GetElement(0,2)); MessageInterface::ShowMessage("Rdot(1,0)=%18.10lf, Rdot(1,1)=%18.10lf, Rdot(1,2)=%18.10lf\n",Rdot.GetElement(1,0),Rdot.GetElement(1,1),Rdot.GetElement(1,2)); MessageInterface::ShowMessage("Rdot(2,0)=%18.10lf, Rdot(2,1)=%18.10lf, Rdot(2,2)=%18.10lf\n\n\n",Rdot.GetElement(2,0),Rdot.GetElement(2,1),Rdot.GetElement(2,2)); #endif #ifdef DEBUG_FIRST_CALL firstCallFired = true; MessageInterface::ShowMessage("NOW exiting ITRFAxes::CalculateRotationMatrix ...\n"); #endif }