File indexing completed on 2024-04-14 03:46:44
0001 /* ---------------------------------------------------------------- 0002 * 0003 * sgp4io.cpp 0004 * 0005 * this file contains a function to read two line element sets. while 0006 * not formerly part of the sgp4 mathematical theory, it is 0007 * required for practical implementation. 0008 * 0009 * companion code for 0010 * fundamentals of astrodynamics and applications 0011 * 2007 0012 * by david vallado 0013 * 0014 * (w) 719-573-2600, email dvallado@agi.com 0015 * 0016 * current : 0017 * 3 sep 08 david vallado 0018 * add operationmode for afspc (a) or improved (i) 0019 * changes : 0020 * 9 may 07 david vallado 0021 * fix year correction to 57 0022 * 27 mar 07 david vallado 0023 * misc fixes to manual inputs 0024 * 14 aug 06 david vallado 0025 * original baseline 0026 * ---------------------------------------------------------------- */ 0027 0028 #include "sgp4io.h" 0029 0030 /* ----------------------------------------------------------------------------- 0031 * 0032 * function twoline2rv 0033 * 0034 * this function converts the two line element set character string data to 0035 * variables and initializes the sgp4 variables. several intermediate varaibles 0036 * and quantities are determined. note that the result is a structure so multiple 0037 * satellites can be processed simultaneously without having to reinitialize. the 0038 * verification mode is an important option that permits quick checks of any 0039 * changes to the underlying technical theory. this option works using a 0040 * modified tle file in which the start, stop, and delta time values are 0041 * included at the end of the second line of data. this only works with the 0042 * verification mode. the catalog mode simply propagates from -1440 to 1440 min 0043 * from epoch and is useful when performing entire catalog runs. 0044 * 0045 * author : david vallado 719-573-2600 1 mar 2001 0046 * 0047 * inputs : 0048 * longstr1 - first line of the tle 0049 * longstr2 - second line of the tle 0050 * typerun - type of run verification 'v', catalog 'c', 0051 * manual 'm' 0052 * typeinput - type of manual input mfe 'm', epoch 'e', dayofyr 'd' 0053 * opsmode - mode of operation afspc or improved 'a', 'i' 0054 * whichconst - which set of constants to use 72, 84 0055 * 0056 * outputs : 0057 * satrec - structure containing all the sgp4 satellite information 0058 * 0059 * coupling : 0060 * getgravconst- 0061 * days2mdhms - conversion of days to month, day, hour, minute, second 0062 * jday - convert day month year hour minute second into julian date 0063 * sgp4init - initialize the sgp4 variables 0064 * 0065 * references : 0066 * norad spacetrack report #3 0067 * vallado, crawford, hujsak, kelso 2006 0068 --------------------------------------------------------------------------- */ 0069 0070 void twoline2rv 0071 ( 0072 char longstr1[130], char longstr2[130], 0073 char typerun, char typeinput, char opsmode, 0074 gravconsttype whichconst, 0075 double& startmfe, double& stopmfe, double& deltamin, 0076 elsetrec& satrec 0077 ) 0078 { 0079 const double deg2rad = M_PI / 180.0; // 0.0174532925199433 0080 const double xpdotp = 1440.0 / (2.0 *M_PI); // 229.1831180523293 0081 0082 double sec, mu, radiusearthkm, tumin, xke, j2, j3, j4, j3oj2; 0083 double startsec, stopsec, startdayofyr, stopdayofyr, jdstart, jdstop; 0084 int startyear, stopyear, startmon, stopmon, startday, stopday, 0085 starthr, stophr, startmin, stopmin; 0086 int cardnumb, numb, j; 0087 long revnum = 0, elnum = 0; 0088 char classification, intldesg[11]; 0089 int year = 0; 0090 int mon, day, hr, minute, nexp, ibexp; 0091 0092 getgravconst( whichconst, tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2 ); 0093 0094 satrec.error = 0; 0095 0096 // set the implied decimal points since doing a formatted read 0097 // fixes for bad input data values (missing, ...) 0098 for (j = 10; j <= 15; j++) 0099 if (longstr1[j] == ' ') 0100 longstr1[j] = '_'; 0101 0102 if (longstr1[44] != ' ') 0103 longstr1[43] = longstr1[44]; 0104 longstr1[44] = '.'; 0105 if (longstr1[7] == ' ') 0106 longstr1[7] = 'U'; 0107 if (longstr1[9] == ' ') 0108 longstr1[9] = '.'; 0109 for (j = 45; j <= 49; j++) 0110 if (longstr1[j] == ' ') 0111 longstr1[j] = '0'; 0112 if (longstr1[51] == ' ') 0113 longstr1[51] = '0'; 0114 if (longstr1[53] != ' ') 0115 longstr1[52] = longstr1[53]; 0116 longstr1[53] = '.'; 0117 longstr2[25] = '.'; 0118 for (j = 26; j <= 32; j++) 0119 if (longstr2[j] == ' ') 0120 longstr2[j] = '0'; 0121 if (longstr1[62] == ' ') 0122 longstr1[62] = '0'; 0123 if (longstr1[68] == ' ') 0124 longstr1[68] = '0'; 0125 0126 sscanf(longstr1,"%2d %5ld %1c %10s %2d %12lf %11lf %7lf %2d %7lf %2d %2d %6ld ", 0127 &cardnumb,&satrec.satnum,&classification, intldesg, &satrec.epochyr, 0128 &satrec.epochdays,&satrec.ndot, &satrec.nddot, &nexp, &satrec.bstar, 0129 &ibexp, &numb, &elnum ); 0130 0131 if (typerun == 'v') // run for specified times from the file 0132 { 0133 if (longstr2[52] == ' ') 0134 sscanf(longstr2,"%2d %5ld %9lf %9lf %8lf %9lf %9lf %10lf %6ld %lf %lf %lf \n", 0135 &cardnumb,&satrec.satnum, &satrec.inclo, 0136 &satrec.nodeo,&satrec.ecco, &satrec.argpo, &satrec.mo, &satrec.no, 0137 &revnum, &startmfe, &stopmfe, &deltamin ); 0138 else 0139 sscanf(longstr2,"%2d %5ld %9lf %9lf %8lf %9lf %9lf %11lf %6ld %lf %lf %lf \n", 0140 &cardnumb,&satrec.satnum, &satrec.inclo, 0141 &satrec.nodeo,&satrec.ecco, &satrec.argpo, &satrec.mo, &satrec.no, 0142 &revnum, &startmfe, &stopmfe, &deltamin ); 0143 } 0144 else // simply run -1 day to +1 day or user input times 0145 { 0146 if (longstr2[52] == ' ') 0147 sscanf(longstr2,"%2d %5ld %9lf %9lf %8lf %9lf %9lf %10lf %6ld \n", 0148 &cardnumb,&satrec.satnum, &satrec.inclo, 0149 &satrec.nodeo,&satrec.ecco, &satrec.argpo, &satrec.mo, &satrec.no, 0150 &revnum ); 0151 else 0152 sscanf(longstr2,"%2d %5ld %9lf %9lf %8lf %9lf %9lf %11lf %6ld \n", 0153 &cardnumb,&satrec.satnum, &satrec.inclo, 0154 &satrec.nodeo,&satrec.ecco, &satrec.argpo, &satrec.mo, &satrec.no, 0155 &revnum ); 0156 } 0157 0158 // ---- find no, ndot, nddot ---- 0159 satrec.no = satrec.no / xpdotp; //* rad/min 0160 satrec.nddot= satrec.nddot * pow(10.0, nexp); 0161 satrec.bstar= satrec.bstar * pow(10.0, ibexp); 0162 0163 // ---- convert to sgp4 units ---- 0164 satrec.a = pow( satrec.no*tumin , (-2.0/3.0) ); 0165 satrec.ndot = satrec.ndot / (xpdotp*1440.0); //* ? * minperday 0166 satrec.nddot= satrec.nddot / (xpdotp*1440.0*1440); 0167 0168 // ---- find standard orbital elements ---- 0169 satrec.inclo = satrec.inclo * deg2rad; 0170 satrec.nodeo = satrec.nodeo * deg2rad; 0171 satrec.argpo = satrec.argpo * deg2rad; 0172 satrec.mo = satrec.mo * deg2rad; 0173 0174 satrec.alta = satrec.a*(1.0 + satrec.ecco) - 1.0; 0175 satrec.altp = satrec.a*(1.0 - satrec.ecco) - 1.0; 0176 0177 // ---------------------------------------------------------------- 0178 // find sgp4epoch time of element set 0179 // remember that sgp4 uses units of days from 0 jan 1950 (sgp4epoch) 0180 // and minutes from the epoch (time) 0181 // ---------------------------------------------------------------- 0182 0183 // ---------------- temp fix for years from 1957-2056 ------------------- 0184 // --------- correct fix will occur when year is 4-digit in tle --------- 0185 if (satrec.epochyr < 57) 0186 year= satrec.epochyr + 2000; 0187 else 0188 year= satrec.epochyr + 1900; 0189 0190 days2mdhms ( year,satrec.epochdays, mon,day,hr,minute,sec ); 0191 jday( year,mon,day,hr,minute,sec, satrec.jdsatepoch ); 0192 0193 // ---- input start stop times manually 0194 if ((typerun != 'v') && (typerun != 'c')) 0195 { 0196 // ------------- enter start/stop ymd hms values -------------------- 0197 if (typeinput == 'e') 0198 { 0199 printf("input start prop year mon day hr min sec \n"); 0200 // make sure there is no space at the end of the format specifiers in scanf! 0201 scanf( "%i %i %i %i %i %lf",&startyear, &startmon, &startday, &starthr, &startmin, &startsec); 0202 fflush(stdin); 0203 jday( startyear,startmon,startday,starthr,startmin,startsec, jdstart ); 0204 0205 printf("input stop prop year mon day hr min sec \n"); 0206 scanf( "%i %i %i %i %i %lf",&stopyear, &stopmon, &stopday, &stophr, &stopmin, &stopsec); 0207 fflush(stdin); 0208 jday( stopyear,stopmon,stopday,stophr,stopmin,stopsec, jdstop ); 0209 0210 startmfe = (jdstart - satrec.jdsatepoch) * 1440.0; 0211 stopmfe = (jdstop - satrec.jdsatepoch) * 1440.0; 0212 0213 printf("input time step in minutes \n"); 0214 scanf( "%lf",&deltamin ); 0215 } 0216 // -------- enter start/stop year and days of year values ----------- 0217 if (typeinput == 'd') 0218 { 0219 printf("input start year dayofyr \n"); 0220 scanf( "%i %lf",&startyear, &startdayofyr ); 0221 printf("input stop year dayofyr \n"); 0222 scanf( "%i %lf",&stopyear, &stopdayofyr ); 0223 0224 days2mdhms ( startyear,startdayofyr, mon,day,hr,minute,sec ); 0225 jday( startyear,mon,day,hr,minute,sec, jdstart ); 0226 days2mdhms ( stopyear,stopdayofyr, mon,day,hr,minute,sec ); 0227 jday( stopyear,mon,day,hr,minute,sec, jdstop ); 0228 0229 startmfe = (jdstart - satrec.jdsatepoch) * 1440.0; 0230 stopmfe = (jdstop - satrec.jdsatepoch) * 1440.0; 0231 0232 printf("input time step in minutes \n"); 0233 scanf( "%lf",&deltamin ); 0234 } 0235 // ------------------ enter start/stop mfe values ------------------- 0236 if (typeinput == 'm') 0237 { 0238 printf("input start min from epoch \n"); 0239 scanf( "%lf",&startmfe ); 0240 printf("input stop min from epoch \n"); 0241 scanf( "%lf",&stopmfe ); 0242 printf("input time step in minutes \n"); 0243 scanf( "%lf",&deltamin ); 0244 } 0245 } 0246 0247 // ------------ perform complete catalog evaluation, -+ 1 day ----------- 0248 if (typerun == 'c') 0249 { 0250 startmfe = -1440.0; 0251 stopmfe = 1440.0; 0252 deltamin = 10.0; 0253 } 0254 0255 // ---------------- initialize the orbit at sgp4epoch ------------------- 0256 sgp4init( whichconst, opsmode, satrec.satnum, satrec.jdsatepoch-2433281.5, satrec.bstar, 0257 satrec.ecco, satrec.argpo, satrec.inclo, satrec.mo, satrec.no, 0258 satrec.nodeo, satrec); 0259 } // end twoline2rv 0260 0261