testAttitudeIntegration.cpp

Go to the documentation of this file.
00001 
00002 
00008 /*  
00009 */
00011 
00012 #include "Matrix.h"
00013 #include "RungeKuttaIntegrator.h"
00014 #include "LinearInterpolator.h"
00015 #include "Plot.h"
00016 #include "Attitude.h"
00017 #include "AttitudeState.h"
00018 #include <vector.h>
00019 using namespace std;
00020 
00021 
00022 // Torque function that will be called each timestep
00023 Vector NullFunctor(const ssfTime& _pSSFTime, const OrbitState& _pOrbitState, const AttitudeState& _pAttitudeState)
00024 {
00025     return Vector(3);
00026 }
00027 /*
00028 static Vector EugeneDynamics(const ssfTime &_time, const Vector& _integratingState, Orbit *_Orbit, Attitude *_Attitude, const Matrix &_parameters, const Functor &_forceFunctorPtr)
00029 {
00030     //function statedot=test1_rhs(t,state)
00031     static Vector h = _integratingState(_(1,3));        //h=state(1:3);
00032     static double T = _integratingState(4);             //T=state(4);
00033 
00034     Matrix I(3,3);                              //I=[100 0 0;0 200 0;0 0 150];
00035         I(1,1) = 100;
00036         I(2,2) = 200;
00037         I(3,3) = 150;
00038     static Vector w = I.inverse() * h;                  //w=inv(I)*h;
00039     Vector ge(3);                               //ge=[0 0 0]';
00040     
00041     static Vector hdot = skew(w) * h + ge;              //hdot=-cr(w)*h+ge;
00042     static Vector wdot = I.inverse() * hdot;            //wdot=inv(I)*hdot;
00043     static Matrix temp = (~ge * wdot);                  //Tdot=ge'*wdot;
00044     double Tdot = temp(1,1);
00045     
00046     static Vector statedot(hdot.getIndexBound() + 1);
00047         statedot(_(1, hdot.getIndexBound())) = hdot(_);
00048         statedot(hdot.getIndexBound()+1) = Tdot;
00049         
00050     return statedot;                            //statedot=[hdot; Tdot];
00051 
00052 }*/
00053 
00056 static Vector AttituteDynamics(const ssfTime &_time, const Vector& _integratingState, Orbit *_pOrbit, Attitude *_pAttitude, const Matrix &_parameters, const Functor &_forceFunctorPtr)
00057 {
00058     // Initialize the vectors used in the calculation.
00059     //  made static, which causes the memory to be allocated the first time the function is called
00060     //  and then left in memory during the program to speed up computation.
00061     static Vector stateDot(7);
00062     static Matrix bMOI(3,3); 
00063     static Matrix qtemp(4,3); 
00064     static Matrix Tmoment(3,1);
00065     static Vector qIn(4); 
00066     static Vector wIn(3);
00067     
00068     // Retrieve the current integration states to a quaternion and angular velocity vector
00069     qIn = _integratingState(_(VectorIndexBase,VectorIndexBase + 3));
00070     wIn = _integratingState(_(VectorIndexBase + 4,VectorIndexBase + 6));
00071     qIn /= norm2(qIn);
00072 
00073     // Calculate qDot
00074     qtemp(_(VectorIndexBase+0,VectorIndexBase+2),_(VectorIndexBase+0,VectorIndexBase+2)) = skew(qIn(_(VectorIndexBase+0,VectorIndexBase+2))) + qIn(VectorIndexBase+3) * eye(3);
00075     qtemp(VectorIndexBase+3, _(VectorIndexBase+0,VectorIndexBase+2)) = -(~qIn(_(VectorIndexBase+0,VectorIndexBase+2)));
00076     qtemp(_,MatrixIndexBase) = 0.5 * qtemp * wIn;
00077 
00078     // Get the moments of inertia and calculate the omegaDot
00079     bMOI = _parameters(_(MatrixIndexBase+0,MatrixIndexBase+2),_(MatrixIndexBase+0,MatrixIndexBase+2));
00080     Tmoment = (bMOI.inverse() * (Tmoment - skew(wIn) * (bMOI * wIn)));
00081     
00082     // Combine the qDot and omegaDot into a stateDot vector
00083     stateDot(_(VectorIndexBase,VectorIndexBase + 3)) = qtemp(_,MatrixIndexBase);
00084     stateDot(_(VectorIndexBase + 4,VectorIndexBase + 6)) = Tmoment(_,MatrixIndexBase);
00085 
00086     cout << 0.5 * ~wIn * (bMOI * wIn);
00087     return stateDot;
00088 }
00089 
00090 int main()
00091 {
00093     // Setup an integrator and any special parameters
00094     RungeKuttaIntegrator myIntegrator; 
00095     myIntegrator.SetNumSteps(1000);
00096     // Integration times
00097     vector<ssfTime> integrationTimes;
00098     ssfTime begin(0);
00099     ssfTime end(begin + 20);
00100     integrationTimes.push_back(begin);
00101     integrationTimes.push_back(end);
00102     
00103     // Create the initial attitude state
00104     AttitudeState myAttitudeState;
00105     myAttitudeState.SetRotation(Rotation(Quaternion(0,0,0,1)));
00106     Vector initAngVelVector(3);
00107         initAngVelVector(1) = 0.1;
00108     myAttitudeState.SetAngularVelocity(initAngVelVector);
00109     SpecificFunctor AttitudeForcesFunctor(&NullFunctor);
00110     
00111     // Create the matrix of parameters needed for the RHS - MOI
00112     Matrix Parameters = eye(3);
00113     
00114     Matrix I(3,3);                              //I=[100 0 0;0 200 0;0 0 150];
00115         I(1,1) = 100;
00116         I(2,2) = 200;
00117         I(3,3) = 150;
00118     Vector h(3);
00119         h(1) = 10;
00120         h(2) = 20;
00121         h(3) = 30;
00122 
00123     Vector w = I.inverse() * h;
00124     Matrix Tmat = 0.5 * (~w * (I * w));
00125     Vector initEugeneState(4);
00126         initEugeneState(_(1,3)) = h(_(1,3));
00127         initEugeneState(4) = Tmat(1,1);
00128 
00129  
00130     cout << "PropTime = " << begin.GetSeconds() << " s -> " << end.GetSeconds() << " s" << endl;
00131     cout << "Attitude State: " << ~myAttitudeState.GetState() << endl;
00133     // Integrate over the desired time interval
00134     tick();
00135     Matrix history = myIntegrator.Integrate(
00136                             integrationTimes,           // seconds
00137                             &AttituteDynamics, 
00138                             myAttitudeState.GetState(),
00139                             NULL,
00140                             NULL,
00141                             Parameters,
00142                             AttitudeForcesFunctor
00143                         );
00144 
00145     cout << "finished propagating in " << tock() << " seconds." << endl;                                 
00146     // Output the flight history
00147     //cout << history;
00148     Matrix plotting = history(_,_(MatrixIndexBase,MatrixIndexBase+4));
00149 
00150 //    Plot2D(plotting);
00151     
00153     // Create & populate an AttitudeHistory object
00154     AttitudeHistory myAttHistory;
00155     myAttHistory.SetInterpolator(new LinearInterpolator);
00156     Vector AngVel(3);
00157     Vector Quat(4);
00158     Rotation myRot;
00159     for(int jj = 1;jj <= history[MatrixRowsIndex].getIndexBound(); ++jj)
00160     {
00161         AngVel = ~(history(jj, _(6,8)));
00162         Quat = ~(history(jj,_(2,5)));
00163         myRot.Set(Quaternion(Quat));
00164         myAttHistory.AppendHistory(history(jj,1), myRot, AngVel);
00165     }
00166     
00168     // Output the attitude state at a requested time    
00169     double requestTime;
00170     cout << "Output attitude state at time (s): " << flush;
00171     cin >> requestTime;
00172     ssfTime myTime(requestTime);
00173     myAttHistory.GetState(myTime, myRot, AngVel);
00174     cout << myTime.GetSeconds() << " : " << ~myRot.GetQuaternion() << endl;
00175 
00176     /*
00177     // Verifying the energy
00178     Matrix calcHistory = history;
00179     for(int ii = 1; ii <= history[MatrixRowsIndex].getIndexBound(); ++ii)
00180     {
00181         h = ~(history(ii,_(2,4)));
00182         w = I.inverse() * h;
00183         Tmat = 0.5 * (~w * (I * w)); 
00184         calcHistory(ii,5) = Tmat(1,1);
00185     }
00186     Plot2D(calcHistory);*/
00187     
00189     // Store the output to file
00190     ofstream ofile;
00191     ofile.open("AttitudeHistory.dat");
00192     ofile << history;
00193     ofile.close();
00194 
00195     return 0;
00196                             
00197 }
00198 // Do not change the comments below - they will be added automatically by CVS
00199 /*****************************************************************************
00200 *       $Log: testAttitudeIntegration.cpp,v $
00201 *       Revision 1.5  2003/05/22 14:48:11  nilspace
00202 *       It works, for now. Changed so integrator just takes NULL pointers to Attitude & Orbit.
00203 *       
00204 *       Revision 1.4  2003/05/22 03:02:52  nilspace
00205 *       Pass pointers to Orbit & Attitude in integrator (pointers to NULL).
00206 *       
00207 *       Revision 1.3  2003/05/19 19:19:55  nilspace
00208 *       Updated to include Eugene's "test case". Also made the RHS dynamic equation variables declared as static.
00209 *       
00210 *       Revision 1.2  2003/05/13 18:55:50  nilspace
00211 *       Fixed to work with the new integrator, eugene's functions, History, and interpolation.
00212 *       
00213 *       Revision 1.1  2003/05/10 01:53:37  nilspace
00214 *       Initial submission. Works, but needs to be refined.
00215 *       
00216 *
00217 ******************************************************************************/
00218 
00219                         

Generated on Wed Aug 6 12:58:53 2003 for Open-Sessame Framework by doxygen1.3