#include "Matrix.h"
#include "RungeKuttaIntegrator.h"
#include "LinearInterpolator.h"
#include "Plot.h"
#include "Attitude.h"
#include "AttitudeState.h"
#include <vector.h>
using namespace std;
Vector NullFunctor(const ssfTime& _pSSFTime, const OrbitState& _pOrbitState, const AttitudeState& _pAttitudeState)
{
return Vector(3);
}
static Vector AttituteDynamics(const ssfTime &_time, const Vector& _integratingState, Orbit *_pOrbit, Attitude *_pAttitude, 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);
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 = (bMOI.inverse() * (Tmoment - skew(wIn) * (bMOI * wIn)));
stateDot(_(VectorIndexBase,VectorIndexBase + 3)) = qtemp(_,MatrixIndexBase);
stateDot(_(VectorIndexBase + 4,VectorIndexBase + 6)) = Tmoment(_,MatrixIndexBase);
cout << 0.5 * ~wIn * (bMOI * wIn);
return stateDot;
}
int main()
{
RungeKuttaIntegrator myIntegrator;
myIntegrator.SetNumSteps(1000);
vector<ssfTime> integrationTimes;
ssfTime begin(0);
ssfTime end(begin + 20);
integrationTimes.push_back(begin);
integrationTimes.push_back(end);
AttitudeState myAttitudeState;
myAttitudeState.SetRotation(Rotation(Quaternion(0,0,0,1)));
Vector initAngVelVector(3);
initAngVelVector(1) = 0.1;
myAttitudeState.SetAngularVelocity(initAngVelVector);
SpecificFunctor AttitudeForcesFunctor(&NullFunctor);
Matrix Parameters = eye(3);
Matrix I(3,3);
I(1,1) = 100;
I(2,2) = 200;
I(3,3) = 150;
Vector h(3);
h(1) = 10;
h(2) = 20;
h(3) = 30;
Vector w = I.inverse() * h;
Matrix Tmat = 0.5 * (~w * (I * w));
Vector initEugeneState(4);
initEugeneState(_(1,3)) = h(_(1,3));
initEugeneState(4) = Tmat(1,1);
cout << "PropTime = " << begin.GetSeconds() << " s -> " << end.GetSeconds() << " s" << endl;
cout << "Attitude State: " << ~myAttitudeState.GetState() << endl;
tick();
Matrix history = myIntegrator.Integrate(
integrationTimes,
&AttituteDynamics,
myAttitudeState.GetState(),
NULL,
NULL,
Parameters,
AttitudeForcesFunctor
);
cout << "finished propagating in " << tock() << " seconds." << endl;
Matrix plotting = history(_,_(MatrixIndexBase,MatrixIndexBase+4));
AttitudeHistory myAttHistory;
myAttHistory.SetInterpolator(new LinearInterpolator);
Vector AngVel(3);
Vector Quat(4);
Rotation myRot;
for(int jj = 1;jj <= history[MatrixRowsIndex].getIndexBound(); ++jj)
{
AngVel = ~(history(jj, _(6,8)));
Quat = ~(history(jj,_(2,5)));
myRot.Set(Quaternion(Quat));
myAttHistory.AppendHistory(history(jj,1), myRot, AngVel);
}
double requestTime;
cout << "Output attitude state at time (s): " << flush;
cin >> requestTime;
ssfTime myTime(requestTime);
myAttHistory.GetState(myTime, myRot, AngVel);
cout << myTime.GetSeconds() << " : " << ~myRot.GetQuaternion() << endl;
ofstream ofile;
ofile.open("AttitudeHistory.dat");
ofile << history;
ofile.close();
return 0;
}