|
|
|
|
@ -4,63 +4,6 @@
|
|
|
|
|
#include "orbits.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double |
|
|
|
|
getPropagatedPosition(orbital_elements orbit, |
|
|
|
|
double initial_anom, |
|
|
|
|
unsigned int time_step) |
|
|
|
|
{ |
|
|
|
|
ellipse_parameters ep = orbit.ep; |
|
|
|
|
|
|
|
|
|
// TODO: break out steps with descriptive function names
|
|
|
|
|
// initial eccentric anomaly
|
|
|
|
|
double E1 = 2 * atan(sqrt((1 - ep.e) / (1 + ep.e)) * tan(initial_anom / 2)); |
|
|
|
|
|
|
|
|
|
// initial mean anomaly
|
|
|
|
|
double M1 = E1 - ep.e * sin(E1); |
|
|
|
|
|
|
|
|
|
// mean motion
|
|
|
|
|
double n = sqrt(orbit.mu / pow(ep.a, 3)); |
|
|
|
|
|
|
|
|
|
// propagated mean anomaly
|
|
|
|
|
double M2 = M1 + n * (time_step); |
|
|
|
|
|
|
|
|
|
// guess starting value for E2
|
|
|
|
|
double E2_1 = M2 + ep.e * sin(M2) + ((pow(ep.e, 2) / 2) * sin(2 * M2)); |
|
|
|
|
|
|
|
|
|
// test if guess is a solution to kepler's equation
|
|
|
|
|
const double ACCEPTABLE_ERROR = 0.00000001; |
|
|
|
|
double E2_test = E2_1; |
|
|
|
|
|
|
|
|
|
for (uint i = 0; i < 10; i++) { |
|
|
|
|
double err = E2_test - ep.e * sin(E2_test) - M2; |
|
|
|
|
|
|
|
|
|
LOG(Debug) << "-------------------------\n"; |
|
|
|
|
LOG(Debug) << "index: " << i << "\n"; |
|
|
|
|
LOG(Debug) << "E2_test: " << E2_test << "\n"; |
|
|
|
|
LOG(Debug) << "err: " << err << "\n"; |
|
|
|
|
LOG(Debug) << "err: " << err << "\n"; |
|
|
|
|
|
|
|
|
|
if (fabs(err) < ACCEPTABLE_ERROR) |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
// compute derivative of the error function
|
|
|
|
|
double derr = 1 - ep.e * cos(E2_test); |
|
|
|
|
LOG(Debug) << "derr: " << derr << "\n"; |
|
|
|
|
|
|
|
|
|
// use Newton's method to compute next trial value of E2
|
|
|
|
|
E2_test = E2_test - (err / derr); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return E2_test; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
double |
|
|
|
|
testTrialEccAnomaly(double trial_value, double e, double M2) |
|
|
|
|
{ |
|
|
|
|
double err = trial_value - e * sin(trial_value) - M2; |
|
|
|
|
return err; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ellipse_parameters |
|
|
|
|
constructEllipse(double a, double b) |
|
|
|
|
{ |
|
|
|
|
@ -95,3 +38,93 @@ constructEllipse3D(ellipse_parameters ep, uint vert_count)
|
|
|
|
|
return e3d; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
double |
|
|
|
|
getEccAnomFromTrueAnom(double ecc, double true_anom) |
|
|
|
|
{ |
|
|
|
|
return 2 * atan(sqrt((1 - ecc) / (1 + ecc)) * tan(true_anom / 2)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
double |
|
|
|
|
getTrueAnomFromEccAnom(double ecc, double ecc_anom) |
|
|
|
|
{ |
|
|
|
|
return 2 * atan(sqrt((1 + ecc) / (1 - ecc)) * tan(ecc_anom / 2)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
double |
|
|
|
|
getMeanAnomFromEccAnom(double ecc_anom, double ecc) |
|
|
|
|
{ |
|
|
|
|
return ecc_anom - ecc * sin(ecc_anom); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
double |
|
|
|
|
getMeanMotion(double mu, double a) |
|
|
|
|
{ |
|
|
|
|
return sqrt(mu / pow(a, 3)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
double |
|
|
|
|
getPropagatedMeanAnom(double mean_anom, double mean_motion, double time_step) |
|
|
|
|
{ |
|
|
|
|
return mean_anom + mean_motion * (time_step); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
double |
|
|
|
|
getInitialTrialValue(double mean_anom, double ecc) |
|
|
|
|
{ |
|
|
|
|
return mean_anom + ecc * sin(mean_anom) |
|
|
|
|
+ ((pow(ecc, 2) / 2) * sin(2 * mean_anom)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
double |
|
|
|
|
getTrialError(double ecc, double test_anom, double mean_anom) |
|
|
|
|
{ |
|
|
|
|
return test_anom - ecc * sin(test_anom) - mean_anom; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
double |
|
|
|
|
getNextTrialValue(double err, double ecc, double test_anom, double mean_anom) |
|
|
|
|
{ |
|
|
|
|
// compute derivative of the error function
|
|
|
|
|
double derr = 1 - ecc * cos(test_anom); |
|
|
|
|
|
|
|
|
|
// use Newton's method to compute next trial value of E2
|
|
|
|
|
return test_anom - (err / derr); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
double |
|
|
|
|
getPropagatedEccAnomaly(orbital_elements orbit, |
|
|
|
|
double initial_anom, |
|
|
|
|
unsigned int time_step) |
|
|
|
|
{ |
|
|
|
|
double e = orbit.ep.e; |
|
|
|
|
double E1 = getEccAnomFromTrueAnom(e, initial_anom); |
|
|
|
|
double M1 = getMeanAnomFromEccAnom(E1, e); |
|
|
|
|
double n = getMeanMotion(orbit.mu, orbit.ep.a); |
|
|
|
|
double M2 = getPropagatedMeanAnom(M1, n, time_step); |
|
|
|
|
double E2_1 = getInitialTrialValue(M2, e); |
|
|
|
|
|
|
|
|
|
// test if guess is a solution to kepler's equation
|
|
|
|
|
const double ACCEPTABLE_ERROR = 0.00000001; |
|
|
|
|
double E2_test = E2_1; |
|
|
|
|
|
|
|
|
|
for (uint i = 0; i < 10; i++) { |
|
|
|
|
double err = getTrialError(e, E2_test, M2); |
|
|
|
|
|
|
|
|
|
if (fabs(err) < ACCEPTABLE_ERROR) |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
E2_test = getNextTrialValue(err, e, E2_test, M2); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return E2_test; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
double |
|
|
|
|
getPropagatedTrueAnomaly(orbital_elements orbit, |
|
|
|
|
double initial_anom, |
|
|
|
|
unsigned int time_step) |
|
|
|
|
{ |
|
|
|
|
double ecc_anom = getPropagatedEccAnomaly(orbit, initial_anom, time_step); |
|
|
|
|
return getTrueAnomFromEccAnom(orbit.ep.e, ecc_anom); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|