def generate_data(tle_file='./data/PROPAGATE_tle.txt', outfile='./data/PROPOGATE_tle_rvt.txt'): """Generate big text file for students to be graded on Uses a saved TLE file - get more using tle.get_tle_spacetrack(outfile, 'rv2coe') """ jd_start, _ = time.date2jd(2018, 11, 14, 0, 0, 0) jd_end, _ = time.date2jd(2018, 11, 27, 0, 0, 0) jd_step = 100 / (24 * 60) jd_span = np.arange(jd_start, jd_end, jd_step) # read the tles sats = tle.get_tle(tle_file) with open(outfile, 'w') as f: for sat in sats: sat.tle_update(jd_span) r_arr = sat.r_eci v_arr = sat.v_eci # just write the position and velocity vector to a text file for r, v in zip(r_arr[0::10], v_arr[0::10]): f.write( '{:16.6f} {:16.6f} {:16.6f} {:16.6f} {:16.6f} {:16.6f} {:16.6f}\n' .format(r[0], r[1], r[2], v[0], v[1], v[2], np.random.randint(1, 86400)))
def run_sim(): start_jd, _ = time.date2jd(2017, 10, 1, 0, 0, 0) end_jd, _ = time.date2jd(2017, 10, 2, 0, 0, 0) num_sec = (end_jd - start_jd) * 86400 num_steps = 1e4 t_step = num_sec / num_steps # time step in Julian days RelTol = 1e-6 AbsTol = 1e-6 sat = satellite.Satellite() # define the initial state as the ISS download = False if download: from spacetrack import SpaceTrackClient password = input('Enter SpaceTrack password: '******'shanks.k', password) iss_tle = st.tle_latest(norad_cat_id=[25544], format='3le', ordinal=1) with open('./data/iss.txt', 'w') as f: f.write(iss_tle) sats = tle.get_tle('./data/iss.txt') iss = sats[0] # propogate to start JD iss.tle_update(np.array([start_jd, end_jd])) # get r,v vectors initial_pos = iss.r_eci[0, :] initial_vel = iss.v_eci[0, :] initial_R = np.eye(3, 3) initial_w = np.zeros(3) initial_state = np.concatenate( (initial_pos, initial_vel, initial_R.reshape(9), initial_w)) # setup the integrator system = integrate.ode(sat.eoms_inertial_ode) system.set_integrator('lsoda', atol=AbsTol, rtol=RelTol, nsteps=num_steps) system.set_initial_value(initial_state, 0) jd_sim = np.zeros(int(num_steps + 1)) i_state = np.zeros((int(num_steps + 1), 18)) i_state[0, :] = initial_state jd_sim[0] = start_jd ii = 1 while system.successful() and system.t < (num_sec - t_step): jd_sim[ii] = (system.t + t_step) / 86400 + start_jd i_state[ii, :] = system.integrate(system.t + t_step) ii += 1 # output state and variables return jd_sim, i_state
""" import numpy as np from astro import time, tle, constants, kepler import matplotlib.pyplot as plt import pdb # open the output file ofile = open('./prob7_rv.txt', 'w') answer_file = open('./prob7_solution.txt', 'w') # get TLE epoch, _ = time.date2jd(2017, 9, 19, 19, 0, 0) sats = tle.get_tle('prob7_tle.txt') for sat in sats: # get RV vector sat.tle_update(epoch, mu=constants.earth.mu) (a, h, period, sme, fpa, r_per, r_apo, r_ijk, v_ijk, r_pqw, v_pqw, r_lvlh, v_lvlh, r, v, v_circ, v_esc, E, M, n) = kepler.elp_orbit_el(sat.coe.p, sat.coe.ecc, sat.coe.inc, sat.coe.raan, sat.coe.argp, sat.coe.nu, constants.earth.mu) ofile.write( '{:10.6f} {:10.6f} {:10.6f} {:10.6f} {:10.6f} {:10.6f}\n'.format( r_lvlh[0], r_lvlh[1], r_lvlh[2], v_lvlh[0], v_lvlh[1], v_lvlh[2])) # get orbital paramters
class TestISSUSAFA(): l0 = "0 ISS (ZARYA) " l1 = "1 25544U 98067A 06164.43693594 .00014277 00000-0 10780-3 0 6795" l2 = "2 25544 51.6455 280.1294 0004346 245.9311 226.9658 15.72751720375095" ifile = 'Predict.dat' # define site location lat = 39.006 lon = -104.883 alt = 2.184 site_location = (lat, lon, alt) start_date = (2006, 6, 19, 0, 0, 0) end_date = (2006, 6, 29, 0, 0, 0) jd_start, _ = time.date2jd(start_date[0], start_date[1], start_date[2], start_date[3], start_date[4], start_date[5]) jd_end, _ = time.date2jd(end_date[0], end_date[1], end_date[2], end_date[3], end_date[4], end_date[5]) jd_step = 2 / (24 * 60) jd_span = np.arange(jd_start, jd_end, jd_step) site = predict.build_site(jd_span, np.deg2rad(site_location[0]), np.deg2rad(site_location[1]), site_location[2]) sats = tle.get_tle(os.path.join(cwd, ifile)) sat = sats[0] sat.tle_update(jd_span) sat.visible(site) r_eci = satellite.tle_update(sat, jd_span) all_passes = satellite.visible(sat.r_eci, site, jd_span) all_passes_parallel = satellite.parallel_predict(sat, jd_span, site) # output using the two functions class_output_file = os.path.join(tempfile.gettempdir(), 'output_class.txt') fcn_output_file = os.path.join(tempfile.gettempdir(), 'output_fcn.txt') # remove if they exist if os.path.isfile(class_output_file): os.remove(class_output_file) if os.path.isfile(fcn_output_file): os.remove(fcn_output_file) satellite.output(sat, all_passes, fcn_output_file) sat.output(class_output_file) def test_validtle(self): np.testing.assert_equal(tle.validtle(self.l0, self.l1, self.l2), True) def test_line1_checksum(self): np.testing.assert_allclose(tle.checksum(self.l1), 5) def test_line2_checksum(self): np.testing.assert_allclose(tle.checksum(self.l2), 5) def test_epoch_year(self): np.testing.assert_allclose(self.sat.epoch_year, 2006) def test_epoch_day(self): np.testing.assert_allclose(self.sat.epoch_day, 164.43693594) def test_ndot2_revperdaysquared(self): np.testing.assert_allclose(self.sat.tle.ndot_over_2, 0.00014277) def test_inclination_deg(self): np.testing.assert_allclose(self.sat.tle.inc, 51.64550000) def test_raan_deg(self): np.testing.assert_allclose(self.sat.tle.raan, 280.12940000) def test_ecc_deg(self): np.testing.assert_allclose(self.sat.tle.ecc, 0.00043460) def test_argp_deg(self): np.testing.assert_allclose(self.sat.tle.argp, 245.93110000) def test_mean_anomaly_deg(self): np.testing.assert_allclose(self.sat.tle.ma, 226.9658000) def test_mean_motion_deg(self): np.testing.assert_allclose(self.sat.tle.mean_motion, 15.72751720) def test_mean_motion_rad(self): np.testing.assert_allclose(self.sat.n0, 0.00114373733) def test_ecc(self): np.testing.assert_allclose(self.sat.ecc0, 0.00043460000) def test_inc_rad(self): np.testing.assert_allclose(self.sat.inc0, 0.90138401884) def test_raan_rad(self): np.testing.assert_allclose(self.sat.raan0, 4.88918036164) def test_argp_rad(self): np.testing.assert_allclose(self.sat.argp0, 4.29230742805) def test_ndot2_radpersecsquared(self): np.testing.assert_allclose(self.sat.ndot2, 1.20168141063e-013) def test_eccdot_persecond(self): np.testing.assert_allclose(self.sat.eccdot, -1.40011545218e-10) def test_mean_anomaly_rad(self): np.testing.assert_allclose(self.sat.mean0, 3.96130049942e0) def test_raandot_radpersecond(self): np.testing.assert_allclose(self.sat.raandot, -1.03554877709e-6) def test_argpdot_radpersecond(self): np.testing.assert_allclose(self.sat.argpdot, 7.72047261206e-7) def test_tle_update_r_eci_initial(self): np.testing.assert_allclose(self.r_eci, self.sat.r_eci) def test_first_visible_pass_jd(self): np.testing.assert_allclose(self.all_passes[0].jd, self.sat.pass_vis[0].jd) def test_first_visible_pass_jd_parallel_predict(self): np.testing.assert_allclose(self.all_passes[0].jd, self.all_passes_parallel[0].jd) def test_output_file(self): np.testing.assert_equal( filecmp.cmp(self.fcn_output_file, self.class_output_file), True)
def generate_solution(ifile='./data/example_tle.txt', ofile='./data/SAT_OUT_EXAMPLE.txt'): ifile = os.path.abspath(ifile) ofile = os.path.abspath(ofile) site_lat = np.deg2rad(float(input("Site Latitude (38.925) : ") or "38.925")) site_lon = np.deg2rad(float(input("Site Longitude (-77.057) : ") or "-77.057")) site_alt = float(input("Site Altitude (0.054) : ") or "0.054") site_ecef = geodetic.lla2ecef(site_lat, site_lon, site_alt) # timespan date_start = [float(i) for i in (input('Start Date UTC (2017 12 1 0 0 0) : ') or "2017 12 1 0 0 0").split()] date_end = [float(i) for i in (input('End Date UTC (2017 12 5 0 0 0) : ') or "2017 12 5 0 0 0").split()] jd_start, _ = time.date2jd(date_start[0], date_start[1], date_start[2], date_start[3], date_start[4], date_start[5]) jd_end, _ = time.date2jd(date_end[0], date_end[1], date_end[2], date_end[3], date_end[4], date_end[5]) jd_step = 2 / (24 * 60) # step size in minutes jd_span = np.arange(jd_start, jd_end, jd_step) # echo check some data with open(ofile, 'w') as f: f.write('PREDICT EXAMPLE RESULTS : Shankar Kulumani\n\n') f.write('Check Input Data : \n\n') f.write('Site Latitude = {:9.6f} rad = {:9.6f} deg\n'.format(site_lat, np.rad2deg(site_lat))) f.write('Site Longitude = {:9.6f} rad = {:9.6f} deg\n'.format(site_lon, np.rad2deg(site_lon))) f.write('Site Altitude = {:9.6f} km = {:9.6f} m\n'.format(site_alt, site_alt * 1000)) f.write('\nObservation Window :\n\n') f.write('Start Date : {} UTC\n'.format(datetime.datetime(int(date_start[0]), int(date_start[1]), int(date_start[2]), int(date_start[3]), int(date_start[4]), int(date_start[5])).isoformat())) f.write('End Date : {} UTC\n\n'.format(datetime.datetime(int(date_end[0]),int(date_end[1]),int(date_end[2]),int(date_end[3]),int(date_end[4]),int(date_end[5])).isoformat())) f.write('Start Julian Date = {}\n'.format(jd_start)) f.write('End Julian Date = {}\n\n'.format(jd_end)) # loop over jd span site = defaultdict(list) site['lat'] = site_lat site['lon'] = site_lon site['alt'] = site_alt site['ecef'] = site_ecef for jd in jd_span: gst, lst = time.gstlst(jd, site_lon) # site_eci = geodetic.site2eci(site_lat, site_alt, lst) # site_eci = attitude.rot3(gst).dot(site_ecef) site_eci = transform.dcm_ecef2eci(jd).dot(site_ecef) # test if site is in the dark sun_eci, _, _ = planets.sun_earth_eci(jd) # append site information to list site['eci'].append(site_eci) site['sun_eci'].append(sun_eci) site['gst'].append(gst) site['lst'].append(lst) with open(ofile, 'a') as f: f.write('Site Data:\n\n') f.write('Start GST : {:9.6f} rad\n'.format(site['gst'][0])) f.write('Start LST : {:9.4f} rad\n'.format(site['lst'][0])) f.write('Site ECEF : {:9.6f} x {:9.6f} y {:9.6f} z km\n'.format(site['ecef'][0], site['ecef'][1], site['ecef'][2])) f.write('Sun ECI_0 : {:9.6f} x {:9.6f} y {:9.6f} z km\n\n'.format(site['sun_eci'][0][0], site['sun_eci'][0][1], site['sun_eci'][0][2])) f.write('{}\n\n'.format('*'*80)) # turn into numpy arrays for key, item in site.items(): site[key] = np.squeeze(np.array(item)) # update the downloaded TLEs if necessary # now we have to read the TLE sats = tle.get_tle(ifile) # now propogate and the check if each satellite is visible for sat in sats: sat.tle_update(jd_span) sat.visible(site) sat.output(ofile)
def generate_data(tle_file='./data/COMFIX_tle.txt', outfile='./data/COMFIX_tle_measurement.txt'): # define a time span jd_start, _ = time.date2jd(2017, 12, 1, 0, 0, 0) # time in UTC jd_end, _ = time.date2jd(2017, 12, 11, 0, 0, 0) jd_step = 1 / (24 * 60) jd_span = np.arange(jd_start, jd_end, jd_step) # define the observing site site_lat = np.deg2rad(38.8999), site_lon = np.deg2rad(-77.0490) site_alt = 0.020 site_ecef = geodetic.lla2ecef(site_lat, site_lon, site_alt) # loop over jd span site = defaultdict(list) site['lat'] = site_lat site['lon'] = site_lon site['alt'] = site_alt site['ecef'] = site_ecef for jd in jd_span: gst, lst = time.gstlst(jd, site_lon) # site_eci = geodetic.site2eci(site_lat, site_alt, lst) # site_eci = attitude.rot3(gst).dot(site_ecef) site_eci = geodetic.eci2ecef(jd).T.dot(site_ecef) # test if site is in the dark sun_eci, _, _ = planets.sun_earth_eci(jd) # append site information to list site['eci'].append(site_eci) site['sun_eci'].append(sun_eci) site['gst'].append(gst) site['lst'].append(lst) # turn into numpy arrays for key, item in site.items(): site[key] = np.squeeze(np.array(item)) # read some TLEs and get the state vector and write to a file sats = tle.get_tle(tle_file) f = open(outfile, 'w') for sat in sats: # propogate for several time periods and get the r, v vectors sat.tle_update(jd_span) sat.visible_radar(site) jd_vis = sat.jd_vis rho_vis = sat.rho_vis az_vis = sat.az_vis el_vis = sat.el_vis drho_vis = sat.drho_vis daz_vis = sat.daz_vis dele_vis = sat.dele_vis # write first line - site latgd, lon, alt (meters), JD obs time f.write('{:9.6f} {:9.6f} {:9.6f} {:16.6f}\n'.format( np.rad2deg(site['lat']), np.rad2deg(site['lon']), site['alt'] * 1e3, jd_vis[0])) # write second line rho, az, el, drho, daz, dele f.write( '{:5g} {:16.6f} {:16.6f} {:16.6f} {:16.6f} {:16.6f} {:16.6f}\n'. format(sat.satnum, rho_vis[0], np.rad2deg(az_vis[0][0]), np.rad2deg(el_vis[0]), drho_vis[0], np.rad2deg(daz_vis[0]), np.rad2deg(dele_vis[0]))) f.close()
s"""Example script which reads TLEs from a given file and prints out some data """ from astro import tle # input file with all of the TLE data filename = './data/example_tle.txt' # if there are multiple TLEs, each TLE object is stored in a Python List sats = tle.get_tle(filename) # since it's a list we can iterate through the list and output some of the data for sat in sats: print('\nsatname : {}, satnum : {}'.format(sat.satname, sat.satnum)) print('\nYear is two digits, and a day with fraction. There is a function already to change this.') print('epoch_year : {}, epoch_day : {}'.format(sat.epoch_year, sat.epoch_day)) print('\nNow print out some of the orbital elements') print('\nThese units are in rev/day. You will need to convert!') print('ndot_over_2 : {}, nddot_over_6 : {}'.format(sat.ndot_over_2, sat.nddot_over_6)) print('\nMake sure you check the units! Degrees!') print('inc : {}, raan : {}, ecc : {}'.format(sat.inc, sat.raan, sat.ecc)) print('M : {}, n : {}'.format(sat.ma, sat.mean_motion))
def predict(site_location, date_start, date_end, step_sec=60, ifile='./tle.txt', ofile='./output.txt'): r"""PREDICT satellite passes for a given Earth location sats, all_passes, site = predict(site_location, date_start, date_end, ifile, ofile) Parameters ---------- site_location : array_like latitude (deg), longitude (deg), altitude (km) of obs site date_start : array_like yr, month, day, hr, min, sec for window start date_end : array_like yr, month, day, hr, min, sec for window end step_sec : float Step size in seconds for prediction window ifile : str path to input TLE file ofile : str path to output file Returns ------- sats : array of Satellite objects Holds the data from TLE and updating functions all_passes : array of Pass objects holds the data for each visible pass site : dictionary dictionary holding the site information See Also -------- see the Satellite module which holds much of the required functions Author ------ Shankar Kulumani GWU [email protected] References ---------- Look at Astro 321 or MAE3145 or Vallado """ print(""" ____________ ___________ _____ _____ _____ | ___ \ ___ \ ___| _ \_ _/ __ \_ _| | |_/ / |_/ / |__ | | | | | | | / \/ | | | __/| /| __|| | | | | | | | | | | | | |\ \| |___| |/ / _| |_| \__/\ | | \_| \_| \_\____/|___/ \___/ \____/ \_/ \n""") logger = logging.getLogger(__name__) ifile = os.path.abspath(ifile) ofile = os.path.abspath(ofile) site_lat = np.deg2rad(site_location[0]) site_lon = np.deg2rad(site_location[1]) site_alt = site_location[2] jd_start, _ = time.date2jd(date_start[0], date_start[1], date_start[2], date_start[3], date_start[4], date_start[5]) jd_end, _ = time.date2jd(date_end[0], date_end[1], date_end[2], date_end[3], date_end[4], date_end[5]) jd_step = step_sec / 86400 jd_span = np.arange(jd_start, jd_end, jd_step) # build the site dictionary logger.info('Starting to create site dicitonary') site = build_site(jd_span, np.deg2rad(site_location[0]), np.deg2rad(site_location[1]), float(site_location[2])) # echo check some data logger.info('Write some input data to the output file {}'.format(ofile)) with open(ofile, 'w') as f: f.write('PREDICT RESULTS : Shankar Kulumani\n\n') f.write('Check Input Data : \n\n') f.write('Site Latitude = {:9.6f} rad = {:9.6f} deg\n'.format(site_lat, np.rad2deg(site_lat))) f.write('Site Longitude = {:9.6f} rad = {:9.6f} deg\n'.format(site_lon, np.rad2deg(site_lon))) f.write('Site Altitude = {:9.6f} km = {:9.6f} m\n'.format(site_alt, site_alt * 1000)) f.write('\nObservation Window :\n\n') f.write('Start Date : {} UTC\n'.format(datetime.datetime(int(date_start[0]), int(date_start[1]), int(date_start[2]), int(date_start[3]), int(date_start[4]), int(date_start[5])).isoformat())) f.write('End Date : {} UTC\n\n'.format(datetime.datetime(int(date_end[0]), int(date_end[1]), int(date_end[2]), int(date_end[3]), int(date_end[4]), int(date_end[5])).isoformat())) f.write('Start Julian Date = {}\n'.format(jd_start)) f.write('End Julian Date = {}\n\n'.format(jd_end)) # now we have to read the TLE logger.info('Read TLEs from {}'.format(ifile)) sats = tle.get_tle(ifile) logger.debug('Read {} sats'.format(len(sats))) parallel_predict = functools.partial( satellite.parallel_predict, jd_span=jd_span, site=site) logger.info('Starting parallel processing for satellites') with multiprocessing.Pool(multiprocessing.cpu_count() - 1) as p: sats_passes = p.map(parallel_predict, sats) logger.info('Now outputting visible data to textfile') for sat, pass_vis in zip(sats, sats_passes): satellite.output(sat, pass_vis, ofile) # for sat in sats: # sat.tle_update(jd_span) # sat.visible(site) # sat.output(ofile) print("Output saved to : \n{}".format(ofile)) return sats, sats_passes, site