forked from cbassa/sattools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sgdp4h.h
362 lines (292 loc) · 10.2 KB
/
sgdp4h.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
/* > sgdp4h.h
*
*
* Paul S. Crawford and Andrew R. Brooks
* Dundee University
*
* NOTE !
* This code is supplied "as is" and without warranty of any sort.
*
* (c) 1994-2004, Paul Crawford, Andrew Brooks
*
*
* 2.00 psc Sun May 28 1995 - Modifed for non-Dundee use.
*
*/
#ifndef _SGDP4H_H
#define _SGDP4H_H
/*
* Set up standard system-dependent names UNIX, LINUX, RISCOS, MSDOS, WIN32
*/
#if defined( unix )
# define UNIX
# if defined( linux ) && !defined( LINUX )
# define LINUX
# endif
#elif defined( __riscos ) && !defined( RISCOS )
# define RISCOS
#elif !defined( MSDOS ) && !defined( WIN32 ) && !defined( __CYGWIN__ )
# define MSDOS
#endif
/*
* Include files
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <memory.h>
#include <time.h>
#include <sys/types.h>
#ifdef UNIX
#include <unistd.h>
#endif
#ifdef SUN4
#include <memory.h>
#endif
#ifdef sun
#include <sys/time.h> /* solaris 7 has struct timeval in here */
#include <sunmath.h> /* for sincos() which is in libsunmath */
#endif
#ifdef linux
#include <stdint.h>
void sincos(double x, double *s, double *c); /* declared where? */
#endif
/*
* ================= SYSTEM SPECIFIC DEFINITIONS =====================
*/
/* Use INLINE keyword when declaring inline functions */
#ifdef WIN32
#define INLINE __inline
#elif defined( MSDOS )
#define INLINE
#else
/*UNIX?*/
#define INLINE inline
#endif
/* Sun C compiler has automatic inline and doesn't understand inline keyword */
#ifdef __SUNPRO_C
#undef INLINE
#define INLINE
#define MACROS_ARE_SAFE
#endif
/* Some very common constants. */
#ifndef M_PI
#define M_PI 3.141592653589793
#endif /* MSDOS */
#ifndef PI
#define PI M_PI
#endif
#define TWOPI (2.0*PI) /* Optimising compiler will deal with this! */
#define PB2 (0.5*PI)
#define PI180 (PI/180.0)
#define SOLAR_DAY (1440.0) /* Minutes per 24 hours */
#define SIDERIAL_DAY (23.0*60.0 + 56.0 + 4.09054/60.0) /* Against stars */
#define EQRAD (6378.137) /* Earth radius at equator, km */
#define LATCON (1.0/298.257) /* Latitude radius constant */
#define ECON ((1.0-LATCON)*(1.0-LATCON))
#define JD1900 2415020.5 /* Julian day number for Jan 1st, 00:00 hours 1900 */
/*
* =============================== MACROS ============================
*
*
* Define macro for sign transfer, double to nearest (long) integer,
* to square an expression (not nested), and A "safe" square, uses test
* to force correct sequence of evaluation when the macro is nested.
*/
/*
* These macros are safe since they make no assignments.
*/
#define SIGN(a, b) ((b) >= 0 ? fabs(a) : -fabs(a))
/* Coordinate conversion macros */
#define DEG(x) ((x)/PI180)
#define RAD(x) ((x)*PI180)
#define GEOC(x) (atan(ECON*tan(x))) /* Geographic to geocentric. */
#define GEOG(x) (atan(tan(x)/ECON))
/*
* All other compilers can have static inline functions.
* (SQR is used badly here: do_cal.c, glat2lat.c, satpos.c, vmath.h).
*/
static INLINE int NINT(double a) { return (int)(a > 0 ? a+0.5 : a-0.5); }
static INLINE long NLONG(double a) { return (long)(a > 0 ? a+0.5 : a-0.5); }
static INLINE double DSQR(double a) { return(a*a); }
static INLINE float FSQR(float a) { return(a*a); }
static INLINE int ISQR(int a) { return(a*a); }
static INLINE double DCUBE(double a) { return(a*a*a); }
static INLINE float FCUBE(float a) { return(a*a*a); }
static INLINE int ICUBE(int a) { return(a*a*a); }
static INLINE double DPOW4(double a) { a*=a; return(a*a); }
static INLINE float FPOW4(float a) { a*=a; return(a*a); }
static INLINE int IPOW4(int a) { a*=a; return(a*a); }
static INLINE double DMAX(double a,double b) { if (a>b) return a; else return b; }
static INLINE float FMAX(float a, float b) { if (a>b) return a; else return b; }
static INLINE int IMAX(int a, int b) { if (a>b) return a; else return b; }
static INLINE double DMIN(double a,double b) { if (a<b) return a; else return b; }
static INLINE float FMIN(float a, float b) { if (a<b) return a; else return b; }
static INLINE int IMIN(int a, int b) { if (a<b) return a; else return b; }
static INLINE double MOD2PI(double a) { a=fmod(a, TWOPI); return a < 0.0 ? a+TWOPI : a; }
static INLINE double MOD360(double a) { a=fmod(a, 360.0); return a < 0.0 ? a+360.0 : a; }
/*
* Unless you have higher than default optimisation the Sun compiler
* would prefer to be told explicitly about inline functions after their
* declaration.
*/
#if defined(__SUNPRO_C) && !defined(MACROS_ARE_SAFE)
#pragma inline_routines(NINT, NLONG, DSQR, FSQR, ISQR, DCUBE, FCUBE, ICUBE, DPOW4, FPOW4, IPOW4)
#pragma inline_routines(DMAX, FMAX, IMAX, DMIN, FMIN, IMIN, MOD2PI, MOD360, S_GEOC, S_GEOG)
#endif
/* ==================================================================== */
typedef struct orbit_s
{
/* Add the epoch time if required. */
int ep_year;/* Year of epoch, e.g. 94 for 1994, 100 for 2000AD */
double ep_day; /* Day of epoch from 00:00 Jan 1st ( = 1.0 ) */
double rev; /* Mean motion, revolutions per day */
double bstar; /* Drag term .*/
double eqinc; /* Equatorial inclination, radians */
double ecc; /* Eccentricity */
double mnan; /* Mean anomaly at epoch from elements, radians */
double argp; /* Argument of perigee, radians */
double ascn; /* Right ascension (ascending node), radians */
double smjaxs; /* Semi-major axis, km */
double ndot2,nddot6; /* Mean motion derivatives */
char desig[10]; /* International designation */
long norb; /* Orbit number, for elements */
int satno; /* Satellite number. */
} orbit_t;
typedef struct xyz_s
{
double x;
double y;
double z;
} xyz_t;
typedef struct kep_s
{
double theta; /* Angle "theta" from equatorial plane (rad) = U. */
double ascn; /* Right ascension (rad). */
double eqinc; /* Equatorial inclination (rad). */
double radius; /* Radius (km). */
double rdotk;
double rfdotk;
/*
* Following are without short-term perturbations but used to
* speed searchs.
*/
double argp; /* Argument of perigee at 'tsince' (rad). */
double smjaxs; /* Semi-major axis at 'tsince' (km). */
double ecc; /* Eccentricity at 'tsince'. */
} kep_t;
/* ================ Single or Double precision options. ================= */
#define DEFAULT_TO_SNGL 0
#if defined( SGDP4_SNGL ) || (DEFAULT_TO_SNGL && !defined( SGDP4_DBLE ))
/* Single precision option. */
typedef float real;
#ifndef SGDP4_SNGL
#define SGDP4_SNGL
#endif
#else
/* Double precision option. */
typedef double real;
#ifndef SGDP4_DBLE
#define SGDP4_DBLE
#endif
#endif /* Single or double choice. */
/* Something silly ? */
#if defined( SGDP4_SNGL ) && defined( SGDP4_DBLE )
#error sgdp4h.h - Cannot have both single and double precision defined
#endif
/* =========== Do we have sincos() functions available or not ? ======= */
/*
We can use the normal ANSI 'C' library functions in sincos() macros, but if
we have sincos() functions they are much faster (25% under some tests). For
DOS programs we use our assembly language functions using the 80387 (and
higher) coprocessor FSINCOS instruction:
void sincos(double x, double *s, double *c);
void sincosf(float x, float *s, float *c);
For the Sun 'C' compiler there is only the system supplied double precision
version of these functions.
*/
#ifdef MACRO_SINCOS
#define sincos(x,s,c) {double sc__tmp=(x);\
*(s)=sin(sc__tmp);\
*(c)=cos(sc__tmp);}
#define SINCOS(x,s,c) {double sc__tmp=(double)(x);\
*(s)=(real)sin(sc__tmp);\
*(c)=(real)cos(sc__tmp);}
#elif !defined( sun )
/* For Microsoft C6.0 compiler, etc. */
#ifdef SGDP4_SNGL
#define SINCOS sincosf
#else
#define SINCOS sincos
#endif /* ! SGDP4_SNGL */
void sincos(double, double *, double *);
void sincosf(float, float *, float *);
#else
/* Sun 'C' compiler. */
#ifdef SGDP4_SNGL
/* Use double function and cast results to single precision. */
#define SINCOS(x,s,c) {double s__tmp, c__tmp;\
sincos((double)(x), &s__tmp, &c__tmp);\
*(s)=(real)s__tmp;\
*(c)=(real)c__tmp);}
#else
#define SINCOS sincos
#endif /* ! SGDP4_SNGL */
#endif /* ! MACRO_SINCOS */
/* ================= Stack space problems ? ======================== */
#if !defined( MSDOS )
/* Automatic variables, faster (?) but needs more stack space. */
#define LOCAL_REAL real
#define LOCAL_DOUBLE double
#else
/* Static variables, slower (?) but little stack space. */
#define LOCAL_REAL static real
#define LOCAL_DOUBLE static double
#endif
/* ======== Macro fixes for float/double in math.h type functions. ===== */
#define SIN(x) (real)sin((double)(x))
#define COS(x) (real)cos((double)(x))
#define SQRT(x) (real)sqrt((double)(x))
#define FABS(x) (real)fabs((double)(x))
#define POW(x,y) (real)pow((double)(x), (double)(y))
#define FMOD(x,y) (real)fmod((double)(x), (double)(y))
#define ATAN2(x,y) (real)atan2((double)(x), (double)(y))
#ifdef SGDP4_SNGL
#define CUBE FCUBE
#define POW4 FPOW4
#else
#define CUBE DCUBE
#define POW4 DPOW4
#endif
/* SGDP4 function return values. */
#define SGDP4_ERROR (-1)
#define SGDP4_NOT_INIT 0
#define SGDP4_ZERO_ECC 1
#define SGDP4_NEAR_SIMP 2
#define SGDP4_NEAR_NORM 3
#define SGDP4_DEEP_NORM 4
#define SGDP4_DEEP_RESN 5
#define SGDP4_DEEP_SYNC 6
#include "satutl.h"
/* ======================= Function prototypes ====================== */
#ifdef __cplusplus
extern "C" {
#endif
/** deep.c **/
int SGDP4_dpinit(double epoch, real omegao, real xnodeo, real xmo,
real orb_eo, real orb_xincl, real aodp, double xmdot,
real omgdot, real xnodot, double xnodp);
int SGDP4_dpsec(double *xll, real *omgasm, real *xnodes, real *em,
real *xinc, double *xn, double tsince);
int SGDP4_dpper(real *em, real *xinc, real *omgasm, real *xnodes,
double *xll, double tsince);
/** sgdp4.c **/
int init_sgdp4(orbit_t *orb);
int sgdp4(double tsince, int withvel, kep_t *kep);
void kep2xyz(kep_t *K, xyz_t *pos, xyz_t *vel);
int satpos_xyz(double jd, xyz_t *pos, xyz_t *vel);
#ifdef __cplusplus
}
#endif
#endif /* !_SGDP4H_H */