00001 #pragma ident "$Id: SatOrbit.cpp 2457 2010-08-18 14:20:12Z coandrei $"
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 "SatOrbit.hpp"
00032 #include "JGM3GravityModel.hpp"
00033 #include "EGM96GravityModel.hpp"
00034 #include "HarrisPriesterDrag.hpp"
00035 #include "Msise00Drag.hpp"
00036 #include "CiraExponentialDrag.hpp"
00037
00038 namespace gpstk
00039 {
00040
00041 Vector<double> SatOrbit::getDerivatives(const double& t,
00042 const Vector<double>& y)
00043 {
00044 if(fmlPrepared == false)
00045 {
00046 createFMObjects(forceConfig);
00047 }
00048
00049
00050 sc.setStateVector(y);
00051
00052 UTCTime utc = utc0;
00053 utc += t;
00054 return forceList.getDerivatives(utc, earthBody, sc);
00055 }
00056
00057 void SatOrbit::init()
00058 {
00059 setSpacecraftData("sc-test01",1000.0,20.0,20.0,1.0,2.2);
00060
00061 enableGeopotential(GM_JGM3,1,1,false,false,false);
00062 enableThirdBodyPerturbation(false,false);
00063 enableAtmosphericDrag(AM_HarrisPriester,false);
00064 enableSolarRadiationPressure(false);
00065 enableRelativeEffect(false);
00066
00067 }
00068
00069
00070 SatOrbit& SatOrbit::setSpacecraftData(std::string name,
00071 const double& mass,
00072 const double& area,
00073 const double& areaSRP,
00074 const double& Cr,
00075 const double& Cd)
00076 {
00077 sc.setName(name);
00078 sc.setDryMass(mass);
00079 sc.setDragArea(area);
00080 sc.setSRPArea(areaSRP);
00081 sc.setDragCoeff(Cd);
00082 sc.setReflectCoeff(Cr);
00083
00084 return (*this);
00085
00086 }
00087
00088 SatOrbit& SatOrbit::setSpaceData(double dayF107,
00089 double aveF107,
00090 double dayKp)
00091 {
00092 forceConfig.dailyF107 = dayF107;
00093 forceConfig.averageF107 = aveF107;
00094 forceConfig.dailyKp = dayKp;
00095
00096 return (*this);
00097 }
00098
00099 SatOrbit& SatOrbit::enableGeopotential(SatOrbit::GravityModel model,
00100 const int& maxDegree,
00101 const int& maxOrder,
00102 const bool& solidTide,
00103 const bool& oceanTide,
00104 const bool& poleTide)
00105 {
00106
00107 if(fmlPrepared) return (*this);
00108
00109 forceConfig.geoEarth = true;
00110
00111 forceConfig.grvModel = model;
00112 forceConfig.grvDegree = maxDegree;
00113 forceConfig.grvOrder = maxOrder;
00114
00115 forceConfig.solidTide = solidTide;
00116 forceConfig.oceanTide = oceanTide;
00117 forceConfig.poleTide = poleTide;
00118
00119 return (*this);
00120
00121 }
00122
00123
00124 SatOrbit& SatOrbit::enableThirdBodyPerturbation(const bool& bsun,
00125 const bool& bmoon)
00126 {
00127
00128 if(fmlPrepared) return (*this);
00129
00130 forceConfig.geoSun = bsun;
00131 forceConfig.geoMoon = bmoon;
00132
00133 return (*this);
00134
00135 }
00136
00137
00138 SatOrbit& SatOrbit::enableAtmosphericDrag(SatOrbit::AtmosphericModel model,
00139 const bool& bdrag)
00140 {
00141
00142 if(fmlPrepared) return (*this);
00143
00144 forceConfig.atmModel = model;
00145 forceConfig.atmDrag = bdrag;
00146
00147 return (*this);
00148
00149 }
00150
00151
00152 SatOrbit& SatOrbit::enableSolarRadiationPressure(bool bsrp)
00153 {
00154
00155 if(fmlPrepared) return (*this);
00156
00157 forceConfig.solarPressure = bsrp;
00158
00159 return (*this);
00160
00161 }
00162
00163
00164 SatOrbit& SatOrbit::enableRelativeEffect(const bool& brel)
00165 {
00166
00167 if(fmlPrepared) return (*this);
00168
00169 forceConfig.relEffect = brel;
00170
00171 return (*this);
00172
00173 }
00174
00175 void SatOrbit::createFMObjects(FMCData& fmc)
00176 {
00177
00178 deleteFMObjects(fmc);
00179
00180
00181
00182
00183 if(fmc.grvModel == GM_JGM3)
00184 {
00185 fmc.pGeoEarth = new JGM3GravityModel();
00186 }
00187 else if(fmc.grvModel == GM_EGM96)
00188 {
00189 fmc.pGeoEarth = new EGM96GravityModel();
00190 }
00191 else
00192 {
00193
00194 }
00195
00196
00197 fmc.pGeoSun = new SunForce();
00198
00199
00200 fmc.pGeoMoon = new MoonForce();
00201
00202
00203 if(fmc.atmModel == AM_HarrisPriester)
00204 {
00205 fmc.pAtmDrag = new HarrisPriesterDrag();
00206 }
00207 else if(fmc.atmModel == AM_MSISE00)
00208 {
00209 fmc.pAtmDrag = new Msise00Drag();
00210 }
00211 else if(fmc.atmModel == AM_CIRA)
00212 {
00213 fmc.pAtmDrag = new CiraExponentialDrag();
00214 }
00215 else
00216 {
00217
00218 }
00219
00220
00221 fmc.pSolarPressure = new SolarRadiationPressure();
00222
00223
00224 fmc.pRelEffect = new RelativityEffect();
00225
00226
00227 if( !fmc.pGeoEarth || !fmc.pGeoSun || !fmc.pGeoMoon ||
00228 !fmc.pAtmDrag || !fmc.pSolarPressure || !fmc.pRelEffect )
00229 {
00230
00231 deleteFMObjects(fmc);
00232
00233 Exception e("Failed to allocate memory for force models !");
00234 GPSTK_THROW(e);
00235 }
00236
00237
00238 fmc.pGeoEarth->setDesiredDegree(fmc.grvDegree,fmc.grvOrder);
00239 fmc.pGeoEarth->enableSolidTide(fmc.solidTide);
00240 fmc.pGeoEarth->enableOceanTide(fmc.oceanTide);
00241 fmc.pGeoEarth->enablePoleTide(fmc.poleTide);
00242
00243 fmc.pAtmDrag->setSpaceData(fmc.dailyF107,
00244 fmc.averageF107, fmc.dailyKp);
00245
00246 forceList.clear();
00247
00248 if(fmc.geoEarth) forceList.addForce(fmc.pGeoEarth);
00249 if(fmc.geoSun) forceList.addForce(fmc.pGeoSun);
00250 if(fmc.geoMoon) forceList.addForce(fmc.pGeoMoon);
00251 if(fmc.atmDrag) forceList.addForce(fmc.pAtmDrag);
00252 if(fmc.solarPressure) forceList.addForce(fmc.pSolarPressure);
00253 if(fmc.relEffect) forceList.addForce(fmc.pRelEffect);
00254
00255
00256 fmlPrepared = true;
00257
00258 }
00259
00260
00261 void SatOrbit::deleteFMObjects(FMCData& fmc)
00262 {
00263
00264 if(fmc.pGeoEarth)
00265 {
00266 if(fmc.grvModel == GM_JGM3)
00267 {
00268 delete (JGM3GravityModel*) fmc.pGeoEarth;
00269 fmc.pGeoEarth = NULL;
00270 }
00271 else if(fmc.grvModel == GM_EGM96)
00272 {
00273 delete (EGM96GravityModel*) fmc.pGeoEarth;
00274 fmc.pGeoEarth = NULL;
00275 }
00276 else
00277 {
00278 delete fmc.pGeoEarth;
00279 fmc.pGeoEarth = NULL;
00280 }
00281 }
00282
00283
00284 if(fmc.pGeoSun)
00285 {
00286 delete fmc.pGeoSun;
00287 fmc.pGeoSun = NULL;
00288 }
00289
00290
00291 if(fmc.pGeoMoon)
00292 {
00293 delete fmc.pGeoMoon;
00294 fmc.pGeoMoon = NULL;
00295 }
00296
00297
00298 if(fmc.pAtmDrag)
00299 {
00300 if(fmc.atmModel == AM_HarrisPriester)
00301 {
00302 delete (HarrisPriesterDrag*) fmc.pAtmDrag;
00303 fmc.pAtmDrag = NULL;
00304 }
00305 else if(fmc.atmModel == AM_MSISE00)
00306 {
00307 delete (Msise00Drag*) fmc.pAtmDrag;
00308 fmc.pAtmDrag = NULL;
00309 }
00310 else if(fmc.atmModel == AM_CIRA)
00311 {
00312 delete (CiraExponentialDrag*) fmc.pAtmDrag;
00313 fmc.pAtmDrag = NULL;
00314 }
00315 else
00316 {
00317 delete fmc.pAtmDrag;
00318 fmc.pAtmDrag = NULL;
00319 }
00320 }
00321
00322
00323 if(fmc.pSolarPressure)
00324 {
00325 delete fmc.pSolarPressure;
00326 fmc.pSolarPressure = NULL;
00327 }
00328
00329
00330 if(fmc.pRelEffect)
00331 {
00332 delete fmc.pRelEffect;
00333 fmc.pRelEffect = NULL;
00334 }
00335
00336
00337
00338
00339 fmlPrepared = false;
00340
00341 }
00342
00343
00344 }
00345
00346
00347