Beispiel #1
0
    def _update_map_views(self, sat_state):
        """ Updates the map views of the visualizer with the given satellite data.

        Parameters
        ----------
        sat_state : SatState
            The satellite data to use
        """

        sat_pos = np.array([
            sat_state.position.x, sat_state.position.y, sat_state.position.z
        ]) * 1000

        # calculate where (latitude and longitude) nadir vector points
        nadir_ll = None
        nadir_los = los_to_earth(sat_pos, sat_state.nadir)
        if nadir_los is not None:
            nadir_ll = np.hstack(
                pm.eci2geodetic(nadir_los[0], nadir_los[1], nadir_los[2],
                                sat_state.timestamp)[:2])

        # calculate where (latitude and longitude) satellite body minus_z axis points
        minus_z_ll = None
        minus_z_normalized = self._sc_body_eci[2] / norm(self._sc_body_eci[2])
        minus_z_los = los_to_earth(sat_pos, minus_z_normalized)
        if minus_z_los is not None:
            minus_z_ll = np.hstack(
                pm.eci2geodetic(minus_z_los[0], minus_z_los[1], minus_z_los[2],
                                sat_state.timestamp)[:2])

        self._update_flat_map_view(sat_state, nadir_ll, minus_z_ll)
Beispiel #2
0
def test_eci2geodetic(use_astropy):
    pytest.importorskip("numpy")
    if use_astropy:
        pytest.importorskip("astropy")

    eci = [-2981784, 5207055, 3161595]
    utc = datetime(2019, 1, 4, 12)
    lla = pm.eci2geodetic(*eci, utc, use_astropy=use_astropy)

    rel = 0.0001 if use_astropy else 0.01
    assert lla == approx([27.881, -163.722, 408850.65], rel=rel)
Beispiel #3
0
def plotnav(nav: xarray.DataArray):
    if not isinstance(nav, xarray.DataArray):
        return

    ax = figure().gca()
    if nav.name == 'S':
        # WARNING: This conversion isn't verified.
        lat, lon, alt = eci2geodetic(nav.loc[:, ['X', 'Y', 'Z']] * 1e3,
                                     nav.t.to_pandas().tolist())
        ax.plot(lon, lat)
        ax.set_xlabel('glon [deg]')
        ax.set_ylabel('glat [deg]')

        print('lat lon', lat, lon)
        print('altitude [km]', alt / 1e3)
Beispiel #4
0
def plotnav(nav: xarray.Dataset):
    if nav is None:
        return

    if not 'X' in nav:
        return

    ax = figure().gca()
    # WARNING: This conversion isn't verified.
    lat, lon, alt = eci2geodetic(nav[['X', 'Y', 'Z']] * 1e3, nav.time)
    ax.plot(lon, lat)
    ax.set_xlabel('glon [deg]')
    ax.set_ylabel('glat [deg]')

    print('lat lon', lat, lon)
    print('altitude [km]', alt / 1e3)
Beispiel #5
0
def test_eci():
    tlla = (42, -82, 200)
    teci = (-3.977913815668146e6, -2.582332196263046e6, 4.250818828152067e6)
    t = datetime(2013, 1, 15, 12, 0, 5, tzinfo=UTC)
    lla = asarray(pm.eci2geodetic(teci, t)).squeeze()
    assert_allclose(lla, tlla, rtol=0.2)

    assert_allclose(
        pm.eci2ecef(teci, t).squeeze(),
        [649012.04640917, -4697980.55129606, 4250818.82815207])

    assert_allclose(
        pm.ecef2eci([649012.04640917, -4697980.55129606, 4250818.82815207],
                    t).squeeze(), teci)

    assert_allclose(
        asarray(pm.eci2aer(teci, 42, -100, 0, t)).squeeze(),
        [83.73050, -6.614478, 1.473510e6])
Beispiel #6
0
def test_eci_vallado():
    t = '2013-01-15T12:00:05'
    lla = pm.eci2geodetic(eci0, t, useastropy=False)
    assert lla == approx(lla0, rel=0.2)

    eci1 = pm.eci2ecef(eci0, t, useastropy=False)
    assert eci1 == approx(
        [649012.04640917, -4697980.55129606, 4250818.82815207], rel=0.001)

    assert pm.ecef2eci(eci1, t, useastropy=False) == approx(eci0, rel=0.001)

    aer1 = pm.eci2aer(eci0, 42, -100, 0, t, useastropy=False)
    assert aer1 == approx([83.73050, -6.614478, 1.473510e6], rel=0.001)

    assert pm.aer2eci(*aer1, 42, -100, 0, t,
                      useastropy=False) == approx(eci0, rel=0.001)

    with pytest.raises(ValueError):
        pm.aer2eci(aer1[0], aer1[1], -1, 42, -100, 0, t, useastropy=False)
