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