Moved orbital parameters out into seperate class

feature/19
Daniel Warner 2011-07-09 22:20:31 +00:00
parent 3049d03fae
commit 3d0c49bf87
6 changed files with 288 additions and 265 deletions

View File

@ -9,6 +9,7 @@ SOURCES=CoordGeodetic.cpp \
Globals.cpp \
Julian.cpp \
Observer.cpp \
OrbitalElements.cpp \
SGP4.cpp \
Timespan.cpp \
Tle.cpp \

51
OrbitalElements.cpp Executable file
View File

@ -0,0 +1,51 @@
#include "OrbitalElements.h"
OrbitalElements::OrbitalElements(const Tle& tle) {
/*
* extract and format tle data
*/
mean_anomoly_ = tle.MeanAnomaly(false);
ascending_node_ = tle.RightAscendingNode(false);
argument_perigee_ = tle.ArgumentPerigee(false);
eccentricity_ = tle.Eccentricity();
inclination_ = tle.Inclination(false);
mean_motion_ = tle.MeanMotion() * kTWOPI / kMINUTES_PER_DAY;
bstar_ = tle.BStar();
epoch_ = tle.Epoch();
/*
* recover original mean motion (xnodp) and semimajor axis (aodp)
* from input elements
*/
const double a1 = pow(kXKE / MeanMotion(), kTWOTHIRD);
const double cosio = cos(Inclination());
const double theta2 = cosio * cosio;
const double x3thm1 = 3.0 * theta2 - 1.0;
const double eosq = Eccentricity() * Eccentricity();
const double betao2 = 1.0 - eosq;
const double betao = sqrt(betao2);
const double temp = (1.5 * kCK2) * x3thm1 / (betao * betao2);
const double del1 = temp / (a1 * a1);
const double a0 = a1 * (1.0 - del1 * (1.0 / 3.0 + del1 * (1.0 + del1 * 134.0 / 81.0)));
const double del0 = temp / (a0 * a0);
recovered_mean_motion_ = MeanMotion() / (1.0 + del0);
/*
* alternative way to calculate
* doesnt affect final results
* recovered_semi_major_axis_ = pow(XKE / RecoveredMeanMotion(), TWOTHIRD);
*/
recovered_semi_major_axis_ = a0 / (1.0 - del0);
/*
* find perigee and period
*/
perigee_ = (RecoveredSemiMajorAxis() * (1.0 - Eccentricity()) - kAE) * kXKMPER;
period_ = kTWOPI / RecoveredMeanMotion();
}
OrbitalElements::~OrbitalElements(void) {
}

112
OrbitalElements.h Executable file
View File

@ -0,0 +1,112 @@
#ifndef ORBITALELEMENTS_H_
#define ORBITALELEMENTS_H_
#include "Tle.h"
class OrbitalElements {
public:
OrbitalElements(const Tle& tle);
virtual ~OrbitalElements(void);
/*
* XMO
*/
double MeanAnomoly() const {
return mean_anomoly_;
}
/*
* XNODEO
*/
double AscendingNode() const {
return ascending_node_;
}
/*
* OMEGAO
*/
double ArgumentPerigee() const {
return argument_perigee_;
}
/*
* EO
*/
double Eccentricity() const {
return eccentricity_;
}
/*
* XINCL
*/
double Inclination() const {
return inclination_;
}
/*
* XNO
*/
double MeanMotion() const {
return mean_motion_;
}
/*
* BSTAR
*/
double BStar() const {
return bstar_;
}
/*
* AODP
*/
double RecoveredSemiMajorAxis() const {
return recovered_semi_major_axis_;
}
/*
* XNODP
*/
double RecoveredMeanMotion() const {
return recovered_mean_motion_;
}
/*
* PERIGE
*/
double Perigee() const {
return perigee_;
}
/*
* Period in minutes
*/
double Period() const {
return period_;
}
/*
* EPOCH
*/
Julian Epoch() const {
return epoch_;
}
private:
double mean_anomoly_;
double ascending_node_;
double argument_perigee_;
double eccentricity_;
double inclination_;
double mean_motion_;
double bstar_;
double recovered_semi_major_axis_;
double recovered_mean_motion_;
double perigee_;
double period_;
Julian epoch_;
};
#endif

View File

