Tidy up of SGP4
parent
f5d96cfc35
commit
5bc13b72de
2
Julian.h
2
Julian.h
|
|
@ -46,7 +46,7 @@ public:
|
||||||
|
|
||||||
~Julian()
|
~Julian()
|
||||||
{
|
{
|
||||||
};
|
}
|
||||||
|
|
||||||
// comparison operators
|
// comparison operators
|
||||||
bool operator==(const Julian &date) const;
|
bool operator==(const Julian &date) const;
|
||||||
|
|
|
||||||
294
SGP4.cpp
294
SGP4.cpp
|
|
@ -6,27 +6,18 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
SGP4::SGP4(const Tle& tle)
|
void SGP4::SetTle(const Tle& tle)
|
||||||
: elements_(tle) {
|
{
|
||||||
|
|
||||||
Initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
SGP4::~SGP4(void) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void SGP4::SetTle(const Tle& tle) {
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* extract and format tle data
|
* extract and format tle data
|
||||||
*/
|
*/
|
||||||
elements_ = OrbitalElements(tle);
|
elements_ = OrbitalElements(tle);
|
||||||
|
|
||||||
Initialize();
|
Initialise();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SGP4::Initialize() {
|
void SGP4::Initialise()
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* reset all constants etc
|
* reset all constants etc
|
||||||
*/
|
*/
|
||||||
|
|
@ -35,11 +26,13 @@ void SGP4::Initialize() {
|
||||||
/*
|
/*
|
||||||
* error checks
|
* error checks
|
||||||
*/
|
*/
|
||||||
if (elements_.Eccentricity() < 0.0 || elements_.Eccentricity() > 1.0 - 1.0e-3) {
|
if (elements_.Eccentricity() < 0.0 || elements_.Eccentricity() > 1.0 - 1.0e-3)
|
||||||
|
{
|
||||||
throw SatelliteException("Eccentricity out of range");
|
throw SatelliteException("Eccentricity out of range");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elements_.Inclination() < 0.0 || elements_.Inclination() > kPI) {
|
if (elements_.Inclination() < 0.0 || elements_.Inclination() > kPI)
|
||||||
|
{
|
||||||
throw SatelliteException("Inclination out of range");
|
throw SatelliteException("Inclination out of range");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -51,9 +44,12 @@ void SGP4::Initialize() {
|
||||||
const double betao2 = 1.0 - eosq;
|
const double betao2 = 1.0 - eosq;
|
||||||
const double betao = sqrt(betao2);
|
const double betao = sqrt(betao2);
|
||||||
|
|
||||||
if (elements_.Period() >= 225.0) {
|
if (elements_.Period() >= 225.0)
|
||||||
|
{
|
||||||
use_deep_space_ = true;
|
use_deep_space_ = true;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
use_deep_space_ = false;
|
use_deep_space_ = false;
|
||||||
use_simple_model_ = false;
|
use_simple_model_ = false;
|
||||||
/*
|
/*
|
||||||
|
|
@ -62,7 +58,8 @@ void SGP4::Initialize() {
|
||||||
* quadratic variation in mean anomly. also, the c3 term, the
|
* quadratic variation in mean anomly. also, the c3 term, the
|
||||||
* delta omega term and the delta m term are dropped
|
* delta omega term and the delta m term are dropped
|
||||||
*/
|
*/
|
||||||
if (elements_.Perigee() < 220.0) {
|
if (elements_.Perigee() < 220.0)
|
||||||
|
{
|
||||||
use_simple_model_ = true;
|
use_simple_model_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -73,9 +70,11 @@ void SGP4::Initialize() {
|
||||||
*/
|
*/
|
||||||
double s4 = kS;
|
double s4 = kS;
|
||||||
double qoms24 = kQOMS2T;
|
double qoms24 = kQOMS2T;
|
||||||
if (elements_.Perigee() < 156.0) {
|
if (elements_.Perigee() < 156.0)
|
||||||
|
{
|
||||||
s4 = elements_.Perigee() - 78.0;
|
s4 = elements_.Perigee() - 78.0;
|
||||||
if (elements_.Perigee() < 98.0) {
|
if (elements_.Perigee() < 98.0)
|
||||||
|
{
|
||||||
s4 = 20.0;
|
s4 = 20.0;
|
||||||
}
|
}
|
||||||
qoms24 = pow((120.0 - s4) * kAE / kXKMPER, 4.0);
|
qoms24 = pow((120.0 - s4) * kAE / kXKMPER, 4.0);
|
||||||
|
|
@ -125,25 +124,30 @@ void SGP4::Initialize() {
|
||||||
common_consts_.t2cof = 1.5 * common_consts_.c1;
|
common_consts_.t2cof = 1.5 * common_consts_.c1;
|
||||||
|
|
||||||
if (fabs(common_consts_.cosio + 1.0) > 1.5e-12)
|
if (fabs(common_consts_.cosio + 1.0) > 1.5e-12)
|
||||||
|
{
|
||||||
common_consts_.xlcof = 0.125 * common_consts_.a3ovk2 * common_consts_.sinio * (3.0 + 5.0 * common_consts_.cosio) / (1.0 + common_consts_.cosio);
|
common_consts_.xlcof = 0.125 * common_consts_.a3ovk2 * common_consts_.sinio * (3.0 + 5.0 * common_consts_.cosio) / (1.0 + common_consts_.cosio);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
common_consts_.xlcof = 0.125 * common_consts_.a3ovk2 * common_consts_.sinio * (3.0 + 5.0 * common_consts_.cosio) / 1.5e-12;
|
common_consts_.xlcof = 0.125 * common_consts_.a3ovk2 * common_consts_.sinio * (3.0 + 5.0 * common_consts_.cosio) / 1.5e-12;
|
||||||
|
}
|
||||||
|
|
||||||
common_consts_.aycof = 0.25 * common_consts_.a3ovk2 * common_consts_.sinio;
|
common_consts_.aycof = 0.25 * common_consts_.a3ovk2 * common_consts_.sinio;
|
||||||
common_consts_.x7thm1 = 7.0 * theta2 - 1.0;
|
common_consts_.x7thm1 = 7.0 * theta2 - 1.0;
|
||||||
|
|
||||||
if (use_deep_space_) {
|
if (use_deep_space_)
|
||||||
|
{
|
||||||
deepspace_consts_.gsto = elements_.Epoch().ToGreenwichSiderealTime();
|
deepspace_consts_.gsto = elements_.Epoch().ToGreenwichSiderealTime();
|
||||||
|
|
||||||
DeepSpaceInitialize(eosq, common_consts_.sinio, common_consts_.cosio, betao,
|
DeepSpaceInitialise(eosq, common_consts_.sinio, common_consts_.cosio, betao,
|
||||||
theta2, betao2,
|
theta2, betao2,
|
||||||
common_consts_.xmdot, common_consts_.omgdot, common_consts_.xnodot);
|
common_consts_.xmdot, common_consts_.omgdot, common_consts_.xnodot);
|
||||||
|
}
|
||||||
} else {
|
else
|
||||||
|
{
|
||||||
double c3 = 0.0;
|
double c3 = 0.0;
|
||||||
if (elements_.Eccentricity() > 1.0e-4) {
|
if (elements_.Eccentricity() > 1.0e-4)
|
||||||
|
{
|
||||||
c3 = coef * tsi * common_consts_.a3ovk2 * elements_.RecoveredMeanMotion() * kAE *
|
c3 = coef * tsi * common_consts_.a3ovk2 * elements_.RecoveredMeanMotion() * kAE *
|
||||||
common_consts_.sinio / elements_.Eccentricity();
|
common_consts_.sinio / elements_.Eccentricity();
|
||||||
}
|
}
|
||||||
|
|
@ -154,12 +158,15 @@ void SGP4::Initialize() {
|
||||||
|
|
||||||
nearspace_consts_.xmcof = 0.0;
|
nearspace_consts_.xmcof = 0.0;
|
||||||
if (elements_.Eccentricity() > 1.0e-4)
|
if (elements_.Eccentricity() > 1.0e-4)
|
||||||
|
{
|
||||||
nearspace_consts_.xmcof = -kTWOTHIRD * coef * elements_.BStar() * kAE / eeta;
|
nearspace_consts_.xmcof = -kTWOTHIRD * coef * elements_.BStar() * kAE / eeta;
|
||||||
|
}
|
||||||
|
|
||||||
nearspace_consts_.delmo = pow(1.0 + common_consts_.eta * (cos(elements_.MeanAnomoly())), 3.0);
|
nearspace_consts_.delmo = pow(1.0 + common_consts_.eta * (cos(elements_.MeanAnomoly())), 3.0);
|
||||||
nearspace_consts_.sinmo = sin(elements_.MeanAnomoly());
|
nearspace_consts_.sinmo = sin(elements_.MeanAnomoly());
|
||||||
|
|
||||||
if (!use_simple_model_) {
|
if (!use_simple_model_)
|
||||||
|
{
|
||||||
const double c1sq = common_consts_.c1 * common_consts_.c1;
|
const double c1sq = common_consts_.c1 * common_consts_.c1;
|
||||||
nearspace_consts_.d2 = 4.0 * elements_.RecoveredSemiMajorAxis() * tsi * c1sq;
|
nearspace_consts_.d2 = 4.0 * elements_.RecoveredSemiMajorAxis() * tsi * c1sq;
|
||||||
const double temp = nearspace_consts_.d2 * tsi * common_consts_.c1 / 3.0;
|
const double temp = nearspace_consts_.d2 * tsi * common_consts_.c1 / 3.0;
|
||||||
|
|
@ -178,23 +185,27 @@ void SGP4::Initialize() {
|
||||||
first_run_ = false;
|
first_run_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Eci SGP4::FindPosition(double tsince) const {
|
Eci SGP4::FindPosition(double tsince) const
|
||||||
|
{
|
||||||
if (use_deep_space_)
|
if (use_deep_space_)
|
||||||
|
{
|
||||||
return FindPositionSDP4(tsince);
|
return FindPositionSDP4(tsince);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
return FindPositionSGP4(tsince);
|
return FindPositionSGP4(tsince);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Eci SGP4::FindPosition(const Julian& date) const {
|
Eci SGP4::FindPosition(const Julian& date) const
|
||||||
|
{
|
||||||
Timespan diff = date - elements_.Epoch();
|
Timespan diff = date - elements_.Epoch();
|
||||||
|
|
||||||
return FindPosition(diff.GetTotalMinutes());
|
return FindPosition(diff.GetTotalMinutes());
|
||||||
}
|
}
|
||||||
|
|
||||||
Eci SGP4::FindPositionSDP4(double tsince) const {
|
Eci SGP4::FindPositionSDP4(double tsince) const
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* the final values
|
* the final values
|
||||||
*/
|
*/
|
||||||
|
|
@ -224,7 +235,8 @@ Eci SGP4::FindPositionSDP4(double tsince) const {
|
||||||
|
|
||||||
DeepSpaceSecular(tsince, &xmdf, &omgadf, &xnode, &e, &xincl, &xn);
|
DeepSpaceSecular(tsince, &xmdf, &omgadf, &xnode, &e, &xincl, &xn);
|
||||||
|
|
||||||
if (xn <= 0.0) {
|
if (xn <= 0.0)
|
||||||
|
{
|
||||||
throw SatelliteException("Error: #2 (xn <= 0.0)");
|
throw SatelliteException("Error: #2 (xn <= 0.0)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -235,14 +247,17 @@ Eci SGP4::FindPositionSDP4(double tsince) const {
|
||||||
/*
|
/*
|
||||||
* fix tolerance for error recognition
|
* fix tolerance for error recognition
|
||||||
*/
|
*/
|
||||||
if (e >= 1.0 || e < -0.001) {
|
if (e >= 1.0 || e < -0.001)
|
||||||
|
{
|
||||||
throw SatelliteException("Error: #1 (e >= 1.0 || e < -0.001)");
|
throw SatelliteException("Error: #1 (e >= 1.0 || e < -0.001)");
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* fix tolerance to avoid a divide by zero
|
* fix tolerance to avoid a divide by zero
|
||||||
*/
|
*/
|
||||||
if (e < 1.0e-6)
|
if (e < 1.0e-6)
|
||||||
|
{
|
||||||
e = 1.0e-6;
|
e = 1.0e-6;
|
||||||
|
}
|
||||||
|
|
||||||
DeepSpacePeriodics(tsince, &e, &xincl, &omgadf, &xnode, &xmam);
|
DeepSpacePeriodics(tsince, &e, &xincl, &omgadf, &xnode, &xmam);
|
||||||
|
|
||||||
|
|
@ -250,7 +265,8 @@ Eci SGP4::FindPositionSDP4(double tsince) const {
|
||||||
* keeping xincl positive important unless you need to display xincl
|
* keeping xincl positive important unless you need to display xincl
|
||||||
* and dislike negative inclinations
|
* and dislike negative inclinations
|
||||||
*/
|
*/
|
||||||
if (xincl < 0.0) {
|
if (xincl < 0.0)
|
||||||
|
{
|
||||||
xincl = -xincl;
|
xincl = -xincl;
|
||||||
xnode += kPI;
|
xnode += kPI;
|
||||||
omgadf -= kPI;
|
omgadf -= kPI;
|
||||||
|
|
@ -259,7 +275,8 @@ Eci SGP4::FindPositionSDP4(double tsince) const {
|
||||||
xl = xmam + omgadf + xnode;
|
xl = xmam + omgadf + xnode;
|
||||||
omega = omgadf;
|
omega = omgadf;
|
||||||
|
|
||||||
if (e < 0.0 || e > 1.0) {
|
if (e < 0.0 || e > 1.0)
|
||||||
|
{
|
||||||
throw SatelliteException("Error: #3 (e < 0.0 || e > 1.0)");
|
throw SatelliteException("Error: #3 (e < 0.0 || e > 1.0)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -277,9 +294,13 @@ Eci SGP4::FindPositionSDP4(double tsince) const {
|
||||||
|
|
||||||
double perturbed_xlcof;
|
double perturbed_xlcof;
|
||||||
if (fabs(perturbed_cosio + 1.0) > 1.5e-12)
|
if (fabs(perturbed_cosio + 1.0) > 1.5e-12)
|
||||||
|
{
|
||||||
perturbed_xlcof = 0.125 * common_consts_.a3ovk2 * perturbed_sinio * (3.0 + 5.0 * perturbed_cosio) / (1.0 + perturbed_cosio);
|
perturbed_xlcof = 0.125 * common_consts_.a3ovk2 * perturbed_sinio * (3.0 + 5.0 * perturbed_cosio) / (1.0 + perturbed_cosio);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
perturbed_xlcof = 0.125 * common_consts_.a3ovk2 * perturbed_sinio * (3.0 + 5.0 * perturbed_cosio) / 1.5e-12;
|
perturbed_xlcof = 0.125 * common_consts_.a3ovk2 * perturbed_sinio * (3.0 + 5.0 * perturbed_cosio) / 1.5e-12;
|
||||||
|
}
|
||||||
|
|
||||||
const double perturbed_aycof = 0.25 * common_consts_.a3ovk2 * perturbed_sinio;
|
const double perturbed_aycof = 0.25 * common_consts_.a3ovk2 * perturbed_sinio;
|
||||||
|
|
||||||
|
|
@ -294,8 +315,8 @@ Eci SGP4::FindPositionSDP4(double tsince) const {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Eci SGP4::FindPositionSGP4(double tsince) const {
|
Eci SGP4::FindPositionSGP4(double tsince) const
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* the final values
|
* the final values
|
||||||
*/
|
*/
|
||||||
|
|
@ -323,7 +344,8 @@ Eci SGP4::FindPositionSGP4(double tsince) const {
|
||||||
omega = omgadf;
|
omega = omgadf;
|
||||||
double xmp = xmdf;
|
double xmp = xmdf;
|
||||||
|
|
||||||
if (!use_simple_model_) {
|
if (!use_simple_model_)
|
||||||
|
{
|
||||||
const double delomg = nearspace_consts_.omgcof * tsince;
|
const double delomg = nearspace_consts_.omgcof * tsince;
|
||||||
const double delm = nearspace_consts_.xmcof * (pow(1.0 + common_consts_.eta * cos(xmdf), 3.0) - nearspace_consts_.delmo);
|
const double delm = nearspace_consts_.xmcof * (pow(1.0 + common_consts_.eta * cos(xmdf), 3.0) - nearspace_consts_.delmo);
|
||||||
const double temp = delomg + delm;
|
const double temp = delomg + delm;
|
||||||
|
|
@ -343,25 +365,29 @@ Eci SGP4::FindPositionSGP4(double tsince) const {
|
||||||
e = elements_.Eccentricity() - tempe;
|
e = elements_.Eccentricity() - tempe;
|
||||||
xl = xmp + omega + xnode + elements_.RecoveredMeanMotion() * templ;
|
xl = xmp + omega + xnode + elements_.RecoveredMeanMotion() * templ;
|
||||||
|
|
||||||
if (xl <= 0.0) {
|
if (xl <= 0.0)
|
||||||
|
{
|
||||||
throw SatelliteException("Error: #2 (xl <= 0.0)");
|
throw SatelliteException("Error: #2 (xl <= 0.0)");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fix tolerance for error recognition
|
* fix tolerance for error recognition
|
||||||
*/
|
*/
|
||||||
if (e >= 1.0 || e < -0.001) {
|
if (e >= 1.0 || e < -0.001)
|
||||||
|
{
|
||||||
throw SatelliteException("Error: #1 (e >= 1.0 || e < -0.001)");
|
throw SatelliteException("Error: #1 (e >= 1.0 || e < -0.001)");
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* fix tolerance to avoid a divide by zero
|
* fix tolerance to avoid a divide by zero
|
||||||
*/
|
*/
|
||||||
if (e < 1.0e-6)
|
if (e < 1.0e-6)
|
||||||
|
{
|
||||||
e = 1.0e-6;
|
e = 1.0e-6;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* using calculated values, find position and velocity
|
* using calculated values, find position and velocity
|
||||||
* we can pass in constants from Initialize() as these dont change
|
* we can pass in constants from Initialise() as these dont change
|
||||||
*/
|
*/
|
||||||
return CalculateFinalPositionVelocity(tsince, e,
|
return CalculateFinalPositionVelocity(tsince, e,
|
||||||
a, omega, xl, xnode,
|
a, omega, xl, xnode,
|
||||||
|
|
@ -375,8 +401,8 @@ Eci SGP4::CalculateFinalPositionVelocity(const double& tsince, const double& e,
|
||||||
const double& a, const double& omega, const double& xl, const double& xnode,
|
const double& a, const double& omega, const double& xl, const double& xnode,
|
||||||
const double& xincl, const double& xlcof, const double& aycof,
|
const double& xincl, const double& xlcof, const double& aycof,
|
||||||
const double& x3thm1, const double& x1mth2, const double& x7thm1,
|
const double& x3thm1, const double& x1mth2, const double& x7thm1,
|
||||||
const double& cosio, const double& sinio) const {
|
const double& cosio, const double& sinio) const
|
||||||
|
{
|
||||||
const double beta = sqrt(1.0 - e * e);
|
const double beta = sqrt(1.0 - e * e);
|
||||||
const double xn = kXKE / pow(a, 1.5);
|
const double xn = kXKE / pow(a, 1.5);
|
||||||
/*
|
/*
|
||||||
|
|
@ -413,7 +439,8 @@ Eci SGP4::CalculateFinalPositionVelocity(const double& tsince, const double& e,
|
||||||
|
|
||||||
bool kepler_running = true;
|
bool kepler_running = true;
|
||||||
|
|
||||||
for (int i = 0; i < 10 && kepler_running; i++) {
|
for (int i = 0; i < 10 && kepler_running; i++)
|
||||||
|
{
|
||||||
sinepw = sin(epw);
|
sinepw = sin(epw);
|
||||||
cosepw = cos(epw);
|
cosepw = cos(epw);
|
||||||
ecose = axn * cosepw + ayn * sinepw;
|
ecose = axn * cosepw + ayn * sinepw;
|
||||||
|
|
@ -421,9 +448,12 @@ Eci SGP4::CalculateFinalPositionVelocity(const double& tsince, const double& e,
|
||||||
|
|
||||||
double f = capu - epw + esine;
|
double f = capu - epw + esine;
|
||||||
|
|
||||||
if (fabs(f) < 1.0e-12) {
|
if (fabs(f) < 1.0e-12)
|
||||||
|
{
|
||||||
kepler_running = false;
|
kepler_running = false;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* 1st order Newton-Raphson correction
|
* 1st order Newton-Raphson correction
|
||||||
*/
|
*/
|
||||||
|
|
@ -434,12 +464,19 @@ Eci SGP4::CalculateFinalPositionVelocity(const double& tsince, const double& e,
|
||||||
* 2nd order Newton-Raphson correction.
|
* 2nd order Newton-Raphson correction.
|
||||||
* f / (fdot - 0.5 * d2f * f/fdot)
|
* f / (fdot - 0.5 * d2f * f/fdot)
|
||||||
*/
|
*/
|
||||||
if (i == 0) {
|
if (i == 0)
|
||||||
|
{
|
||||||
if (delta_epw > max_newton_naphson)
|
if (delta_epw > max_newton_naphson)
|
||||||
|
{
|
||||||
delta_epw = max_newton_naphson;
|
delta_epw = max_newton_naphson;
|
||||||
|
}
|
||||||
else if (delta_epw < -max_newton_naphson)
|
else if (delta_epw < -max_newton_naphson)
|
||||||
|
{
|
||||||
delta_epw = -max_newton_naphson;
|
delta_epw = -max_newton_naphson;
|
||||||
} else {
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
delta_epw = f / (fdot + 0.5 * esine * delta_epw);
|
delta_epw = f / (fdot + 0.5 * esine * delta_epw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -455,7 +492,8 @@ Eci SGP4::CalculateFinalPositionVelocity(const double& tsince, const double& e,
|
||||||
const double temp21 = 1.0 - elsq;
|
const double temp21 = 1.0 - elsq;
|
||||||
const double pl = a * temp21;
|
const double pl = a * temp21;
|
||||||
|
|
||||||
if (pl < 0.0) {
|
if (pl < 0.0)
|
||||||
|
{
|
||||||
throw SatelliteException("Error: #4 (pl < 0.0)");
|
throw SatelliteException("Error: #4 (pl < 0.0)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -486,7 +524,8 @@ Eci SGP4::CalculateFinalPositionVelocity(const double& tsince, const double& e,
|
||||||
const double rdotk = rdot - xn * temp42 * x1mth2 * sin2u;
|
const double rdotk = rdot - xn * temp42 * x1mth2 * sin2u;
|
||||||
const double rfdotk = rfdot + xn * temp42 * (x1mth2 * cos2u + 1.5 * x3thm1);
|
const double rfdotk = rfdot + xn * temp42 * (x1mth2 * cos2u + 1.5 * x3thm1);
|
||||||
|
|
||||||
if (rk < 1.0) {
|
if (rk < 1.0)
|
||||||
|
{
|
||||||
throw SatelliteException("Error: #6 Satellite decayed (rk < 1.0)");
|
throw SatelliteException("Error: #6 Satellite decayed (rk < 1.0)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -528,18 +567,18 @@ Eci SGP4::CalculateFinalPositionVelocity(const double& tsince, const double& e,
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline double EvaluateCubicPolynomial(const double x, const double constant,
|
static inline double EvaluateCubicPolynomial(const double x, const double constant,
|
||||||
const double linear, const double squared, const double cubed) {
|
const double linear, const double squared, const double cubed)
|
||||||
|
{
|
||||||
return constant + x * (linear + x * (squared + x * cubed));
|
return constant + x * (linear + x * (squared + x * cubed));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* deep space initialization
|
* deep space initialisation
|
||||||
*/
|
*/
|
||||||
void SGP4::DeepSpaceInitialize(const double& eosq, const double& sinio, const double& cosio, const double& betao,
|
void SGP4::DeepSpaceInitialise(const double& eosq, const double& sinio, const double& cosio, const double& betao,
|
||||||
const double& theta2, const double& betao2,
|
const double& theta2, const double& betao2,
|
||||||
const double& xmdot, const double& omgdot, const double& xnodot) {
|
const double& xmdot, const double& omgdot, const double& xnodot)
|
||||||
|
{
|
||||||
double se = 0.0;
|
double se = 0.0;
|
||||||
double si = 0.0;
|
double si = 0.0;
|
||||||
double sl = 0.0;
|
double sl = 0.0;
|
||||||
|
|
@ -613,7 +652,8 @@ void SGP4::DeepSpaceInitialize(const double& eosq, const double& sinio, const do
|
||||||
double ze = ZES;
|
double ze = ZES;
|
||||||
const double xnoi = 1.0 / elements_.RecoveredMeanMotion();
|
const double xnoi = 1.0 / elements_.RecoveredMeanMotion();
|
||||||
|
|
||||||
for (int cnt = 0; cnt < 2; cnt++) {
|
for (int cnt = 0; cnt < 2; cnt++)
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* solar terms are done a second time after lunar terms are done
|
* solar terms are done a second time after lunar terms are done
|
||||||
*/
|
*/
|
||||||
|
|
@ -668,9 +708,12 @@ void SGP4::DeepSpaceInitialize(const double& eosq, const double& sinio, const do
|
||||||
* with
|
* with
|
||||||
* shdq = (-zn * s2 * (z21 + z23)) / sinio
|
* shdq = (-zn * s2 * (z21 + z23)) / sinio
|
||||||
*/
|
*/
|
||||||
if (elements_.Inclination() < 5.2359877e-2 || elements_.Inclination() > kPI - 5.2359877e-2) {
|
if (elements_.Inclination() < 5.2359877e-2 || elements_.Inclination() > kPI - 5.2359877e-2)
|
||||||
|
{
|
||||||
shdq = 0.0;
|
shdq = 0.0;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
shdq = (-zn * s2 * (z21 + z23)) / sinio;
|
shdq = (-zn * s2 * (z21 + z23)) / sinio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -688,7 +731,9 @@ void SGP4::DeepSpaceInitialize(const double& eosq, const double& sinio, const do
|
||||||
deepspace_consts_.xh3 = -2.0 * s2 * (z23 - z21);
|
deepspace_consts_.xh3 = -2.0 * s2 * (z23 - z21);
|
||||||
|
|
||||||
if (cnt == 1)
|
if (cnt == 1)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* do lunar terms
|
* do lunar terms
|
||||||
*/
|
*/
|
||||||
|
|
@ -728,12 +773,12 @@ void SGP4::DeepSpaceInitialize(const double& eosq, const double& sinio, const do
|
||||||
|
|
||||||
deepspace_consts_.resonance_flag = false;
|
deepspace_consts_.resonance_flag = false;
|
||||||
deepspace_consts_.synchronous_flag = false;
|
deepspace_consts_.synchronous_flag = false;
|
||||||
bool initialize_integrator = true;
|
bool initialise_integrator = true;
|
||||||
|
|
||||||
if (elements_.RecoveredMeanMotion() < 0.0052359877 && elements_.RecoveredMeanMotion() > 0.0034906585) {
|
|
||||||
|
|
||||||
|
if (elements_.RecoveredMeanMotion() < 0.0052359877 && elements_.RecoveredMeanMotion() > 0.0034906585)
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* 24h synchronous resonance terms initialization
|
* 24h synchronous resonance terms initialisation
|
||||||
*/
|
*/
|
||||||
deepspace_consts_.resonance_flag = true;
|
deepspace_consts_.resonance_flag = true;
|
||||||
deepspace_consts_.synchronous_flag = true;
|
deepspace_consts_.synchronous_flag = true;
|
||||||
|
|
@ -754,11 +799,15 @@ void SGP4::DeepSpaceInitialize(const double& eosq, const double& sinio, const do
|
||||||
bfact = xmdot + xpidot - kTHDT;
|
bfact = xmdot + xpidot - kTHDT;
|
||||||
bfact += deepspace_consts_.ssl + deepspace_consts_.ssg + deepspace_consts_.ssh;
|
bfact += deepspace_consts_.ssl + deepspace_consts_.ssg + deepspace_consts_.ssh;
|
||||||
|
|
||||||
} else if (elements_.RecoveredMeanMotion() < 8.26e-3 || elements_.RecoveredMeanMotion() > 9.24e-3 || elements_.Eccentricity() < 0.5) {
|
}
|
||||||
initialize_integrator = false;
|
else if (elements_.RecoveredMeanMotion() < 8.26e-3 || elements_.RecoveredMeanMotion() > 9.24e-3 || elements_.Eccentricity() < 0.5)
|
||||||
} else {
|
{
|
||||||
|
initialise_integrator = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* geopotential resonance initialization for 12 hour orbits
|
* geopotential resonance initialisation for 12 hour orbits
|
||||||
*/
|
*/
|
||||||
deepspace_consts_.resonance_flag = true;
|
deepspace_consts_.resonance_flag = true;
|
||||||
|
|
||||||
|
|
@ -771,23 +820,29 @@ void SGP4::DeepSpaceInitialize(const double& eosq, const double& sinio, const do
|
||||||
|
|
||||||
double g201 = -0.306 - (elements_.Eccentricity() - 0.64) * 0.440;
|
double g201 = -0.306 - (elements_.Eccentricity() - 0.64) * 0.440;
|
||||||
|
|
||||||
if (elements_.Eccentricity() <= 0.65) {
|
if (elements_.Eccentricity() <= 0.65)
|
||||||
|
{
|
||||||
g211 = EvaluateCubicPolynomial(elements_.Eccentricity(), 3.616, -13.247, +16.290, 0.0);
|
g211 = EvaluateCubicPolynomial(elements_.Eccentricity(), 3.616, -13.247, +16.290, 0.0);
|
||||||
g310 = EvaluateCubicPolynomial(elements_.Eccentricity(), -19.302, 117.390, -228.419, 156.591);
|
g310 = EvaluateCubicPolynomial(elements_.Eccentricity(), -19.302, 117.390, -228.419, 156.591);
|
||||||
g322 = EvaluateCubicPolynomial(elements_.Eccentricity(), -18.9068, 109.7927, -214.6334, 146.5816);
|
g322 = EvaluateCubicPolynomial(elements_.Eccentricity(), -18.9068, 109.7927, -214.6334, 146.5816);
|
||||||
g410 = EvaluateCubicPolynomial(elements_.Eccentricity(), -41.122, 242.694, -471.094, 313.953);
|
g410 = EvaluateCubicPolynomial(elements_.Eccentricity(), -41.122, 242.694, -471.094, 313.953);
|
||||||
g422 = EvaluateCubicPolynomial(elements_.Eccentricity(), -146.407, 841.880, -1629.014, 1083.435);
|
g422 = EvaluateCubicPolynomial(elements_.Eccentricity(), -146.407, 841.880, -1629.014, 1083.435);
|
||||||
g520 = EvaluateCubicPolynomial(elements_.Eccentricity(), -532.114, 3017.977, -5740.032, 3708.276);
|
g520 = EvaluateCubicPolynomial(elements_.Eccentricity(), -532.114, 3017.977, -5740.032, 3708.276);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
g211 = EvaluateCubicPolynomial(elements_.Eccentricity(), -72.099, 331.819, -508.738, 266.724);
|
g211 = EvaluateCubicPolynomial(elements_.Eccentricity(), -72.099, 331.819, -508.738, 266.724);
|
||||||
g310 = EvaluateCubicPolynomial(elements_.Eccentricity(), -346.844, 1582.851, -2415.925, 1246.113);
|
g310 = EvaluateCubicPolynomial(elements_.Eccentricity(), -346.844, 1582.851, -2415.925, 1246.113);
|
||||||
g322 = EvaluateCubicPolynomial(elements_.Eccentricity(), -342.585, 1554.908, -2366.899, 1215.972);
|
g322 = EvaluateCubicPolynomial(elements_.Eccentricity(), -342.585, 1554.908, -2366.899, 1215.972);
|
||||||
g410 = EvaluateCubicPolynomial(elements_.Eccentricity(), -1052.797, 4758.686, -7193.992, 3651.957);
|
g410 = EvaluateCubicPolynomial(elements_.Eccentricity(), -1052.797, 4758.686, -7193.992, 3651.957);
|
||||||
g422 = EvaluateCubicPolynomial(elements_.Eccentricity(), -3581.69, 16178.11, -24462.77, 12422.52);
|
g422 = EvaluateCubicPolynomial(elements_.Eccentricity(), -3581.69, 16178.11, -24462.77, 12422.52);
|
||||||
|
|
||||||
if (elements_.Eccentricity() <= 0.715) {
|
if (elements_.Eccentricity() <= 0.715)
|
||||||
|
{
|
||||||
g520 = EvaluateCubicPolynomial(elements_.Eccentricity(), 1464.74, -4664.75, 3763.64, 0.0);
|
g520 = EvaluateCubicPolynomial(elements_.Eccentricity(), 1464.74, -4664.75, 3763.64, 0.0);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
g520 = EvaluateCubicPolynomial(elements_.Eccentricity(), -5149.66, 29936.92, -54087.36, 31324.56);
|
g520 = EvaluateCubicPolynomial(elements_.Eccentricity(), -5149.66, 29936.92, -54087.36, 31324.56);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -796,11 +851,14 @@ void SGP4::DeepSpaceInitialize(const double& eosq, const double& sinio, const do
|
||||||
double g521;
|
double g521;
|
||||||
double g532;
|
double g532;
|
||||||
|
|
||||||
if (elements_.Eccentricity() < 0.7) {
|
if (elements_.Eccentricity() < 0.7)
|
||||||
|
{
|
||||||
g533 = EvaluateCubicPolynomial(elements_.Eccentricity(), -919.2277, 4988.61, -9064.77, 5542.21);
|
g533 = EvaluateCubicPolynomial(elements_.Eccentricity(), -919.2277, 4988.61, -9064.77, 5542.21);
|
||||||
g521 = EvaluateCubicPolynomial(elements_.Eccentricity(), -822.71072, 4568.6173, -8491.4146, 5337.524);
|
g521 = EvaluateCubicPolynomial(elements_.Eccentricity(), -822.71072, 4568.6173, -8491.4146, 5337.524);
|
||||||
g532 = EvaluateCubicPolynomial(elements_.Eccentricity(), -853.666, 4690.25, -8624.77, 5341.4);
|
g532 = EvaluateCubicPolynomial(elements_.Eccentricity(), -853.666, 4690.25, -8624.77, 5341.4);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
g533 = EvaluateCubicPolynomial(elements_.Eccentricity(), -37995.78, 161616.52, -229838.2, 109377.94);
|
g533 = EvaluateCubicPolynomial(elements_.Eccentricity(), -37995.78, 161616.52, -229838.2, 109377.94);
|
||||||
g521 = EvaluateCubicPolynomial(elements_.Eccentricity(), -51752.104, 218913.95, -309468.16, 146349.42);
|
g521 = EvaluateCubicPolynomial(elements_.Eccentricity(), -51752.104, 218913.95, -309468.16, 146349.42);
|
||||||
g532 = EvaluateCubicPolynomial(elements_.Eccentricity(), -40023.88, 170470.89, -242699.48, 115605.82);
|
g532 = EvaluateCubicPolynomial(elements_.Eccentricity(), -40023.88, 170470.89, -242699.48, 115605.82);
|
||||||
|
|
@ -850,10 +908,10 @@ void SGP4::DeepSpaceInitialize(const double& eosq, const double& sinio, const do
|
||||||
bfact = bfact + deepspace_consts_.ssl + deepspace_consts_.ssh + deepspace_consts_.ssh;
|
bfact = bfact + deepspace_consts_.ssl + deepspace_consts_.ssh + deepspace_consts_.ssh;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (initialize_integrator) {
|
if (initialise_integrator)
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* initialize integrator
|
* initialise integrator
|
||||||
*/
|
*/
|
||||||
integrator_consts_.xfact = bfact - elements_.RecoveredMeanMotion();
|
integrator_consts_.xfact = bfact - elements_.RecoveredMeanMotion();
|
||||||
integrator_params_.atime = 0.0;
|
integrator_params_.atime = 0.0;
|
||||||
|
|
@ -867,8 +925,8 @@ void SGP4::DeepSpaceInitialize(const double& eosq, const double& sinio, const do
|
||||||
}
|
}
|
||||||
|
|
||||||
void SGP4::DeepSpaceCalculateLunarSolarTerms(const double t, double* pe, double* pinc,
|
void SGP4::DeepSpaceCalculateLunarSolarTerms(const double t, double* pe, double* pinc,
|
||||||
double* pl, double* pgh, double* ph) const {
|
double* pl, double* pgh, double* ph) const
|
||||||
|
{
|
||||||
static const double ZES = 0.01675;
|
static const double ZES = 0.01675;
|
||||||
static const double ZNS = 1.19459E-5;
|
static const double ZNS = 1.19459E-5;
|
||||||
static const double ZNL = 1.5835218E-4;
|
static const double ZNL = 1.5835218E-4;
|
||||||
|
|
@ -879,7 +937,9 @@ void SGP4::DeepSpaceCalculateLunarSolarTerms(const double t, double* pe, double*
|
||||||
*/
|
*/
|
||||||
double zm = deepspace_consts_.zmos + ZNS * t;
|
double zm = deepspace_consts_.zmos + ZNS * t;
|
||||||
if (first_run_)
|
if (first_run_)
|
||||||
|
{
|
||||||
zm = deepspace_consts_.zmos;
|
zm = deepspace_consts_.zmos;
|
||||||
|
}
|
||||||
double zf = zm + 2.0 * ZES * sin(zm);
|
double zf = zm + 2.0 * ZES * sin(zm);
|
||||||
double sinzf = sin(zf);
|
double sinzf = sin(zf);
|
||||||
double f2 = 0.5 * sinzf * sinzf - 0.25;
|
double f2 = 0.5 * sinzf * sinzf - 0.25;
|
||||||
|
|
@ -896,7 +956,9 @@ void SGP4::DeepSpaceCalculateLunarSolarTerms(const double t, double* pe, double*
|
||||||
zm = deepspace_consts_.zmol + ZNL * t;
|
zm = deepspace_consts_.zmol + ZNL * t;
|
||||||
|
|
||||||
if (first_run_)
|
if (first_run_)
|
||||||
|
{
|
||||||
zm = deepspace_consts_.zmol;
|
zm = deepspace_consts_.zmol;
|
||||||
|
}
|
||||||
zf = zm + 2.0 * ZEL * sin(zm);
|
zf = zm + 2.0 * ZEL * sin(zm);
|
||||||
sinzf = sin(zf);
|
sinzf = sin(zf);
|
||||||
f2 = 0.5 * sinzf * sinzf - 0.25;
|
f2 = 0.5 * sinzf * sinzf - 0.25;
|
||||||
|
|
@ -921,8 +983,8 @@ void SGP4::DeepSpaceCalculateLunarSolarTerms(const double t, double* pe, double*
|
||||||
* calculate lunar / solar periodics and apply
|
* calculate lunar / solar periodics and apply
|
||||||
*/
|
*/
|
||||||
void SGP4::DeepSpacePeriodics(const double& t, double* em,
|
void SGP4::DeepSpacePeriodics(const double& t, double* em,
|
||||||
double* xinc, double* omgasm, double* xnodes, double* xll) const {
|
double* xinc, double* omgasm, double* xnodes, double* xll) const
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* storage for lunar / solar terms set by DeepSpaceCalculateLunarSolarTerms()
|
* storage for lunar / solar terms set by DeepSpaceCalculateLunarSolarTerms()
|
||||||
*/
|
*/
|
||||||
|
|
@ -937,8 +999,8 @@ void SGP4::DeepSpacePeriodics(const double& t, double* em,
|
||||||
*/
|
*/
|
||||||
DeepSpaceCalculateLunarSolarTerms(t, &pe, &pinc, &pl, &pgh, &ph);
|
DeepSpaceCalculateLunarSolarTerms(t, &pe, &pinc, &pl, &pgh, &ph);
|
||||||
|
|
||||||
if (!first_run_) {
|
if (!first_run_)
|
||||||
|
{
|
||||||
(*xinc) += pinc;
|
(*xinc) += pinc;
|
||||||
(*em) += pe;
|
(*em) += pe;
|
||||||
|
|
||||||
|
|
@ -954,7 +1016,8 @@ void SGP4::DeepSpacePeriodics(const double& t, double* em,
|
||||||
const double sinis = sin(*xinc);
|
const double sinis = sin(*xinc);
|
||||||
const double cosis = cos(*xinc);
|
const double cosis = cos(*xinc);
|
||||||
|
|
||||||
if ((*xinc) >= 0.2) {
|
if ((*xinc) >= 0.2)
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* apply periodics directly
|
* apply periodics directly
|
||||||
*/
|
*/
|
||||||
|
|
@ -963,7 +1026,9 @@ void SGP4::DeepSpacePeriodics(const double& t, double* em,
|
||||||
(*omgasm) += pgh - cosis * tmp_ph;
|
(*omgasm) += pgh - cosis * tmp_ph;
|
||||||
(*xnodes) += tmp_ph;
|
(*xnodes) += tmp_ph;
|
||||||
(*xll) += pl;
|
(*xll) += pl;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* apply periodics with lyddane modification
|
* apply periodics with lyddane modification
|
||||||
*/
|
*/
|
||||||
|
|
@ -979,7 +1044,9 @@ void SGP4::DeepSpacePeriodics(const double& t, double* em,
|
||||||
|
|
||||||
(*xnodes) = fmod((*xnodes), kTWOPI);
|
(*xnodes) = fmod((*xnodes), kTWOPI);
|
||||||
if ((*xnodes) < 0.0)
|
if ((*xnodes) < 0.0)
|
||||||
|
{
|
||||||
(*xnodes) += kTWOPI;
|
(*xnodes) += kTWOPI;
|
||||||
|
}
|
||||||
|
|
||||||
double xls = (*xll) + (*omgasm) + cosis * (*xnodes);
|
double xls = (*xll) + (*omgasm) + cosis * (*xnodes);
|
||||||
double dls = pl + pgh - pinc * (*xnodes) * sinis;
|
double dls = pl + pgh - pinc * (*xnodes) * sinis;
|
||||||
|
|
@ -992,18 +1059,25 @@ void SGP4::DeepSpacePeriodics(const double& t, double* em,
|
||||||
|
|
||||||
(*xnodes) = atan2(alfdp, betdp);
|
(*xnodes) = atan2(alfdp, betdp);
|
||||||
if ((*xnodes) < 0.0)
|
if ((*xnodes) < 0.0)
|
||||||
|
{
|
||||||
(*xnodes) += kTWOPI;
|
(*xnodes) += kTWOPI;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get perturbed xnodes in to same quadrant as original.
|
* Get perturbed xnodes in to same quadrant as original.
|
||||||
* RAAN is in the range of 0 to 360 degrees
|
* RAAN is in the range of 0 to 360 degrees
|
||||||
* atan2 is in the range of -180 to 180 degrees
|
* atan2 is in the range of -180 to 180 degrees
|
||||||
*/
|
*/
|
||||||
if (fabs(oldxnodes - (*xnodes)) > kPI) {
|
if (fabs(oldxnodes - (*xnodes)) > kPI)
|
||||||
|
{
|
||||||
if ((*xnodes) < oldxnodes)
|
if ((*xnodes) < oldxnodes)
|
||||||
|
{
|
||||||
(*xnodes) += kTWOPI;
|
(*xnodes) += kTWOPI;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
(*xnodes) -= kTWOPI;
|
(*xnodes) -= kTWOPI;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(*xll) += pl;
|
(*xll) += pl;
|
||||||
|
|
@ -1016,8 +1090,8 @@ void SGP4::DeepSpacePeriodics(const double& t, double* em,
|
||||||
* deep space secular effects
|
* deep space secular effects
|
||||||
*/
|
*/
|
||||||
void SGP4::DeepSpaceSecular(const double& t, double* xll, double* omgasm,
|
void SGP4::DeepSpaceSecular(const double& t, double* xll, double* omgasm,
|
||||||
double* xnodes, double* em, double* xinc, double* xn) const {
|
double* xnodes, double* em, double* xinc, double* xn) const
|
||||||
|
{
|
||||||
static const double STEP = 720.0;
|
static const double STEP = 720.0;
|
||||||
static const double STEP2 = 259200.0;
|
static const double STEP2 = 259200.0;
|
||||||
|
|
||||||
|
|
@ -1028,7 +1102,9 @@ void SGP4::DeepSpaceSecular(const double& t, double* xll, double* omgasm,
|
||||||
(*xinc) += deepspace_consts_.ssi * t;
|
(*xinc) += deepspace_consts_.ssi * t;
|
||||||
|
|
||||||
if (!deepspace_consts_.resonance_flag)
|
if (!deepspace_consts_.resonance_flag)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 1st condition (if t is less than one time step from epoch)
|
* 1st condition (if t is less than one time step from epoch)
|
||||||
|
|
@ -1037,7 +1113,8 @@ void SGP4::DeepSpaceSecular(const double& t, double* xll, double* omgasm,
|
||||||
*/
|
*/
|
||||||
if (fabs(t) < STEP ||
|
if (fabs(t) < STEP ||
|
||||||
t * integrator_params_.atime <= 0.0 ||
|
t * integrator_params_.atime <= 0.0 ||
|
||||||
fabs(t) < fabs(integrator_params_.atime)) {
|
fabs(t) < fabs(integrator_params_.atime))
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* restart from epoch
|
* restart from epoch
|
||||||
*/
|
*/
|
||||||
|
|
@ -1057,17 +1134,20 @@ void SGP4::DeepSpaceSecular(const double& t, double* xll, double* omgasm,
|
||||||
* if time difference (ft) is greater than the time step (720.0)
|
* if time difference (ft) is greater than the time step (720.0)
|
||||||
* loop around until integrator_params_.atime is within one time step of t
|
* loop around until integrator_params_.atime is within one time step of t
|
||||||
*/
|
*/
|
||||||
if (fabs(ft) >= STEP) {
|
if (fabs(ft) >= STEP)
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* calculate step direction to allow integrator_params_.atime
|
* calculate step direction to allow integrator_params_.atime
|
||||||
* to catch up with t
|
* to catch up with t
|
||||||
*/
|
*/
|
||||||
double delt = -STEP;
|
double delt = -STEP;
|
||||||
if (ft >= 0.0)
|
if (ft >= 0.0)
|
||||||
|
{
|
||||||
delt = STEP;
|
delt = STEP;
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* integrate using current dot terms
|
* integrate using current dot terms
|
||||||
*/
|
*/
|
||||||
|
|
@ -1090,16 +1170,20 @@ void SGP4::DeepSpaceSecular(const double& t, double* xll, double* omgasm,
|
||||||
const double temp = -(*xnodes) + deepspace_consts_.gsto + t * kTHDT;
|
const double temp = -(*xnodes) + deepspace_consts_.gsto + t * kTHDT;
|
||||||
|
|
||||||
if (deepspace_consts_.synchronous_flag)
|
if (deepspace_consts_.synchronous_flag)
|
||||||
|
{
|
||||||
(*xll) = xl + temp - (*omgasm);
|
(*xll) = xl + temp - (*omgasm);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
(*xll) = xl + temp + temp;
|
(*xll) = xl + temp + temp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* calculate dot terms
|
* calculate dot terms
|
||||||
*/
|
*/
|
||||||
void SGP4::DeepSpaceCalcDotTerms(struct IntegratorValues *values) const {
|
void SGP4::DeepSpaceCalcDotTerms(struct IntegratorValues *values) const
|
||||||
|
{
|
||||||
static const double G22 = 5.7686396;
|
static const double G22 = 5.7686396;
|
||||||
static const double G32 = 0.95240898;
|
static const double G32 = 0.95240898;
|
||||||
static const double G44 = 1.8014998;
|
static const double G44 = 1.8014998;
|
||||||
|
|
@ -1109,7 +1193,8 @@ void SGP4::DeepSpaceCalcDotTerms(struct IntegratorValues *values) const {
|
||||||
static const double FASX4 = 2.8843198;
|
static const double FASX4 = 2.8843198;
|
||||||
static const double FASX6 = 0.37448087;
|
static const double FASX6 = 0.37448087;
|
||||||
|
|
||||||
if (deepspace_consts_.synchronous_flag) {
|
if (deepspace_consts_.synchronous_flag)
|
||||||
|
{
|
||||||
|
|
||||||
values->xndot = deepspace_consts_.del1 * sin(integrator_params_.xli - FASX2) +
|
values->xndot = deepspace_consts_.del1 * sin(integrator_params_.xli - FASX2) +
|
||||||
deepspace_consts_.del2 * sin(2.0 * (integrator_params_.xli - FASX4)) +
|
deepspace_consts_.del2 * sin(2.0 * (integrator_params_.xli - FASX4)) +
|
||||||
|
|
@ -1118,8 +1203,9 @@ void SGP4::DeepSpaceCalcDotTerms(struct IntegratorValues *values) const {
|
||||||
deepspace_consts_.del2 * cos(2.0 * (integrator_params_.xli - FASX4)) + 3.0 *
|
deepspace_consts_.del2 * cos(2.0 * (integrator_params_.xli - FASX4)) + 3.0 *
|
||||||
deepspace_consts_.del3 * cos(3.0 * (integrator_params_.xli - FASX6));
|
deepspace_consts_.del3 * cos(3.0 * (integrator_params_.xli - FASX6));
|
||||||
|
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
const double xomi = elements_.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 x2omi = xomi + xomi;
|
||||||
const double x2li = integrator_params_.xli + integrator_params_.xli;
|
const double x2li = integrator_params_.xli + integrator_params_.xli;
|
||||||
|
|
@ -1154,8 +1240,8 @@ void SGP4::DeepSpaceCalcDotTerms(struct IntegratorValues *values) const {
|
||||||
* deep space integrator for time period of delt
|
* deep space integrator for time period of delt
|
||||||
*/
|
*/
|
||||||
void SGP4::DeepSpaceIntegrator(const double delt, const double step2,
|
void SGP4::DeepSpaceIntegrator(const double delt, const double step2,
|
||||||
const struct IntegratorValues &values) const {
|
const struct IntegratorValues &values) const
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* integrator
|
* integrator
|
||||||
*/
|
*/
|
||||||
|
|
@ -1168,8 +1254,8 @@ void SGP4::DeepSpaceIntegrator(const double delt, const double step2,
|
||||||
integrator_params_.atime += delt;
|
integrator_params_.atime += delt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SGP4::Reset() {
|
void SGP4::Reset()
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* common variables
|
* common variables
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
58
SGP4.h
58
SGP4.h
|
|
@ -9,19 +9,27 @@
|
||||||
class SGP4
|
class SGP4
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SGP4(const Tle& tle);
|
SGP4(const Tle& tle)
|
||||||
virtual ~SGP4(void);
|
: elements_(tle)
|
||||||
|
{
|
||||||
|
Initialise();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~SGP4()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void SetTle(const Tle& tle);
|
void SetTle(const Tle& tle);
|
||||||
Eci FindPosition(double tsince) const;
|
Eci FindPosition(double tsince) const;
|
||||||
Eci FindPosition(const Julian& date) const;
|
Eci FindPosition(const Julian& date) const;
|
||||||
|
|
||||||
struct CommonConstants {
|
struct CommonConstants
|
||||||
|
{
|
||||||
CommonConstants()
|
CommonConstants()
|
||||||
: cosio(0.0), sinio(0.0), eta(0.0), t2cof(0.0), a3ovk2(0.0),
|
: cosio(0.0), sinio(0.0), eta(0.0), t2cof(0.0), a3ovk2(0.0),
|
||||||
x1mth2(0.0), x3thm1(0.0), x7thm1(0.0), aycof(0.0), xlcof(0.0),
|
x1mth2(0.0), x3thm1(0.0), x7thm1(0.0), aycof(0.0), xlcof(0.0),
|
||||||
xnodcf(0.0), c1(0.0), c4(0.0), omgdot(0.0), xnodot(0.0), xmdot(0.0) {
|
xnodcf(0.0), c1(0.0), c4(0.0), omgdot(0.0), xnodot(0.0), xmdot(0.0)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
double cosio;
|
double cosio;
|
||||||
|
|
@ -42,11 +50,12 @@ public:
|
||||||
double xmdot; // secular rate of xmo (radians/sec)
|
double xmdot; // secular rate of xmo (radians/sec)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NearSpaceConstants {
|
struct NearSpaceConstants
|
||||||
|
{
|
||||||
NearSpaceConstants()
|
NearSpaceConstants()
|
||||||
: c5(0.0), omgcof(0.0), xmcof(0.0), delmo(0.0), sinmo(0.0), d2(0.0),
|
: c5(0.0), omgcof(0.0), xmcof(0.0), delmo(0.0), sinmo(0.0), d2(0.0),
|
||||||
d3(0.0), d4(0.0), t3cof(0.0), t4cof(0.0), t5cof(0.0) {
|
d3(0.0), d4(0.0), t3cof(0.0), t4cof(0.0), t5cof(0.0)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
double c5;
|
double c5;
|
||||||
|
|
@ -62,8 +71,8 @@ public:
|
||||||
double t5cof;
|
double t5cof;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DeepSpaceConstants {
|
struct DeepSpaceConstants
|
||||||
|
{
|
||||||
DeepSpaceConstants()
|
DeepSpaceConstants()
|
||||||
: gsto(0.0), zmol(0.0), zmos(0.0), resonance_flag(false),
|
: gsto(0.0), zmol(0.0), zmos(0.0), resonance_flag(false),
|
||||||
synchronous_flag(false), sse(0.0), ssi(0.0), ssl(0.0), ssg(0.0),
|
synchronous_flag(false), sse(0.0), ssi(0.0), ssl(0.0), ssg(0.0),
|
||||||
|
|
@ -72,7 +81,8 @@ public:
|
||||||
e3(0.0), xi2(0.0), xi3(0.0), xl2(0.0), xl3(0.0), xl4(0.0), xgh2(0.0),
|
e3(0.0), xi2(0.0), xi3(0.0), xl2(0.0), xl3(0.0), xl4(0.0), xgh2(0.0),
|
||||||
xgh3(0.0), xgh4(0.0), xh2(0.0), xh3(0.0), d2201(0.0), d2211(0.0),
|
xgh3(0.0), xgh4(0.0), xh2(0.0), xh3(0.0), d2201(0.0), d2211(0.0),
|
||||||
d3210(0.0), d3222(0.0), d4410(0.0), d4422(0.0), d5220(0.0), d5232(0.0),
|
d3210(0.0), d3222(0.0), d4410(0.0), d4422(0.0), d5220(0.0), d5232(0.0),
|
||||||
d5421(0.0), d5433(0.0), del1(0.0), del2(0.0), del3(0.0) {
|
d5421(0.0), d5433(0.0), del1(0.0), del2(0.0), del3(0.0)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
double gsto;
|
double gsto;
|
||||||
|
|
@ -143,8 +153,10 @@ public:
|
||||||
double del3;
|
double del3;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IntegratorValues {
|
struct IntegratorValues
|
||||||
IntegratorValues() : xndot(0.0), xnddt(0.0), xldot(0.0) {
|
{
|
||||||
|
IntegratorValues() : xndot(0.0), xnddt(0.0), xldot(0.0)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
double xndot;
|
double xndot;
|
||||||
|
|
@ -152,9 +164,10 @@ public:
|
||||||
double xldot;
|
double xldot;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IntegratorConstants {
|
struct IntegratorConstants
|
||||||
|
{
|
||||||
IntegratorConstants() : xfact(0.0), xlamo(0.0) {
|
IntegratorConstants() : xfact(0.0), xlamo(0.0)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -169,9 +182,10 @@ public:
|
||||||
struct IntegratorValues values_0;
|
struct IntegratorValues values_0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IntegratorParams {
|
struct IntegratorParams
|
||||||
|
{
|
||||||
IntegratorParams() : xli(0.0), xni(0.0), atime(0.0) {
|
IntegratorParams() : xli(0.0), xni(0.0), atime(0.0)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -187,8 +201,8 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Initialize();
|
void Initialise();
|
||||||
void DeepSpaceInitialize(const double& eosq, const double& sinio, const double& cosio, const double& betao,
|
void DeepSpaceInitialise(const double& eosq, const double& sinio, const double& cosio, const double& betao,
|
||||||
const double& theta2, const double& betao2,
|
const double& theta2, const double& betao2,
|
||||||
const double& xmdot, const double& omgdot, const double& xnodot);
|
const double& xmdot, const double& omgdot, const double& xnodot);
|
||||||
void DeepSpaceCalculateLunarSolarTerms(const double t, double* pe, double* pinc,
|
void DeepSpaceCalculateLunarSolarTerms(const double t, double* pe, double* pinc,
|
||||||
|
|
@ -206,7 +220,7 @@ private:
|
||||||
const double& cosio, const double& sinio) const;
|
const double& cosio, const double& sinio) const;
|
||||||
void DeepSpaceCalcDotTerms(struct IntegratorValues *values) const;
|
void DeepSpaceCalcDotTerms(struct IntegratorValues *values) const;
|
||||||
void DeepSpaceIntegrator(const double delt, const double step2,
|
void DeepSpaceIntegrator(const double delt, const double step2,
|
||||||
const struct IntegratorValues& values)const;
|
const struct IntegratorValues& values) const;
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue