예제 #1
0
파일: predict.py 프로젝트: skulumani/astro
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
예제 #2
0
def dcm_eci2ecef(jd):
    """Rotation matrix to convert from ECI to ECEF

    Will gradually improve this function to include all of the Earth
    motion terms. For now, just use sidereal time to get the rotation matrix
    """

    gst, _ = time.gstlst(jd, 0)

    dcm = attitude.rot3(gst, 'r')

    return dcm
예제 #3
0
class TestTimeGSTValladoEx3_3():
    dateexp = (1995, 2, 24, 12, 0, 0)
    jdexp = 2449773.0
    gstexp = np.deg2rad(333.893486)
    jd, mjd = time.date2jd(dateexp[0], dateexp[1], dateexp[2], dateexp[3], dateexp[4], dateexp[5])
    date = time.jd2date(jdexp)
    gst, _ = time.gstlst(jd, 0)

    def test_jd(self):
        np.testing.assert_allclose(self.jd, self.jdexp)

    def test_date(self):
        np.testing.assert_allclose(self.date, self.dateexp)

    def test_gst(self):
        np.testing.assert_allclose(self.gst, self.gstexp)
예제 #4
0
def ecef2eci(JD, lon):
    r"""Computes the updated COEs given the time change

    Inputs:
    JD :(time) Julian Date

    Outputs:
    ecef2eci :(Rotation Matrix) Unitless

    Author: Thomas J Susi       GWU         [email protected]
    """

    gst, lst = time.gstlst(JD, lon)

    thetag = gst

    ecef2eci = np.array([[np.cos(thetag),-np.sin(thetag),0],[np.sin(thetag),np.cos(thetag),0],[0,0,1]])

    return ecef2eci
예제 #5
0
class TestECI2ECEF():
    """Test to make sure we can convert a location on the earth to the correct ECEF vector
    """

    lonexp = np.deg2rad(72.5529)
    latgdexp = np.deg2rad(34.352496)
    latgcexp = np.deg2rad(34.173429)
    altexp = 5085.22  # kilometer

    eci_exp = np.array([6524.834, 6862.875, 6448.296])
    jd_exp = 2449773.0
    _, lst = time.gstlst(jd_exp, lonexp)
    eci = geodetic.site2eci(latgdexp, altexp, lst)
    ecef = geodetic.lla2ecef(latgdexp, lonexp, altexp)
    Reci2ecef = transform.dcm_eci2ecef(jd_exp)
    eci_from_ecef = Reci2ecef.T.dot(ecef)

    def test_eci_vallado(self):
        np.testing.assert_allclose(self.eci, self.eci_exp, rtol=1e-2)

    def test_eci_from_ecef(self):
        np.testing.assert_allclose(self.eci_from_ecef, self.eci_exp, rtol=1e-2)
예제 #6
0
class TestECEF2ECI():
    """Example pg.106 in BMW
    """
    lon = np.deg2rad(-57.296)
    lat = 0
    alt = 6.378  # kilometer above equator
    date = (1970, 1, 2, 6, 0, 0)
    jd, _ = time.date2jd(date[0], date[1], date[2], date[3], date[4], date[5])
    gst0_exp = 1.749333
    gst_exp = attitude.normalize(9.6245, 0, 2 * np.pi)
    lst_exp = attitude.normalize(8.6245, 0, 2 * np.pi)

    eci_exp = np.array([-0.697 * 6378.137, 0.718 * 6378.137, 0])

    gst0 = time.gsttime0(date[0])
    gst, lst = time.gstlst(jd, lon)

    eci = geodetic.site2eci(lat, alt, lst)
    ecef = geodetic.lla2ecef(lat, lon, alt)
    Reci2ecef = transform.dcm_eci2ecef(jd)
    eci_from_ecef = Reci2ecef.T.dot(ecef)

    def test_gst0(self):
        np.testing.assert_allclose(self.gst0, self.gst0_exp, rtol=1e-4)

    def test_gst(self):
        np.testing.assert_allclose(self.gst, self.gst_exp, rtol=1e-4)

    def test_lst(self):
        np.testing.assert_allclose(self.lst, self.lst_exp, rtol=1e-3)

    def test_eci(self):
        np.testing.assert_allclose(self.eci, self.eci_exp, rtol=1e-2)

    def test_eci_from_ecef(self):
        np.testing.assert_allclose(self.eci_from_ecef, self.eci_exp, rtol=1e-2)
