SatOrbitPropagator.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: SatOrbitPropagator.cpp 2457 2010-08-18 14:20:12Z coandrei $"
00002 
00008 //============================================================================
00009 //
00010 //  This file is part of GPSTk, the GPS Toolkit.
00011 //
00012 //  The GPSTk is free software; you can redistribute it and/or modify
00013 //  it under the terms of the GNU Lesser General Public License as published
00014 //  by the Free Software Foundation; either version 2.1 of the License, or
00015 //  any later version.
00016 //
00017 //  The GPSTk is distributed in the hope that it will be useful,
00018 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 //  GNU Lesser General Public License for more details.
00021 //
00022 //  You should have received a copy of the GNU Lesser General Public
00023 //  License along with GPSTk; if not, write to the Free Software Foundation,
00024 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 //
00026 //  Wei Yan - Chinese Academy of Sciences . 2009, 2010
00027 //
00028 //============================================================================
00029 
00030 
00031 #include "SatOrbitPropagator.hpp"
00032 
00033 #include "ASConstant.hpp"
00034 #include "KeplerOrbit.hpp"
00035 #include "ReferenceFrames.hpp"
00036 #include "IERS.hpp"
00037 
00038 namespace gpstk
00039 {
00040 
00041       // Constructor
00042    SatOrbitPropagator::SatOrbitPropagator()
00043       : pIntegrator(NULL),
00044         curT(0.0)
00045    {
00046       setDefaultIntegrator();
00047       setDefaultOrbit();
00048 
00049       setStepSize(1.0);
00050 
00051        setFMT.clear();
00052       //setFMT.insert(ForceModel::Cd);
00053       //setFMT.insert(ForceModel::Cr);
00054       pOrbit->setForceModelType(setFMT);
00055 
00056      
00057       
00058    }  // End of constructor 'SatOrbitPropagator::SatOrbitPropagator()'
00059    
00060 
00061       // Default destructor
00062    SatOrbitPropagator::~SatOrbitPropagator()
00063    {
00064       pIntegrator = NULL;
00065       pOrbit = NULL;
00066    }
00067    
00068       /* Take a single integration step.
00069        *
00070        * @param x     time or independent variable
00071        * @param y     containing needed inputs (usually the state)
00072        * @param tf    next time
00073        * @return      containing the new state
00074        */
00075    Vector<double> SatOrbitPropagator::integrateTo(double t,Vector<double> y,double tf)
00076    {
00077       try
00078       {
00079          curT = tf;
00080          curState = pIntegrator->integrateTo(t,y,pOrbit,tf);
00081          
00082          updateMatrix();
00083 
00084          return curState;
00085       }
00086       catch(...)
00087       {
00088          Exception e("Error in OrbitPropagator::integrateTo()");
00089          GPSTK_THROW(e);
00090       }
00091 
00092    }  // End of method 'SatOrbitPropagator::integrateTo()'
00093 
00094 
00095    bool SatOrbitPropagator::integrateTo(double tf)
00096    {
00097       try
00098       {
00099          double t = curT;
00100          Vector<double> y = curState;
00101 
00102          curT = tf;
00103          curState = pIntegrator->integrateTo(t, y, pOrbit, tf);
00104          
00105          updateMatrix();
00106 
00107          return true;
00108       }
00109       catch(Exception& e)
00110       {
00111          GPSTK_RETHROW(e);
00112       }
00113 
00114       catch(...)
00115       {
00116          Exception e("Unknown error in SatOrbitPropagator::integrateTo()");
00117          GPSTK_THROW(e);
00118       }
00119 
00120       return false;
00121 
00122    }  // End of method 'SatOrbitPropagator::integrateTo()'
00123 
00124       /*
00125        * set init state
00126        * utc0   init epoch
00127        * rv0    init state
00128        */
00129    SatOrbitPropagator& SatOrbitPropagator::setInitState(UTCTime utc0, Vector<double> rv0)
00130    {
00131       const int np = setFMT.size();
00132       
00133       curT = double(0.0);
00134       curState.resize(42+6*np,0.0);
00135       
00136       // position and velocity
00137       curState(0) = rv0(0);
00138       curState(1) = rv0(1);
00139       curState(2) = rv0(2);
00140       curState(3) = rv0(3);
00141       curState(4) = rv0(4);
00142       curState(5) = rv0(5);
00143 
00144       double I[9] = {1.0, 0.0 ,0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
00145       
00146       for(int i = 0; i < 9; i++)
00147       {
00148          curState(6+i) = I[i];
00149          curState(33+3*np+i) = I[i];
00150       }
00151       
00152       updateMatrix();
00153       
00154       // set reference epoch
00155       setRefEpoch(utc0);
00156 
00157 
00158       return (*this);
00159 
00160    }  // End of method 'SatOrbitPropagator::setInitState()'
00161 
00162    
00164    void SatOrbitPropagator::updateMatrix()
00165    {
00166       const int np = getNP();
00167 
00168       Vector<double> dr_dr0(9,0.0);
00169       Vector<double> dr_dv0(9,0.0);
00170       Vector<double> dr_dp0(3*np,0.0);
00171       Vector<double> dv_dr0(9,0.0);
00172       Vector<double> dv_dv0(9,0.0);
00173       Vector<double> dv_dp0(3*np,0.0);
00174 
00175       for(int i = 0; i < 9; i++)
00176       {
00177          dr_dr0(i) = curState(6+i);
00178          dr_dv0(i) = curState(15+i);
00179 
00180          dv_dr0(i) = curState(24+3*np+i);
00181          dv_dv0(i) = curState(33+3*np+i);
00182       }
00183       for(int i = 0;i < 3*np; i++)
00184       {
00185          dr_dp0 = curState(24+i);
00186          dv_dp0 = curState(42+3*np+i);
00187       }
00188 
00189       // update phiMatrix
00190       phiMatrix.resize(6,6,0.0);
00191 
00192       // dr/dr0
00193       phiMatrix(0,0) = dr_dr0(0);
00194       phiMatrix(0,1) = dr_dr0(1);
00195       phiMatrix(0,2) = dr_dr0(2);
00196       phiMatrix(1,0) = dr_dr0(3);
00197       phiMatrix(1,1) = dr_dr0(4);
00198       phiMatrix(1,2) = dr_dr0(5);
00199       phiMatrix(2,0) = dr_dr0(6);
00200       phiMatrix(2,1) = dr_dr0(7);
00201       phiMatrix(2,2) = dr_dr0(8);
00202       // dr/dv0
00203       phiMatrix(0,3) = dr_dv0(0);
00204       phiMatrix(0,4) = dr_dv0(1);
00205       phiMatrix(0,5) = dr_dv0(2);
00206       phiMatrix(1,3) = dr_dv0(3);
00207       phiMatrix(1,4) = dr_dv0(4);
00208       phiMatrix(1,5) = dr_dv0(5);
00209       phiMatrix(2,3) = dr_dv0(6);
00210       phiMatrix(2,4) = dr_dv0(7);
00211       phiMatrix(2,5) = dr_dv0(8);
00212       // dv/dr0
00213       phiMatrix(3,0) = dv_dr0(0);
00214       phiMatrix(3,1) = dv_dr0(1);
00215       phiMatrix(3,2) = dv_dr0(2);
00216       phiMatrix(4,0) = dv_dr0(3);
00217       phiMatrix(4,1) = dv_dr0(4);
00218       phiMatrix(4,2) = dv_dr0(5);
00219       phiMatrix(5,0) = dv_dr0(6);
00220       phiMatrix(5,1) = dv_dr0(7);
00221       phiMatrix(5,2) = dv_dr0(8);
00222       // dv/dv0
00223       phiMatrix(3,3) = dv_dv0(0);
00224       phiMatrix(3,4) = dv_dv0(1);
00225       phiMatrix(3,5) = dv_dv0(2);
00226       phiMatrix(4,3) = dv_dv0(3);
00227       phiMatrix(4,4) = dv_dv0(4);
00228       phiMatrix(4,5) = dv_dv0(5);
00229       phiMatrix(5,3) = dv_dv0(6);
00230       phiMatrix(5,4) = dv_dv0(7);
00231       phiMatrix(5,5) = dv_dv0(8);
00232 
00233       // update sMatrix 6*np
00234       sMatrix.resize(6,np,0.0);
00235       for(int i = 0; i<np; i++)
00236       {
00237          sMatrix(0,i) = dr_dp0(0*np+i);
00238          sMatrix(1,i) = dr_dp0(1*np+i);
00239          sMatrix(2,i) = dr_dp0(2*np+i);
00240 
00241          sMatrix(3,i) = dv_dp0(0*np+i);
00242          sMatrix(4,i) = dv_dp0(1*np+i);
00243          sMatrix(5,i) = dv_dp0(2*np+i);
00244       }
00245       
00246       // update rvVector
00247       rvVector.resize(6,0.0);
00248       for(int i = 0; i < 6; i++) 
00249       { 
00250          rvVector(i) = curState(i);
00251       }
00252 
00253    }  // End of method 'SatOrbitPropagator::updateMatrix()'
00254    
00255 
00256       /* set initial state of the the integrator
00257        *
00258        *  v      3
00259        * dr_dr0    3*3
00260        * dr_dv0   3*3
00261        * dr_dp0   3*np
00262        * dv_dr0   3*3
00263        * dv_dv0   3*3
00264        * dv_dp0   3*np
00265        */
00266    void SatOrbitPropagator::setState(Vector<double> state)
00267    {
00268       int np = (state.size()-42)/6;
00269       if(np<0)
00270       {
00271          Exception e("The size of the imput state is not valid");
00272          GPSTK_THROW(e);
00273       }
00274       curT = 0;
00275       curState.resize(state.size(),0.0);
00276       for(int i=0;i<state.size();i++)
00277       {
00278          curState(i) = state(i);
00279       }
00280 
00281       updateMatrix();
00282 
00283    }  // End of method 'SatOrbitPropagator::setState()'
00284 
00285 
00286    Vector<double> SatOrbitPropagator::rvState(bool bJ2k)
00287    {
00288       if(bJ2k == true)      // state ICRF
00289       {
00290          return rvVector;
00291       }
00292       else                 // state in ITRF
00293       {
00294          UTCTime utc = getCurTime();
00295          return ReferenceFrames::J2kPosVelToECEF(utc,rvVector);
00296       }
00297       
00298    }  // End of method 'SatOrbitPropagator::rvState()'
00299 
00300 
00302    void SatOrbitPropagator::writeToFile(ostream& s)
00303    {
00304       UTCTime utcRef = pOrbit->getRefEpoch();
00305       UTCTime utc = utcRef;
00306       utc += curT;
00307       
00308       const int np = getNP();
00309 
00310       s << fixed;
00311       s << "#" << utc << " "
00312         << setprecision(12) << utc.mjdUTC() << endl;
00313       
00314       for(int i=0;i<6;i++)
00315       {
00316          s << setw(20) << setprecision(12) << rvVector(i) << " ";
00317       }
00318       s << endl;
00319 
00320       // [phi s]
00321       for(int i=0;i<6;i++)
00322       {
00323          for(int j=0;j<6;j++)
00324          {
00325             s << setw(20) << setprecision(12) << phiMatrix(i,j) << " ";
00326          }
00327          for(int j=0;j<np;j++)
00328          {
00329             s << setw(20) << setprecision(12) << sMatrix(i,j) << " ";
00330          }
00331 
00332          s << endl;
00333       }
00334    }
00335 
00336       /*
00337        * Stream output for OrbitPropagator objects.  Typically used for debugging.
00338        * @param s stream to append formatted DayTime to.
00339        * @param t DayTime to append to stream  s.
00340        * @return reference to  s.
00341        */
00342    ostream& operator<<(ostream& s,SatOrbitPropagator& op)
00343    {
00344       op.writeToFile(s);
00345 
00346       return s;
00347    }
00348 
00349 
00350    /*
00351    void OrbitPropagator::setForceModel(ForceModelSetting& fms)
00352    {
00353       if(pOrbit)
00354       {
00355          pOrbit->setForceModel(fms);
00356       }
00357    }*/
00358 
00359       /* For Testing and Debuging...
00360        */
00361    void SatOrbitPropagator::test()
00362    {
00363       cout<<"testing OrbitPropagator[KeplerOrbit]"<<endl;
00364       cout<<fixed<<setprecision(6);
00365 
00366       // load global data
00367       IERS::loadSTKFile("InputData\\EOP-v1.1.txt");
00368       ReferenceFrames::setJPLEphFile("InputData\\DE405\\jplde405");
00369      
00370       ofstream fout("outorbit.txt");
00371 
00372       UTCTime utc0(2002,3,1,0,0,0.0);
00373 
00374       double state[42]={2682920.8943,4652720.5672,4244260.0400,2215.5999,4183.3573,-5989.0576,
00375       1,0,0,
00376       0,1,0,
00377       0,0,1,
00378       0,0,0,
00379       0,0,0,
00380       0,0,0,
00381       0,0,0,
00382       0,0,0,
00383       0,0,0,
00384       1,0,0,
00385       0,1,0,
00386       0,0,1};
00387       
00388       Vector<double> y0(42,0.0);
00389       y0 = state;
00390 
00391       Vector<double> yy0(6,0.0);
00392       yy0(0) = y0(0);
00393       yy0(1) = y0(1);
00394       yy0(2) = y0(2);
00395       yy0(3) = y0(3);
00396       yy0(4) = y0(4);
00397       yy0(5) = y0(5);
00398       
00399    
00400       Vector<double> kep(6,0.0);
00401       kep = KeplerOrbit::Elements(ASConstant::GM_Earth, yy0);
00402 
00403 
00404       SatOrbitPropagator op;
00405 
00406       SatOrbit* porbit = op.getSatOrbitPointer();
00407       porbit->enableGeopotential(SatOrbit::GM_JGM3,1,1);
00408 
00409 
00410       op.setRefEpoch(utc0.mjdUTC());
00411       op.setStepSize(10.0);
00412 
00413       double tt = 3600.0*24;
00414       double step = 60.0;
00415 
00416       cout << fixed << setw(12)<<setprecision(5);
00417       
00418       double t=0.0;
00419       while(t < tt)
00420       {
00421          Vector<double> yy = op.integrateTo(t,y0,t+step);
00422 
00423          fout << op;
00424 
00425          Vector<double> yy_prev(6,0.0);
00426          Vector<double> yy_out(6,0.0);
00427          for(int i=0; i<6; i++) 
00428          {
00429             yy_prev(i) = y0(i);
00430             yy_out(i) = yy(i);
00431          }
00432          
00433          Vector<double> yy_ref(6,0.0);
00434          Matrix<double> phi_ref(6,6,0.0);
00435          KeplerOrbit::TwoBody(ASConstant::GM_Earth,yy0,t+step,yy_ref,phi_ref);
00436          Vector<double> checky0 = KeplerOrbit::State(ASConstant::GM_Earth, kep, t+step);
00437 
00438          Matrix<double> phi = op.transitionMatrix();
00439 
00440          Vector<double> diff = yy_out - yy_ref;
00441          
00442          UTCTime utc = op.getCurTime();
00443          cout << utc << " " << diff <<endl;
00444          cout << phi-phi_ref << endl;
00445          
00446          t += step;
00447          y0 = yy;
00448       }
00449       
00450       fout.close();
00451       
00452    }
00453 
00454 }  // End of namespace 'gpstk'
00455 
00456 
00457 

Generated on Tue May 22 03:31:01 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1