Beispiel #7
0
def test_eci_astropy():
    pytest.importorskip('astropy')

    t = '2013-01-15T12:00:05'
    lla = pm.eci2geodetic(eci0, t)
    assert lla == approx(lla0, rel=0.2)

    eci1 = pm.eci2ecef(eci0, t)
    assert eci1 == approx(
        [649012.04640917, -4697980.55129606, 4250818.82815207])

    assert pm.ecef2eci(eci1, t) == approx(eci0)

    aer1 = pm.eci2aer(eci0, 42, -100, 0, t)
    assert aer1 == approx([83.73050, -6.614478, 1.473510e6])

    assert pm.aer2eci(*aer1, 42, -100, 0, t) == approx(eci0)

    with pytest.raises(ValueError):
        pm.aer2eci(aer1[0], aer1[1], -1, 42, -100, 0, t)
Beispiel #8
0
def iridium_ncdf(fn,day,tlim,ellim, camlla):
    assert len(ellim) == 2,'must specify elevation limits'
    fn = Path(fn).expanduser()
    day = forceutc(day)
#%% get all sats psuedo SV number
    with Dataset(str(fn),'r') as f:
        #psv_border = nonzero(diff(f['pseudo_sv_num'])!=0)[0] #didn't work because of consequtively reused psv #unique doesn't work because psv's can be recycled
        psv_border = (diff(f['time'])<0).nonzero()[0] + 1 #note unequal number of samples per satellite, +1 for how diff() is defined
#%% iterate over psv, but remember different number of time samples for each sv.
# since we are only interested in one satellite at a time, why not just iterate one by one, throwing away uninteresting results
# qualified by crossing of FOV.

#%% consider only satellites above az,el limits for this location
#TODO assumes only one satellite meets elevation and time criteria
        lind = [0,0] #init
        for i in psv_border:
            lind = [lind[1],i]
            cind = arange(lind[0],lind[1]-1,dtype=int) # all times for this SV
            #now handle times for this SV
            t = array([day + timedelta(hours=h) for h in f['time'][cind].astype(float)])
            if tlim:
                mask = (tlim[0] <= t) & (t <= tlim[1])
                t = t[mask]
                cind = cind[mask]
            #now filter by az,el criteria
            az,el,r = eci2aer(f['pos_eci'][cind,:], camlla[0], camlla[1], camlla[2],t)
            if ellim and ((ellim[0] <= el) & (el <= ellim[1])).any():
               # print(t)
                #print('sat psv {}'.format(f['pseudo_sv_num'][i]))
                eci = f['pos_eci'][cind,:]
                lat,lon,alt = eci2geodetic(eci,t)
                x,y,z = eci2ecef(eci,t)
                #print('ecef {} {} {}'.format(x,y,z))

                ecef = DataFrame(index=t, columns=['x','y','z'], data=column_stack((x,y,z)))
                lla  = DataFrame(index=t, columns=['lat','lon','alt'], data=column_stack((lat,lon,alt)))
                aer  = DataFrame(index=t, columns=['az','el','srng'], data=column_stack((az,el,r)))
                return ecef,lla,aer,eci

    print('no FOV crossings for your time span were found.')
    return (None,None)
Beispiel #9
0
    def test_eci(self):
        if numpy is None or astropy is None:
            logging.warning('ECI not tested')
            return

        teci = (-3.977913815668146e6, -2.582332196263046e6,
                4.250818828152067e6)
        t = datetime(2013, 1, 15, 12, 0, 5, tzinfo=UTC)
        lla = numpy.asarray(pm.eci2geodetic(teci, t)).squeeze()
        assert_allclose(lla, lla0, rtol=0.2)

        assert_allclose(
            pm.eci2ecef(teci, t).squeeze(),
            [649012.04640917, -4697980.55129606, 4250818.82815207])

        assert_allclose(
            pm.ecef2eci([649012.04640917, -4697980.55129606, 4250818.82815207],
                        t).squeeze(), teci)

        assert_allclose(
            numpy.asarray(pm.eci2aer(teci, 42, -100, 0, t)).squeeze(),
            [83.73050, -6.614478, 1.473510e6])
