00001 #pragma ident "$Id: SolarRadiationPressure.cpp 2457 2010-08-18 14:20:12Z coandrei $"
00002
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "SolarRadiationPressure.hpp"
00033 #include "ASConstant.hpp"
00034 #include "ReferenceFrames.hpp"
00035
00036 namespace gpstk
00037 {
00038
00039
00040
00041
00042
00043
00044
00045
00046 double SolarRadiationPressure::getShadowFunction(Vector<double> r,
00047 Vector<double> r_Sun,
00048 Vector<double> r_Moon,
00049 SolarRadiationPressure::ShadowModel sm)
00050 {
00051
00052 double v = 0.0;
00053
00054
00055 const double R_sun = ASConstant::R_Sun;
00056 const double R_moon = ASConstant::R_Moon;
00057 const double R_earth = ASConstant::R_Earth;
00058
00059 Vector<double> e_Sun = r_Sun/norm(r_Sun);
00060
00061 double r_dot_sun = dot(r,e_Sun);
00062
00063 if(r_dot_sun>0)
00064 {
00065
00066 v= 1.0;
00067 return v;
00068 }
00069
00070 if(sm == SM_CYLINDRICAL)
00071 {
00072
00073 v = ((r_dot_sun>0 || norm(r-r_dot_sun*e_Sun)>R_earth) ? 1.0 : 0.0);
00074 return v;
00075 }
00076 else if(sm == SM_CONICAL)
00077 {
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00143
00144 double r_sun_mag = norm(r_Sun);
00145 double r_mag = norm(r);
00146
00147 Vector<double> d = r_Sun-r;
00148 double dmag = norm(d);
00149
00150 double a = std::asin(R_sun/dmag);
00151 double b = std::asin(R_earth/r_mag);
00152 double c = std::acos(-1.0*dot(r,d)/(r_mag*dmag));
00153
00154 if((a+b)<=c)
00155 {
00156 v = 1.0;
00157 }
00158 else if(c < (b-a))
00159 {
00160 v = 0.0;
00161 }
00162 else
00163 {
00164 double x = (c*c+a*a-b*b)/(2*c);
00165 double y = std::sqrt(a*a-x*x);
00166 double A = a*a*std::acos(x/a)+b*b*std::acos((c-x)/b)-c*y;
00167 v = 1.0 - A/(ASConstant::PI*a*a);
00168 }
00169
00170 return v;
00171 }
00172 else
00173 {
00174
00175 Exception e("Unexpect ShadowModel in getShadowFunction()");
00176 GPSTK_THROW(e);
00177 }
00178
00179 return v;
00180
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190 Vector<double> SolarRadiationPressure::accelSRP(Vector<double> r, Vector<double> r_Sun)
00191 {
00192
00193 Vector<double> d = r-r_Sun;
00194 double dmag = norm(d);
00195 double dcubed = dmag * dmag * dmag;
00196 double au2 = ASConstant::AU * ASConstant::AU;
00197
00198 double P_STK = 4.5344321837439e-06;
00199
00200
00201
00202 double Ls = 3.823e26;
00203 double factor = reflectCoeff * (crossArea/dryMass) * Ls
00204 / (4.0*ASConstant::PI*ASConstant::SPEED_OF_LIGHT*dcubed);
00205
00206 Vector<double> out = d * factor;
00207
00208 return out;
00209
00210 }
00211
00212
00213
00214
00215
00216
00217
00218
00219 double SolarRadiationPressure::partial_illumination(Vector<double> r, Vector<double> r_Sun )
00220 {
00221 double r_sun_mag = norm(r_Sun);
00222 double r_mag = norm(r);
00223
00224 double R_sun = ASConstant::R_Sun;
00225 double R_earth = ASConstant::R_Earth;
00226 Vector<double> d = r_Sun-r;
00227 double dmag = norm(d);
00228 double sd = -1.0 * dot(r,d);
00229 double a = std::asin(R_sun/dmag);
00230 double b = std::asin(R_earth/r_mag);
00231 double c = std::acos(sd/(r_mag*dmag));
00232
00233 if((a+b)<=c)
00234 {
00235 return 1.0;
00236 }
00237 else if(c < (b-a))
00238 {
00239 return 0.0;
00240 }
00241 else
00242 {
00243 double x = (c*c+a*a-b*b)/(2*c);
00244 double y = std::sqrt(a*a-x*x);
00245 double A = a*a*std::acos(x/a)+b*b*std::acos((c-x)/b)-c*y;
00246 double nu = 1 - A/(ASConstant::PI*a*a);
00247 return nu;
00248 }
00249
00250 }
00251
00252
00253 void SolarRadiationPressure::doCompute(UTCTime utc, EarthBody& rb, Spacecraft& sc)
00254 {
00255 crossArea = sc.getDragArea();
00256 dryMass = sc.getDryMass();
00257 reflectCoeff = sc.getReflectCoeff();
00258
00259 Vector<double> r_sun = ReferenceFrames::getJ2kPosition(utc.asTDB(),SolarSystem::Sun);
00260 Vector<double> r_moon = ReferenceFrames::getJ2kPosition(utc.asTDB(),SolarSystem::Moon);
00261
00262
00263 r_sun = r_sun*1000.0;
00264 r_moon = r_moon*1000.0;
00265
00266
00267 a = accelSRP(sc.R(),r_sun)*getShadowFunction(sc.R(),r_sun,r_moon,SM_CONICAL);
00268
00269
00270
00271 da_dr.resize(3,3,0.0);
00272
00273 double au2 = ASConstant::AU * ASConstant::AU;
00274 double factor = -1.0*reflectCoeff * (crossArea/dryMass) * ASConstant::P_Sol*au2;
00275
00276 Vector<double> d = sc.R() - r_sun;
00277 double dmag = norm(d);
00278 double dcubed = dmag * dmag *dmag;
00279
00280 Vector<double> temp1 = d / dcubed;
00281
00282 double smag = norm(r_sun);
00283 double scubed = smag * smag * smag;
00284
00285 double muod3 = factor / dcubed;
00286 double jk = 3.0 * muod3/dmag/dmag;
00287
00288 double xx = d(0);
00289 double yy = d(1);
00290 double zz = d(2);
00291
00292 da_dr(0,0) = jk * xx * xx - muod3;
00293 da_dr(0,1) = jk * xx * yy;
00294 da_dr(0,2) = jk * xx * zz;
00295
00296 da_dr(1,0) = da_dr(0,1);
00297 da_dr(1,1) = jk * yy * yy - muod3;
00298 da_dr(1,2) = jk * yy * zz;
00299
00300 da_dr(2,0) = da_dr(0,2);
00301 da_dr(2,1) = da_dr(1,2);
00302 da_dr(2,2) = jk * zz * zz - muod3;
00303
00304
00305 da_dv.resize(3,3,0.0);
00306
00307
00308 dadcr.resize(3,0.0);
00309 dadcr = a /reflectCoeff;
00310
00311 da_dcr(0,0) = dadcr(0);
00312 da_dcr(1,0) = dadcr(1);
00313 da_dcr(2,0) = dadcr(2);
00314
00315 }
00316
00317 }
00318