Skip to content

Commit 0f17291

Browse files
committed
major orbital physics improvements
1 parent 7810bb8 commit 0f17291

1 file changed

Lines changed: 31 additions & 12 deletions

File tree

src/astro.c

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -123,29 +123,48 @@ void load_tle_data(const char* filename) {
123123
fclose(file);
124124
}
125125

126-
// figure out where the satellite is right now
126+
// figure out where the satellite is right now (with j2 spheroid perturbations)
127127
Vector3 calculate_position(Satellite* sat, double current_time_days) {
128128
double delta_time_s = (current_time_days - sat->epoch_days) * 86400.0;
129+
130+
// earth oblateness (j2) effects
131+
double e2 = sat->eccentricity * sat->eccentricity;
132+
double p = sat->semi_major_axis * (1.0 - e2);
133+
134+
// j2 math constants
135+
const double J2 = 0.00108262668;
136+
const double RE = 6378.137; // earth radius in km
137+
138+
double n_J2_Re2_p2 = sat->mean_motion * J2 * (RE * RE) / (p * p);
139+
double raan_dot = -1.5 * n_J2_Re2_p2 * cos(sat->inclination);
140+
double arg_perigee_dot = 0.75 * n_J2_Re2_p2 * (4.0 - 5.0 * pow(sin(sat->inclination), 2));
141+
142+
double current_raan = sat->raan + raan_dot * delta_time_s;
143+
double current_arg_perigee = sat->arg_perigee + arg_perigee_dot * delta_time_s;
144+
129145
double M = sat->mean_anomaly + sat->mean_motion * delta_time_s;
130146
M = fmod(M, 2.0 * PI);
131-
if (M < 0) M += 2.0 * PI;
147+
if (M < 0.0) M += 2.0 * PI;
132148

133-
double E = M;
149+
// improved guess for kepler's equation
150+
double E = M + sat->eccentricity * sin(M);
151+
double sinE, cosE;
134152
for (int i = 0; i < 10; i++) {
135-
double delta = (E - sat->eccentricity * sin(E) - M) / (1.0 - sat->eccentricity * cos(E));
153+
sinE = sin(E);
154+
cosE = cos(E);
155+
double delta = (E - sat->eccentricity * sinE - M) / (1.0 - sat->eccentricity * cosE);
136156
E -= delta;
137157
if (fabs(delta) < 1e-6) break;
138158
}
139159

140-
double nu = 2.0 * atan2(sqrt(1.0 + sat->eccentricity) * sin(E / 2.0),
141-
sqrt(1.0 - sat->eccentricity) * cos(E / 2.0));
142-
143-
double r = sat->semi_major_axis * (1.0 - sat->eccentricity * cos(E));
144-
double x_orb = r * cos(nu);
145-
double y_orb = r * sin(nu);
160+
// bypass true anomaly calculation
161+
double sqrt_1_minus_e2 = sqrt(1.0 - e2);
162+
double x_orb = sat->semi_major_axis * (cosE - sat->eccentricity);
163+
double y_orb = sat->semi_major_axis * sqrt_1_minus_e2 * sinE;
146164

147-
double cw = cos(sat->arg_perigee), sw = sin(sat->arg_perigee);
148-
double cO = cos(sat->raan), sO = sin(sat->raan);
165+
// use perturbed angles for orientation
166+
double cw = cos(current_arg_perigee), sw = sin(current_arg_perigee);
167+
double cO = cos(current_raan), sO = sin(current_raan);
149168
double ci = cos(sat->inclination), si = sin(sat->inclination);
150169

151170
Vector3 pos;

0 commit comments

Comments
 (0)