@ -16,8 +16,7 @@
void RunTle(Tle tle, double start, double end, double inc) {
double current = start;
SGP4 model;
model.SetTle(tle);
SGP4 model(tle);
bool running = true;
bool first_run = true;
std::cout << " " << std::setprecision(0) << tle.NoradNumber() << " xx" << std::endl;

281
SGP4.cpp
View File

@ -6,14 +6,10 @@
#include <cmath>
#include <iomanip>
SGP4::SGP4(void) {
SGP4::SGP4(const Tle& tle)
: elements_(tle) {
Reset();
}
SGP4::SGP4(const Tle& tle) {
SetTle(tle);
Initialize();
}
SGP4::~SGP4(void) {
@ -21,84 +17,41 @@ SGP4::~SGP4(void) {
void SGP4::SetTle(const Tle& tle) {
/*
* reset all constants etc
*/
Reset();
/*
* extract and format tle data
*/
mean_anomoly_ = tle.MeanAnomaly(false);
ascending_node_ = tle.RightAscendingNode(false);
argument_perigee_ = tle.ArgumentPerigee(false);
eccentricity_ = tle.Eccentricity();
inclination_ = tle.Inclination(false);
mean_motion_ = tle.MeanMotion() * kTWOPI / kMINUTES_PER_DAY;
bstar_ = tle.BStar();
epoch_ = tle.Epoch();
/*
* error checks
*/
if (eccentricity_ < 0.0 || eccentricity_ > 1.0 - 1.0e-3) {
throw SatelliteException("Eccentricity out of range");
}
if (inclination_ < 0.0 || eccentricity_ > kPI) {
throw SatelliteException("Inclination out of range");
}
elements_ = OrbitalElements(tle);
Initialize();
}
void SGP4::Initialize() {
/*
* reset all constants etc
*/
Reset();
/*
* recover original mean motion (xnodp) and semimajor axis (aodp)
* from input elements
* error checks
*/
const double a1 = pow(kXKE / MeanMotion(), kTWOTHIRD);
common_consts_.cosio = cos(Inclination());
common_consts_.sinio = sin(Inclination());
if (elements_.Eccentricity() < 0.0 || elements_.Eccentricity() > 1.0 - 1.0e-3) {
throw SatelliteException("Eccentricity out of range");
}
if (elements_.Inclination() < 0.0 || elements_.Inclination() > kPI) {
throw SatelliteException("Inclination out of range");
}
common_consts_.cosio = cos(elements_.Inclination());
common_consts_.sinio = sin(elements_.Inclination());
const double theta2 = common_consts_.cosio * common_consts_.cosio;
common_consts_.x3thm1 = 3.0 * theta2 - 1.0;
const double eosq = Eccentricity() * Eccentricity();
const double eosq = elements_.Eccentricity() * elements_.Eccentricity();
const double betao2 = 1.0 - eosq;
const double betao = sqrt(betao2);
const double temp = (1.5 * kCK2) * common_consts_.x3thm1 / (betao * betao2);
const double del1 = temp / (a1 * a1);
const double a0 = a1 * (1.0 - del1 * (1.0 / 3.0 + del1 * (1.0 + del1 * 134.0 / 81.0)));
const double del0 = temp / (a0 * a0);
recovered_mean_motion_ = MeanMotion() / (1.0 + del0);
/*
* alternative way to calculate
* doesnt affect final results
* recovered_semi_major_axis_ = pow(XKE / RecoveredMeanMotion(), TWOTHIRD);
*/
recovered_semi_major_axis_ = a0 / (1.0 - del0);
/*
* find perigee and period
*/
perigee_ = (RecoveredSemiMajorAxis() * (1.0 - Eccentricity()) - kAE) * kXKMPER;
period_ = kTWOPI / RecoveredMeanMotion();
if (Period() >= 225.0) {
if (elements_.Period() >= 225.0) {
use_deep_space_ = true;
} else {
use_deep_space_ = false;
@ -109,7 +62,7 @@ void SGP4::Initialize() {
* quadratic variation in mean anomly. also, the c3 term, the
* delta omega term and the delta m term are dropped
*/
if (Perigee() < 220.0) {
if (elements_.Perigee() < 220.0) {
use_simple_model_ = true;
}
}
@ -120,9 +73,9 @@ void SGP4::Initialize() {
*/
double s4 = kS;
double qoms24 = kQOMS2T;
if (Perigee() < 156.0) {
s4 = Perigee() - 78.0;
if (Perigee() < 98.0) {
if (elements_.Perigee() < 156.0) {
s4 = elements_.Perigee() - 78.0;
if (elements_.Perigee() < 98.0) {
s4 = 20.0;
}
qoms24 = pow((120.0 - s4) * kAE / kXKMPER, 4.0);
@ -132,33 +85,33 @@ void SGP4::Initialize() {
/*
* generate constants
*/
const double pinvsq = 1.0 / (RecoveredSemiMajorAxis() * RecoveredSemiMajorAxis() * betao2 * betao2);
const double tsi = 1.0 / (RecoveredSemiMajorAxis() - s4);
common_consts_.eta = RecoveredSemiMajorAxis() * Eccentricity() * tsi;
const double pinvsq = 1.0 / (elements_.RecoveredSemiMajorAxis() * elements_.RecoveredSemiMajorAxis() * betao2 * betao2);
const double tsi = 1.0 / (elements_.RecoveredSemiMajorAxis() - s4);
common_consts_.eta = elements_.RecoveredSemiMajorAxis() * elements_.Eccentricity() * tsi;
const double etasq = common_consts_.eta * common_consts_.eta;
const double eeta = Eccentricity() * common_consts_.eta;
const double eeta = elements_.Eccentricity() * common_consts_.eta;
const double psisq = fabs(1.0 - etasq);
const double coef = qoms24 * pow(tsi, 4.0);
const double coef1 = coef / pow(psisq, 3.5);
const double c2 = coef1 * RecoveredMeanMotion() * (RecoveredSemiMajorAxis() *
const double c2 = coef1 * elements_.RecoveredMeanMotion() * (elements_.RecoveredSemiMajorAxis() *
(1.0 + 1.5 * etasq + eeta * (4.0 + etasq)) +
0.75 * kCK2 * tsi / psisq *
common_consts_.x3thm1 * (8.0 + 3.0 * etasq *
(8.0 + etasq)));
common_consts_.c1 = BStar() * c2;
common_consts_.c1 = elements_.BStar() * c2;
common_consts_.a3ovk2 = -kXJ3 / kCK2 * pow(kAE, 3.0);
common_consts_.x1mth2 = 1.0 - theta2;
common_consts_.c4 = 2.0 * RecoveredMeanMotion() * coef1 * RecoveredSemiMajorAxis() * betao2 *
(common_consts_.eta * (2.0 + 0.5 * etasq) + Eccentricity() * (0.5 + 2.0 * etasq) -
2.0 * kCK2 * tsi / (RecoveredSemiMajorAxis() * psisq) *
common_consts_.c4 = 2.0 * elements_.RecoveredMeanMotion() * coef1 * elements_.RecoveredSemiMajorAxis() * betao2 *
(common_consts_.eta * (2.0 + 0.5 * etasq) + elements_.Eccentricity() * (0.5 + 2.0 * etasq) -
2.0 * kCK2 * tsi / (elements_.RecoveredSemiMajorAxis() * psisq) *
(-3.0 * common_consts_.x3thm1 * (1.0 - 2.0 * eeta + etasq *
(1.5 - 0.5 * eeta)) + 0.75 * common_consts_.x1mth2 * (2.0 * etasq - eeta *
(1.0 + etasq)) * cos(2.0 * ArgumentPerigee())));
(1.0 + etasq)) * cos(2.0 * elements_.ArgumentPerigee())));
const double theta4 = theta2 * theta2;
const double temp1 = 3.0 * kCK2 * pinvsq * RecoveredMeanMotion();
const double temp1 = 3.0 * kCK2 * pinvsq * elements_.RecoveredMeanMotion();
const double temp2 = temp1 * kCK2 * pinvsq;
const double temp3 = 1.25 * kCK4 * pinvsq * pinvsq * RecoveredMeanMotion();
common_consts_.xmdot = RecoveredMeanMotion() + 0.5 * temp1 * betao *
const double temp3 = 1.25 * kCK4 * pinvsq * pinvsq * elements_.RecoveredMeanMotion();
common_consts_.xmdot = elements_.RecoveredMeanMotion() + 0.5 * temp1 * betao *
common_consts_.x3thm1 + 0.0625 * temp2 * betao *
(13.0 - 78.0 * theta2 + 137.0 * theta4);
const double x1m5th = 1.0 - 5.0 * theta2;
@ -181,7 +134,7 @@ void SGP4::Initialize() {
if (use_deep_space_) {
deepspace_consts_.gsto = Epoch().ToGreenwichSiderealTime();
deepspace_consts_.gsto = elements_.Epoch().ToGreenwichSiderealTime();
DeepSpaceInitialize(eosq, common_consts_.sinio, common_consts_.cosio, betao,
theta2, betao2,
@ -190,29 +143,29 @@ void SGP4::Initialize() {
} else {
double c3 = 0.0;
if (Eccentricity() > 1.0e-4) {
c3 = coef * tsi * common_consts_.a3ovk2 * RecoveredMeanMotion() * kAE *
common_consts_.sinio / Eccentricity();
if (elements_.Eccentricity() > 1.0e-4) {
c3 = coef * tsi * common_consts_.a3ovk2 * elements_.RecoveredMeanMotion() * kAE *
common_consts_.sinio / elements_.Eccentricity();
}
nearspace_consts_.c5 = 2.0 * coef1 * RecoveredSemiMajorAxis() * betao2 * (1.0 + 2.75 *
nearspace_consts_.c5 = 2.0 * coef1 * elements_.RecoveredSemiMajorAxis() * betao2 * (1.0 + 2.75 *
(etasq + eeta) + eeta * etasq);
nearspace_consts_.omgcof = BStar() * c3 * cos(ArgumentPerigee());
nearspace_consts_.omgcof = elements_.BStar() * c3 * cos(elements_.ArgumentPerigee());
nearspace_consts_.xmcof = 0.0;
if (Eccentricity() > 1.0e-4)
nearspace_consts_.xmcof = -kTWOTHIRD * coef * BStar() * kAE / eeta;
if (elements_.Eccentricity() > 1.0e-4)
nearspace_consts_.xmcof = -kTWOTHIRD * coef * elements_.BStar() * kAE / eeta;
nearspace_consts_.delmo = pow(1.0 + common_consts_.eta * (cos(MeanAnomoly())), 3.0);
nearspace_consts_.sinmo = sin(MeanAnomoly());
nearspace_consts_.delmo = pow(1.0 + common_consts_.eta * (cos(elements_.MeanAnomoly())), 3.0);
nearspace_consts_.sinmo = sin(elements_.MeanAnomoly());
if (!use_simple_model_) {
const double c1sq = common_consts_.c1 * common_consts_.c1;
nearspace_consts_.d2 = 4.0 * RecoveredSemiMajorAxis() * tsi * c1sq;
nearspace_consts_.d2 = 4.0 * elements_.RecoveredSemiMajorAxis() * tsi * c1sq;
const double temp = nearspace_consts_.d2 * tsi * common_consts_.c1 / 3.0;
nearspace_consts_.d3 = (17.0 * RecoveredSemiMajorAxis() + s4) * temp;
nearspace_consts_.d4 = 0.5 * temp * RecoveredSemiMajorAxis() *
tsi * (221.0 * RecoveredSemiMajorAxis() + 31.0 * s4) * common_consts_.c1;
nearspace_consts_.d3 = (17.0 * elements_.RecoveredSemiMajorAxis() + s4) * temp;
nearspace_consts_.d4 = 0.5 * temp * elements_.RecoveredSemiMajorAxis() *
tsi * (221.0 * elements_.RecoveredSemiMajorAxis() + 31.0 * s4) * common_consts_.c1;
nearspace_consts_.t3cof = nearspace_consts_.d2 + 2.0 * c1sq;
nearspace_consts_.t4cof = 0.25 * (3.0 * nearspace_consts_.d3 + common_consts_.c1 *
(12.0 * nearspace_consts_.d2 + 10.0 * c1sq));
@ -235,7 +188,7 @@ void SGP4::FindPosition(Eci* eci, double tsince) const {
void SGP4::FindPosition(Eci* eci, const Julian& date) const {
Timespan diff = date - Epoch();
Timespan diff = date - elements_.Epoch();
FindPosition(eci, diff.GetTotalMinutes());
}
@ -255,19 +208,19 @@ void SGP4::FindPositionSDP4(Eci* eci, double tsince) const {
/*
* update for secular gravity and atmospheric drag
*/
double xmdf = MeanAnomoly() + common_consts_.xmdot * tsince;
double omgadf = ArgumentPerigee() + common_consts_.omgdot * tsince;
const double xnoddf = AscendingNode() + common_consts_.xnodot * tsince;
double xmdf = elements_.MeanAnomoly() + common_consts_.xmdot * tsince;
double omgadf = elements_.ArgumentPerigee() + common_consts_.omgdot * tsince;
const double xnoddf = elements_.AscendingNode() + common_consts_.xnodot * tsince;
const double tsq = tsince * tsince;
xnode = xnoddf + common_consts_.xnodcf * tsq;
double tempa = 1.0 - common_consts_.c1 * tsince;
double tempe = BStar() * common_consts_.c4 * tsince;
double tempe = elements_.BStar() * common_consts_.c4 * tsince;
double templ = common_consts_.t2cof * tsq;
double xn = RecoveredMeanMotion();
e = Eccentricity();
xincl = Inclination();
double xn = elements_.RecoveredMeanMotion();
e = elements_.Eccentricity();
xincl = elements_.Inclination();
DeepSpaceSecular(tsince, &xmdf, &omgadf, &xnode, &e, &xincl, &xn);
@ -277,7 +230,7 @@ void SGP4::FindPositionSDP4(Eci* eci, double tsince) const {
a = pow(kXKE / xn, kTWOTHIRD) * pow(tempa, 2.0);
e -= tempe;
double xmam = xmdf + RecoveredMeanMotion() * templ;
double xmam = xmdf + elements_.RecoveredMeanMotion() * templ;
/*
* fix tolerance for error recognition
@ -356,17 +309,17 @@ void SGP4::FindPositionSGP4(Eci* eci, double tsince) const {
/*
* update for secular gravity and atmospheric drag
*/
const double xmdf = MeanAnomoly() + common_consts_.xmdot * tsince;
const double omgadf = ArgumentPerigee() + common_consts_.omgdot * tsince;
const double xnoddf = AscendingNode() + common_consts_.xnodot * tsince;
const double xmdf = elements_.MeanAnomoly() + common_consts_.xmdot * tsince;
const double omgadf = elements_.ArgumentPerigee() + common_consts_.omgdot * tsince;
const double xnoddf = elements_.AscendingNode() + common_consts_.xnodot * tsince;
const double tsq = tsince * tsince;
xnode = xnoddf + common_consts_.xnodcf * tsq;
double tempa = 1.0 - common_consts_.c1 * tsince;
double tempe = BStar() * common_consts_.c4 * tsince;
double tempe = elements_.BStar() * common_consts_.c4 * tsince;
double templ = common_consts_.t2cof * tsq;
xincl = Inclination();
xincl = elements_.Inclination();
omega = omgadf;
double xmp = xmdf;
@ -382,13 +335,13 @@ void SGP4::FindPositionSGP4(Eci* eci, double tsince) const {
const double tfour = tsince * tcube;
tempa = tempa - nearspace_consts_.d2 * tsq - nearspace_consts_.d3 * tcube - nearspace_consts_.d4 * tfour;
tempe += BStar() * nearspace_consts_.c5 * (sin(xmp) - nearspace_consts_.sinmo);
tempe += elements_.BStar() * nearspace_consts_.c5 * (sin(xmp) - nearspace_consts_.sinmo);
templ += nearspace_consts_.t3cof * tcube + tfour * (nearspace_consts_.t4cof + tsince * nearspace_consts_.t5cof);
}
a = RecoveredSemiMajorAxis() * pow(tempa, 2.0);
e = Eccentricity() - tempe;
xl = xmp + omega + xnode + RecoveredMeanMotion() * templ;
a = elements_.RecoveredSemiMajorAxis() * pow(tempa, 2.0);
e = elements_.Eccentricity() - tempe;
xl = xmp + omega + xnode + elements_.RecoveredMeanMotion() * templ;
if (xl <= 0.0) {
throw SatelliteException("Error: #2 (xl <= 0.0)");
@ -567,7 +520,7 @@ void SGP4::CalculateFinalPositionVelocity(Eci* eci, const double& tsince, const
Vector velocity(xdot, ydot, zdot);
Timespan diff(tsince);
Julian julian = Epoch() + diff;
Julian julian = elements_.Epoch() + diff;
(*eci) = Eci(julian, position, velocity);
}
@ -611,17 +564,17 @@ void SGP4::DeepSpaceInitialize(const double& eosq, const double& sinio, const do
static const double ROOT52 = 1.1428639E-7;
static const double ROOT54 = 2.1765803E-9;
const double aqnv = 1.0 / RecoveredSemiMajorAxis();
const double aqnv = 1.0 / elements_.RecoveredSemiMajorAxis();
const double xpidot = omgdot + xnodot;
const double sinq = sin(AscendingNode());
const double cosq = cos(AscendingNode());
const double sing = sin(ArgumentPerigee());
const double cosg = cos(ArgumentPerigee());
const double sinq = sin(elements_.AscendingNode());
const double cosq = cos(elements_.AscendingNode());
const double sing = sin(elements_.ArgumentPerigee());
const double cosg = cos(elements_.ArgumentPerigee());
/*
* initialize lunar / solar terms
*/
const double jday = Epoch().FromJan1_12h_1900();
const double jday = elements_.Epoch().FromJan1_12h_1900();
const double xnodce = 4.5236020 - 9.2422029e-4 * jday;
const double xnodce_temp = fmod(xnodce, kTWOPI);
@ -655,7 +608,7 @@ void SGP4::DeepSpaceInitialize(const double& eosq, const double& sinio, const do
double cc = C1SS;
double zn = ZNS;
double ze = ZES;
const double xnoi = 1.0 / RecoveredMeanMotion();
const double xnoi = 1.0 / elements_.RecoveredMeanMotion();
for (int cnt = 0; cnt < 2; cnt++) {
/*
@ -697,7 +650,7 @@ void SGP4::DeepSpaceInitialize(const double& eosq, const double& sinio, const do
const double s3 = cc * xnoi;
const double s2 = -0.5 * s3 / betao;
const double s4 = s3 * betao;
const double s1 = -15.0 * Eccentricity() * s4;
const double s1 = -15.0 * elements_.Eccentricity() * s4;
const double s5 = x1 * x3 + x2 * x4;
const double s6 = x2 * x3 + x1 * x4;
const double s7 = x2 * x4 - x1 * x3;
@ -712,7 +665,7 @@ void SGP4::DeepSpaceInitialize(const double& eosq, const double& sinio, const do
* with
* shdq = (-zn * s2 * (z21 + z23)) / sinio
*/
if (Inclination() < 5.2359877e-2 || Inclination() > kPI - 5.2359877e-2) {
if (elements_.Inclination() < 5.2359877e-2 || elements_.Inclination() > kPI - 5.2359877e-2) {
shdq = 0.0;
} else {
shdq = (-zn * s2 * (z21 + z23)) / sinio;
@ -774,7 +727,7 @@ void SGP4::DeepSpaceInitialize(const double& eosq, const double& sinio, const do
deepspace_consts_.synchronous_flag = false;
bool initialize_integrator = true;
if (RecoveredMeanMotion() < 0.0052359877 && RecoveredMeanMotion() > 0.0034906585) {
if (elements_.RecoveredMeanMotion() < 0.0052359877 && elements_.RecoveredMeanMotion() > 0.0034906585) {
/*
* 24h synchronous resonance terms initialization
@ -789,16 +742,16 @@ void SGP4::DeepSpaceInitialize(const double& eosq, const double& sinio, const do
const double f311 = 0.9375 * sinio * sinio * (1.0 + 3.0 * cosio) - 0.75 * (1.0 + cosio);
double f330 = 1.0 + cosio;
f330 = 1.875 * f330 * f330 * f330;
deepspace_consts_.del1 = 3.0 * RecoveredMeanMotion() * RecoveredMeanMotion() * aqnv * aqnv;
deepspace_consts_.del1 = 3.0 * elements_.RecoveredMeanMotion() * elements_.RecoveredMeanMotion() * aqnv * aqnv;
deepspace_consts_.del2 = 2.0 * deepspace_consts_.del1 * f220 * g200 * Q22;
deepspace_consts_.del3 = 3.0 * deepspace_consts_.del1 * f330 * g300 * Q33 * aqnv;
deepspace_consts_.del1 = deepspace_consts_.del1 * f311 * g310 * Q31 * aqnv;
integrator_consts_.xlamo = MeanAnomoly() + AscendingNode() + ArgumentPerigee() - deepspace_consts_.gsto;
integrator_consts_.xlamo = elements_.MeanAnomoly() + elements_.AscendingNode() + elements_.ArgumentPerigee() - deepspace_consts_.gsto;
bfact = xmdot + xpidot - kTHDT;
bfact += deepspace_consts_.ssl + deepspace_consts_.ssg + deepspace_consts_.ssh;
} else if (RecoveredMeanMotion() < 8.26e-3 || RecoveredMeanMotion() > 9.24e-3 || Eccentricity() < 0.5) {
} else if (elements_.RecoveredMeanMotion() < 8.26e-3 || elements_.RecoveredMeanMotion() > 9.24e-3 || elements_.Eccentricity() < 0.5) {
initialize_integrator = false;
} else {
/*
@ -813,26 +766,26 @@ void SGP4::DeepSpaceInitialize(const double& eosq, const double& sinio, const do
double g422;
double g520;
double g201 = -0.306 - (Eccentricity() - 0.64) * 0.440;
double g201 = -0.306 - (elements_.Eccentricity() - 0.64) * 0.440;
if (Eccentricity() <= 0.65) {
g211 = EvaluateCubicPolynomial(Eccentricity(), 3.616, -13.247, +16.290, 0.0);
g310 = EvaluateCubicPolynomial(Eccentricity(), -19.302, 117.390, -228.419, 156.591);
g322 = EvaluateCubicPolynomial(Eccentricity(), -18.9068, 109.7927, -214.6334, 146.5816);
g410 = EvaluateCubicPolynomial(Eccentricity(), -41.122, 242.694, -471.094, 313.953);
g422 = EvaluateCubicPolynomial(Eccentricity(), -146.407, 841.880, -1629.014, 1083.435);
g520 = EvaluateCubicPolynomial(Eccentricity(), -532.114, 3017.977, -5740.032, 3708.276);
if (elements_.Eccentricity() <= 0.65) {
g211 = EvaluateCubicPolynomial(elements_.Eccentricity(), 3.616, -13.247, +16.290, 0.0);
g310 = EvaluateCubicPolynomial(elements_.Eccentricity(), -19.302, 117.390, -228.419, 156.591);
g322 = EvaluateCubicPolynomial(elements_.Eccentricity(), -18.9068, 109.7927, -214.6334, 146.5816);
g410 = EvaluateCubicPolynomial(elements_.Eccentricity(), -41.122, 242.694, -471.094, 313.953);
g422 = EvaluateCubicPolynomial(elements_.Eccentricity(), -146.407, 841.880, -1629.014, 1083.435);
g520 = EvaluateCubicPolynomial(elements_.Eccentricity(), -532.114, 3017.977, -5740.032, 3708.276);
} else {
g211 = EvaluateCubicPolynomial(Eccentricity(), -72.099, 331.819, -508.738, 266.724);
g310 = EvaluateCubicPolynomial(Eccentricity(), -346.844, 1582.851, -2415.925, 1246.113);
g322 = EvaluateCubicPolynomial(Eccentricity(), -342.585, 1554.908, -2366.899, 1215.972);
g410 = EvaluateCubicPolynomial(Eccentricity(), -1052.797, 4758.686, -7193.992, 3651.957);
g422 = EvaluateCubicPolynomial(Eccentricity(), -3581.69, 16178.11, -24462.77, 12422.52);
g211 = EvaluateCubicPolynomial(elements_.Eccentricity(), -72.099, 331.819, -508.738, 266.724);
g310 = EvaluateCubicPolynomial(elements_.Eccentricity(), -346.844, 1582.851, -2415.925, 1246.113);
g322 = EvaluateCubicPolynomial(elements_.Eccentricity(), -342.585, 1554.908, -2366.899, 1215.972);
g410 = EvaluateCubicPolynomial(elements_.Eccentricity(), -1052.797, 4758.686, -7193.992, 3651.957);
g422 = EvaluateCubicPolynomial(elements_.Eccentricity(), -3581.69, 16178.11, -24462.77, 12422.52);
if (Eccentricity() <= 0.715) {
g520 = EvaluateCubicPolynomial(Eccentricity(), 1464.74, -4664.75, 3763.64, 0.0);
if (elements_.Eccentricity() <= 0.715) {
g520 = EvaluateCubicPolynomial(elements_.Eccentricity(), 1464.74, -4664.75, 3763.64, 0.0);
} else {
g520 = EvaluateCubicPolynomial(Eccentricity(), -5149.66, 29936.92, -54087.36, 31324.56);
g520 = EvaluateCubicPolynomial(elements_.Eccentricity(), -5149.66, 29936.92, -54087.36, 31324.56);
}
}
@ -840,14 +793,14 @@ void SGP4::DeepSpaceInitialize(const double& eosq, const double& sinio, const do
double g521;
double g532;
if (Eccentricity() < 0.7) {
g533 = EvaluateCubicPolynomial(Eccentricity(), -919.2277, 4988.61, -9064.77, 5542.21);
g521 = EvaluateCubicPolynomial(Eccentricity(), -822.71072, 4568.6173, -8491.4146, 5337.524);
g532 = EvaluateCubicPolynomial(Eccentricity(), -853.666, 4690.25, -8624.77, 5341.4);
if (elements_.Eccentricity() < 0.7) {
g533 = EvaluateCubicPolynomial(elements_.Eccentricity(), -919.2277, 4988.61, -9064.77, 5542.21);
g521 = EvaluateCubicPolynomial(elements_.Eccentricity(), -822.71072, 4568.6173, -8491.4146, 5337.524);
g532 = EvaluateCubicPolynomial(elements_.Eccentricity(), -853.666, 4690.25, -8624.77, 5341.4);
} else {
g533 = EvaluateCubicPolynomial(Eccentricity(), -37995.78, 161616.52, -229838.2, 109377.94);
g521 = EvaluateCubicPolynomial(Eccentricity(), -51752.104, 218913.95, -309468.16, 146349.42);
g532 = EvaluateCubicPolynomial(Eccentricity(), -40023.88, 170470.89, -242699.48, 115605.82);
g533 = EvaluateCubicPolynomial(elements_.Eccentricity(), -37995.78, 161616.52, -229838.2, 109377.94);
g521 = EvaluateCubicPolynomial(elements_.Eccentricity(), -51752.104, 218913.95, -309468.16, 146349.42);
g532 = EvaluateCubicPolynomial(elements_.Eccentricity(), -40023.88, 170470.89, -242699.48, 115605.82);
}
const double sini2 = sinio * sinio;
@ -866,7 +819,7 @@ void SGP4::DeepSpaceInitialize(const double& eosq, const double& sinio, const do
const double f543 = 29.53125 * sinio * (-2.0 - 8.0 * cosio + theta2 *
(12.0 + 8.0 * cosio - 10.0 * theta2));
const double xno2 = RecoveredMeanMotion() * RecoveredMeanMotion();
const double xno2 = elements_.RecoveredMeanMotion() * elements_.RecoveredMeanMotion();
const double ainv2 = aqnv * aqnv;
double temp1 = 3.0 * xno2 * ainv2;
@ -889,7 +842,7 @@ void SGP4::DeepSpaceInitialize(const double& eosq, const double& sinio, const do
deepspace_consts_.d5421 = temp * f542 * g521;
deepspace_consts_.d5433 = temp * f543 * g533;
integrator_consts_.xlamo = MeanAnomoly() + AscendingNode() + AscendingNode() - deepspace_consts_.gsto - deepspace_consts_.gsto;
integrator_consts_.xlamo = elements_.MeanAnomoly() + elements_.AscendingNode() + elements_.AscendingNode() - deepspace_consts_.gsto - deepspace_consts_.gsto;
bfact = xmdot + xnodot + xnodot - kTHDT - kTHDT;
bfact = bfact + deepspace_consts_.ssl + deepspace_consts_.ssh + deepspace_consts_.ssh;
}
@ -899,9 +852,9 @@ void SGP4::DeepSpaceInitialize(const double& eosq, const double& sinio, const do
/*
* initialize integrator
*/
integrator_consts_.xfact = bfact - RecoveredMeanMotion();
integrator_consts_.xfact = bfact - elements_.RecoveredMeanMotion();
integrator_params_.atime = 0.0;
integrator_params_.xni = RecoveredMeanMotion();
integrator_params_.xni = elements_.RecoveredMeanMotion();
integrator_params_.xli = integrator_consts_.xlamo;
/*
* precompute dot terms for epoch
@ -990,7 +943,7 @@ void SGP4::DeepSpacePeriodics(const double& t, double* em,
* added to xinc (oldxinc), but apparently report # 6 has then
* from after they are added.
* use for strn3
* if (Inclination() >= 0.2)
* if (elements_.Inclination() >= 0.2)
* use for gsfc
* if (xinc >= 0.2)
* (moved from start of function)
@ -1086,7 +1039,7 @@ void SGP4::DeepSpaceSecular(const double& t, double* xll, double* omgasm,
* restart from epoch
*/
integrator_params_.atime = 0.0;
integrator_params_.xni = RecoveredMeanMotion();
integrator_params_.xni = elements_.RecoveredMeanMotion();
integrator_params_.xli = integrator_consts_.xlamo;
/*
@ -1166,7 +1119,7 @@ void SGP4::DeepSpaceCalcDotTerms(double* xndot, double* xnddt, double* xldot) co
} else {
const double xomi = ArgumentPerigee() + common_consts_.omgdot * integrator_params_.atime;
const double xomi = elements_.ArgumentPerigee() + common_consts_.omgdot * integrator_params_.atime;
const double x2omi = xomi + xomi;
const double x2li = integrator_params_.xli + integrator_params_.xli;
@ -1222,10 +1175,4 @@ void SGP4::Reset() {
first_run_ = true;
use_simple_model_ = false;
use_deep_space_ = false;
mean_anomoly_ = ascending_node_ = argument_perigee_ = eccentricity_ =
inclination_ = mean_motion_ = bstar_ = recovered_semi_major_axis_ =
recovered_mean_motion_ = perigee_ = period_ = 0.0;
epoch_ = Julian();
}

105
SGP4.h
View File

@ -2,12 +2,12 @@
#define SGP4_H_
#include "Tle.h"
#include "OrbitalElements.h"
#include "Eci.h"
#include "SatelliteException.h"
class SGP4 {
public:
SGP4(void);
SGP4(const Tle& tle);
virtual ~SGP4(void);
@ -15,87 +15,6 @@ public:
void FindPosition(Eci* eci, double tsince) const;
void FindPosition(Eci* eci, const Julian& date) const;
/*
* XMO
*/
double MeanAnomoly() const {
return mean_anomoly_;
}
/*
* XNODEO
*/
double AscendingNode() const {
return ascending_node_;
}
/*
* OMEGAO
*/
double ArgumentPerigee() const {
return argument_perigee_;
}
/*
* EO
*/
double Eccentricity() const {
return eccentricity_;
}
/*
* XINCL
*/
double Inclination() const {
return inclination_;
}
/*
* XNO
*/
double MeanMotion() const {
return mean_motion_;
}
/*
* BSTAR
*/
double BStar() const {
return bstar_;
}
/*
* AODP
*/
double RecoveredSemiMajorAxis() const {
return recovered_semi_major_axis_;
}
/*
* XNODP
*/
double RecoveredMeanMotion() const {
return recovered_mean_motion_;
}
/*
* PERIGE
*/
double Perigee() const {
return perigee_;
}
double Period() const {
return period_;
}
/*
* EPOCH
*/
Julian Epoch() const {
return epoch_;
}
struct CommonConstants {
CommonConstants()
@ -286,10 +205,16 @@ private:
const double xndot, const double xnddt, const double xldot)const;
void Reset();
/*
* flags
*/
bool first_run_;
bool use_simple_model_;
bool use_deep_space_;
/*
* the constants used
*/
struct CommonConstants common_consts_;
struct NearSpaceConstants nearspace_consts_;
struct DeepSpaceConstants deepspace_consts_;
@ -297,21 +222,9 @@ private:
mutable struct IntegratorParams integrator_params_;
/*
* these variables are set at the very start
* and should not be changed after that
* the orbit data
*/
double mean_anomoly_;
double ascending_node_;
double argument_perigee_;
double eccentricity_;
double inclination_;
double mean_motion_;
double bstar_;
double recovered_semi_major_axis_;
double recovered_mean_motion_;
double perigee_;
double period_;
Julian epoch_;
OrbitalElements elements_;
};
#endif