testPropagation.cpp

This example demonstrates how to use a CombinedNumericPropagator to propagate a combined orbit & attitude.


/*  
*/
#include "Matrix.h"
#include "Rotation.h"
#include "Attitude.h"
#include "Orbit.h"
#include "CombinedNumericPropagator.h"
#include "RungeKuttaIntegrator.h"
#include "orbitmodels/TwoBodyDynamics.h"
#include "EarthCentralBody.h"
#include "OrbitState.h"
#include "AttitudeState.h"
#include "orbitstaterep/PositionVelocity.h"
#include "orbitframes/OrbitFrameIJK.h"
#include "Plot.h"
using namespace O_SESSAME;

NumericPropagator* SetupPropagator();
Environment* SetupEnvironment();
Orbit* SetupOrbit();
Attitude* SetupAttitude();
void myOrbitStateConvFunc(const Matrix &_meshPoint, OrbitState &_convertedOrbitState);
void myAttitudeStateConvFunc(const Matrix &_meshPoint, AttitudeState &_convertedAttitudeState);

int main()
{
    cout << "Calling SetupOrbit()" << endl;
    Orbit* myOrbit = SetupOrbit();
    cout << "Calling SetupAttitude()" << endl;
    Attitude* myAttitude = SetupAttitude();
    
    // Setup Propagator
    cout << "Calling SetupPropagator()" << endl;
    NumericPropagator* myPropagator = SetupPropagator();
    myOrbit->SetPropagator(myPropagator);
    myAttitude->SetPropagator(myPropagator);

    // Setup external environment
    cout << "Calling SetupEnvironment()" << endl;
    Environment* myEnvironment = SetupEnvironment();
    myOrbit->SetEnvironment(myEnvironment);
    myAttitude->SetEnvironment(myEnvironment);

    // Integration Times
    double numOrbits = 1/10.0;
    cout << "Number of Orbits: " << flush;
//        cin >> numOrbits;
    vector<ssfTime> integrationTimes;
    ssfTime begin(0);
    ssfTime end(begin + 92*60*numOrbits);
    integrationTimes.push_back(begin);
    integrationTimes.push_back(end);
    cout << "PropTime = " << begin.GetSeconds() << " s -> " << end.GetSeconds() << " s" << endl;
    cout << "Orbit State: " << ~myOrbit->GetStateObject().GetState() << endl;
    cout << "Attitude State: " << ~myAttitude->GetStateObject().GetState() << endl;

    // Integrate over the desired time interval
    tick();
    myPropagator->Propagate(integrationTimes, myOrbit->GetStateObject().GetState(), myAttitude->GetStateObject().GetState());
    ssfSeconds calcTime = tock();
    cout << "finished propagating in " << calcTime << " seconds." << endl;                                 

for (int ii = 0; ii < 2 ; ++ii)
{
    // Integrate again
    integrationTimes[0] = integrationTimes[1];
    integrationTimes[1] = integrationTimes[0] + 92*60*numOrbits;
    cout << integrationTimes[0] << " -> " << integrationTimes[1] << endl;
    myPropagator->Propagate(integrationTimes, myOrbit->GetStateObject().GetState(), myAttitude->GetStateObject().GetState());
}

    Matrix orbitHistory = myOrbit->GetHistory().GetHistory();
    Matrix orbitPlotting = orbitHistory(_,_(MatrixIndexBase+1,MatrixIndexBase+3));
    Matrix attitudeHistory = myAttitude->GetHistory().GetHistory();
    Matrix attitudePlotting = attitudeHistory(_,_(MatrixIndexBase,MatrixIndexBase+4));


    Plot3D(orbitPlotting);
//    Plot attitudePlot(attitudePlotting);
    Plot2D(attitudePlotting);
   
    // Store the output to file
    ofstream ofile;
    ofile.open("OrbitHistory.dat");
    ofile << myOrbit->GetHistory().GetHistory();
    ofile.close();
    
    ofile.open("AttitudeHistory.dat");
    ofile << myAttitude->GetHistory().GetHistory();
    ofile.close();

    return 0;
                            
}

