Satellite Observers Workbench. NOT yet complete, just published for forum posters to \"cherry pick\" pieces of code as requiered as an example.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sgp_in.c Source File

sgp_in.c

00001 /* Unit SGP_In */
00002 /*           Author:  Dr TS Kelso */
00003 /* Original Version:  1992 Jun 25 */
00004 /* Current Revision:  1999 Nov 27 */
00005 /*          Version:  2.10 */
00006 /*        Copyright:  1992-1999, All Rights Reserved */
00007 
00008 /* Ported to C by N. Kyriazis  April 6  2001 */
00009 
00010 #include "sgp4sdp4.h"
00011 
00012 /* Calculates the checksum mod 10 of a line from a TLE set and */
00013 /* returns 1 if it compares with checksum in column 68, else 0.*/
00014 /* tle_set is a character string holding the two lines read    */
00015 /* from a text file containing NASA format Keplerian elements. */
00016 int
00017 Checksum_Good( char *tle_set )
00018 {
00019   int i, check_digit, value, checksum = 0;
00020 
00021   for(i = 0; i < 68; i++)
00022     {
00023       if( (tle_set[i] >= '0') && (tle_set[i] <= '9') )
00024     value = tle_set[i] - '0';
00025       else if( tle_set[i] == '-' )
00026     value = 1;
00027       else
00028     value = 0;
00029 
00030       checksum += value;
00031     } /* End for(i = 0; i < 68; i++) */
00032 
00033   checksum %= 10;
00034   check_digit = tle_set[68] - '0';
00035 
00036   return( checksum == check_digit );
00037 } /* Function Checksums_Good */
00038 
00039 /*------------------------------------------------------------------*/
00040 
00041 /* Carries out various checks on a TLE set to verify its validity */
00042 /* tle_set is a character string holding the two lines read    */
00043 /* from a text file containing NASA format Keplerian elements. */
00044 int
00045 Good_Elements( char *tle_set )
00046 {
00047   /* Verify checksum of both lines of a TLE set */
00048   if( !Checksum_Good(&tle_set[0]) || !Checksum_Good(&tle_set[69]) )
00049     return (0);
00050   /* Check the line number of each line */
00051   if( (tle_set[0] != '1') || (tle_set[69] != '2') )
00052     return (0);
00053   /* Verify that Satellite Number is same in both lines */
00054   if( strncmp( &tle_set[2], &tle_set[71], 5 ) != 0 )
00055     return (0);
00056   /* Check that various elements are in the right place */
00057   if( 
00058      (tle_set[ 23] != '.') ||
00059      (tle_set[ 34] != '.') ||
00060      (tle_set[ 80] != '.') ||
00061      (tle_set[ 89] != '.') ||
00062      (tle_set[106] != '.') ||
00063      (tle_set[115] != '.') ||
00064      (tle_set[123] != '.') ||
00065      (strncmp(&tle_set[61], " 0 ", 3) != 0)
00066      )
00067     return (0);
00068 
00069   return(1);
00070 }  /* Function Good_Elements */
00071 
00072 /*------------------------------------------------------------------*/
00073 
00074 /* Converts the strings in a raw two-line element set  */
00075 /* to their intended numerical values. No processing   */
00076 /* of these values is done, e.g. from deg to rads etc. */
00077 /* This is done in the select_ephemeris() function.    */
00078 void
00079 Convert_Satellite_Data( char *tle_set, tle_t *tle )
00080 { 
00081   char buff[15];
00082 
00083   /** Decode Card 1 **/
00084   /* Satellite's catalogue number */
00085   strncpy( buff, &tle_set[2],5 );
00086   buff[5] = '\0';
00087   tle->catnr = atoi(buff);
00088 
00089   /* International Designator for satellite */
00090   strncpy( tle->idesg, &tle_set[9],8 );
00091   tle->idesg[8] = '\0';
00092 
00093   /* Satellite's epoch */
00094   strncpy( buff, &tle_set[18],14 );
00095   buff[14] = '\0';
00096   tle->epoch = atof(buff);
00097 
00098   /* Satellite's First Time Derivative */
00099   strncpy( buff, &tle_set[33],10 );
00100   buff[10]='\0';
00101   tle->xndt2o = atof(buff);
00102 
00103   /* Satellite's Second Time Derivative */
00104   strncpy( buff, &tle_set[44],1 );
00105   buff[1] = '.';
00106   strncpy( &buff[2], &tle_set[45],5 );
00107   buff[7] = 'E';
00108   strncpy( &buff[8], &tle_set[50],2 );
00109   buff[10]='\0';
00110   tle->xndd6o = atof(buff);
00111 
00112   /* Satellite's bstar drag term */
00113   strncpy( buff, &tle_set[53],1 );
00114   buff[1] = '.';
00115   strncpy( &buff[2], &tle_set[54],5 );
00116   buff[7] = 'E';
00117   strncpy( &buff[8], &tle_set[59],2 );
00118   buff[10]='\0';
00119   tle->bstar = atof(buff);
00120 
00121   /* Element Number */
00122   strncpy( buff, &tle_set[64],4 );
00123   buff[4]='\0';
00124   tle->elset = atoi(buff);
00125 
00126   /** Decode Card 2 **/
00127   /* Satellite's Orbital Inclination (degrees) */
00128   strncpy( buff, &tle_set[77], 8 );
00129   buff[8]='\0';
00130   tle->xincl = atof(buff);
00131 
00132   /* Satellite's RAAN (degrees) */
00133   strncpy( buff, &tle_set[86], 8 );
00134   buff[8]='\0';
00135   tle->xnodeo = atof(buff);
00136 
00137   /* Satellite's Orbital Eccentricity */
00138   buff[0] = '.';
00139   strncpy( &buff[1], &tle_set[95], 7 );
00140   buff[8]='\0';
00141   tle->eo = atof(buff);
00142 
00143   /* Satellite's Argument of Perigee (degrees) */
00144   strncpy( buff, &tle_set[103], 8 );
00145   buff[8]='\0';
00146   tle->omegao = atof(buff);
00147 
00148   /* Satellite's Mean Anomaly of Orbit (degrees) */
00149   strncpy( buff, &tle_set[112], 8 );
00150   buff[8]='\0';
00151   tle->xmo = atof(buff);
00152 
00153   /* Satellite's Mean Motion (rev/day) */
00154   strncpy( buff, &tle_set[121], 10 );
00155   buff[10]='\0';
00156   tle->xno = atof(buff);
00157 
00158   /* Satellite's Revolution number at epoch */
00159   strncpy( buff, &tle_set[132], 5 );
00160   buff[5]='\0';
00161   tle->revnum = atof(buff);
00162 
00163 } /* Procedure Convert_Satellite_Data */
00164 
00165 /*------------------------------------------------------------------*/
00166 
00167 int
00168 Get_Next_Tle_Set( char line[3][80], tle_t *tle)
00169 {
00170   int idx,  /* Index for loops and arrays    */
00171       chr;  /* Used for inputting characters */
00172 
00173   char tle_set[139]; /* Two lines of a TLE set */
00174 
00175   /* Read the satellite's name */
00176   for (idx = 0 ; idx < 25; idx++)
00177   {
00178       if( ((chr = line[0][idx]) != CR) && (chr != LF) && (chr != '\0'))
00179       tle->sat_name[idx] = chr;
00180       else
00181       {
00182       /* strip off trailing spaces */
00183       while ((chr = line[0][--idx]) == ' ');
00184       tle->sat_name[++idx] = '\0';
00185         break;
00186       }
00187   }
00188 
00189   /* Read in first line of TLE set */
00190   strncpy(tle_set, line[1], 70);
00191   
00192   /* Read in second line of TLE set and terminate string */
00193   strncpy(&tle_set[69], line[2], 70);
00194   tle_set[138]='\0';
00195   
00196   /* Check TLE set and abort if not valid */
00197   if( !Good_Elements(tle_set) )
00198     return(-2);
00199 
00200   /* Convert the TLE set to orbital elements */
00201   Convert_Satellite_Data( tle_set, tle );
00202 
00203   return(1);
00204 }
00205 
00206 /*------------------------------------------------------------------*/
00207 
00208 /* Selects the apropriate ephemeris type to be used */
00209 /* for predictions according to the data in the TLE */
00210 /* It also processes values in the tle set so that  */
00211 /* they are apropriate for the sgp4/sdp4 routines   */
00212 void
00213 select_ephemeris(tle_t *tle)
00214 {
00215   double ao,xnodp,dd1,dd2,delo,temp,a1,del1,r1;
00216 
00217   /* Preprocess tle set */
00218   tle->xnodeo *= de2ra;
00219   tle-> omegao *= de2ra;
00220   tle->xmo *= de2ra;
00221   tle->xincl *= de2ra;
00222   temp = twopi/xmnpda/xmnpda;
00223   tle->xno = tle->xno*temp*xmnpda;
00224   tle->xndt2o *= temp;
00225   tle->xndd6o = tle->xndd6o*temp/xmnpda;
00226   tle->bstar /= ae;
00227 
00228   /* Period > 225 minutes is deep space */
00229   dd1 = (xke/tle->xno);
00230   dd2 = tothrd;
00231   a1 = pow(dd1, dd2);
00232   r1 = cos(tle->xincl);
00233   dd1 = (1.0-tle->eo*tle->eo);
00234   temp = ck2*1.5f*(r1*r1*3.0-1.0)/pow(dd1, 1.5);
00235   del1 = temp/(a1*a1);
00236   ao = a1*(1.0-del1*(tothrd*.5+del1*
00237              (del1*1.654320987654321+1.0)));
00238   delo = temp/(ao*ao);
00239   xnodp = tle->xno/(delo+1.0);
00240 
00241   /* Select a deep-space/near-earth ephemeris */
00242   if (twopi/xnodp/xmnpda >= .15625)
00243     SetFlag(DEEP_SPACE_EPHEM_FLAG);
00244   else
00245     ClearFlag(DEEP_SPACE_EPHEM_FLAG);
00246 
00247   return;
00248 } /* End of select_ephemeris() */
00249 
00250 /*------------------------------------------------------------------*/
00251