Beispiel #10
0
def igrffx(eci_vec, time):
    #import igrf12
    import numpy
    import pyIGRF
    import pymap3d
    from pymap3d import ecef2eci
    import navpy
    from navpy import ned2ecef
    import datetime
    from datetime import datetime
    import astropy
    #eci_vec is a xyz vector in ECI  km
    #output B_ECI is a 3 item array in units of T

    #get our lat long and alt from ECI
    geod = pymap3d.eci2geodetic(1000 * eci_vec, time, useastropy=True)

    latitude = geod[0][0]  #degrees
    longitude = geod[1][0]  #degrees
    altitude = geod[2]  #meters

    #call igrf to get b vector in NED
    #mag = igrf12.igrf('2019-01-12', glat=latitude, glon=longitude, alt_km=altitude/1000)
    b = pyIGRF.igrf_value(latitude, longitude, altitude / 1000, 2019)

    #combine NED components back into an array
    #NED = numpy.array([b_north,b_east,b_down])
    NED = b[3:6]

    #convert from NED to ECEF
    ECEF = navpy.ned2ecef(NED, latitude, longitude, altitude)

    #convert from ECEF to ECI
    B_ECI = (pymap3d.ecef2eci(ECEF, time, useastropy=True)) * 10**(-9)

    return B_ECI
def RAY_INTERSECT_WGS84_TERRAIN(point,
                                ray_dir,
                                t,
                                DEM_FILE_LOCATION=None,
                                nom_height=0):
    lat, lon, height = RAY_INTERSECT_WGS84(point, ray_dir, t)
    s, height_min = Height_From_DEM(lon, lat, DEM_FILE_LOCATION)
    if (s == 0):
        return RAY_INTERSECT_WGS84(point, ray_dir, t)
    #print(Max_Local_Height_From_DEM(lon,lat,DEM_FILE_LOCATION,scale=(5,5)))
    s, (max_lat, max_lon,
        max_height) = Max_Local_Height_From_DEM(lon,
                                                lat,
                                                DEM_FILE_LOCATION,
                                                scale=(5, 5))
    if (s == 0):
        return RAY_INTERSECT_WGS84(point, ray_dir, t)

    eci_ter = pm.ecef2eci(pm.geodetic2ecef(lat, lon, height), t)
    #print([(max_lon,max_lat),max_height, t])
    eci_ter_lmax = pm.ecef2eci(pm.geodetic2ecef(max_lat, max_lon, max_height),
                               t)

    #print(mid_llh[2],height_mid

    xd = ray_dir[0]  #-31.46071792#-
    yd = ray_dir[1]  #58.59611618#-
    zd = ray_dir[2]  #27.47631664#-

    xc = -point[0]
    yc = -point[1]
    zc = -point[2]

    xn = eci_ter_lmax[0]
    yn = eci_ter_lmax[1]
    zn = eci_ter_lmax[2]

    #print(xn,yn,zn)

    t_par = (((xn)**2 + (yn)**2 + (zn)**2) - (xc * xn) - (yc * yn) -
             (zc * zn)) / (xd * xn + yd * yn + zd * zn)
    rez = np.array([xc + t_par * xd, yc + t_par * yd, zc + t_par * zd])
    #print(pm.eci2geodetic((rez),t))

    #print(eci_ter)
    height_delta = 9999999999
    eci_ter_mid = (eci_ter + rez) / 2
    height_delta_old = 9898989898
    while (abs(height_delta) > 5 and height_delta_old != height_delta):
        #print(str(height_delta)+': height delta')
        mid_llh = pm.eci2geodetic(eci_ter_mid, t)  #latlonheight
        s, height_mid = Height_From_DEM(mid_llh[1], mid_llh[0],
                                        DEM_FILE_LOCATION)
        if (s == 0):
            return RAY_INTERSECT_WGS84(point, ray_dir, t)
        #print(mid_llh[2],height_mid[2],mid_llh[2]-height_mid[2])
        height_delta_old = height_delta
        height_delta = mid_llh[2] - height_mid[2]

        if (height_delta < 0):
            eci_ter_mid_new = (rez + eci_ter_mid) / 2
            eci_ter = eci_ter_mid
            eci_ter_mid = eci_ter_mid_new
        else:
            eci_ter_mid_new = (eci_ter_mid + eci_ter) / 2
            rez = eci_ter_mid
            eci_ter_mid = eci_ter_mid_new
    #print(mid_llh)
    return (mid_llh)
Beispiel #12
0
def test_eci_geodetic(useastropy):
    pytest.importorskip("numpy")
    t = "2013-01-15T12:00:05"
    lla = pm.eci2geodetic(*eci0, t, useastropy=useastropy)
    assert lla == approx(lla0, rel=0.2)
Beispiel #13
0
def test_eci_geodetic(useastropy):
    t = '2013-01-15T12:00:05'
    lla = pm.eci2geodetic(*eci0, t, useastropy=useastropy)
    assert lla == approx(lla0, rel=0.2)
Beispiel #14
0
def test_eci_geodetic(useastropy):
    t = '2013-01-15T12:00:05'
    lla = pm.eci2geodetic(*eci0, t, useastropy=useastropy)
    assert lla == approx(lla0, rel=0.2)