// *************************
// ****** ENVIRONMENT ****** 
// *************************
// Force function that will be called each timestep
Vector GravityForceFunction(const ssfTime &_currentTime, const OrbitState  &_currentOrbitState, const AttitudeState &_currentAttitudeState, const EnvFuncParamaterType &_parameterList)
{
//    Vector state = _currentOrbitState.GetState();
    static Vector Forces(3);
//    Vector Position(3); Position(_) = state(_(VectorIndexBase,VectorIndexBase+2));
    static Vector Position(3); Position(_) = _currentOrbitState.GetState()(_(VectorIndexBase,VectorIndexBase+2));
    Forces = -398600.441 / pow(norm2(Position),3) * Position;
    return Forces;
}

Vector DragForceFunction(const ssfTime &_currentTime, const OrbitState &_currentOrbitState, const AttitudeState &_currentAttitudeState, const EnvFuncParamaterType &_parameterList)
{
    static Vector Forces(3);
    double BC = *(reinterpret_cast<double*>(_parameterList[0]));
    static Vector Vrel(3); Vrel(_) = _currentOrbitState.GetState()(_(VectorIndexBase+3,VectorIndexBase+5));
    double Vrel_mag = norm2(Vrel);
    double rho = *(reinterpret_cast<double*>(_parameterList[1]));
    Forces = -1/2 * rho / BC * pow(Vrel_mag,2) * Vrel / Vrel_mag; 
    return Forces;
}

Environment* SetupEnvironment()
{
    // ENVIRONMENT TESTING
    Environment* pEarthEnv = new Environment;
    EarthCentralBody *pCBEarth = new EarthCentralBody;
    pEarthEnv->SetCentralBody(pCBEarth);
    
    // Add Gravity force function
    cout << "Filling Parameters" << endl;
    EnvFunction TwoBodyGravity(&GravityForceFunction);
    pEarthEnv->AddForceFunction(TwoBodyGravity);
    
    // Add Drag Force Function
    EnvFunction DragForce(&DragForceFunction);
    double *BC = new double(200);
    DragForce.AddParameter(reinterpret_cast<void*>(BC), 1);
    double *rho = new double(1.13 * pow(static_cast<double>(10), static_cast<double>(-12))); // kg/m^3
    DragForce.AddParameter(reinterpret_cast<void*>(rho), 2);
    pEarthEnv->AddForceFunction(DragForce);
    
    cout << "Finished Setting up Earth Environment" << endl;
    return pEarthEnv;
}

// *************************
// ****** PROPAGATOR ******* 
// ************************* 
NumericPropagator* SetupPropagator()
{
    CombinedNumericPropagator* myProp = new CombinedNumericPropagator;
    
    // Create & setup the integator
        // Setup an integrator and any special parameters
    RungeKuttaIntegrator* orbitIntegrator = new RungeKuttaIntegrator; 
    RungeKuttaIntegrator* attitudeIntegrator = new RungeKuttaIntegrator; 

    orbitIntegrator->SetNumSteps(100);
    myProp->SetOrbitIntegrator(orbitIntegrator);
    attitudeIntegrator->SetNumSteps(1000);
    myProp->SetAttitudeIntegrator(attitudeIntegrator);
    
    myProp->SetOrbitStateConversion(&myOrbitStateConvFunc);
    myProp->SetAttitudeStateConversion(&myAttitudeStateConvFunc);
    return myProp;
}

// *************************
// ********* ORBIT ********* 
// ************************* 
void myOrbitStateConvFunc(const Matrix &_meshPoint, OrbitState &_convertedOrbitState)
{
    static Vector tempVector(_meshPoint[MatrixColsIndex].getIndexBound() - 1);
    tempVector(_) = ~_meshPoint(_,_(MatrixIndexBase+1, _meshPoint[MatrixColsIndex].getIndexBound()));
    _convertedOrbitState.SetState(tempVector);
    return;
}

Orbit* SetupOrbit()
{
    Orbit* myOrbit = new Orbit;
    
    // Create & initialize the orbit
    OrbitState myOrbitState;
    myOrbitState.SetStateRepresentation(new PositionVelocity);
    myOrbitState.SetOrbitFrame(new OrbitFrameIJK);
    Vector initPV(6);
        // Space station
        initPV(VectorIndexBase+0) = -5776.6; // km
        initPV(VectorIndexBase+1) = -157; // km       
        initPV(VectorIndexBase+2) = 3496.9; // km    
        initPV(VectorIndexBase+3) = -2.595;  // km/s
        initPV(VectorIndexBase+4) = -5.651;  // km/s        
        initPV(VectorIndexBase+5) = -4.513; // km/s
    myOrbitState.SetState(initPV);
    myOrbit->SetStateObject(myOrbitState);
    
    myOrbit->SetDynamicsEq(&TwoBodyDynamics);
    
    // Setup Parameters (ie mass, etc)
    Matrix Parameters(1,1);
    Parameters(MatrixIndexBase,MatrixIndexBase) = 398600.441; //km / s^2
    myOrbit->SetParameters(Parameters);
    return myOrbit;
}


