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

Dependencies:   mbed

Committer:
AjK
Date:
Mon Oct 11 10:34:55 2010 +0000
Revision:
0:0a841b89d614
Totally Alpha quality as this project isn\t completed. Just publishing it as it answers many questions asked in the forums

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AjK 0:0a841b89d614 1 /* Unit SGP_In */
AjK 0:0a841b89d614 2 /* Author: Dr TS Kelso */
AjK 0:0a841b89d614 3 /* Original Version: 1992 Jun 25 */
AjK 0:0a841b89d614 4 /* Current Revision: 1999 Nov 27 */
AjK 0:0a841b89d614 5 /* Version: 2.10 */
AjK 0:0a841b89d614 6 /* Copyright: 1992-1999, All Rights Reserved */
AjK 0:0a841b89d614 7
AjK 0:0a841b89d614 8 /* Ported to C by N. Kyriazis April 6 2001 */
AjK 0:0a841b89d614 9
AjK 0:0a841b89d614 10 #include "sgp4sdp4.h"
AjK 0:0a841b89d614 11
AjK 0:0a841b89d614 12 /* Calculates the checksum mod 10 of a line from a TLE set and */
AjK 0:0a841b89d614 13 /* returns 1 if it compares with checksum in column 68, else 0.*/
AjK 0:0a841b89d614 14 /* tle_set is a character string holding the two lines read */
AjK 0:0a841b89d614 15 /* from a text file containing NASA format Keplerian elements. */
AjK 0:0a841b89d614 16 int
AjK 0:0a841b89d614 17 Checksum_Good( char *tle_set )
AjK 0:0a841b89d614 18 {
AjK 0:0a841b89d614 19 int i, check_digit, value, checksum = 0;
AjK 0:0a841b89d614 20
AjK 0:0a841b89d614 21 for(i = 0; i < 68; i++)
AjK 0:0a841b89d614 22 {
AjK 0:0a841b89d614 23 if( (tle_set[i] >= '0') && (tle_set[i] <= '9') )
AjK 0:0a841b89d614 24 value = tle_set[i] - '0';
AjK 0:0a841b89d614 25 else if( tle_set[i] == '-' )
AjK 0:0a841b89d614 26 value = 1;
AjK 0:0a841b89d614 27 else
AjK 0:0a841b89d614 28 value = 0;
AjK 0:0a841b89d614 29
AjK 0:0a841b89d614 30 checksum += value;
AjK 0:0a841b89d614 31 } /* End for(i = 0; i < 68; i++) */
AjK 0:0a841b89d614 32
AjK 0:0a841b89d614 33 checksum %= 10;
AjK 0:0a841b89d614 34 check_digit = tle_set[68] - '0';
AjK 0:0a841b89d614 35
AjK 0:0a841b89d614 36 return( checksum == check_digit );
AjK 0:0a841b89d614 37 } /* Function Checksums_Good */
AjK 0:0a841b89d614 38
AjK 0:0a841b89d614 39 /*------------------------------------------------------------------*/
AjK 0:0a841b89d614 40
AjK 0:0a841b89d614 41 /* Carries out various checks on a TLE set to verify its validity */
AjK 0:0a841b89d614 42 /* tle_set is a character string holding the two lines read */
AjK 0:0a841b89d614 43 /* from a text file containing NASA format Keplerian elements. */
AjK 0:0a841b89d614 44 int
AjK 0:0a841b89d614 45 Good_Elements( char *tle_set )
AjK 0:0a841b89d614 46 {
AjK 0:0a841b89d614 47 /* Verify checksum of both lines of a TLE set */
AjK 0:0a841b89d614 48 if( !Checksum_Good(&tle_set[0]) || !Checksum_Good(&tle_set[69]) )
AjK 0:0a841b89d614 49 return (0);
AjK 0:0a841b89d614 50 /* Check the line number of each line */
AjK 0:0a841b89d614 51 if( (tle_set[0] != '1') || (tle_set[69] != '2') )
AjK 0:0a841b89d614 52 return (0);
AjK 0:0a841b89d614 53 /* Verify that Satellite Number is same in both lines */
AjK 0:0a841b89d614 54 if( strncmp( &tle_set[2], &tle_set[71], 5 ) != 0 )
AjK 0:0a841b89d614 55 return (0);
AjK 0:0a841b89d614 56 /* Check that various elements are in the right place */
AjK 0:0a841b89d614 57 if(
AjK 0:0a841b89d614 58 (tle_set[ 23] != '.') ||
AjK 0:0a841b89d614 59 (tle_set[ 34] != '.') ||
AjK 0:0a841b89d614 60 (tle_set[ 80] != '.') ||
AjK 0:0a841b89d614 61 (tle_set[ 89] != '.') ||
AjK 0:0a841b89d614 62 (tle_set[106] != '.') ||
AjK 0:0a841b89d614 63 (tle_set[115] != '.') ||
AjK 0:0a841b89d614 64 (tle_set[123] != '.') ||
AjK 0:0a841b89d614 65 (strncmp(&tle_set[61], " 0 ", 3) != 0)
AjK 0:0a841b89d614 66 )
AjK 0:0a841b89d614 67 return (0);
AjK 0:0a841b89d614 68
AjK 0:0a841b89d614 69 return(1);
AjK 0:0a841b89d614 70 } /* Function Good_Elements */
AjK 0:0a841b89d614 71
AjK 0:0a841b89d614 72 /*------------------------------------------------------------------*/
AjK 0:0a841b89d614 73
AjK 0:0a841b89d614 74 /* Converts the strings in a raw two-line element set */
AjK 0:0a841b89d614 75 /* to their intended numerical values. No processing */
AjK 0:0a841b89d614 76 /* of these values is done, e.g. from deg to rads etc. */
AjK 0:0a841b89d614 77 /* This is done in the select_ephemeris() function. */
AjK 0:0a841b89d614 78 void
AjK 0:0a841b89d614 79 Convert_Satellite_Data( char *tle_set, tle_t *tle )
AjK 0:0a841b89d614 80 {
AjK 0:0a841b89d614 81 char buff[15];
AjK 0:0a841b89d614 82
AjK 0:0a841b89d614 83 /** Decode Card 1 **/
AjK 0:0a841b89d614 84 /* Satellite's catalogue number */
AjK 0:0a841b89d614 85 strncpy( buff, &tle_set[2],5 );
AjK 0:0a841b89d614 86 buff[5] = '\0';
AjK 0:0a841b89d614 87 tle->catnr = atoi(buff);
AjK 0:0a841b89d614 88
AjK 0:0a841b89d614 89 /* International Designator for satellite */
AjK 0:0a841b89d614 90 strncpy( tle->idesg, &tle_set[9],8 );
AjK 0:0a841b89d614 91 tle->idesg[8] = '\0';
AjK 0:0a841b89d614 92
AjK 0:0a841b89d614 93 /* Satellite's epoch */
AjK 0:0a841b89d614 94 strncpy( buff, &tle_set[18],14 );
AjK 0:0a841b89d614 95 buff[14] = '\0';
AjK 0:0a841b89d614 96 tle->epoch = atof(buff);
AjK 0:0a841b89d614 97
AjK 0:0a841b89d614 98 /* Satellite's First Time Derivative */
AjK 0:0a841b89d614 99 strncpy( buff, &tle_set[33],10 );
AjK 0:0a841b89d614 100 buff[10]='\0';
AjK 0:0a841b89d614 101 tle->xndt2o = atof(buff);
AjK 0:0a841b89d614 102
AjK 0:0a841b89d614 103 /* Satellite's Second Time Derivative */
AjK 0:0a841b89d614 104 strncpy( buff, &tle_set[44],1 );
AjK 0:0a841b89d614 105 buff[1] = '.';
AjK 0:0a841b89d614 106 strncpy( &buff[2], &tle_set[45],5 );
AjK 0:0a841b89d614 107 buff[7] = 'E';
AjK 0:0a841b89d614 108 strncpy( &buff[8], &tle_set[50],2 );
AjK 0:0a841b89d614 109 buff[10]='\0';
AjK 0:0a841b89d614 110 tle->xndd6o = atof(buff);
AjK 0:0a841b89d614 111
AjK 0:0a841b89d614 112 /* Satellite's bstar drag term */
AjK 0:0a841b89d614 113 strncpy( buff, &tle_set[53],1 );
AjK 0:0a841b89d614 114 buff[1] = '.';
AjK 0:0a841b89d614 115 strncpy( &buff[2], &tle_set[54],5 );
AjK 0:0a841b89d614 116 buff[7] = 'E';
AjK 0:0a841b89d614 117 strncpy( &buff[8], &tle_set[59],2 );
AjK 0:0a841b89d614 118 buff[10]='\0';
AjK 0:0a841b89d614 119 tle->bstar = atof(buff);
AjK 0:0a841b89d614 120
AjK 0:0a841b89d614 121 /* Element Number */
AjK 0:0a841b89d614 122 strncpy( buff, &tle_set[64],4 );
AjK 0:0a841b89d614 123 buff[4]='\0';
AjK 0:0a841b89d614 124 tle->elset = atoi(buff);
AjK 0:0a841b89d614 125
AjK 0:0a841b89d614 126 /** Decode Card 2 **/
AjK 0:0a841b89d614 127 /* Satellite's Orbital Inclination (degrees) */
AjK 0:0a841b89d614 128 strncpy( buff, &tle_set[77], 8 );
AjK 0:0a841b89d614 129 buff[8]='\0';
AjK 0:0a841b89d614 130 tle->xincl = atof(buff);
AjK 0:0a841b89d614 131
AjK 0:0a841b89d614 132 /* Satellite's RAAN (degrees) */
AjK 0:0a841b89d614 133 strncpy( buff, &tle_set[86], 8 );
AjK 0:0a841b89d614 134 buff[8]='\0';
AjK 0:0a841b89d614 135 tle->xnodeo = atof(buff);
AjK 0:0a841b89d614 136
AjK 0:0a841b89d614 137 /* Satellite's Orbital Eccentricity */
AjK 0:0a841b89d614 138 buff[0] = '.';
AjK 0:0a841b89d614 139 strncpy( &buff[1], &tle_set[95], 7 );
AjK 0:0a841b89d614 140 buff[8]='\0';
AjK 0:0a841b89d614 141 tle->eo = atof(buff);
AjK 0:0a841b89d614 142
AjK 0:0a841b89d614 143 /* Satellite's Argument of Perigee (degrees) */
AjK 0:0a841b89d614 144 strncpy( buff, &tle_set[103], 8 );
AjK 0:0a841b89d614 145 buff[8]='\0';
AjK 0:0a841b89d614 146 tle->omegao = atof(buff);
AjK 0:0a841b89d614 147
AjK 0:0a841b89d614 148 /* Satellite's Mean Anomaly of Orbit (degrees) */
AjK 0:0a841b89d614 149 strncpy( buff, &tle_set[112], 8 );
AjK 0:0a841b89d614 150 buff[8]='\0';
AjK 0:0a841b89d614 151 tle->xmo = atof(buff);
AjK 0:0a841b89d614 152
AjK 0:0a841b89d614 153 /* Satellite's Mean Motion (rev/day) */
AjK 0:0a841b89d614 154 strncpy( buff, &tle_set[121], 10 );
AjK 0:0a841b89d614 155 buff[10]='\0';
AjK 0:0a841b89d614 156 tle->xno = atof(buff);
AjK 0:0a841b89d614 157
AjK 0:0a841b89d614 158 /* Satellite's Revolution number at epoch */
AjK 0:0a841b89d614 159 strncpy( buff, &tle_set[132], 5 );
AjK 0:0a841b89d614 160 buff[5]='\0';
AjK 0:0a841b89d614 161 tle->revnum = atof(buff);
AjK 0:0a841b89d614 162
AjK 0:0a841b89d614 163 } /* Procedure Convert_Satellite_Data */
AjK 0:0a841b89d614 164
AjK 0:0a841b89d614 165 /*------------------------------------------------------------------*/
AjK 0:0a841b89d614 166
AjK 0:0a841b89d614 167 int
AjK 0:0a841b89d614 168 Get_Next_Tle_Set( char line[3][80], tle_t *tle)
AjK 0:0a841b89d614 169 {
AjK 0:0a841b89d614 170 int idx, /* Index for loops and arrays */
AjK 0:0a841b89d614 171 chr; /* Used for inputting characters */
AjK 0:0a841b89d614 172
AjK 0:0a841b89d614 173 char tle_set[139]; /* Two lines of a TLE set */
AjK 0:0a841b89d614 174
AjK 0:0a841b89d614 175 /* Read the satellite's name */
AjK 0:0a841b89d614 176 for (idx = 0 ; idx < 25; idx++)
AjK 0:0a841b89d614 177 {
AjK 0:0a841b89d614 178 if( ((chr = line[0][idx]) != CR) && (chr != LF) && (chr != '\0'))
AjK 0:0a841b89d614 179 tle->sat_name[idx] = chr;
AjK 0:0a841b89d614 180 else
AjK 0:0a841b89d614 181 {
AjK 0:0a841b89d614 182 /* strip off trailing spaces */
AjK 0:0a841b89d614 183 while ((chr = line[0][--idx]) == ' ');
AjK 0:0a841b89d614 184 tle->sat_name[++idx] = '\0';
AjK 0:0a841b89d614 185 break;
AjK 0:0a841b89d614 186 }
AjK 0:0a841b89d614 187 }
AjK 0:0a841b89d614 188
AjK 0:0a841b89d614 189 /* Read in first line of TLE set */
AjK 0:0a841b89d614 190 strncpy(tle_set, line[1], 70);
AjK 0:0a841b89d614 191
AjK 0:0a841b89d614 192 /* Read in second line of TLE set and terminate string */
AjK 0:0a841b89d614 193 strncpy(&tle_set[69], line[2], 70);
AjK 0:0a841b89d614 194 tle_set[138]='\0';
AjK 0:0a841b89d614 195
AjK 0:0a841b89d614 196 /* Check TLE set and abort if not valid */
AjK 0:0a841b89d614 197 if( !Good_Elements(tle_set) )
AjK 0:0a841b89d614 198 return(-2);
AjK 0:0a841b89d614 199
AjK 0:0a841b89d614 200 /* Convert the TLE set to orbital elements */
AjK 0:0a841b89d614 201 Convert_Satellite_Data( tle_set, tle );
AjK 0:0a841b89d614 202
AjK 0:0a841b89d614 203 return(1);
AjK 0:0a841b89d614 204 }
AjK 0:0a841b89d614 205
AjK 0:0a841b89d614 206 /*------------------------------------------------------------------*/
AjK 0:0a841b89d614 207
AjK 0:0a841b89d614 208 /* Selects the apropriate ephemeris type to be used */
AjK 0:0a841b89d614 209 /* for predictions according to the data in the TLE */
AjK 0:0a841b89d614 210 /* It also processes values in the tle set so that */
AjK 0:0a841b89d614 211 /* they are apropriate for the sgp4/sdp4 routines */
AjK 0:0a841b89d614 212 void
AjK 0:0a841b89d614 213 select_ephemeris(tle_t *tle)
AjK 0:0a841b89d614 214 {
AjK 0:0a841b89d614 215 double ao,xnodp,dd1,dd2,delo,temp,a1,del1,r1;
AjK 0:0a841b89d614 216
AjK 0:0a841b89d614 217 /* Preprocess tle set */
AjK 0:0a841b89d614 218 tle->xnodeo *= de2ra;
AjK 0:0a841b89d614 219 tle-> omegao *= de2ra;
AjK 0:0a841b89d614 220 tle->xmo *= de2ra;
AjK 0:0a841b89d614 221 tle->xincl *= de2ra;
AjK 0:0a841b89d614 222 temp = twopi/xmnpda/xmnpda;
AjK 0:0a841b89d614 223 tle->xno = tle->xno*temp*xmnpda;
AjK 0:0a841b89d614 224 tle->xndt2o *= temp;
AjK 0:0a841b89d614 225 tle->xndd6o = tle->xndd6o*temp/xmnpda;
AjK 0:0a841b89d614 226 tle->bstar /= ae;
AjK 0:0a841b89d614 227
AjK 0:0a841b89d614 228 /* Period > 225 minutes is deep space */
AjK 0:0a841b89d614 229 dd1 = (xke/tle->xno);
AjK 0:0a841b89d614 230 dd2 = tothrd;
AjK 0:0a841b89d614 231 a1 = pow(dd1, dd2);
AjK 0:0a841b89d614 232 r1 = cos(tle->xincl);
AjK 0:0a841b89d614 233 dd1 = (1.0-tle->eo*tle->eo);
AjK 0:0a841b89d614 234 temp = ck2*1.5f*(r1*r1*3.0-1.0)/pow(dd1, 1.5);
AjK 0:0a841b89d614 235 del1 = temp/(a1*a1);
AjK 0:0a841b89d614 236 ao = a1*(1.0-del1*(tothrd*.5+del1*
AjK 0:0a841b89d614 237 (del1*1.654320987654321+1.0)));
AjK 0:0a841b89d614 238 delo = temp/(ao*ao);
AjK 0:0a841b89d614 239 xnodp = tle->xno/(delo+1.0);
AjK 0:0a841b89d614 240
AjK 0:0a841b89d614 241 /* Select a deep-space/near-earth ephemeris */
AjK 0:0a841b89d614 242 if (twopi/xnodp/xmnpda >= .15625)
AjK 0:0a841b89d614 243 SetFlag(DEEP_SPACE_EPHEM_FLAG);
AjK 0:0a841b89d614 244 else
AjK 0:0a841b89d614 245 ClearFlag(DEEP_SPACE_EPHEM_FLAG);
AjK 0:0a841b89d614 246
AjK 0:0a841b89d614 247 return;
AjK 0:0a841b89d614 248 } /* End of select_ephemeris() */
AjK 0:0a841b89d614 249
AjK 0:0a841b89d614 250 /*------------------------------------------------------------------*/
AjK 0:0a841b89d614 251