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