def build_site(jd_span, site_lat, site_lon, site_alt): r"""Create the site dictionary site = build_site(jd_span, site_lat, site_lon, site_alt) Parameters ---------- jd_span : array Array of Julian date times for teh window site_lat : float site latitude in radians site_lon : float site longitude in radians site_alt : float site altitude in kilometers Returns ------- site : dictionary site dicitonary holding data on the observation site Author ------ Shankar Kulumani GWU [email protected] """ 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 = 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) # turn into numpy arrays for key, item in site.items(): site[key] = np.squeeze(np.array(item)) return site
def test_sun_eci_vallado(): jd, mjd = time.date2jd(1994, 4, 2, 0, 0, 0) jd_vallado = 2449444.5 rsun_vallado = np.array([146241097, 28574940, 12389196]) ra_vallado, dec_vallado = np.deg2rad(11.056071), np.deg2rad(4.7529393) rsun, ra, dec = planets.sun_earth_eci(jd) np.testing.assert_allclose(jd, jd_vallado) np.testing.assert_allclose(rsun, rsun_vallado, rtol=1e-4) np.testing.assert_allclose((ra, dec), (ra_vallado, dec_vallado), rtol=1e-4)
def test_sun_earth_eci_usafa(): jd = 2453905.50000000 expected_rsun = [6371243.918400, 139340081.269385, 60407749.811252] rsun, ra, dec = planets.sun_earth_eci(jd) np.testing.assert_allclose(rsun, expected_rsun, rtol=1e-4)
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()
def visible(r_sat_eci, r_site_eci, lat, lon, GST, JD): r"""Checks if visibility constraints are valid for satellite information Inputs: r_sat_eci :(vector) Given in ECI frame with units km r_site_eci :(vector) Given in ECI frame with units km lat :(angle) Given in units of radians LST :(angle) Given in units of radians JD :(time) Given as Julian Date Outputs: flag :(scalar) Given as unitless, 0 = Not Visible, 1 = Visible Author: Thomas J Susi GWU [email protected] """ flag = 0 r_sun = planets.sun_earth_eci(JD)[0] """Range and Angle""" p_eci = r_sat_eci - r_site_eci ecef2eci = ecef2eci = np.array([[np.cos(GST), -np.sin(GST), 0], [np.sin(GST), np.cos(GST), 0], [0, 0, 1]]) p_ecef = np.dot(np.transpose(ecef2eci), p_eci) b2ecef = np.array([[np.cos(lon), -np.sin(lon), 0], [np.sin(lon), np.cos(lon), 0], [0, 0, 1]]) sez2b = np.array([[np.cos(np.pi / 2 - lat), 0, np.sin(np.pi / 2 - lat)], [0, 1, 0], [-np.sin(np.pi / 2 - lat), 0, np.cos(np.pi / 2 - lat)]]) sez2ecef = b2ecef.dot(sez2b) p_sez = np.dot(np.transpose(sez2ecef), p_ecef) rang = np.linalg.norm(p_sez) elev = np.arcsin(p_sez[2] / rang) elev_num = abs(float(elev)) p_mag = np.linalg.norm(p_eci) """Darkness""" dark = np.dot(r_sun, r_site_eci) """In Sunlight""" sin_angle = np.dot( r_sun, r_sat_eci) / (np.linalg.norm(r_sun) * np.linalg.norm(r_sat_eci)) cos_angle = np.dot( r_sun, r_sat_eci) / (np.linalg.norm(r_sun) * np.linalg.norm(r_sat_eci)) angle = np.dot(r_sun, r_sat_eci) / (np.linalg.norm(r_sun) * np.linalg.norm(r_sat_eci)) + 2 * np.pi dist = np.linalg.norm(r_sat_eci) * angle dist_num = float(dist) import pdb pdb.set_trace() """If Statement""" if (elev_num > np.deg2rad(10) and p_mag < 1500 and dark < 0 and dist_num > 6378.137): flag = 1 return flag