1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 
3 #ifndef SGP4SDP4_H
4 #define SGP4SDP4_H 1
5 
6 #include <math.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include <stdlib.h>
10 #include <time.h>
11 /* #include <unistd.h> */
12 
13 /* from David Kaelbling <drk@sgi.com> */
14 #define select duplicate_select
15 #include <unistd.h>
16 #undef select
17 
18 
19 /** Type definitions **/
20 
21 
22 typedef enum {
23 	ORBIT_TYPE_UNKNOWN = 0,
24 	ORBIT_TYPE_LEO,            /*!< Low Earth orbit, up to 1200 km. */
25 	ORBIT_TYPE_ICO,            /*!< Intermediate Circular Orbit, up to 1400 km. */
26 	ORBIT_TYPE_GEO,            /*!< Geostationary. */
27 	ORBIT_TYPE_GSO,            /*!< Geosynchronuous. */
28 	ORBIT_TYPE_MOLNIYA,
29 	ORBIT_TYPE_TUNDRA,
30 	ORBIT_TYPE_POLAR,
31 	ORBIT_TYPE_SUNSYNC,
32 	ORBIT_TYPE_DECAYED
33 } orbit_type_t;
34 
35 /** \brief Operational status of satellite. */
36 typedef enum {
37 	OP_STAT_UNKNOWN = 0,
38 	OP_STAT_OPERATIONAL,  /*!< Operational           [+] */
39 	OP_STAT_NONOP,        /*!< Nonoperational        [-] */
40 	OP_STAT_PARTIAL,      /*!< Partially operational [P] */
41 	OP_STAT_STDBY,        /*!< Backup/Standby        [B] */
42 	OP_STAT_SPARE,        /*!< Spare                 [S] */
43 	OP_STAT_EXTENDED      /*!< Extended Mission      [X] */
44 } op_stat_t;
45 
46 
47 /** \brief Two-line-element satellite orbital data.
48  *  \ingroup sgpsdpif
49  *  \bug doc incomplete.
50  */
51 typedef struct {
52     double epoch;            /*!< Epoch Time in NORAD TLE format YYDDD.FFFFFFFF */
53 	unsigned int epoch_year; /*!< Epoch: year */
54 	unsigned int epoch_day;  /*!< Epoch: day of year */
55 	double epoch_fod;        /*!< Epoch: Fraction of day. */
56 	double xndt2o;           /*!< 1. time derivative of mean motion */
57 	double xndd6o;           /*!< 2. time derivative of mean motion */
58 	double bstar;            /*!< Bstar drag coefficient. */
59 	double xincl;            /*!< Inclination */
60 	double xnodeo;           /*!< R.A.A.N. */
61 	double eo;               /*!< Eccentricity */
62 	double omegao;           /*!< argument of perigee */
63 	double xmo;              /*!< mean anomaly */
64 	double xno;              /*!< mean motion */
65 
66 	int    catnr;            /*!< Catalogue Number.  */
67 	int    elset;            /*!< Element Set number. */
68 	int    revnum;           /*!< Revolution Number at epoch. */
69 
70         char   sat_name[25];     /*!< Satellite name string. */
71 	char   idesg[9];         /*!< International Designator. */
72 	op_stat_t status;        /*!< Operational status. */
73 
74 	/* values needed for squint calculations */
75 	double xincl1;
76 	double xnodeo1;
77 	double omegao1;
78 } tle_t;
79 
80 
81 /** \brief Geodetic position data structure.
82  *  \ingroup sgpsdpif
83  *
84  * \bug It is uncertain whether the units are uniform across all functions.
85  */
86 typedef struct {
87 	double lat;    /*!< Lattitude [rad] */
88 	double lon;    /*!< Longitude [rad] */
89 	double alt;    /*!< Altitude [km]? */
90 	double theta;
91 } geodetic_t;
92 
93 /** \brief General three-dimensional vector structure.
94  *  \ingroup sgpsdpif
95  */
96 typedef struct {
97 	double x;   /*!< X component */
98 	double y;   /*!< Y component */
99 	double z;   /*!< Z component */
100 	double w;   /*!< Magnitude */
101 } vector_t;
102 
103 
104 /** \brief Bearing to satellite from observer
105  *  \ingroup sgpsdpif
106  */
107 typedef struct {
108 	double az;            /*!< Azimuth [deg] */
109 	double el;            /*!< Elevation [deg] */
110 	double range;         /*!< Range [km] */
111 	double range_rate;    /*!< Velocity [km/sec] */
112 } obs_set_t;
113 
114 typedef struct {
115 	double ra;   /*!< Right Ascension [dec] */
116 	double dec;  /*!< Declination [dec] */
117 } obs_astro_t;
118 
119 
120 /* Common arguments between deep-space functions */
121 typedef struct {
122 	/* Used by dpinit part of Deep() */
123 	double eosq,sinio,cosio,betao,aodp,theta2,sing,cosg;
124 	double betao2,xmdot,omgdot,xnodot,xnodp;
125 
126 	/* Used by dpsec and dpper parts of Deep() */
127 	double xll,omgadf,xnode,em,xinc,xn,t;
128 
129 	/* Used by thetg and Deep() */
130 	double ds50;
131 } deep_arg_t;
132 
133 /* static data for SGP4 and SDP4 */
134 typedef struct {
135 	double aodp,aycof,c1,c4,c5,cosio,d2,d3,d4,delmo,omgcof;
136 	double eta,omgdot,sinio,xnodp,sinmo,t2cof,t3cof,t4cof,t5cof;
137 	double x1mth2,x3thm1,x7thm1,xmcof,xmdot,xnodcf,xnodot,xlcof;
138 } sgpsdp_static_t;
139 
140 /* static data for DEEP */
141 typedef struct {
142 	double thgr,xnq,xqncl,omegaq,zmol,zmos,savtsn,ee2,e3,xi2;
143 	double xl2,xl3,xl4,xgh2,xgh3,xgh4,xh2,xh3,sse,ssi,ssg,xi3;
144 	double se2,si2,sl2,sgh2,sh2,se3,si3,sl3,sgh3,sh3,sl4,sgh4;
145 	double ssl,ssh,d3210,d3222,d4410,d4422,d5220,d5232,d5421;
146 	double d5433,del1,del2,del3,fasx2,fasx4,fasx6,xlamo,xfact;
147 	double xni,atime,stepp,stepn,step2,preep,pl,sghs,xli;
148 	double d2201,d2211,sghl,sh1,pinc,pe,shs,zsingl,zcosgl;
149 	double zsinhl,zcoshl,zsinil,zcosil;
150 } deep_static_t;
151 
152 /** \brief Satellite data structure
153  *  \ingroup sgpsdpif
154  *
155  */
156 typedef struct {
157         char           *name;
158         char           *nickname;
159         char           *website;
160 	tle_t           tle;     /*!< Keplerian elements */
161 	int             flags;   /*!< Flags for algo ctrl */
162 	sgpsdp_static_t sgps;
163 	deep_static_t   dps;
164 	deep_arg_t      deep_arg;
165 	vector_t        pos;       /*!< Raw position and range */
166 	vector_t        vel;       /*!< Raw velocity */
167 
168 	/*** FIXME: REMOVE */
169 	obs_set_t       bearing;   /*!< Az, El, range and vel */
170 	obs_astro_t     astro;     /*!< Ra and Decl */
171 	/*** END */
172 
173 	/* time keeping fields */
174 	double          jul_epoch;
175 	double          jul_utc;
176 	double          tsince;
177 	double          aos;         /*!< Next AOS. */
178 	double          los;         /*!< Next LOS */
179 
180 	double          az;          /*!< Azimuth [deg] */
181 	double          el;          /*!< Elevation [deg] */
182 	double          range;       /*!< Range [km] */
183 	double          range_rate;  /*!< Range Rate [km/sec] */
184 	double          ra;          /*!< Right Ascension [deg] */
185 	double          dec;         /*!< Declination [deg] */
186 	double          ssplat;      /*!< SSP latitude [deg] */
187 	double          ssplon;      /*!< SSP longitude [deg] */
188 	double          alt;         /*!< altitude [km] */
189 	double          velo;        /*!< velocity [km/s] */
190 	double          ma;          /*!< mean anomaly */
191 	double          footprint;   /*!< footprint */
192 	double          phase;       /*!< orbit phase */
193 	double          meanmo;      /*!< mean motion kept in rev/day */
194 	long   orbit;       /*!< orbit number */
195 	orbit_type_t    otype;       /*!< orbit type. */
196 } sat_t;
197 
198 
199 /** \brief Type casting macro */
200 #define SAT(sat)  ((sat_t *) sat)
201 
202 
203 /** Table of constant values **/
204 #define de2ra    1.74532925E-2   /* Degrees to Radians */
205 #define pi       3.1415926535898 /* Pi */
206 #define pio2     1.5707963267949 /* Pi/2 */
207 #define x3pio2   4.71238898      /* 3*Pi/2 */
208 #define twopi    6.2831853071796 /* 2*Pi  */
209 #define e6a      1.0E-6
210 #define tothrd   6.6666667E-1    /* 2/3 */
211 #define xj2      1.0826158E-3    /* J2 Harmonic */
212 #define xj3     -2.53881E-6      /* J3 Harmonic */
213 #define xj4     -1.65597E-6      /* J4 Harmonic */
214 #define xke      7.43669161E-2
215 #define xkmper   6.378135E3      /* Earth radius km */
216 #define xmnpda   1.44E3          /* Minutes per day */
217 #define ae       1.0
218 #define ck2      5.413079E-4
219 #define ck4      6.209887E-7
220 #define __f      3.352779E-3
221 #define ge       3.986008E5
222 #define __s__    1.012229
223 #define qoms2t   1.880279E-09
224 #define secday   8.6400E4        /* Seconds per day */
225 #define omega_E  1.0027379
226 #define omega_ER 6.3003879
227 #define zns      1.19459E-5
228 #define c1ss     2.9864797E-6
229 #define zes      1.675E-2
230 #define znl      1.5835218E-4
231 #define c1l      4.7968065E-7
232 #define zel      5.490E-2
233 #define zcosis   9.1744867E-1
234 #define zsinis   3.9785416E-1
235 #define zsings  -9.8088458E-1
236 #define zcosgs   1.945905E-1
237 #define zcoshs   1
238 #define zsinhs   0
239 #define q22      1.7891679E-6
240 #define q31      2.1460748E-6
241 #define q33      2.2123015E-7
242 #define g22      5.7686396
243 #define g32      9.5240898E-1
244 #define g44      1.8014998
245 #define g52      1.0508330
246 #define g54      4.4108898
247 #define root22   1.7891679E-6
248 #define root32   3.7393792E-7
249 #define root44   7.3636953E-9
250 #define root52   1.1428639E-7
251 #define root54   2.1765803E-9
252 #define thdt     4.3752691E-3
253 #define rho      1.5696615E-1
254 #define mfactor  7.292115E-5
255 #define __sr__   6.96000E5      /*Solar radius - kilometers (IAU 76)*/
256 #define AU       1.49597870E8   /*Astronomical unit - kilometers (IAU 76)*/
257 
258 /* Entry points of Deep()
259 FIXME: Change to enu */
260 #define dpinit   1 /* Deep-space initialization code */
261 #define dpsec    2 /* Deep-space secular code        */
262 #define dpper    3 /* Deep-space periodic code       */
263 
264 /* Carriage return and line feed */
265 #define CR  0x0A
266 #define LF  0x0D
267 
268 /* Flow control flag definitions */
269 #define ALL_FLAGS              -1
270 #define SGP_INITIALIZED_FLAG   0x000001
271 #define SGP4_INITIALIZED_FLAG  0x000002
272 #define SDP4_INITIALIZED_FLAG  0x000004
273 #define SGP8_INITIALIZED_FLAG  0x000008
274 #define SDP8_INITIALIZED_FLAG  0x000010
275 #define SIMPLE_FLAG            0x000020
276 #define DEEP_SPACE_EPHEM_FLAG  0x000040
277 #define LUNAR_TERMS_DONE_FLAG  0x000080
278 #define NEW_EPHEMERIS_FLAG     0x000100
279 #define DO_LOOP_FLAG           0x000200
280 #define RESONANCE_FLAG         0x000400
281 #define SYNCHRONOUS_FLAG       0x000800
282 #define EPOCH_RESTART_FLAG     0x001000
283 #define VISIBLE_FLAG           0x002000
284 #define SAT_ECLIPSED_FLAG      0x004000
285 
286 
287 /** Function prototypes **/
288 
289 
290 /* sgp4sdp4.c */
291 void    SGP4 (sat_t *sat, double tsince);
292 void    SDP4 (sat_t *sat, double tsince);
293 void    Deep (int ientry, sat_t *sat);
294 int     isFlagSet(int flag);
295 int     isFlagClear(int flag);
296 void    SetFlag(int flag);
297 void    ClearFlag(int flag);
298 
299 /* sgp_in.c */
300 int     Checksum_Good(char *tle_set);
301 int     Good_Elements(char *tle_set);
302 void    Convert_Satellite_Data(char *tle_set, tle_t *tle);
303 int     Get_Next_Tle_Set( char lines[3][80], tle_t *tle );
304 void    select_ephemeris(sat_t *sat);
305 
306 /* sgp_math.c */
307 int     Sign(double arg);
308 double  Sqr(double arg);
309 double  Cube(double arg);
310 double  Radians(double arg);
311 double  Degrees(double arg);
312 double  ArcSin(double arg);
313 double  ArcCos(double arg);
314 void    Magnitude(vector_t *v);
315 void    Vec_Add(vector_t *v1, vector_t *v2, vector_t *v3);
316 void    Vec_Sub(vector_t *v1, vector_t *v2, vector_t *v3);
317 void    Scalar_Multiply(double k, vector_t *v1, vector_t *v2);
318 void    Scale_Vector(double k, vector_t *v);
319 double  Dot(vector_t *v1, vector_t *v2);
320 double  Angle(vector_t *v1, vector_t *v2);
321 void    Cross(vector_t *v1, vector_t *v2, vector_t *v3);
322 void    Normalize(vector_t *v);
323 double  AcTan(double sinx, double cosx);
324 double  FMod2p(double x);
325 double  Modulus(double arg1, double arg2);
326 double  Frac(double arg);
327 int     Round(double arg);
328 double  Int(double arg);
329 void    Convert_Sat_State(vector_t *pos, vector_t *vel);
330 
331 /* sgp_obs.c */
332 void    Calculate_User_PosVel(double _time, geodetic_t *geodetic,
333                               vector_t *obs_pos, vector_t *obs_vel);
334 void    Calculate_LatLonAlt(double _time, vector_t *pos, geodetic_t *geodetic);
335 void    Calculate_Obs(double _time, vector_t *pos, vector_t *vel,
336                       geodetic_t *geodetic, obs_set_t *obs_set);
337 void    Calculate_RADec_and_Obs(double _time, vector_t *pos, vector_t *vel,
338 				geodetic_t *geodetic, obs_astro_t *obs_set);
339 
340 /* sgp_time.c */
341 double  Julian_Date_of_Epoch(double epoch);
342 double  Epoch_Time(double jd);
343 int     DOY(int yr, int mo, int dy);
344 double  Fraction_of_Day(int hr, int mi, int se);
345 void    Calendar_Date(double jd, struct tm *cdate);
346 void    Time_of_Day(double jd, struct tm *cdate);
347 double  Julian_Date(struct tm *cdate);
348 void    Date_Time(double jd, struct tm *cdate);
349 int     Check_Date(struct tm *cdate);
350 void Time_to_UTC(struct tm *cdate, struct tm *odate);
351 struct tm Time_from_UTC(struct tm *cdate);
352 double  JD_to_UTC(double jt);
353 double  JD_from_UTC(double jt);
354 double  Delta_ET(double year);
355 double  Julian_Date_of_Year(double year);
356 double  ThetaG(double epoch, deep_arg_t *deep_arg);
357 double  ThetaG_JD(double jd);
358 void    UTC_Calendar_Now(struct tm *cdate);
359 
360 /* solar.c */
361 void    Calculate_Solar_Position(double _time, vector_t *solar_vector);
362 int     Sat_Eclipsed(vector_t *pos, vector_t *sol, double *depth);
363 
364 
365 #endif
366