PredicThirteen::geodetic_t PredicThirteen::calc(PredicThirteen::tle_t t){ printTle(&t); DEBUG_PRINTLN("----------------------------------------"); PredicThirteen::vector_t zero_vector={0,0,0,0}; PredicThirteen::vector_t pos = zero_vector; PredicThirteen::vector_t vel = zero_vector; PredicThirteen::geodetic_t geo = {0,0,0,0}; jul_utc = daynum +723244000000LL; jul_epoch=Julian_Date_of_Epoch(t.epoch_year, t.epoch_day); printUint64("TestNum", (uint64_t) 11118562939LL); printUint64("daynum", daynum); printUint64("jul_utc",jul_utc); printUint64("jul_epoch",jul_epoch); tsince = ((jul_utc - jul_epoch)/1000000.0) * minday; select_ephemeris(&t); SGP4(tsince, &t, &pos, &vel); Convert_Sat_State(&pos, &vel); Magnitude(&vel); printVar("jul_utc", jul_utc); Calculate_LatLonAlt(jul_utc, &pos, &geo); printVector(&pos); printVector(&vel); printGeo(&geo); LAT = geo.lat; LON = geo.lon; Serial.print("LAT: "); Serial.println(LAT); Serial.print("LON: "); Serial.println(LON); return geo; }
/** \brief Copy satellite data. * \param source Pointer to the source satellite to copy data from. * \param dest Pointer to the destination satellite to copy data into. * \param qth Pointer to the observer data (needed to initialize sat) * * This function copies the satellite data from a source sat_t structure into * the destination. The function copies the tle_t data and calls gtk_sat_data_inti_sat() * function for initializing the other fields. * */ void gtk_sat_data_copy_sat (const sat_t *source, sat_t *dest, qth_t *qth) { guint i; g_return_if_fail ((source != NULL) && (dest != NULL)); dest->tle.epoch = source->tle.epoch; dest->tle.epoch_year = source->tle.epoch_year; dest->tle.epoch_day = source->tle.epoch_day; dest->tle.epoch_fod = source->tle.epoch_fod; dest->tle.xndt2o = source->tle.xndt2o; dest->tle.xndd6o = source->tle.xndd6o; dest->tle.bstar = source->tle.bstar; dest->tle.xincl = source->tle.xincl; dest->tle.xnodeo = source->tle.xnodeo; dest->tle.eo = source->tle.eo; dest->tle.omegao = source->tle.omegao; dest->tle.xmo = source->tle.xmo; dest->tle.xno = source->tle.xno; dest->tle.catnr = source->tle.catnr; dest->tle.elset = source->tle.elset; dest->tle.revnum = source->tle.revnum; dest->name = g_strdup (source->name); dest->nickname = g_strdup (source->nickname); for (i = 0; i < 9; i++) dest->tle.idesg[i] = source->tle.idesg[i]; dest->tle.status = source->tle.status; dest->tle.xincl1 = source->tle.xincl1; dest->tle.omegao1 = source->tle.omegao1; dest->otype = source->otype; /* very important */ dest->flags = 0; select_ephemeris (dest); /* initialise variable fields */ dest->jul_utc = 0.0; dest->tsince = 0.0; dest->az = 0.0; dest->el = 0.0; dest->range = 0.0; dest->range_rate = 0.0; dest->ra = 0.0; dest->dec = 0.0; dest->ssplat = 0.0; dest->ssplon = 0.0; dest->alt = 0.0; dest->velo = 0.0; dest->ma = 0.0; dest->footprint = 0.0; dest->phase = 0.0; dest->aos = 0.0; dest->los = 0.0; gtk_sat_data_init_sat (dest, qth); }
/* Main program */ int main( const int argc, const char **argv) { const char *tle_filename = ((argc == 1) ? "test.tle" : argv[1]); FILE *ifile = fopen( tle_filename, "rb"); tle_t tle; /* Pointer to two-line elements set for satellite */ char line1[100], line2[100]; int ephem = 1; /* default to SGP4 */ int i; /* Index for loops etc */ int n_failures = 0, n_simple = 0, n_simplex = 0; bool failures_only = false; for( i = 2; i < argc; i++) if( argv[i][0] == '-') switch( argv[i][1]) { case 'f': failures_only = true; break; case 'v': verbose = 1; break; case 'd': dist_offset = atof( argv[i] + 2); break; case 's': vel_offset = atof( argv[i] + 2); break; default: printf( "Option '%s' unrecognized\n", argv[i]); break; } if( !ifile) { printf( "Couldn't open input TLE file %s\n", tle_filename); exit( -1); } *line1 = '\0'; while( fgets( line2, sizeof( line2), ifile)) { int got_data = 0; double state_vect[6]; set_tle_defaults( &tle); if( strlen( line2) > 110 && line2[7] == '.' && line2[18] == '.' && line2[0] == '2' && line2[1] == '4') { got_data = 3; /* Find_Orb state vector ephemeris */ tle.epoch = atof( line2); sscanf( line2 + 13, "%lf %lf %lf %lf %lf %lf", state_vect + 0, state_vect + 1, state_vect + 2, state_vect + 3, state_vect + 4, state_vect + 5); } else if( strlen( line1) > 55 && !memcmp( line1 + 50, " (TDB)", 6)) { /* JPL Horizons vector */ const double obliq_2000 = 23.4392911 * PI / 180.; tle.epoch = atof( line1); /* get JD epoch from header... */ strcpy( line1, line2); if( fgets( line2, sizeof( line2), ifile)) got_data = 1; sscanf( line1, "%lf %lf %lf", state_vect + 0, state_vect + 1, state_vect + 2); sscanf( line2, "%lf %lf %lf", state_vect + 3, state_vect + 4, state_vect + 5); /* Cvt ecliptic to equatorial 2000: */ rotate_vector( state_vect , obliq_2000, 0); rotate_vector( state_vect + 3, obliq_2000, 0); } else if( parse_elements( line1, line2, &tle) >= 0) got_data = 2; if( got_data == 1 || got_data == 3) tle.epoch -= 68.00 / 86400.; /* rough convert TDT to UTC */ if( got_data) /* hey! we got a TLE! */ { double sat_params[N_SAT_PARAMS], trial_state[6]; int simple_rval; bool failed = false; tle_t new_tle; if( got_data == 1 || got_data == 3) { ephem = 3; /* Use SDP4 for JPL Horizons vectors */ for( i = 0; i < 6 && fabs( state_vect[i]) < 1.; i++) ; if( i == 6) /* all small quantities, must be in AU & AU/day : */ { for( i = 0; i < 6; i++) state_vect[i] *= AU_IN_KM; for( i = 3; i < 6; i++) state_vect[i] /= seconds_per_day; } for( i = 3; i < 6; i++) /* cvt km/sec to km/min */ state_vect[i] *= seconds_per_minute; if( !failures_only) show_results( "Before:", NULL, state_vect); } else { int is_deep = select_ephemeris( &tle); if( is_deep && (ephem == 1 || ephem == 2)) ephem += 2; /* switch to an SDx */ if( !is_deep && (ephem == 3 || ephem == 4)) ephem -= 2; /* switch to an SGx */ /* Calling of NORAD routines */ /* Each NORAD routine (SGP, SGP4, SGP8, SDP4, SDP8) */ /* will be called in turn with the appropriate TLE set */ switch( ephem) { case 0: SGP_init( sat_params, &tle); SGP( 0., &tle, sat_params, state_vect, state_vect + 3); break; case 1: SGP4_init( sat_params, &tle); SGP4( 0., &tle, sat_params, state_vect, state_vect + 3); break; case 2: SGP8_init( sat_params, &tle); SGP8( 0., &tle, sat_params, state_vect, state_vect + 3); break; case 3: SDP4_init( sat_params, &tle); SDP4( 0., &tle, sat_params, state_vect, state_vect + 3); break; case 4: SDP8_init( sat_params, &tle); SDP8( 0., &tle, sat_params, state_vect, state_vect + 3); break; } if( !failures_only) show_results( "Before:", &tle, state_vect); } new_tle = tle; simple_rval = compute_tle_from_state_vector( &new_tle, state_vect, ephem, trial_state); if( simple_rval) { n_simplex++; find_tle_via_simplex_method( &new_tle, state_vect, trial_state, ephem); } else n_simple++; compute_new_state_vect( &new_tle, trial_state, ephem); for( i = 0; i < 6; i++) { trial_state[i] -= state_vect[i]; if( fabs( trial_state[i]) > 1e-6) failed = true; } if( failed && failures_only) show_results( "Before:", &tle, state_vect); if( failed || !failures_only) show_results( (simple_rval ? "Simplex result:" : "Simplest method:"), &new_tle, trial_state); if( failed) n_failures++; } strcpy( line1, line2); } fclose( ifile); printf( "%d solved with simple method; %d with simplex\n", n_simple, n_simplex); if( n_failures) printf( "%d failures\n", n_failures); return(0); } /* End of main() */
/** \brief Read TLE data for a given satellite into memory. * \param catnum The catalog number of the satellite. * \param sat Pointer to a valid sat_t structure. * \return 0 if successfull, 1 if an I/O error occurred, * 2 if the TLE data appears to be bad. * */ gint gtk_sat_data_read_sat (gint catnum, sat_t *sat) { guint errorcode = 0; GError *error = NULL; GKeyFile *data; gchar *filename = NULL, *path = NULL; gchar *tlestr1,*tlestr2,*rawtle; /* ensure that sat != NULL */ g_return_val_if_fail (sat != NULL, 1); /* .sat file names */ filename = g_strdup_printf ("%d.sat", catnum); path = sat_file_name_from_catnum (catnum); /* open .sat file */ data = g_key_file_new (); if (!g_key_file_load_from_file (data, path, G_KEY_FILE_KEEP_COMMENTS, &error)) { /* an error occurred */ sat_log_log (SAT_LOG_LEVEL_ERROR, _("%s: Failed to load data from %s (%s)"), __func__, path, error->message); g_clear_error (&error); errorcode = 1; } else { /* read name, nickname, and website */ sat->name = g_key_file_get_string (data, "Satellite", "NAME", &error); if (error != NULL) { sat_log_log (SAT_LOG_LEVEL_ERROR, _("%s: Error reading NAME from %s (%s)"), __func__, path, error->message); g_clear_error (&error); sat->name = g_strdup ("Error"); } sat->nickname = g_key_file_get_string (data, "Satellite", "NICKNAME", &error); if (error != NULL) { sat_log_log (SAT_LOG_LEVEL_INFO, _("%s: Satellite %d has no NICKNAME"), __func__, catnum); g_clear_error (&error); sat->nickname = g_strdup (sat->name); } sat->website = g_key_file_get_string (data, "Satellite", "WEBSITE", NULL); /* website may be NULL */ /* get TLE data */ tlestr1 = g_key_file_get_string (data, "Satellite", "TLE1", NULL); if (error != NULL) { sat_log_log (SAT_LOG_LEVEL_ERROR, _("%s: Error reading TLE line 1 from %s (%s)"), __func__, path, error->message); g_clear_error (&error); } tlestr2 = g_key_file_get_string (data, "Satellite", "TLE2", NULL); if (error != NULL) { sat_log_log (SAT_LOG_LEVEL_ERROR, _("%s: Error reading TLE line 2 from %s (%s)"), __func__, path, error->message); g_clear_error (&error); } rawtle = g_strconcat (tlestr1, tlestr2, NULL); if (!Good_Elements (rawtle)) { sat_log_log (SAT_LOG_LEVEL_ERROR, _("%s: TLE data for %d appears to be bad"), __func__, catnum); errorcode = 2; } else { Convert_Satellite_Data (rawtle, &sat->tle); } if (g_key_file_has_key(data, "Satellite", "STATUS",NULL)) sat->tle.status = g_key_file_get_integer (data, "Satellite", "STATUS", NULL); g_free (tlestr1); g_free (tlestr2); g_free (rawtle); /* VERY, VERY important! If not done, some sats will not get initialised, the first time SGP4/SDP4 is called. Consequently, the resulting data will be NAN, INF or similar nonsense. For some reason, not even using g_new0 seems to be enough. */ sat->flags = 0; select_ephemeris (sat); /* initialise variable fields */ sat->jul_utc = 0.0; sat->tsince = 0.0; sat->az = 0.0; sat->el = 0.0; sat->range = 0.0; sat->range_rate = 0.0; sat->ra = 0.0; sat->dec = 0.0; sat->ssplat = 0.0; sat->ssplon = 0.0; sat->alt = 0.0; sat->velo = 0.0; sat->ma = 0.0; sat->footprint = 0.0; sat->phase = 0.0; sat->aos = 0.0; sat->los = 0.0; /* calculate satellite data at epoch */ gtk_sat_data_init_sat (sat, NULL); } g_free (filename); g_free (path); g_key_file_free (data); return errorcode; }
/* Main program */ int main(void) { /* TLE source file */ char tle_file[] = "./rax.txt"; /* Observer's geodetic co-ordinates. */ /* Lat North, Lon East in rads, Alt in km */ geodetic_t obs_geodetic = {0.7368, -1.4615, 0.251, 0.0}; /* Two-line Orbital Elements for the satellite */ tle_t tle ; /* Zero vector for initializations */ vector_t zero_vector = {0,0,0,0}; /* Satellite position and velocity vectors */ vector_t vel = zero_vector; vector_t pos = zero_vector; /* Satellite Az, El, Range, Range rate */ vector_t obs_set; /* Solar ECI position vector */ vector_t solar_vector = zero_vector; /* Solar observed azi and ele vector */ vector_t solar_set; /* Calendar date and time (UTC) */ struct tm utc; /* Satellite's predicted geodetic position */ geodetic_t sat_geodetic; double tsince, /* Time since epoch (in minutes) */ jul_epoch, /* Julian date of epoch */ jul_utc, /* Julian UTC date */ eclipse_depth = 0, /* Depth of satellite eclipse */ /* Satellite's observed position, range, range rate */ sat_azi, sat_ele, sat_range, sat_range_rate, /* Satellites geodetic position and velocity */ sat_lat, sat_lon, sat_alt, sat_vel, /* Solar azimuth and elevation */ sun_azi, sun_ele; /* Used for storing function return codes */ int flg; char ephem[5], /* Ephemeris in use string */ sat_status[12]; /* Satellite eclipse status */ /* Input one (first!) TLE set from file */ flg = Input_Tle_Set(tle_file, &tle); /* Abort if file open fails */ if( flg == -1 ) { printf(" File open failed - Exiting!\n"); exit(-1); } /* Print satellite name and TLE read status */ printf(" %s: ", tle.sat_name); if( flg == -2 ) { printf("TLE set bad - Exiting!\n"); exit(-2); } else printf("TLE set good - Happy Tracking!\n"); /* Printout of tle set data for tests if needed */ /* printf("\n %s %s %i %i %i\n" " %14f %10f %8f %8f\n" " %8f %8f %9f %8f %8f %12f\n", tle.sat_name, tle.idesg, tle.catnr, tle.elset, tle.revnum, tle.epoch, tle.xndt2o, tle.xndd6o, tle.bstar, tle.xincl, tle.xnodeo, tle.eo, tle.omegao, tle.xmo, tle.xno); */ /** !Clear all flags! **/ /* Before calling a different ephemeris */ /* or changing the TLE set, flow control */ /* flags must be cleared in main(). */ ClearFlag(ALL_FLAGS); /** Select ephemeris type **/ /* Will set or clear the DEEP_SPACE_EPHEM_FLAG */ /* depending on the TLE parameters of the satellite. */ /* It will also pre-process tle members for the */ /* ephemeris functions SGP4 or SDP4 so this function */ /* must be called each time a new tle set is used */ select_ephemeris(&tle); do /* Loop */ { /* Get UTC calendar and convert to Julian */ UTC_Calendar_Now(&utc); jul_utc = Julian_Date(&utc); /* Convert satellite's epoch time to Julian */ /* and calculate time since epoch in minutes */ jul_epoch = Julian_Date_of_Epoch(tle.epoch); tsince = (jul_utc - jul_epoch) * xmnpda; /* Copy the ephemeris type in use to ephem string */ if( isFlagSet(DEEP_SPACE_EPHEM_FLAG) ) strcpy(ephem,"SDP4"); else strcpy(ephem,"SGP4"); /* Call NORAD routines according to deep-space flag */ if( isFlagSet(DEEP_SPACE_EPHEM_FLAG) ) SDP4(tsince, &tle, &pos, &vel); else SGP4(tsince, &tle, &pos, &vel); /* Scale position and velocity vectors to km and km/sec */ Convert_Sat_State( &pos, &vel ); /* Calculate velocity of satellite */ Magnitude( &vel ); sat_vel = vel.w; /** All angles in rads. Distance in km. Velocity in km/s **/ /* Calculate satellite Azi, Ele, Range and Range-rate */ Calculate_Obs(jul_utc, &pos, &vel, &obs_geodetic, &obs_set); /* Calculate satellite Lat North, Lon East and Alt. */ Calculate_LatLonAlt(jul_utc, &pos, &sat_geodetic); /* Calculate solar position and satellite eclipse depth */ /* Also set or clear the satellite eclipsed flag accordingly */ Calculate_Solar_Position(jul_utc, &solar_vector); Calculate_Obs(jul_utc,&solar_vector,&zero_vector,&obs_geodetic,&solar_set); if( Sat_Eclipsed(&pos, &solar_vector, &eclipse_depth) ) SetFlag( SAT_ECLIPSED_FLAG ); else ClearFlag( SAT_ECLIPSED_FLAG ); /* Copy a satellite eclipse status string in sat_status */ if( isFlagSet( SAT_ECLIPSED_FLAG ) ) strcpy( sat_status, "Eclipsed" ); else strcpy( sat_status, "In Sunlight" ); /* Convert and print satellite and solar data */ sat_azi = Degrees(obs_set.x); sat_ele = Degrees(obs_set.y); sat_range = obs_set.z; sat_range_rate = obs_set.w; sat_lat = Degrees(sat_geodetic.lat); sat_lon = Degrees(sat_geodetic.lon); sat_alt = sat_geodetic.alt; sun_azi = Degrees(solar_set.x); sun_ele = Degrees(solar_set.y); printf("\n Date: %02d/%02d/%04d UTC: %02d:%02d:%02d Ephemeris: %s" "\n Azi=%6.1f Ele=%6.1f Range=%8.1f Range Rate=%6.2f" "\n Lat=%6.1f Lon=%6.1f Alt=%8.1f Vel=%8.3f" "\n Stellite Status: %s - Depth: %2.3f" "\n Sun Azi=%6.1f Sun Ele=%6.1f\n", utc.tm_mday, utc.tm_mon, utc.tm_year, utc.tm_hour, utc.tm_min, utc.tm_sec, ephem, sat_azi, sat_ele, sat_range, sat_range_rate, sat_lat, sat_lon, sat_alt, sat_vel, sat_status, eclipse_depth, sun_azi, sun_ele); sleep(1); } /* End of do */ while( 1 ); /* This stops Compaq ccc 'unreachcode' warning! */ return(0); } /* End of main() */
int main( const int argc, const char **argv) { const char *tle_file_name = "ALL_TLE.TXT"; FILE *ifile = fopen( argv[1], "rb"), *tle_file; FILE *stations; char line1[100], line2[100], buff[90]; double search_radius = .2; /* default to .2-degree search */ double lon = 0., rho_sin_phi = 0., rho_cos_phi = 0.; char curr_mpc_code[4]; int i, debug_level = 0, show_non_mpc_report_lines = 0; char prev_obj[20]; double prev_jd = 0., prev_ra = 0., prev_dec = 0.; if( argc == 1) error_exit( -2); if( !ifile) { printf( "Couldn't open input file %s\n", argv[1]); exit( -1); } stations = fopen( "ObsCodes.html", "rb"); if( !stations) /* perhaps stored with truncated extension? */ stations = fopen( "ObsCodes.htm", "rb"); if( !stations) /* Or as a text file? */ stations = fopen( "stations.txt", "rb"); if( !stations) { printf( "Failed to find MPC station list 'ObsCodes.html'\n"); printf( "This can be downloaded at:\n\n"); printf( "http://www.minorplanetcenter.org/iau/lists/ObsCodes.html\n"); exit( -1); } curr_mpc_code[0] = curr_mpc_code[3] = '\0'; for( i = 1; i < argc; i++) if( argv[i][0] == '-') switch( argv[i][1]) { case 'r': search_radius = atof( argv[i] + 2); break; case 't': tle_file_name = argv[i] + 2; break; break; case 'd': debug_level = atoi( argv[i] + 2); break; case 'a': show_non_mpc_report_lines = 1; break; default: printf( "Unrecognized command-line option '%s'\n", argv[i]); exit( -2); break; } tle_file = fopen( tle_file_name, "rb"); if( !tle_file) { printf( "Couldn't open TLE file %s\n", tle_file_name); exit( -1); } *prev_obj = '\0'; while( fgets( buff, sizeof( buff), ifile)) { double target_ra, target_dec, jd; if( !get_mpc_data( buff, &jd, &target_ra, &target_dec)) { char preceding_line[80], line0[100]; double observer_loc[3], observer_loc2[3]; printf( "\n%s", buff); if( !memcmp( prev_obj, buff, 12) && fabs( jd - prev_jd) < .3) { double motion, posn_ang; if( !compute_motion( jd - prev_jd, (target_ra - prev_ra) * cos( (prev_dec + target_dec) / 2.), (target_dec - prev_dec), &motion, &posn_ang)) printf( " Object motion is %.3lf'/sec at PA %.1lf\n", motion, posn_ang); } memcpy( prev_obj, buff, 12); prev_ra = target_ra; prev_dec = target_dec; prev_jd = jd; if( memcmp( curr_mpc_code, buff + 77, 3)) { char tbuff[100]; int got_it = 0; memcpy( curr_mpc_code, buff + 77, 3); fseek( stations, 0L, SEEK_SET); while( !got_it && fgets( tbuff, sizeof( tbuff), stations)) got_it = !memcmp( tbuff, curr_mpc_code, 3); if( got_it) sscanf( tbuff + 3, "%lf %lf %lf", &lon, &rho_cos_phi, &rho_sin_phi); if( !got_it) printf( "FAILED to find MPC code %s\n", curr_mpc_code); } if( debug_level) printf( "lon = %.5lf rho cos phi = %.5lf rho sin phi = %.5lf\n", lon, rho_cos_phi, rho_sin_phi); observer_cartesian_coords( jd, lon * PI / 180., rho_cos_phi, rho_sin_phi, observer_loc); observer_cartesian_coords( jd + TIME_EPSILON, lon * PI / 180., rho_cos_phi, rho_sin_phi, observer_loc2); fseek( tle_file, 0L, SEEK_SET); *line0 = '\0'; if( fgets( line1, sizeof( line1), tle_file)) while( fgets( line2, sizeof( line2), tle_file)) { tle_t tle; /* Structure for two-line elements set for satellite */ if( parse_elements( line1, line2, &tle) >= 0) { /* hey! we got a TLE! */ int is_deep = select_ephemeris( &tle); double sat_params[N_SAT_PARAMS], radius, d_ra, d_dec; double ra, dec, dist_to_satellite, t_since; double pos[3]; /* Satellite position vector */ double unused_delta2; if( debug_level > 1) printf( "%s", line1); t_since = (jd - tle.epoch) * 1440.; if( is_deep) { SDP4_init( sat_params, &tle); SDP4( t_since, &tle, sat_params, pos, NULL); } else { SGP4_init( sat_params, &tle); SGP4( t_since, &tle, sat_params, pos, NULL); } if( debug_level > 1) printf( "%s", line2); if( debug_level > 2) printf( " %.5lf %.5lf %.5lf\n", pos[0], pos[1], pos[2]); get_satellite_ra_dec_delta( observer_loc, pos, &ra, &dec, &dist_to_satellite); if( debug_level > 3) printf( "RA: %.5lf dec: %.5lf\n", ra * 180. / PI, dec * 180. / PI); epoch_of_date_to_j2000( jd, &ra, &dec); d_ra = (ra - target_ra + PI * 4.); while( d_ra > PI) d_ra -= PI + PI; d_dec = dec - target_dec; radius = sqrt( d_ra * d_ra + d_dec * d_dec) * 180. / PI; if( radius < search_radius) /* good enough for us! */ { double arcmin_per_sec, posn_ang; /* Compute position one second later, so we */ /* can show speed/PA of motion: */ t_since += TIME_EPSILON * 1440.; if( is_deep) SDP4( t_since, &tle, sat_params, pos, NULL); else SGP4( t_since, &tle, sat_params, pos, NULL); get_satellite_ra_dec_delta( observer_loc2, pos, &d_ra, &d_dec, &unused_delta2); epoch_of_date_to_j2000( jd, &d_ra, &d_dec); d_ra -= ra; d_dec -= dec; while( d_ra > PI) d_ra -= PI + PI; while( d_ra < -PI) d_ra += PI + PI; /* Put RA into 0 to 2pi range: */ if( !compute_motion( TIME_EPSILON, d_ra * cos( dec), d_dec, &arcmin_per_sec, &posn_ang)) { line1[8] = line1[16] = '\0'; memcpy( line1 + 30, line1 + 11, 6); line1[11] = '\0'; printf( " %s = %s%s-%s", line1 + 2, (line1[9] >= '6' ? "19" : "20"), line1 + 9, line1 + 30); printf( " e=%.2lf; P=%.1lf min; i=%.1lf", tle.eo, 2. * PI / tle.xno, tle.xincl * 180. / PI); if( strlen( line0) < 30) /* object name given... */ printf( ": %s\n", line0); /* not all TLEs do this */ else printf( "\n"); printf( " delta=%8.1lf km; offset=%5.2lf degrees; motion %6.3lf'/sec at PA=%.1lf\n", dist_to_satellite, radius, arcmin_per_sec, posn_ang); /* "Speed" is displayed in arcminutes/second, or in degrees/minute */ } } } strcpy( preceding_line, line1); strcpy( line0, line1); strcpy( line1, line2); for( i = 0; line0[i] >= ' '; i++) ; line0[i] = '\0'; /* remove trailing CR/LF */ } } else if( show_non_mpc_report_lines) printf( "%s", buff); } fclose( tle_file); fclose( stations); fclose( ifile); return( 0); } /* End of main() */
int main( const int argc, const char **argv) { FILE *ifile = fopen( argv[1], "rb"); char line1[100], line2[100]; const char *intl_id = NULL; double step_size = .1; int i, n_steps = 100; if( !ifile) { printf( "Couldn't open input file\n"); exit( -1); } for( i = 1; i < argc; i++) if( argv[i][0] == '-') switch( argv[i][1]) { case 'i': intl_id = argv[i] + 2; break; case 'n': n_steps = atoi( argv[i] + 2); break; default: printf( "Unrecognized option '%s'\n", argv[i]); break; } *line1 = '\0'; sxpx_set_implementation_param( SXPX_DUNDEE_COMPLIANCE, 1); while( fgets( line2, sizeof( line2), ifile)) { tle_t tle; /* Pointer to two-line elements set for satellite */ int err_val; if( (!intl_id || !memcmp( intl_id, line1 + 9, 6)) && (err_val = parse_elements( line1, line2, &tle)) >= 0) { /* hey! we got a TLE! */ int is_deep = select_ephemeris( &tle); double sat_params[N_SAT_PARAMS], observer_loc[3]; if( err_val) printf( "WARNING: TLE parsing error %d\n", err_val); for( i = 0; i < 3; i++) observer_loc[i] = '\0'; if( is_deep) SDP4_init( sat_params, &tle); else SGP4_init( sat_params, &tle); for( i = 0; i < n_steps; i++) { double ra, dec, dist_to_satellite; double pos[3]; /* Satellite position vector */ double t_since = (double)( i - n_steps / 2) * step_size; double jd = tle.epoch + t_since; t_since *= 1440.; if( is_deep) err_val = SDP4( t_since, &tle, sat_params, pos, NULL); else err_val = SGP4( t_since, &tle, sat_params, pos, NULL); if( err_val) printf( "Ephemeris error %d\n", err_val); get_satellite_ra_dec_delta( observer_loc, pos, &ra, &dec, &dist_to_satellite); epoch_of_date_to_j2000( jd, &ra, &dec); printf( "%-14sC%13.5f %08.4f %+08.4f", intl_id, jd, ra * 180. / PI, dec * 180. / PI); printf( " TLEs 500\n"); } } strcpy( line1, line2); } fclose( ifile); return( 0); } /* End of main() */