Loading...
Searching...
No Matches
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
72void
73twoline2rv(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 {
106 if (longstr1[j] == ' ')
107 {
108 longstr1[j] = '_';
109 }
110 }
111
112 if (longstr1[44] != ' ')
113 {
114 longstr1[43] = longstr1[44];
115 }
116 longstr1[44] = '.';
117 if (longstr1[7] == ' ')
118 {
119 longstr1[7] = 'U';
120 }
121 if (longstr1[9] == ' ')
122 {
123 longstr1[9] = '.';
124 }
125 for (j = 45; j <= 49; j++)
126 {
127 if (longstr1[j] == ' ')
128 {
129 longstr1[j] = '0';
130 }
131 }
132 if (longstr1[51] == ' ')
133 {
134 longstr1[51] = '0';
135 }
136 if (longstr1[53] != ' ')
137 {
138 longstr1[52] = longstr1[53];
139 }
140 longstr1[53] = '.';
141 longstr2[25] = '.';
142 for (j = 26; j <= 32; j++)
143 {
144 if (longstr2[j] == ' ')
145 {
146 longstr2[j] = '0';
147 }
148 }
149 if (longstr1[62] == ' ')
150 {
151 longstr1[62] = '0';
152 }
153 if (longstr1[68] == ' ')
154 {
155 longstr1[68] = '0';
156 }
157
158 sscanf(longstr1,
159 "%2d %5ld %1c %10s %2d %12lf %11lf %7lf %2d %7lf %2d %2d %6ld ",
160 &cardnumb,
161 &satrec.satnum,
162 &classification,
163 intldesg,
164 &satrec.epochyr,
165 &satrec.epochdays,
166 &satrec.ndot,
167 &satrec.nddot,
168 &nexp,
169 &satrec.bstar,
170 &ibexp,
171 &numb,
172 &elnum);
173
174 if (typerun == 'v') // run for specified times from the file
175 {
176 if (longstr2[52] == ' ')
177 {
178 sscanf(longstr2,
179 "%2d %5ld %9lf %9lf %8lf %9lf %9lf %10lf %6ld %lf %lf %lf \n",
180 &cardnumb,
181 &satrec.satnum,
182 &satrec.inclo,
183 &satrec.nodeo,
184 &satrec.ecco,
185 &satrec.argpo,
186 &satrec.mo,
187 &satrec.no,
188 &revnum,
189 &startmfe,
190 &stopmfe,
191 &deltamin);
192 }
193 else
194 {
195 sscanf(longstr2,
196 "%2d %5ld %9lf %9lf %8lf %9lf %9lf %11lf %6ld %lf %lf %lf \n",
197 &cardnumb,
198 &satrec.satnum,
199 &satrec.inclo,
200 &satrec.nodeo,
201 &satrec.ecco,
202 &satrec.argpo,
203 &satrec.mo,
204 &satrec.no,
205 &revnum,
206 &startmfe,
207 &stopmfe,
208 &deltamin);
209 }
210 }
211 else // simply run -1 day to +1 day or user input times
212 {
213 if (longstr2[52] == ' ')
214 {
215 sscanf(longstr2,
216 "%2d %5ld %9lf %9lf %8lf %9lf %9lf %10lf %6ld \n",
217 &cardnumb,
218 &satrec.satnum,
219 &satrec.inclo,
220 &satrec.nodeo,
221 &satrec.ecco,
222 &satrec.argpo,
223 &satrec.mo,
224 &satrec.no,
225 &revnum);
226 }
227 else
228 {
229 sscanf(longstr2,
230 "%2d %5ld %9lf %9lf %8lf %9lf %9lf %11lf %6ld \n",
231 &cardnumb,
232 &satrec.satnum,
233 &satrec.inclo,
234 &satrec.nodeo,
235 &satrec.ecco,
236 &satrec.argpo,
237 &satrec.mo,
238 &satrec.no,
239 &revnum);
240 }
241 }
242
243 // ---- find no, ndot, nddot ----
244 satrec.no = satrec.no / xpdotp; //* rad/min
245 satrec.nddot = satrec.nddot * pow(10.0, nexp);
246 satrec.bstar = satrec.bstar * pow(10.0, ibexp);
247
248 // ---- convert to sgp4 units ----
249 satrec.a = pow(satrec.no * tumin, (-2.0 / 3.0));
250 satrec.ndot = satrec.ndot / (xpdotp * 1440.0); //* ? * minperday
251 satrec.nddot = satrec.nddot / (xpdotp * 1440.0 * 1440);
252
253 // ---- find standard orbital elements ----
254 satrec.inclo = satrec.inclo * deg2rad;
255 satrec.nodeo = satrec.nodeo * deg2rad;
256 satrec.argpo = satrec.argpo * deg2rad;
257 satrec.mo = satrec.mo * deg2rad;
258
259 satrec.alta = satrec.a * (1.0 + satrec.ecco) - 1.0;
260 satrec.altp = satrec.a * (1.0 - satrec.ecco) - 1.0;
261
262 // ----------------------------------------------------------------
263 // find sgp4epoch time of element set
264 // remember that sgp4 uses units of days from 0 jan 1950 (sgp4epoch)
265 // and minutes from the epoch (time)
266 // ----------------------------------------------------------------
267
268 // ---------------- temp fix for years from 1957-2056 -------------------
269 // --------- correct fix will occur when year is 4-digit in tle ---------
270 if (satrec.epochyr < 57)
271 {
272 year = satrec.epochyr + 2000;
273 }
274 else
275 {
276 year = satrec.epochyr + 1900;
277 }
278
279 days2mdhms(year, satrec.epochdays, mon, day, hr, minute, sec);
280 jday(year, mon, day, hr, minute, sec, satrec.jdsatepoch);
281
282 // ---- input start stop times manually
283 if ((typerun != 'v') && (typerun != 'c'))
284 {
285 // ------------- enter start/stop ymd hms values --------------------
286 if (typeinput == 'e')
287 {
288 printf("input start prop year mon day hr min sec \n");
289 // make sure there is no space at the end of the format specifiers in silence = scanf!
290 silence = scanf("%i %i %i %i %i %lf",
291 &startyear,
292 &startmon,
293 &startday,
294 &starthr,
295 &startmin,
296 &startsec);
297 fflush(stdin);
298 jday(startyear, startmon, startday, starthr, startmin, startsec, jdstart);
299
300 printf("input stop prop year mon day hr min sec \n");
301 silence = scanf("%i %i %i %i %i %lf",
302 &stopyear,
303 &stopmon,
304 &stopday,
305 &stophr,
306 &stopmin,
307 &stopsec);
308 fflush(stdin);
309 jday(stopyear, stopmon, stopday, stophr, stopmin, stopsec, jdstop);
310
311 startmfe = (jdstart - satrec.jdsatepoch) * 1440.0;
312 stopmfe = (jdstop - satrec.jdsatepoch) * 1440.0;
313
314 printf("input time step in minutes \n");
315 silence = scanf("%lf", &deltamin);
316 }
317 // -------- enter start/stop year and days of year values -----------
318 if (typeinput == 'd')
319 {
320 printf("input start year dayofyr \n");
321 silence = scanf("%i %lf", &startyear, &startdayofyr);
322 printf("input stop year dayofyr \n");
323 silence = scanf("%i %lf", &stopyear, &stopdayofyr);
324
325 days2mdhms(startyear, startdayofyr, mon, day, hr, minute, sec);
326 jday(startyear, mon, day, hr, minute, sec, jdstart);
327 days2mdhms(stopyear, stopdayofyr, mon, day, hr, minute, sec);
328 jday(stopyear, mon, day, hr, minute, sec, jdstop);
329
330 startmfe = (jdstart - satrec.jdsatepoch) * 1440.0;
331 stopmfe = (jdstop - satrec.jdsatepoch) * 1440.0;
332
333 printf("input time step in minutes \n");
334 silence = scanf("%lf", &deltamin);
335 }
336 // ------------------ enter start/stop mfe values -------------------
337 if (typeinput == 'm')
338 {
339 printf("input start min from epoch \n");
340 silence = scanf("%lf", &startmfe);
341 printf("input stop min from epoch \n");
342 silence = scanf("%lf", &stopmfe);
343 printf("input time step in minutes \n");
344 silence = scanf("%lf", &deltamin);
345 }
346 }
347
348 // ------------ perform complete catalog evaluation, -+ 1 day -----------
349 if (typerun == 'c')
350 {
351 startmfe = -1440.0;
352 stopmfe = 1440.0;
353 deltamin = 10.0;
354 }
355
356 // the compiler will only stop complaining if the variable is used
357 silence += 1;
358
359 // ---------------- initialize the orbit at sgp4epoch -------------------
360 sgp4init(whichconst,
361 opsmode,
362 satrec.satnum,
363 satrec.jdsatepoch - 2433281.5,
364 satrec.bstar,
365 satrec.ecco,
366 satrec.argpo,
367 satrec.inclo,
368 satrec.mo,
369 satrec.no,
370 satrec.nodeo,
371 satrec);
372} // 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
long int satnum