00001
00002
00003 #include "astro/EarthOrbit.h"
00004 #include "astro/EarthCoordinate.h"
00005
00006 #include <cmath>
00007
00008 namespace {
00009
00010 double SecondsPerDay = 86400.;
00011 double R2D = 180/M_PI;
00012 double EarthFlat= (1/298.25);
00013
00014 void range (double *s, double m)
00015 {
00016 while((*s)>=m) (*s)-=m;
00017 while((*s)<0) (*s)+=m;
00018 }
00019
00020
00021 inline double sqr(double x){return x*x;}
00022
00023 astro::JulianDate JD_missionStart =astro::JulianDate(2005, 1, 1,0.0);
00024 astro::JulianDate JDStart = astro::JulianDate(2005.,7,18,0.0);
00025 }
00026
00027
00028
00029 namespace astro {
00030 double EarthOrbit::s_altitude = 550.e3 ;
00031 double EarthOrbit::s_incl = 28.5*M_PI/180;
00032 double EarthOrbit::s_e = 0.;
00033
00034 double EarthOrbit::s_radius = 6378145.;
00035
00036
00037
00038
00039 EarthOrbit::EarthOrbit()
00040 {
00041 initialize();
00042 }
00043
00044 void EarthOrbit::initialize()
00045 {
00046 double sini = sin(s_incl), cosi = cos(s_incl);
00047 static double J2=1.0822e-3;
00048
00049 m_alt=(s_radius + s_altitude)/1000.;
00050 m_a = 1.0 + s_altitude/s_radius;
00051
00052 double T = M_PI/2*pow(m_a,1.5)/sqrt(5.98e24*6.67e-11)*pow(s_radius,1.5) ;
00053
00054 double u = 3.9860044e14/pow(s_radius,3) ;
00055 double n = sqrt(u / pow(m_a,3));
00056 double n1 = n*(1. + 3.*J2/2.*sqrt(1. - s_e*s_e)/(m_a*m_a)/pow((1. - s_e*s_e),2)*(1.-1.5*sini*sini));
00057 m_dwdt = n1*3.*J2/2./(m_a*m_a)/pow((1. - s_e*s_e),2)*(2. - 2.5*sini*sini);
00058
00059 m_dOmegadt = -n1*3.*J2/2./(m_a*m_a)/pow((1. - s_e*s_e),2)*cosi;
00060 m_dMdt = n1;
00061
00062
00063
00064 double StartSimDate = (JDStart-JD_missionStart) * SecondsPerDay;
00065 m_M0 = m_dMdt*StartSimDate;
00066 m_Omega0 = m_dOmegadt*StartSimDate;
00067 m_w0 = m_dwdt*StartSimDate;
00068
00069 range(&m_M0,6.28);
00070
00071 }
00072
00073
00074 Hep3Vector EarthOrbit::position(JulianDate JD) const
00075 {
00076 double elapse = (JD - JDStart)*SecondsPerDay;
00077
00078 double M=m_M0+m_dMdt*elapse;
00079
00080 double Omega = m_Omega0+m_dOmegadt*elapse;
00081
00082
00083 range(&M,6.28);
00084 range(&Omega,6.28);
00085
00086 double w = m_w0+m_dwdt*elapse;
00087 double Enew =Kepler(M,s_e);
00088
00089
00090 Hep3Vector pos= Hep3Vector( cos(Enew)-s_e, sqrt(1.-sqr(s_e))*sin(Enew), 0 ).unit()*m_alt;
00091 pos.rotateZ(w).rotateX(s_incl).rotateZ(Omega);
00092
00093 return pos;
00094 }
00095
00096 double EarthOrbit::Kepler(double MeanAnomaly,double Eccentricity)
00097 {
00098 double E = MeanAnomaly;
00099 if( Eccentricity==0) return E;
00100 double Error;
00101 double TrueAnomaly;
00102
00103 do
00104 {
00105 Error = (E - Eccentricity*sin(E) - MeanAnomaly)
00106 / (1. - Eccentricity*cos(E));
00107 E -= Error;
00108 }
00109 while (fabs(Error) >= 0.000001);
00110
00111 if (fabs(E-M_PI) < 0.000001)
00112 TrueAnomaly = M_PI;
00113 else
00114 TrueAnomaly = 2.*atan(sqrt((1.+Eccentricity)/(1.-Eccentricity))
00115 *tan(E/2.));
00116 if (TrueAnomaly < 0)
00117 TrueAnomaly += 2.*M_PI;
00118
00119 return TrueAnomaly;
00120 }
00121
00122 }