satellite-sgp4io.cc
Go to the documentation of this file.
1 /* ----------------------------------------------------------------
2  *
3  * sgp4io.h;
4  *
5  * this file contains a function to read two line element sets. while
6  * not formerly part of the sgp4 mathematical theory, it is
7  * required for practical implemenation.
8  *
9  * companion code for
10  * fundamentals of astrodynamics and applications
11  * 2007
12  * by david vallado
13  *
14  * (w) 719-573-2600, email dvallado@agi.com
15  *
16  * current :
17  * 3 sep 07 david vallado
18  * add operationmode for afspc (a) or improved (i)
19  * changes :
20  * 20 apr 07 david vallado
21  * misc updates for manual operation
22  * 14 aug 06 david vallado
23  * original baseline
24  *
25  * code from https://gitlab.inesctec.pt/pmms/ns3-satellite
26  * ---------------------------------------------------------------- */
27 
28 #include "satellite-sgp4io.h"
29 
30 #include <stdint.h>
31 
32 /* -----------------------------------------------------------------------------
33  *
34  * function twoline2rv
35  *
36  * this function converts the two line element set character string data to
37  * variables and initializes the sgp4 variables. several intermediate varaibles
38  * and quantities are determined. note that the result is a structure so multiple
39  * satellites can be processed simultaneously without having to reinitialize. the
40  * verification mode is an important option that permits quick checks of any
41  * changes to the underlying technical theory. this option works using a
42  * modified tle file in which the start, stop, and delta time values are
43  * included at the end of the second line of data. this only works with the
44  * verification mode. the catalog mode simply propagates from -1440 to 1440 min
45  * from epoch and is useful when performing entire catalog runs.
46  *
47  * author : david vallado 719-573-2600 1 mar 2001
48  *
49  * inputs :
50  * longstr1 - first line of the tle
51  * longstr2 - second line of the tle
52  * typerun - type of run verification 'v', catalog 'c',
53  * manual 'm'
54  * typeinput - type of manual input mfe 'm', epoch 'e', dayofyr 'd'
55  * opsmode - mode of operation afspc or improved 'a', 'i'
56  * whichconst - which set of constants to use 72, 84
57  *
58  * outputs :
59  * satrec - structure containing all the sgp4 satellite information
60  *
61  * coupling :
62  * getgravconst-
63  * days2mdhms - conversion of days to month, day, hour, minute, second
64  * jday - convert day month year hour minute second into julian date
65  * sgp4init - initialize the sgp4 variables
66  *
67  * references :
68  * norad spacetrack report #3
69  * vallado, crawford, hujsak, kelso 2006
70  * --------------------------------------------------------------------------- */
71 
72 void
73 twoline2rv(char longstr1[130],
74  char longstr2[130],
75  char typerun,
76  char typeinput,
77  char opsmode,
78  gravconsttype whichconst,
79  double& startmfe,
80  double& stopmfe,
81  double& deltamin,
82  elsetrec& satrec)
83 {
84  const double deg2rad = pi / 180.0; // 0.0174532925199433
85  const double xpdotp = 1440.0 / (2.0 * pi); // 229.1831180523293
86 
87  double sec, mu, radiusearthkm, tumin, xke, j2, j3, j4, j3oj2;
88  double startsec, stopsec, startdayofyr, stopdayofyr, jdstart, jdstop;
89  int startyear, stopyear, startmon, stopmon, startday, stopday, starthr, stophr, startmin,
90  stopmin;
91  int cardnumb, numb, j;
92  long revnum = 0, elnum = 0;
93  char classification, intldesg[11];
94  int year = 0;
95  int mon, day, hr, minute, nexp, ibexp;
96  int silence;
97 
98  getgravconst(whichconst, tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2);
99 
100  satrec.error = 0;
101 
102  // set the implied decimal points since doing a formated read
103  // fixes for bad input data values (missing, ...)
104  for (j = 10; j <= 15; j++)
105  if (longstr1[j] == ' ')
106  longstr1[j] = '_';
107 
108  if (longstr1[44] != ' ')
109  longstr1[43] = longstr1[44];
110  longstr1[44] = '.';
111  if (longstr1[7] == ' ')
112  longstr1[7] = 'U';
113  if (longstr1[9] == ' ')
114  longstr1[9] = '.';
115  for (j = 45; j <= 49; j++)
116  if (longstr1[j] == ' ')
117  longstr1[j] = '0';
118  if (longstr1[51] == ' ')
119  longstr1[51] = '0';
120  if (longstr1[53] != ' ')
121  longstr1[52] = longstr1[53];
122  longstr1[53] = '.';
123  longstr2[25] = '.';
124  for (j = 26; j <= 32; j++)
125  if (longstr2[j] == ' ')
126  longstr2[j] = '0';
127  if (longstr1[62] == ' ')
128  longstr1[62] = '0';
129  if (longstr1[68] == ' ')
130  longstr1[68] = '0';
131 
132  sscanf(longstr1,
133  "%2d %5ld %1c %10s %2d %12lf %11lf %7lf %2d %7lf %2d %2d %6ld ",
134  &cardnumb,
135  &satrec.satnum,
136  &classification,
137  intldesg,
138  &satrec.epochyr,
139  &satrec.epochdays,
140  &satrec.ndot,
141  &satrec.nddot,
142  &nexp,
143  &satrec.bstar,
144  &ibexp,
145  &numb,
146  &elnum);
147 
148  if (typerun == 'v') // run for specified times from the file
149  {
150  if (longstr2[52] == ' ')
151  sscanf(longstr2,
152  "%2d %5ld %9lf %9lf %8lf %9lf %9lf %10lf %6ld %lf %lf %lf \n",
153  &cardnumb,
154  &satrec.satnum,
155  &satrec.inclo,
156  &satrec.nodeo,
157  &satrec.ecco,
158  &satrec.argpo,
159  &satrec.mo,
160  &satrec.no,
161  &revnum,
162  &startmfe,
163  &stopmfe,
164  &deltamin);
165  else
166  sscanf(longstr2,
167  "%2d %5ld %9lf %9lf %8lf %9lf %9lf %11lf %6ld %lf %lf %lf \n",
168  &cardnumb,
169  &satrec.satnum,
170  &satrec.inclo,
171  &satrec.nodeo,
172  &satrec.ecco,
173  &satrec.argpo,
174  &satrec.mo,
175  &satrec.no,
176  &revnum,
177  &startmfe,
178  &stopmfe,
179  &deltamin);
180  }
181  else // simply run -1 day to +1 day or user input times
182  {
183  if (longstr2[52] == ' ')
184  sscanf(longstr2,
185  "%2d %5ld %9lf %9lf %8lf %9lf %9lf %10lf %6ld \n",
186  &cardnumb,
187  &satrec.satnum,
188  &satrec.inclo,
189  &satrec.nodeo,
190  &satrec.ecco,
191  &satrec.argpo,
192  &satrec.mo,
193  &satrec.no,
194  &revnum);
195  else
196  sscanf(longstr2,
197  "%2d %5ld %9lf %9lf %8lf %9lf %9lf %11lf %6ld \n",
198  &cardnumb,
199  &satrec.satnum,
200  &satrec.inclo,
201  &satrec.nodeo,
202  &satrec.ecco,
203  &satrec.argpo,
204  &satrec.mo,
205  &satrec.no,
206  &revnum);
207  }
208 
209  // ---- find no, ndot, nddot ----
210  satrec.no = satrec.no / xpdotp; //* rad/min
211  satrec.nddot = satrec.nddot * pow(10.0, nexp);
212  satrec.bstar = satrec.bstar * pow(10.0, ibexp);
213 
214  // ---- convert to sgp4 units ----
215  satrec.a = pow(satrec.no * tumin, (-2.0 / 3.0));
216  satrec.ndot = satrec.ndot / (xpdotp * 1440.0); //* ? * minperday
217  satrec.nddot = satrec.nddot / (xpdotp * 1440.0 * 1440);
218 
219  // ---- find standard orbital elements ----
220  satrec.inclo = satrec.inclo * deg2rad;
221  satrec.nodeo = satrec.nodeo * deg2rad;
222  satrec.argpo = satrec.argpo * deg2rad;
223  satrec.mo = satrec.mo * deg2rad;
224 
225  satrec.alta = satrec.a * (1.0 + satrec.ecco) - 1.0;
226  satrec.altp = satrec.a * (1.0 - satrec.ecco) - 1.0;
227 
228  // ----------------------------------------------------------------
229  // find sgp4epoch time of element set
230  // remember that sgp4 uses units of days from 0 jan 1950 (sgp4epoch)
231  // and minutes from the epoch (time)
232  // ----------------------------------------------------------------
233 
234  // ---------------- temp fix for years from 1957-2056 -------------------
235  // --------- correct fix will occur when year is 4-digit in tle ---------
236  if (satrec.epochyr < 57)
237  year = satrec.epochyr + 2000;
238  else
239  year = satrec.epochyr + 1900;
240 
241  days2mdhms(year, satrec.epochdays, mon, day, hr, minute, sec);
242  jday(year, mon, day, hr, minute, sec, satrec.jdsatepoch);
243 
244  // ---- input start stop times manually
245  if ((typerun != 'v') && (typerun != 'c'))
246  {
247  // ------------- enter start/stop ymd hms values --------------------
248  if (typeinput == 'e')
249  {
250  printf("input start prop year mon day hr min sec \n");
251  // make sure there is no space at the end of the format specifiers in silence = scanf!
252  silence = scanf("%i %i %i %i %i %lf",
253  &startyear,
254  &startmon,
255  &startday,
256  &starthr,
257  &startmin,
258  &startsec);
259  fflush(stdin);
260  jday(startyear, startmon, startday, starthr, startmin, startsec, jdstart);
261 
262  printf("input stop prop year mon day hr min sec \n");
263  silence = scanf("%i %i %i %i %i %lf",
264  &stopyear,
265  &stopmon,
266  &stopday,
267  &stophr,
268  &stopmin,
269  &stopsec);
270  fflush(stdin);
271  jday(stopyear, stopmon, stopday, stophr, stopmin, stopsec, jdstop);
272 
273  startmfe = (jdstart - satrec.jdsatepoch) * 1440.0;
274  stopmfe = (jdstop - satrec.jdsatepoch) * 1440.0;
275 
276  printf("input time step in minutes \n");
277  silence = scanf("%lf", &deltamin);
278  }
279  // -------- enter start/stop year and days of year values -----------
280  if (typeinput == 'd')
281  {
282  printf("input start year dayofyr \n");
283  silence = scanf("%i %lf", &startyear, &startdayofyr);
284  printf("input stop year dayofyr \n");
285  silence = scanf("%i %lf", &stopyear, &stopdayofyr);
286 
287  days2mdhms(startyear, startdayofyr, mon, day, hr, minute, sec);
288  jday(startyear, mon, day, hr, minute, sec, jdstart);
289  days2mdhms(stopyear, stopdayofyr, mon, day, hr, minute, sec);
290  jday(stopyear, mon, day, hr, minute, sec, jdstop);
291 
292  startmfe = (jdstart - satrec.jdsatepoch) * 1440.0;
293  stopmfe = (jdstop - satrec.jdsatepoch) * 1440.0;
294 
295  printf("input time step in minutes \n");
296  silence = scanf("%lf", &deltamin);
297  }
298  // ------------------ enter start/stop mfe values -------------------
299  if (typeinput == 'm')
300  {
301  printf("input start min from epoch \n");
302  silence = scanf("%lf", &startmfe);
303  printf("input stop min from epoch \n");
304  silence = scanf("%lf", &stopmfe);
305  printf("input time step in minutes \n");
306  silence = scanf("%lf", &deltamin);
307  }
308  }
309 
310  // ------------ perform complete catalog evaluation, -+ 1 day -----------
311  if (typerun == 'c')
312  {
313  startmfe = -1440.0;
314  stopmfe = 1440.0;
315  deltamin = 10.0;
316  }
317 
318  // the compiler will only stop complaining if the variable is used
319  silence += 1;
320 
321  // ---------------- initialize the orbit at sgp4epoch -------------------
322  sgp4init(whichconst,
323  opsmode,
324  satrec.satnum,
325  satrec.jdsatepoch - 2433281.5,
326  satrec.bstar,
327  satrec.ecco,
328  satrec.argpo,
329  satrec.inclo,
330  satrec.mo,
331  satrec.no,
332  satrec.nodeo,
333  satrec);
334 } // end twoline2rv
void days2mdhms(int year, double days, int &mon, int &day, int &hr, int &minute, double &sec)
void jday(int year, int mon, int day, int hr, int minute, double sec, double &jd)
void twoline2rv(char longstr1[130], char longstr2[130], char typerun, char typeinput, char opsmode, gravconsttype whichconst, double &startmfe, double &stopmfe, double &deltamin, elsetrec &satrec)
void getgravconst(gravconsttype whichconst, double &tumin, double &mu, double &radiusearthkm, double &xke, double &j2, double &j3, double &j4, double &j3oj2)
bool sgp4init(gravconsttype whichconst, char opsmode, const long int satn, const double epoch, const double xbstar, const double xecco, const double xargpo, const double xinclo, const double xmo, const double xno, const double xnodeo, elsetrec &satrec)
#define pi
gravconsttype
double jdsatepoch
double epochdays
long int satnum