예제 #7
0
def test_lst_vallado():
    expected_lst = 48.578787886
    _, actual_lst = time.gstlst(2448855.009722, -104 * deg2rad)
    np.testing.assert_allclose(actual_lst * rad2deg, expected_lst, rtol=1e-3)
예제 #8
0
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)
예제 #9
0
def solution(meas_file='./data/COMFIX_tle_measurement.txt',
             outfile='./data/COMFIX_tle_solution.txt'):
    # read in the measurement data
    fout = open(outfile, 'w')

    with open(meas_file, 'r') as f:
        l0 = f.readline().split()
        l0 = [float(x) for x in l0]
        while l0:
            l1 = f.readline().split()
            l1 = [float(x) for x in l1]
            latgd, lon, alt, jd = np.deg2rad(l0[0]), np.deg2rad(
                l0[1]), l0[2] / 1e3, l0[3]
            satnum, rho, az, el, drho, daz, dele = l1[0], l1[1], np.deg2rad(
                l1[2]), np.deg2rad(l1[3]), l1[4], np.deg2rad(
                    l1[5]), np.deg2rad(l1[6])

            # GST, LST
            gst, lst = time.gstlst(jd, lon)
            # find satellite vector in SEZ
            rho_sez, drho_sez = geodetic.rhoazel2sez(rho, az, el, drho, daz,
                                                     dele)
            R_eci2ecef = geodetic.eci2ecef(jd)
            R_ecef2eci = geodetic.ecef2eci(jd)
            R_sez2ecef = transform.dcm_sez2ecef(latgd, lon, alt)

            # find  site vector in ECEF/ECI
            site_ecef = geodetic.lla2ecef(latgd, lon, alt)
            site_eci = R_ecef2eci.dot(site_ecef)

            # transform satellite vector from SEZ to ECI
            rho_ecef = R_sez2ecef.dot(rho_sez)
            rho_eci = R_ecef2eci.dot(rho_ecef)

            drho_ecef = R_sez2ecef.dot(drho_sez)
            drho_eci = R_ecef2eci.dot(drho_ecef)

            pos_eci = site_eci + rho_eci
            vel_eci = drho_eci + np.cross(
                np.array([0, 0, constants.earth.omega]), pos_eci)
            # find orbital elements
            p, a, ecc, inc, raan, arg_p, nu, _, _, _, _ = kepler.rv2coe(
                pos_eci, vel_eci, constants.earth.mu)

            # compute orbit properties
            prop_string = kepler.orbit_el(p, ecc, inc, raan, arg_p, nu,
                                          constants.earth.mu)

            l0 = f.readline().split()
            l0 = [float(x) for x in l0]
            # output to text file
            fout.write(
                '#################### COMFIX SATELLITE {:g} ####################################\n\n'
                .format(satnum))
            fout.write(
                '------------------------ INPUT DATA -------------------------------------------\n\n'
            )
            fout.write('LAT (deg)    LON (deg)     ALT (m)       JD\n')
            fout.write(
                '{:<9.4f}    {:<9.4f}     {:<9.4f}      {:<16.6f}\n\n'.format(
                    np.rad2deg(latgd), np.rad2deg(lon), alt * 1e3, jd))
            fout.write(
                'RHO (km)     AZ (deg)    EL (deg)   DRHO (km/s)   DAZ (deg/s)   DEL (deg/s)\n'
            )
            fout.write(
                '{:<9.4f}     {:<6.4f}    {:<6.4f}     {:<6.4f}     {:<6.4f}        {:<6.4f}\n'
                .format(rho, np.rad2deg(az), np.rad2deg(el), drho,
                        np.rad2deg(daz), np.rad2deg(dele)))

            fout.write(
                '------------------------- WORKING DATA ----------------------------------------\n\n'
            )
            fout.write('LAT (rad)    LON (rad)     ALT (m)       JD\n')
            fout.write(
                '{:<9.4f}    {:<9.4f}     {:<9.4f}      {:<16.6f}\n\n'.format(
                    latgd, lon, alt, jd))
            fout.write(
                'RHO (km)     AZ (rad)    EL (rad)   DRHO (km/s)   DAZ (rad/s)   DEL (rad/s)\n'
            )
            fout.write(
                '{:<9.4f}     {:<6.4f}    {:<6.4f}     {:<6.4f}     {:<6.4f}        {:<6.4f}\n\n'
                .format(rho, az, el, drho, daz, dele))
            fout.write('GST  = {:16.9f} rad = {:16.9f} deg\n'.format(
                gst, np.rad2deg(gst)))
            fout.write('LST  = {:16.9f} rad = {:16.9f} deg\n\n'.format(
                lst, np.rad2deg(lst)))

            fout.write(
                '---------------------------- VECTORS ------------------------------------------\n'
            )
            fout.write(
                '{:9s} = {:13.4f} S {:13.4f} E {:13.4f} Z MAG = {:7.4f} km\n'.
                format('rho_sez', rho_sez[0], rho_sez[1], rho_sez[2],
                       np.linalg.norm(rho_sez)))
            fout.write(
                '{:9s} = {:13.4f} I {:13.4f} J {:13.4f} K MAG = {:7.4f} km\n'.
                format('rho_ecef', rho_ecef[0], rho_ecef[1], rho_ecef[2],
                       np.linalg.norm(rho_ecef)))
            fout.write(
                '{:9s} = {:13.4f} I {:13.4f} J {:13.4f} K MAG = {:7.4f} km\n'.
                format('rho_eci', rho_eci[0], rho_eci[1], rho_eci[2],
                       np.linalg.norm(rho_eci)))
            fout.write(
                '{:9s} = {:13.4f} S {:13.4f} E {:13.4f} Z MAG = {:7.4f} km/s\n'
                .format('drho_sez', drho_sez[0], drho_sez[1], drho_sez[2],
                        np.linalg.norm(drho_sez)))
            fout.write(
                '{:9s} = {:13.4f} I {:13.4f} J {:13.4f} K MAG = {:7.4f} km/s\n'
                .format('drho_ecef', drho_ecef[0], drho_ecef[1], drho_ecef[2],
                        np.linalg.norm(drho_ecef)))
            fout.write(
                '{:9s} = {:13.4f} I {:13.4f} J {:13.4f} K MAG = {:7.4f} km/s\n'
                .format('drho_eci', drho_eci[0], drho_eci[1], drho_eci[2],
                        np.linalg.norm(drho_eci)))
            fout.write(
                '{:9s} = {:13.4f} I {:13.4f} J {:13.4f} K MAG = {:7.4f} km\n'.
                format('site_ecef', site_ecef[0], site_ecef[1], site_ecef[2],
                       np.linalg.norm(site_ecef)))
            fout.write(
                '{:9s} = {:13.4f} I {:13.4f} J {:13.4f} K MAG = {:7.4f} km\n'.
                format('site_eci', site_eci[0], site_eci[1], site_eci[2],
                       np.linalg.norm(site_eci)))
            fout.write(
                '{:9s} = {:13.4f} I {:13.4f} J {:13.4f} K MAG = {:7.4f} km\n'.
                format('pos_eci', pos_eci[0], pos_eci[1], pos_eci[2],
                       np.linalg.norm(pos_eci)))
            fout.write(
                '{:9s} = {:13.4f} I {:13.4f} J {:13.4f} K MAG = {:7.4f} km/s\n'
                .format('vel_eci', vel_eci[0], vel_eci[1], vel_eci[2],
                        np.linalg.norm(vel_eci)))

            fout.write(prop_string + '\n')
    fout.close()
