Hello! I’ve write a program for orbit propagation and choose numerical integration method runge-kutta 4. I wrote only 2 perturbation effect: 2-body and atmospheric drag. Here is the code of main cycle:
My implementation of RK4:
Partial calculation:
Implementation of atmospheric drag which I find in “O.Montenbruck, E. Gill; Satellite Orbits - Models, Methods, and Applications” :
I know that in matlab it’s dorman-prince method but difference in values only -+1-5, it’s okay for me.
May be I am not right and propagate with only atmospheric drag is incorrect? Or it's error in code?
Code:
Satellite sat(QVector3D(7000,0,500), QVector3D(0,9,0),0.0025, 3725.0);
QVector< QVector3D > satellite;
double h = 1.0;
QDateTime dt = QDateTime(QDate(1983,9,23),QTime(0,0,0,0));
for (int j = 0.0; j < 100; j++) {
double Mjd_UTC = MJD(dt);
// 32.184 – UTC-TAI
double Mjd_TT = Mjd_UTC + 32.184/86400.0;
RK4step(h, sat, Mjd_TT);
dt = dt.addDays(j);
satellite.push_back(sat.loc);
satellite.push_back(sat.vel);
}
My implementation of RK4:
Code:
void RK4step(const double& h, Satellite& y, const double &Mjd_TT) {
QVector3D loc(y.loc);
QVector3D vel(y.vel);
QVector3D k1,k2,k3,k4, acceleration;
// rotation matrix for satellite relative to Earth at time Mjd_TT
// O.Montenbruck, E. Gill; Satellite Orbits - Models, Methods, and Applications
QMatrix3x3 T = NutationMatrix(Mjd_TT) * PreccessionMatrix(MJD_J2000, Mjd_TT);
k1 = partialStep(y, T, y.size, y.mass);
k2 = partialStep(y + k1 * h/2, T, y.size, y.mass);
k3 = partialStep(y + k2 * h/2, T, y.size, y.mass);
k4 = partialStep(y + k3 * h, T, y.size, y.mass);
acceleration += (k1 + (k2 + k3) * 2 + k4) / 6;
y.vel += acceleration * h;
y.loc += y.vel * h;
}
Partial calculation:
Code:
QVector3D partialStep(const Satellite &y, const QMatrix3x3 &T,
const double& satSize, const double& satMass ) {
QVector3D acceleration (0.0, 0.0, 0.0);
double r = Magnitude(y.loc);
// MU - Earth gravity = 398602
double temp = -MU / (r * r * r);
QVector3D acc2Body = y.loc * temp;
double Cd = 2.2;
QVector3D accFromAir = AccelDrag(0.0, y.loc, y.vel, T, satSize, satMass, Cd);
acceleration = acc2Body + accFromAir;
return acceleration;
}
Implementation of atmospheric drag which I find in “O.Montenbruck, E. Gill; Satellite Orbits - Models, Methods, and Applications” :
Code:
QVector3D AccelDrag ( double Mjd_TT, const QVector3D &loc, const QVector3D &vel,
const QMatrix3x3& T, double Area, double mass, double CD )
{
// W3 – Earth rotation = 0.0000729211 rad/sec
const QVector3D omega (0.0, 0.0, W3);
double vel_abs, dens;
QVector3D loc_tod, vel_tod;
QVector3D vel_rel, acc_tod;
QMatrix3x3 T_trp;
// for converting to ICRF/EME2000
T_trp = T.transposed();
loc_tod = T * loc;
vel_tod = T * vel;
// velocity relative to Earth rotation
vel_rel = vel_tod - QVector3D::crossProduct(omega, loc_tod);
vel_abs = Magnitude2(vel_rel);
// Harris-Priester atmospheric density model
dens = Density_HP (Mjd_TT, loc_tod);
// atmospheric acceleration
acc_tod = -0.5*CD*(Area/mass)*dens*vel_abs*vel_rel;
return T_trp * acc_tod;
}
With solo 2-body perturbation effect orbit change correctly to check this I find other several implementations of it, for example matlab simple propagator of this guy: https://github.com/komrad36/SimpleOrbitalPropagatorI know that in matlab it’s dorman-prince method but difference in values only -+1-5, it’s okay for me.
The problem is that with solo atmospheric drag satellite position change not quit correct, I guess. Following common sense satellite must go down sooner or later, but it fly away from Earth all the time position vector just increase. And I don’t find simple example to compare results with mine.May be I am not right and propagate with only atmospheric drag is incorrect? Or it's error in code?