// *************************
// ******* ATTITUDE ******** 
// ************************* 
void myAttitudeStateConvFunc(const Matrix &_meshPoint, AttitudeState &_convertedAttitudeState)
{
    static Vector tempQ(4); tempQ(_) = ~_meshPoint(_,_(2, 5));
    static Vector tempVector(3); tempVector(_) = ~_meshPoint(1, _(6, 8));
    _convertedAttitudeState.SetState(Rotation(Quaternion(tempQ)), tempVector);
    return;
}
static Vector AttituteDynamics(const ssfTime &_time, const Vector& _integratingState, Orbit *_Orbit, Attitude *_Attitude, const Matrix &_parameters, const Functor &_forceFunctorPtr)
{
    static Vector stateDot(7);
    static Matrix bMOI(3,3); 
    static Matrix qtemp(4,3); 
    static Matrix Tmoment(3,1);
    static Vector qIn(4); 
    static Vector wIn(3);
    qIn = _integratingState(_(VectorIndexBase,VectorIndexBase + 3));
    wIn = _integratingState(_(VectorIndexBase + 4,VectorIndexBase + 6));
    qIn /= norm2(qIn);

//    _attitudeState->SetState(Rotation(Quaternion(qIn)), wIn);  // Need to speed up in some way
    qtemp(_(VectorIndexBase+0,VectorIndexBase+2),_(VectorIndexBase+0,VectorIndexBase+2)) = skew(qIn(_(VectorIndexBase+0,VectorIndexBase+2))) + qIn(VectorIndexBase+3) * eye(3);
    qtemp(VectorIndexBase+3, _(VectorIndexBase+0,VectorIndexBase+2)) = -(~qIn(_(VectorIndexBase+0,VectorIndexBase+2)));
    qtemp(_,MatrixIndexBase) = 0.5 * qtemp * wIn;

    bMOI = _parameters(_(MatrixIndexBase+0,MatrixIndexBase+2),_(MatrixIndexBase+0,MatrixIndexBase+2));
    Tmoment(_,_) = (_forceFunctorPtr.Call(_time, _Orbit->GetStateObject(), _Attitude->GetStateObject()))(_);
    Tmoment = (bMOI.inverse() * (Tmoment - skew(wIn) * (bMOI * wIn)));
    
    stateDot(_(VectorIndexBase,VectorIndexBase + 3)) = qtemp(_,MatrixIndexBase);
    stateDot(_(VectorIndexBase + 4,VectorIndexBase + 6)) = Tmoment(_,MatrixIndexBase);

    return stateDot;
}

Attitude* SetupAttitude()
{
    Attitude* myAttitude = new Attitude;
    
    AttitudeState myAttitudeState;
    myAttitudeState.SetRotation(Rotation(Quaternion(0,0,0,1)));
    Vector initAngVelVector(3);
        initAngVelVector(1) = 0.1;
    myAttitudeState.SetAngularVelocity(initAngVelVector);

    myAttitude->SetStateObject(myAttitudeState);
    myAttitude->SetDynamicsEq(&AttituteDynamics);
    myAttitude->SetParameters(eye(3));
    
    return myAttitude;
    
}

// Do not change the comments below - they will be added automatically by CVS
/*****************************************************************************
*       $Log: testPropagation.cpp,v $
*       Revision 1.4  2003/05/27 17:47:13  nilspace
*       Updated example to have seperate orbit & attitude integrators.
*       
*       Revision 1.3  2003/05/20 19:24:43  nilspace
*       Updated.
*       
*       Revision 1.2  2003/05/13 18:57:32  nilspace
*       Clened up to work with new Propagators.
*       
*       Revision 1.1  2003/05/01 02:42:47  nilspace
*       New propagation test file.
*       
*
******************************************************************************/

                        

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