예제 #10
0
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()
예제 #11
0
 r_sat_eci_turned, v_sat_eci = PREDICT.coe2rv(
     n_s, e_s, raan_s, w_s, theta_s, i_s, 398600.5)
 r_sat_eci = np.array([
     float(r_sat_eci_turned[0]),
     float(r_sat_eci_turned[1]),
     float(r_sat_eci_turned[2])
 ])
 """Get Site Info At Time"""
 ecef2eci = COMFIX.ecef2eci(stp, lon)
 r_site_eci_turned = np.dot(ecef2eci, r_site_ecef)
 r_site_eci = np.array([
     r_site_eci_turned[0][0], r_site_eci_turned[1][0],
     r_site_eci_turned[2][0]
 ])
 """Check Visibility At Time"""
 GST, LST = time.gstlst(stp, lon)
 import pdb
 pdb.set_trace()
 visible_check = PREDICT.visible(r_sat_eci, r_site_eci, lat, lon,
                                 LST, stp)
 """Determine Where to Look At Time"""
 if (visible_check == 1):
     print("Y Script")
     rang, azm, elev = PREDICT.rhoazel(r_sat_eci, r_site_eci, lat,
                                       lon, GST)
     year, month, day, hour, minute, second = time.jd2date(stp)
     Line_out = [
         'Where to Look at {}/{}/{}\t {}:{}:{} JD:\n\tRange(km): {}\n\tAzmuth(deg): {}\n\tElevation(deg): {}\n'
         .format(int(month), int(day), int(year), int(hour),
                 int(minute), int(second), rang, np.rad2deg(azm),
                 np.rad2deg(elev))
예제 #12
0
def test_lst_vallado():
    expected_lst = 48.578787886
    _, actual_lst = time.gstlst(2448855.009722, -104 * deg2rad)
    np.testing.assert_allclose(actual_lst * rad2deg, expected_lst, rtol=1e-3)
예제 #13
0
"""COMFIX practice questions from  HW6 2017
"""

from astro import constants, geodetic, time, transform
import numpy as np

# observation
lat, lon, alt = np.deg2rad(77.7), np.deg2rad(-68.5), 0.050
jd = 2454154.6376157
rho, az, el, rhodot, azdot, eldot = 2121.418, np.deg2rad(18.9606), np.deg2rad(
    35.3507), -3.3204, np.deg2rad(-.07653), np.deg2rad(.20367)

gst, lst = time.gstlst(jd, lon)
print('JD : {}'.format(jd))
print('GST : {} rad = {} deg'.format(gst, np.rad2deg(gst)))
print('LST : {} rad = {} deg'.format(lst, np.rad2deg(lst)))

# site location
site_ecef = geodetic.lla2ecef(lat, lon, alt)
Recef2eci = transform.dcm_ecef2eci(jd)
site_eci = Recef2eci.dot(site_ecef)
print('Site ECEF : {} km'.format(site_ecef))
print('ECEF TO ECI : \n{}'.format(Recef2eci))
print('Site ECI : {} km'.format(site_eci))

# convert measurement to SEZ then to ECEF then to ECI
rho_sez, drho_sez = geodetic.rhoazel2sez(rho, az, el, rhodot, azdot, eldot)
R_sez2ecef = transform.dcm_sez2ecef(lat, lon, alt)

# transform satellite vector from SEZ to ECI
rho_ecef = R_sez2ecef.dot(rho_sez)
예제 #14
0
var = "False"

while var != "True":
    print("\n\nTest Line {}".format(countl))

    #Create 'string' of individual float values
    readarray1 = [float(n) for n in l1.split()]
    #Create arrays of 3 values each through numpy
    lat = np.array(readarray1[0]) * deg2rad
    longit = np.array(readarray1[1]) * deg2rad
    alt = np.array(readarray1[2]) * (0.001)

    t = np.array(readarray1[3])
    #print(longit, lat, alt, t)

    (gst, lst) = time.gstlst(t, longit)
    #print(gst, lst)
    N = (eartha)/(1 - (earthe**2 * (np.sin(lat))**2))**.5
    #print(N)

    readarray2 = [float(n) for n in l2.split()]
    IDN = np.array(readarray2[0])
    rho = np.array(readarray2[1])
    azm = np.array(readarray2[2]) * deg2rad
    ele = np.array(readarray2[3]) * deg2rad
    rhor = np.array(readarray2[4])
    azmr = np.array(readarray2[5]) * deg2rad
    eler = np.array(readarray2[6]) * deg2rad
    #print(IDN, rho, azm, ele, rhor, azmr, eler)

    Recef = cf.ela2ecef(lat, longit, alt, N)