#include "orbitmodels/TwoBodyDynamics.h"
#include "Matrix.h"
#include "RungeKuttaFehlbergIntegrator.h"
#include "OrbitState.h"
#include "Plot.h"
#include "orbitframes/OrbitFrameIJK.h"
#include "orbitstaterep/PositionVelocity.h"
#include "LinearInterpolator.h"
#include <vector.h>
using namespace std;
using namespace O_SESSAME;
Vector OrbitForcesFunctor(const ssfTime& _pSSFTime, const OrbitState& _pOrbitState, const AttitudeState& _pAttitudeState)
{
Vector Forces;
Vector Position(3); Position(_) = _pOrbitState.GetStateRepresentation()->GetPositionVelocity()(_(VectorIndexBase,VectorIndexBase+2));
Forces = -398600.4418 / pow(norm2(Position),3) * Position;
return Forces;
}
Vector OrbitForcesWithDragFunctor(const ssfTime& _pSSFTime, const OrbitState& _pOrbitState, const AttitudeState& _pAttitudeState)
{
Vector Forces;
Vector Position(3); Position(_) = _pOrbitState.GetStateRepresentation()->GetPositionVelocity()(_(VectorIndexBase,VectorIndexBase+2));
double BC = 0.5;
Vector Vrel(3); Vrel = _pOrbitState.GetStateRepresentation()->GetPositionVelocity()(_(VectorIndexBase+3,VectorIndexBase+5));
double Vrel_mag = norm2(Vrel);
Forces = -398600.4418 / pow(norm2(Position),3) * Position;
Forces += -1/2 *1/BC * pow(Vrel_mag,2) * Vrel / Vrel_mag;
return Forces;
}
int main()
{
RungeKuttaFehlbergIntegrator myIntegrator;
int numOrbits = 1;
int numSteps = 100;
cout << "Number of Orbits: " << flush;
cin >> numOrbits;
cout << "Number of Integration Steps: "<< flush;
cin >> numSteps;
vector<ssfTime> integrationTimes;
ssfTime begin(0);
ssfTime end(begin + 92*60*numOrbits);
integrationTimes.push_back(begin);
integrationTimes.push_back(end);
OrbitState myOrbit;
myOrbit.SetStateRepresentation(new PositionVelocity);
myOrbit.SetOrbitFrame(new OrbitFrameIJK);
Vector initPV(6);
initPV(VectorIndexBase+0) = -5776.6;
initPV(VectorIndexBase+1) = -157;
initPV(VectorIndexBase+2) = 3496.9;
initPV(VectorIndexBase+3) = -2.595;
initPV(VectorIndexBase+4) = -5.651;
initPV(VectorIndexBase+5) = -4.513;
myOrbit.GetStateRepresentation()->SetPositionVelocity(initPV);
SpecificFunctor OrbitForcesFunctor(&OrbitForcesWithDragFunctor);
Matrix Parameters(1,1);
Parameters(MatrixIndexBase,MatrixIndexBase) = 398600.4418;
cout << "PropTime = " << begin.GetSeconds() << " s -> " << end.GetSeconds() << " s" << endl;
cout << "Orbit State: " << ~myOrbit.GetStateRepresentation()->GetPositionVelocity() << endl;
tick();
Matrix history = myIntegrator.Integrate(
integrationTimes,
&TwoBodyDynamics,
myOrbit.GetStateRepresentation()->GetPositionVelocity(),
NULL,
NULL,
Parameters,
OrbitForcesFunctor
);
cout << "finished propagating in " << tock() << " seconds." << endl;
Matrix plotting = history(_,_(MatrixIndexBase+1,MatrixIndexBase+3));
Plot3D(plotting);
ofstream ofile;
ofile.open("OrbitHistory.dat");
ofile << history;
ofile.close();
OrbitHistory myOrbHistory;
myOrbHistory.SetInterpolator(new LinearInterpolator);
Vector PosVel(6);
for(int jj = 1;jj <= history[MatrixRowsIndex].getIndexBound(); ++jj)
{
PosVel(_) = ~history(jj,_(2,7));
myOrbit.GetStateRepresentation()->SetPositionVelocity(PosVel);
myOrbHistory.AppendHistory(history(jj,1), myOrbit);
}
double inspectTime;
cout << "Output state at time (s): " << flush;
cin >> inspectTime;
ssfTime myTime(inspectTime);
myOrbHistory.GetState(myTime, myOrbit);
cout << myTime.GetSeconds() << " : " << ~myOrbit.GetStateRepresentation()->GetPositionVelocity() << endl;
return 0;
}