Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages | Examples

Tutorials.h

Go to the documentation of this file.
00001 /*! \page TutorialsPage Tutorials
00002   \ref TableOfContents : \ref IntroductionPage : \ref TutorialAnswersPage
00003 
00004     The following sections are sets of tutorials meant to lead the user through the basics of using the Open-Sessame Framework
00005 all the way to creating a full spacecraft simulation application. Each section is a listing of a textual 
00006 description of the problem to be solved, followed by a reference to the answer sheet. Don't cheat! Following the 
00007 successful completion of each lesson, the user should move onto the next lesson until all the tutorials are complete.
00008 
00009 \par Running Tutorials:
00010     To build and run a tutorial, (after writing your file, e.g. myFile.cpp) follow the following instructions:
00011     -# Put the @em .cpp file in the @em spacecraft/src/test directory:
00012         \verbatim cp myFile.cpp spacecraft/src/test 
00013             cd spacecraft/src/test\endverbatim
00014         or use whatever method you choose for getting it there (ftp, sftp, scp, drag -n- drop, mv, etc.)
00015     -# Build the program by running the generalized makefile with the target of your source file, minus the @em cpp extension:
00016         \verbatim make myFile \endverbatim
00017     -# Run the program in the same directory (the executable will be the same as the source file minus the extension):
00018         \verbatim ./myFile \endverbatim
00019     -# Debug the code (unless your implementation was perfect, then check your answers)
00020         - If you need help check the suggested \ref ProgrammingTroubleshooting
00021         
00022   \section RotationTutorials Rotation Tutorials
00023 -# Create a Quaternion that has the initial parameters (0.5,0.5,0.5,0.5).
00024 -# Output this quaternion to the console in both quaternion and Modified Rodriguez Parameters (MRP) form.
00025 -# Create a Direction Cosine Matrix corresponding to a 321 rotation with angles: 10, -30, 150 degrees.
00026 -# Create 2 "Rotation"s that are intialized by the quaternion and Direction Cosine Matrix.
00027 -# Determine the successive rotation of these two rotations and output to the console in DCM form.
00028 -# Verify that the answer you got was the correct (expected) one.
00029 
00030 \ref TutorialAnswersPage
00031 
00032 \section UtilityTutorials Utility Tutorials
00033 -# Create an ssfTime object, set the epoch to the current real time, and the stored 'current' time to 50 seconds later. Output both of these in DateTime and JulianDate format to the console.
00034 -# Plot a Matrix of values corresponding to the \f$ f(x)=\sin{x}\f$ for \f$x=0:2\pi \f$ using the Open-Sessame GnuPlot interface.
00035 -# Create a linear interpolation of the \f$\sin{}\f$ function using a step-size of 0.1
00036 
00037 \ref TutorialAnswersPage
00038 
00039   \section AttitudeTutorials Attitude Tutorials
00040 -# Create an AttitudeState object instance that is initialized to an aligned rotation in the Orbit-Inertial Frame (attitudeframe not yet implemented fully).
00041 -# Integrate an attitude for 50 seconds using the following conditions:
00042     - Quaternion Kinematics
00043     - Euler's equations of motion
00044     - Gravity-gradient torque disturbance
00045     - Initial conditions of: \f$\bar{\bf q}_0 = [0,0,0,1]^{T}\f$ and \f$\omega_{0} = [0,0.1, -0.05]^{T} \frac{rad}{s}\f$.
00046     - Principle Moments of Inertia: \f$[100, 300, 150]\f$
00047 -# Store the attitude to a text file.
00048 -# Plot the attitude history using GnuPlot.
00049 -# Store the attitude in DirectionCosineMatrix format in a MatLab file.
00050 
00051 \ref AttitudeTutorialAnswer
00052 
00053   \section OrbitTutorials Orbit Tutorials
00054 -# Create an OrbitState object instance that is initialized to the current state of the spacestation in inertial coordinates.
00055 -# Convert to ECEF coordinates and output to the console. 
00056 -# Integrate an orbit for 2 orbits using the following conditions:
00057     - 2-body force function above the Earth (mass = 200 kg).
00058     - Solar-radiation pressure force disturbance (assume constant \f$Area=20 m^2\f$).
00059     - Initial conditions of: \f${\bf r}=[-5776.6, -157, 3496.9]^{T}\f$ (km) and \f${\bf v} = [-2.595, -5.651, -4.513]^{T}\f$ (km/s).
00060 -# Store the position and velocity to a text file.
00061 -# Plot the orbit position vector using GnuPlot.
00062 -# Store the orbit Keplerian parameters in a MatLab file.
00063 
00064 \ref OrbitTutorialAnswer
00065 
00066 \section CoupledTutorials Coupled Attitude & Orbit Tutorials
00067 -# Create an Environment object of the Earth using the above (Orbit \& Attitude) disturbance force \& torque functions.
00068 -# Create a Propagator that will propagate the above Orbit \& Attitude objects and using the Environment object.
00069     - Use a linear interpolator for the OrbitHistory.
00070     - Use loose coupling (orbit independent of attitude, but attitude dependent on position).
00071 -# Propagate the orbit and attitude for 2 orbits.
00072 -# Plot the position and attitude using gnuplot.
00073 -# Propagate another 2 orbits.
00074 -# Add the new states to the previously made plots.
00075 
00076 \ref CoupledTutorialAnswer
00077 */
00078 
00079 /*! \page TutorialAnswersPage Tutorial Answers Page
00080   \ref TableOfContents : \ref IntroductionPage : \ref TutorialsPage
00081 
00082 \section RotationTutorialAnswer Rotation Tutorial Answer
00083 
00084 \code
00085 // Create a Quaternion that has the initial parameters (0.5,0.5,0.5,0.5).
00086 Quaternion myQuat(0.5, 0.5, 0.5, 0.5);
00087 
00088 // Output this quaternion to the console in both quaternion and MRP form
00089 cout << myQuat;
00090 cout << myQuat.GetMRP();
00091 
00092 // Create a Direction Cosine Matrix corresponding to a 321 rotation with angles: 10, -30, 150 degrees.
00093 DirectionCosineMatrix myDCM(10*RPD, -30*RPD, 150*RPD, 321);
00094 
00095 // Create 2 "Rotation"s that are intialized by the quaternion and Direction Cosine Matrix.
00096 Rotation myRot1(myQuat);
00097 Rotation myRot2(myDCM);
00098 
00099 // Determine the successive rotation of these two rotations and output to the console in DCM form.
00100 cout << (myRot1 * myRot2).GetDCM();
00101 
00102 // Verify that the answer you got was the correct (expected) one. 
00103 Matrix Answer(3,3);
00104 
00105 \endcode
00106 
00107 Back to: \ref RotationTutorials
00108 <hr>
00109 
00110 \section UtilityTutorialAnswer Utility Tutorial Answer
00111 -# Create an ssfTime object, set the epoch to the current real time, and the stored 'current' time to 50 seconds later. Output both of these in DateTime and JulianDate format to the console.
00112 \code
00113 ssfTime myTime;
00114 myTime.SetEpoch(Now());
00115 myTime.Set(myTime.GetEpoch() + 50);
00116 cout << myTime.GetDateTime().tm_mon << "/" << myTime.GetDateTime().tm_mday << "/" << myTime.GetDateTime().tm_year << endl;
00117 cout << myTime.GetJulianDate() << endl;
00118 \endcode
00119 
00120 -# Plot a Matrix of values corresponding to the \f$ f(x)=\sin{x}\f$ for \f$x=0:2\pi \f$ using the Open-Sessame GnuPlot interface.
00121 \code
00122 int stepsize = 0.1;
00123 Matrix datavec(2*M_PI / stepsize,2);
00124 for (int jj = 1; jj <= datavec[MatrixRowsIndex].getIndexBound();  ++jj)
00125 {
00126     datavec(jj,1) = jj * stepsize;
00127     datavec(jj,2) = sin(jj * stepsize);
00128 }
00129 Plot2D(datavec);
00130 \endcode
00131 -# Create a linear interpolation of the \f$\sin{}\f$ function using a step-size of 0.1
00132 \code
00133 int stepsize = 0.1;
00134 Vector timeVec(2*M_PI / stepsize);
00135 Matrix dataMat(timeVec[MatrixRowsIndex].getIndexBound(), 1);
00136 for (int jj = 1; jj < timeVec[MatrixRowsIndex].getIndexBound();  ++jj)
00137 {
00138     timeVec(jj) = jj * stepsize;
00139     dataMat(jj,1) = sin(jj * stepsize);
00140 }
00141 
00142 LinearInterpolator interp(timeVec,dataMat);
00143 Vector chk = interp.Evaluate(0.25);
00144 cout <<  timevec << endl << datavec << endl << sin(0.25) << " = " << chk << endl;
00145 \endcode
00146 Back to: \ref UtilityTutorials
00147 <hr>
00148 
00149 \section AttitudeTutorialAnswer Attitude Tutorial Answer
00150 -# Create an AttitudeState object instance that is initialized to an aligned rotation in the Orbit-Inertial Frame (attitudeframe not yet implemented fully).
00151 \code
00152 AttitudeState myAttState(Rotation(), new AttitudeFrameOI);
00153 \endcode
00154 
00155 -# Integrate an attitude for 50 seconds using the following conditions:
00156 
00157 First setup the kinematics equation:
00158 \code
00159 static Vector AttituteDynamics(const ssfTime &_time, const Vector& _integratingState, Orbit *_pOrbit, Attitude *_pAttitude, const Matrix &_parameters, const Functor &_forceFunctorPtr)
00160 {
00161     // Initialize the vectors used in the calculation.
00162     //  made static, which causes the memory to be allocated the first time the function is called
00163     //  and then left in memory during the program to speed up computation.
00164     static Vector stateDot(7);
00165     static Matrix bMOI(3,3); 
00166     static Matrix qtemp(4,3); 
00167     static Matrix Tmoment(3,1);
00168     static Vector qIn(4); 
00169     static Vector wIn(3);
00170     
00171     // Retrieve the current integration states to a quaternion and angular velocity vector
00172     qIn = _integratingState(_(VectorIndexBase,VectorIndexBase + 3));
00173     wIn = _integratingState(_(VectorIndexBase + 4,VectorIndexBase + 6));
00174     qIn /= norm2(qIn);
00175 
00176     // Calculate qDot
00177     qtemp(_(VectorIndexBase+0,VectorIndexBase+2),_(VectorIndexBase+0,VectorIndexBase+2)) = skew(qIn(_(VectorIndexBase+0,VectorIndexBase+2))) + qIn(VectorIndexBase+3) * eye(3);
00178     qtemp(VectorIndexBase+3, _(VectorIndexBase+0,VectorIndexBase+2)) = -(~qIn(_(VectorIndexBase+0,VectorIndexBase+2)));
00179     qtemp(_,MatrixIndexBase) = 0.5 * qtemp * wIn;
00180 
00181     // Get the moments of inertia and calculate the omegaDot
00182     bMOI = _parameters(_(MatrixIndexBase+0,MatrixIndexBase+2),_(MatrixIndexBase+0,MatrixIndexBase+2));
00183     Tmoment = (bMOI.inverse() * (Tmoment - skew(wIn) * (bMOI * wIn)));
00184     
00185     // Combine the qDot and omegaDot into a stateDot vector
00186     stateDot(_(VectorIndexBase,VectorIndexBase + 3)) = qtemp(_,MatrixIndexBase);
00187     stateDot(_(VectorIndexBase + 4,VectorIndexBase + 6)) = Tmoment(_,MatrixIndexBase);
00188 
00189     return stateDot;
00190 }
00191 \endcode
00192 
00193 Then setup the driver code to run the above dynamics equation:
00194 \code
00195 // Setup an integrator and any special parameters
00196 RungeKuttaIntegrator myIntegrator; 
00197 myIntegrator.SetNumSteps(1000);
00198 // Integration times
00199 vector<ssfTime> integrationTimes;
00200 ssfTime begin(0);
00201 ssfTime end(begin + 50);
00202 integrationTimes.push_back(begin);
00203 integrationTimes.push_back(end);
00204 
00205 // Create the initial attitude state
00206 AttitudeState myAttitudeState;
00207 myAttitudeState.SetRotation(Rotation(Quaternion(0,0,0,1)));
00208 Vector initAngVelVector(3);
00209     initAngVelVector(1) = 0;
00210     initAngVelVector(2) = 0.1;
00211     initAngVelVector(2) = -0.5;
00212 myAttitudeState.SetAngularVelocity(initAngVelVector);
00213 SpecificFunctor AttitudeForcesFunctor(&NullFunctor);
00214 
00215 // Create the matrix of parameters needed for the RHS - MOI
00216 Matrix Parameters = eye(3);
00217     Parameters(1) = 100;
00218     Parameters(2) = 300;
00219     Parameters(3) = 150;
00220     
00221 // Integrate over the desired time interval
00222 Matrix history = myIntegrator.Integrate(
00223                             integrationTimes,           // seconds
00224                             &AttituteDynamics, 
00225                             myAttitudeState.GetState(),
00226                             NULL,
00227                             NULL,
00228                             Parameters,
00229                             AttitudeForcesFunctor
00230                         );
00231 \endcode
00232 -# Store the attitude to a text file.
00233 \code
00234 ofstream ofile;
00235 ofile.open("AttitudeHistory.dat");
00236 ofile << history;
00237 ofile.close();
00238 \endcode
00239 
00240 -# Plot the attitude history using GnuPlot.
00241 \code
00242 Matrix plotting = history(_,_(MatrixIndexBase,MatrixIndexBase+4));
00243 Plot2D(plotting);
00244 \endcode
00245 
00246 -# Store the attitude in DirectionCosineMatrix format in a MatLab file.
00247 
00248 Back to: \ref AttitudeTutorials
00249 <hr>
00250 
00251 \section OrbitTutorialAnswer Orbit Tutorial Answer
00252 Setup the dynamic equations:
00253 \code
00254 static Vector TwoBodyDynamics(const ssfTime &_time, const Vector& _integratingState, Orbit *_Orbit, Attitude *_Attitude, const Matrix &_parameters, const Functor &_forceFunctorPtr)
00255 {
00256     static Vector Forces(3);
00257     static Vector Velocity(3);
00258     static Vector stateDot(6);
00259     static AttitudeState tempAttState; // don't need this except to pass an empty one if there is no attitude
00260     static OrbitState orbState(new PositionVelocity);
00261 
00262     orbState.GetStateRepresentation()->SetPositionVelocity(_integratingState);
00263 
00264     if(_Attitude)
00265         Forces = _forceFunctorPtr.Call(_time, orbState, _Attitude->GetStateObject());
00266     else 
00267         Forces = _forceFunctorPtr.Call(_time, orbState, tempAttState);
00268 
00269     Velocity(_) = _integratingState(_(VectorIndexBase+3,VectorIndexBase+5));
00270     
00271 
00272     stateDot(_(VectorIndexBase, VectorIndexBase+2)) = Velocity(_);
00273     stateDot(_(VectorIndexBase+3, VectorIndexBase+5)) = Forces(_);
00274     return stateDot;
00275 }
00276 \endcode
00277 The force functions are setup as follows (using drag instead of solar radiation pressure):
00278 \code
00279 Vector OrbitForcesWithDragFunctor(const ssfTime& _pSSFTime, const OrbitState& _pOrbitState, const AttitudeState& _pAttitudeState)
00280 {
00281     Vector Forces;
00282     Vector Position(3); Position(_) = _pOrbitState.GetStateRepresentation()->GetPositionVelocity()(_(VectorIndexBase,VectorIndexBase+2));
00283             
00284     double BC = 0.5;
00285     Vector Vrel(3); Vrel = _pOrbitState.GetStateRepresentation()->GetPositionVelocity()(_(VectorIndexBase+3,VectorIndexBase+5));
00286     double Vrel_mag = norm2(Vrel);
00287     Forces = -398600.4418 / pow(norm2(Position),3) * Position;
00288     
00289     Forces += -1/2 *1/BC * pow(Vrel_mag,2) * Vrel / Vrel_mag; 
00290     return Forces;
00291 }
00292 \endcode
00293 
00294 Finally create the driver program and call the integration:
00295 \code
00296 // Setup an integrator and any special parameters
00297 RungeKuttaIntegrator myIntegrator; 
00298     int numOrbits = 2;
00299     int numSteps = 100;
00300 myIntegrator.SetNumSteps(numSteps);
00301     
00302 vector<ssfTime> integrationTimes;
00303 ssfTime begin(0);
00304 ssfTime end(begin + 92*60*numOrbits);
00305 integrationTimes.push_back(begin);
00306 integrationTimes.push_back(end);
00307     
00308 OrbitState myOrbitState;
00309 myOrbitState.SetStateRepresentation(new PositionVelocity);
00310 myOrbitState.SetOrbitFrame(new OrbitFrameIJK);
00311 Vector initPV(6);
00312     initPV(VectorIndexBase+0) = -5776.6; // km/s
00313     initPV(VectorIndexBase+1) = -157; // km/s        
00314     initPV(VectorIndexBase+2) = 3496.9; // km/s    
00315     initPV(VectorIndexBase+3) = -2.595;  // km/s
00316     initPV(VectorIndexBase+4) = -5.651;  // km/s        
00317     initPV(VectorIndexBase+5) = -4.513; // km/s
00318 myOrbitState.GetStateRepresentation()->SetPositionVelocity(initPV);
00319 
00320 Matrix history = myIntegrator.Integrate(
00321                             integrationTimes,           // seconds
00322                             &TwoBodyDynamics, 
00323                             myOrbit.GetStateRepresentation()->GetPositionVelocity(),
00324                             NULL,
00325                             NULL,
00326                             Parameters,
00327                             OrbitForcesFunctor
00328                         );
00329 \endcode
00330 
00331 -# Store the position and velocity to a text file.
00332 \code
00333 ofstream ofile;
00334 ofile.open("OrbitHistory.dat");
00335 ofile << history;
00336 ofile.close();
00337 \endcode
00338 
00339 -# Plot the orbit position vector using GnuPlot.
00340 \code
00341 // Create the plot using Columns 2:4
00342 Matrix orbitHistory = myOrbit->GetHistory().GetHistory();
00343 Matrix orbitPlotting = orbitHistory(_,_(2,4));
00344 Plot3D(orbitPlotting);
00345 \endcode
00346 Here is a check for your answer (without solar radiation pressure):
00347 \verbatim
00348 [ time, r1, r2, r3, v1, v2, v3]
00349 [ 5400, -5386.654,  562.845,  4034.074, -3.518027, -5.617977, -3.890888 ] 
00350 \endverbatim
00351 
00352 -# Store the orbit Keplerian parameters in a MatLab file.
00353 
00354 Back to: \ref OrbitTutorials
00355 
00356 \section CoupledTutorialAnswer Coupled Tutorial Answers
00357 -# Create an Environment object of the Earth using the above (Orbit \& Attitude) disturbance force \& torque functions.
00358 
00359 -# Create a Propagator that will propagate the above Orbit \& Attitude objects and using the Environment object.
00360     - Use a linear interpolator for the OrbitHistory.
00361     - Use loose coupling (orbit independent of attitude, but attitude dependent on position).
00362 
00363 -# Propagate the orbit and attitude for 2 orbits.
00364 
00365 -# Plot the position and attitude using gnuplot.
00366 
00367 -# Propagate another 2 orbits.
00368 
00369 -# Add the new states to the previously made plots.
00370 
00371 Back to: \ref CoupledTutorials
00372 
00373 */

Generated on Wed Sep 5 12:54:27 2007 for DSACSS Operational Code by  doxygen 1.3.9.1