Esempio n. 1
0
def test_array_ecef2geodetic():
    """
    tests ecef2geodetic can handle numpy array data in addition to singular floats
    """
    np = pytest.importorskip("numpy")
    # test values with no points inside ellipsoid
    lla0_array = (
        np.array([lla0[0], lla0[0]]),
        np.array([lla0[1], lla0[1]]),
        np.array([lla0[2], lla0[2]]),
    )
    xyz = pm.geodetic2ecef(*lla0_array)
    lats, lons, alts = pm.ecef2geodetic(*xyz)

    assert lats == approx(lla0_array[0])
    assert lons == approx(lla0_array[1])
    assert alts == approx(lla0_array[2])

    # test values with some (but not all) points inside ellipsoid
    lla0_array_inside = (
        np.array([lla0[0], lla0[0]]),
        np.array([lla0[1], lla0[1]]),
        np.array([lla0[2], -lla0[2]]),
    )
    xyz = pm.geodetic2ecef(*lla0_array_inside)
    lats, lons, alts = pm.ecef2geodetic(*xyz)

    assert lats == approx(lla0_array_inside[0])
    assert lons == approx(lla0_array_inside[1])
    assert alts == approx(lla0_array_inside[2])
Esempio n. 2
0
def test_geodetic():
    xyz = pm.geodetic2ecef(*lla0)

    assert xyz == approx(xyz0)
    assert pm.geodetic2ecef(*rlla0, deg=False) == approx(xyz)

    with pytest.raises(ValueError):
        pm.geodetic2ecef(lla0[0], lla0[1], -1)

    with pytest.raises(ValueError):
        pm.geodetic2ecef(-100, lla0[1], lla0[2])

    with pytest.raises(ValueError):
        pm.geodetic2ecef(lla0[0], -200, lla0[2])

    assert pm.ecef2geodetic(*xyz) == approx(lla0)
    assert pm.ecef2geodetic(*xyz, deg=False) == approx(rlla0)

    lla2 = pm.aer2geodetic(*aer0, *lla0)
    rlla2 = pm.aer2geodetic(*raer0, *rlla0, deg=False)

    with pytest.raises(ValueError):
        pm.aer2geodetic(aer0[0], aer0[1], -1, *lla0)

    assert lla2 == approx(lla1)
    assert rlla2 == approx(rlla1)

    assert pm.geodetic2aer(*lla2, *lla0) == approx(aer0)
    assert pm.geodetic2aer(*rlla2, *rlla0, deg=False) == approx(raer0)

    anan = np.empty((10, 10))
    anan.fill(np.nan)
    assert np.isnan(pm.geodetic2aer(anan, anan, anan, *lla0)).all()
    assert np.isnan(pm.aer2geodetic(anan, anan, anan, *lla0)).all()
Esempio n. 3
0
def test_ecef():
    xyz = pm.geodetic2ecef(*lla0)

    assert xyz == approx(xyz0)
    assert pm.geodetic2ecef(*rlla0, deg=False) == approx(xyz)

    with pytest.raises(ValueError):
        pm.geodetic2ecef(-100, lla0[1], lla0[2])

    with pytest.raises(ValueError):
        pm.geodetic2ecef(lla0[0], -200, lla0[2])

    assert pm.ecef2geodetic(*xyz) == approx(lla0)
    assert pm.ecef2geodetic(*xyz, deg=False) == approx(rlla0)
Esempio n. 4
0
def test_ecef():
    xyz = pm.geodetic2ecef(*lla0)

    assert xyz == approx(xyz0)
    assert pm.geodetic2ecef(*rlla0, deg=False) == approx(xyz)

    with pytest.raises(ValueError):
        pm.geodetic2ecef(-100, lla0[1], lla0[2])

    assert pm.ecef2geodetic(*xyz) == approx(lla0)
    assert pm.ecef2geodetic(*xyz, deg=False) == approx(rlla0)

    assert pm.ecef2geodetic((A - 1) / np.sqrt(2),
                            (A - 1) / np.sqrt(2), 0) == approx([0, 45, -1])
Esempio n. 5
0
def dataFromNC(fnc,fnav,sv,
               el_mask=30,tlim=None, 
               satpos=False,
               ipp=False,
               ipp_alt=None):
    leap_seconds = uf.getLeapSeconds(fnav)
    D = gr.load(fnc, useindicators=True).sel(sv=sv)
    if tlim is not None:
        if len(tlim) == 2:
            D = D.where(np.logical_and(D.time >= np.datetime64(tlim[0]), D.time <= np.datetime64(tlim[1])), drop=True)
    obstimes64 = D.time.values
    dt = np.array([Timestamp(t).to_pydatetime() for t in obstimes64]) - \
               datetime.timedelta(seconds = leap_seconds)
    rx_xyz = D.position
    aer = gpsSatPosition(fnav,dt,sv=sv, rx_position=rx_xyz, coords='aer')
    idel = (aer[1] >= el_mask)
    aer = aer[:, idel]
    dt = dt[idel]
    if satpos:
        D['az'] = aer[0]
        D['el'] = aer[1]
    if ipp:
        if ipp_alt is None:
            print ('Auto assigned altitude of the IPP: 250 km')
            ipp_alt = 250e3
        else:
            ipp_alt *= 1e3
        rec_lat, rec_lon, rec_alt = ecef2geodetic(rx_xyz[0], rx_xyz[1], rx_xyz[2])
        fm = np.sin(np.radians(aer[1]))
        r_new = ipp_alt / fm
        lla_vector = np.array(aer2geodetic(aer[0], aer[1], r_new, rec_lat, rec_lon, rec_alt))
        D['ipp_lon'] = lla_vector[1]
        D['ipp_lat'] = lla_vector[0]
        D['ipp_alt'] = ipp_alt
    return dt, D, idel
Esempio n. 6
0
def test_3d_ecef2geodetic():
    np = pytest.importorskip("numpy")
    xyz = (np.atleast_3d(xyz0[0]), np.atleast_3d(xyz0[1]), np.atleast_3d(xyz0[2]))

    lat, lon, alt = pm.ecef2geodetic(*xyz)

    assert [lat, lon, alt] == approx(lla0, rel=1e-4)
Esempio n. 7
0
def test_scalar_ecef2geodetic():
    """
    verify we can handle the wide variety of input data type users might use
    """
    lat, lon, alt = pm.ecef2geodetic(xyz0[0], xyz0[1], xyz0[2])

    assert [lat, lon, alt] == approx(lla0, rel=1e-4)
Esempio n. 8
0
def payload_parachute_dynamics(x, t, rocket):
    pos_ECI = x[0:3]
    vel_ECI = x[3:6]

    DCM_ECI2ECEF = coord.DCM_ECI2ECEF(t)
    pos_ECEF = DCM_ECI2ECEF.dot(pos_ECI)
    pos_LLH = pm.ecef2geodetic(pos_ECEF[0], pos_ECEF[1], pos_ECEF[2])

    altitude = pos_LLH[2]
    DCM_ECEF2NED = coord.DCM_ECEF2NED(rocket.pos0_LLH)
    vel_ECEF = coord.vel_ECI2ECEF(vel_ECI, DCM_ECI2ECEF, pos_ECI)
    vel_NED = DCM_ECEF2NED.dot(vel_ECEF)
    vel_decent = vel_NED[2]

    g_NED = np.array([0.0, 0.0, env.gravity(altitude)])
    Ta, Pa, rho, Cs = env.std_atmo(altitude)

    drag_NED = np.array([
        0, 0, -0.5 * rho * vel_decent * np.abs(vel_decent) * rocket.payload.CdS
    ])
    acc_NED = drag_NED / rocket.payload.mass + g_NED
    acc_ECI = DCM_ECI2ECEF.transpose().dot(
        DCM_ECEF2NED.transpose().dot(acc_NED))

    wind_NED = env.Wind_NED(rocket.wind_speed(altitude),
                            rocket.wind_direction(altitude))
    vel_NED = vel_NED + wind_NED
    vel_ecef = DCM_ECEF2NED.transpose().dot(vel_NED)
    vel_ECI = coord.vel_ECEF2ECI(vel_ecef, DCM_ECI2ECEF, pos_ECI)

    dx = np.zeros(6)
    dx[0:3] = vel_ECI
    dx[3:6] = acc_ECI

    return dx
Esempio n. 9
0
def test_scalar_ecef2geodetic(xyz):
    """
    verify we can handle the wide variety of input data type users might use
    """
    lat, lon, alt = pm.ecef2geodetic(*xyz)

    assert [lat, lon, alt] == approx(lla0, rel=1e-4)
Esempio n. 10
0
def test_geodetic():
    assert_allclose(pm.ecef2geodetic(tx, ty, tz), (ec2la, ec2lo, ec2a),
                    rtol=0.01,
                    err_msg='ecef2geodetic: ' +
                    str(pm.ecef2geodetic(tx, ty, tz)))

    assert_allclose(pm.geodetic2aer(lat2, lon2, alt2, tlat, tlon, talt),
                    (g2az, g2el, g2rn),
                    rtol=0.05,
                    err_msg='geodetic2aer: {}'.format(
                        pm.geodetic2aer(lat2, lon2, alt2, tlat, tlon, talt)))

    assert_allclose(pm.geodetic2ecef(tlat, tlon, talt), (g2x, g2y, g2z),
                    rtol=0.01,
                    err_msg='geodetic2ecef: {}'.format(
                        pm.geodetic2ecef(tlat, tlon, talt)))
Esempio n. 11
0
def gpsSatPosition(fnav, dt, sv=None, rx_position=None, coords='xyz'):
    navdata = gr.load(fnav).sel(sv=sv)
    timesarray = np.asarray(dt,dtype='datetime64[ns]') #[datetime64 [ns]]
    # Manipulate with times, epochs and crap like this
    navtimes = navdata.time.values # [datetime64 [ns]]
    idnan = np.isfinite(navdata['Toe'].values)
    navtimes = navtimes[idnan]
    bestephind = []
    for t in timesarray:
        idt = abs(navtimes - t).argmin() #if t>navtimes[abs(navtimes - t).argmin()] else abs(navtimes - t).argmin()-1
        bestephind.append(idt)
#    bestephind = np.array([np.argmin(abs(navtimes-t)) for t in timesarray])
    gpstime = np.array([getGpsTime(t) for t in dt])
    t = gpstime - navdata['Toe'][idnan][bestephind].values # [datetime.datetime]
    # constants
    GM = 3986005.0E8 # universal gravational constant
    OeDOT = 7.2921151467E-5
    # Elements
    ecc = navdata['Eccentricity'][idnan][bestephind].values # Eccentricity
    Mk = navdata['M0'][idnan][bestephind].values + \
         t *(np.sqrt(GM / navdata['sqrtA'][idnan][bestephind].values**6) + 
             navdata['DeltaN'][idnan][bestephind].values)
    Ek = solveIter(Mk,ecc)
    Vk = np.arctan2(np.sqrt(1.0 - ecc**2) * np.sin(Ek), np.cos(Ek) - ecc)
    PhiK = Vk + navdata['omega'][idnan][bestephind].values
    # Perturbations
    delta_uk = navdata['Cuc'][idnan][bestephind].values * np.cos(2.0*PhiK) + \
              navdata['Cus'][idnan][bestephind].values * np.sin(2.0*PhiK)
    Uk = PhiK + delta_uk
    
    delta_rk = navdata['Crc'][idnan][bestephind].values * np.cos(2.0*PhiK) + \
               navdata['Crs'][idnan][bestephind].values * np.sin(2.0*PhiK)
    Rk = navdata['sqrtA'][idnan][bestephind].values**2 * (1.0 - ecc * np.cos(Ek)) + delta_rk
    
    delta_ik = navdata['Cic'][idnan][bestephind].values * np.cos(2.0*PhiK) + \
               navdata['Cis'][idnan][bestephind].values * np.sin(2.0*PhiK)
    Ik = navdata['Io'][idnan][bestephind].values + \
         navdata['IDOT'][idnan][bestephind].values * t + delta_ik
    
    #Compute the right ascension
    Omegak = navdata['Omega0'][idnan][bestephind].values + \
             (navdata['OmegaDot'][idnan][bestephind].values - OeDOT) * t - \
             (OeDOT * navdata['Toe'][idnan][bestephind].values)
             
    #X,Y coordinate corrections
    Xkprime = Rk * np.cos(Uk)
    Ykprime = Rk * np.sin(Uk)
    # ECEF XYZ
    X = Xkprime * np.cos(Omegak) - (Ykprime * np.sin(Omegak) * np.cos(Ik))
    Y = Xkprime * np.sin(Omegak) + (Ykprime * np.cos(Omegak) * np.cos(Ik))
    Z = Ykprime * np.sin(Ik)
    
    if coords == 'xyz':
        return np.array([X,Y,Z])
    elif coords == 'aer':
        assert rx_position is not None
        rec_lat, rec_lon, rec_alt = ecef2geodetic(rx_position[0], rx_position[1], rx_position[2])
        A,E,R = ecef2aer(X, Y, Z, rec_lat, rec_lon, rec_alt)
        return np.array([A,E,R])
def cartesian_to_spherical(vector):
	theta, phi = get_theta_phi(vector)
	ECEF = array(([1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]))
	if not theta and not phi:
		phi, theta, _ = pm.ecef2geodetic(vector[0], vector[1], vector[2])
		# print(theta, phi)
		phi = 90 - degrees(arccos(scal(ECEF[2], vector)))
	return radians(theta), radians(phi)
Esempio n. 13
0
def ecef_to_geodetic(point: Union[np.ndarray, Sequence[float]]) -> np.ndarray:
    """Convert given ECEF coordinate into latitude, longitude, altitude.

    Args:
        point (Union[np.ndarray, Sequence[float]]): ECEF coordinate vector

    Returns:
        np.ndarray: latitude, altitude, longitude
    """
    return np.array(pm.ecef2geodetic(point[0], point[1], point[2]))
Esempio n. 14
0
def plotnav(nav: xarray.Dataset):
    if nav is None:
        return

    svs = nav.sv.values

    ax = figure().gca(projection=cartopy.crs.PlateCarree())

    ax.add_feature(cpf.LAND)
    ax.add_feature(cpf.OCEAN)
    ax.add_feature(cpf.COASTLINE)
    ax.add_feature(cpf.BORDERS, linestyle=':')

    for sv in svs:
        if sv[0] == 'S':
            lat, lon, alt = ecef2geodetic(nav.sel(sv=sv)['X'].dropna(dim='time', how='all'),
                                          nav.sel(sv=sv)['Y'].dropna(
                                              dim='time', how='all'),
                                          nav.sel(sv=sv)['Z'].dropna(dim='time', how='all'))
            assert ((35.7e6 < alt) & (alt < 35.9e6)).all(
            ), 'unrealistic geostationary satellite altitudes'
            assert ((-1 < lat) & (lat < 1)
                    ).all(), 'unrealistic geostationary satellite latitudes'
        elif sv[0] == 'R':
            lat, lon, alt = ecef2geodetic(nav.sel(sv=sv)['X'].dropna(dim='time', how='all'),
                                          nav.sel(sv=sv)['Y'].dropna(
                                              dim='time', how='all'),
                                          nav.sel(sv=sv)['Z'].dropna(dim='time', how='all'))
            assert ((19.0e6 < alt) & (alt < 19.4e6)).all(
            ), 'unrealistic GLONASS satellite altitudes'
            assert ((-67 < lat) & (lat < 67)
                    ).all(), 'GPS inclination ~ 65 degrees'
        elif sv[0] == 'G':
            ecef = keplerian2ecef(nav.sel(sv=sv))
            lat, lon, alt = ecef2geodetic(*ecef)
            assert ((19.4e6 < alt) & (alt < 21.0e6)).all(
            ), 'unrealistic GPS satellite altitudes'
            assert ((-57 < lat) & (lat < 57)
                    ).all(), 'GPS inclination ~ 55 degrees'
        else:
            continue

        ax.plot(lon, lat, label=sv)
Esempio n. 15
0
        def getTileChildren(pnts_task):
            las_target = pnts_task.requires().output().load()
            data = las_target.obj.points['point']
            x_min = np.min(data['X'])
            x_max = np.max(data['X'])
            y_min = np.min(data['Y'])
            y_max = np.max(data['Y'])

            domain_min = np.dot(np.array([x_min, y_min, 0, 1]), mat_xyz)
            domain_max = np.dot(np.array([x_max, x_max, 0, 1]), mat_xyz)
            domain_latlon_min = pymap3d.ecef2geodetic(
                *tuple(domain_min[0:3].tolist()))
            domain_latlon_max = pymap3d.ecef2geodetic(
                *tuple(domain_max[0:3].tolist()))

            south, west, _ = domain_latlon_min
            north, east, _ = domain_latlon_max

            target_tile = os.path.basename(pnts_task.output().path)

            tileset_def = {
                'boundingVolume': {
                    'region': [
                        # TODO calcurate accurate bounding box
                        # west / 180.0 * math.pi,  # lon_min
                        # south / 180.0 * math.pi,  # lat_min
                        # east / 180.0 * math.pi,  # lon_max
                        # north / 180.0 * math.pi,  # lat_max
                        min(domain_lon) / 180.0 * math.pi,  # lon_min
                        min(domain_lat) / 180.0 * math.pi,  # lat_min
                        max(domain_lon) / 180.0 * math.pi,  # lon_max
                        max(domain_lat) / 180.0 * math.pi,  # lat_max
                        min(height_range),
                        max(height_range),
                    ]
                },
                'geometricError': 0,
                'refine': 'ADD',
                'content': {
                    'url': target_tile,
                },
            }
            return tileset_def
Esempio n. 16
0
def test_scalar_ecef2geodetic(xyz):
    """
    verify we can handle the wide variety of input data type users might use
    """
    if isinstance(xyz[0], list):
        pytest.importorskip("numpy")

    lat, lon, alt = pm.ecef2geodetic(*xyz)

    assert [lat, lon, alt] == approx(lla0, rel=1e-4)
def cartesian_to_galactic(system, vector):
    vector = unit(vector)
    system = normvec(system)
    ECEF = array(([1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]))
    R = transform_matrix(ECEF, system)
    vector_in_system = R.dot(vector)
    phi, theta, _ = pm.ecef2geodetic(vector_in_system[0], vector_in_system[1],
                                     vector_in_system[2])
    # print(theta, phi)
    return theta, phi
Esempio n. 18
0
def dump_for_hotspot(conn=conn):
    c = conn.cursor()
    sensors = []
    for row in c.execute("SELECT X, Y, Z, Amplitude FROM Sensors;"):
        lat, lon, _ = pm.ecef2geodetic(x, y, z)
        row = (x, z, Amplitude)
        sensors.append(row)
    sensors = np.array(sensors)
    sensors = latlon_to_fake_xy(sensors)
    return sensors
Esempio n. 19
0
def getIonosphericPiercingPoints(rx_xyz, sv, obstimes, ipp_alt, navfn,
                                 cs='wsg84', rx_xyz_coords='xyz', el0=0):
    """
    Sebastijan Mrak
    Function returns a list of Ionospheric Piersing Point (IPP) trajectory in WSG84
    coordinate system (CS). Function takes as parameter a receiver location in 
    ECEF CS, satellite number, times ob observation and desired altitude of a IPP
    trajectory. You also have to specify a full path to th navigation data file.
    It returns IPP location in either WSG84 or AER coordinate system.
    """
    
    ipp_alt = ipp_alt * 1E3
    if rx_xyz_coords == 'xyz':
        rec_lat, rec_lon, rec_alt = ecef2geodetic(rx_xyz[0], rx_xyz[1], rx_xyz[2])
    else:
        if not isinstance(rx_xyz, list): rx_xyz = list(rx_xyz)
        if len(rx_xyz) == 2: rx_xyz.append(0)
        assert len(rx_xyz) == 3
        
        rec_lat = rx_xyz[0]
        rec_lon = rx_xyz[1]
        rec_alt = rx_xyz[2]
        rx_xyz = geodetic2ecef(lat = rec_lon, lon = rec_lat, alt = rec_alt)
    
    if sv[0] == 'G':
        if navfn.endswith('n'):
            xyz = gpsSatPosition(navfn, obstimes, sv=sv, rx_position=rx_xyz, coords='xyz')
        elif navfn.endswith('sp3'):
            xyz = gpsSatPositionSP3(navfn, obstimes, sv=sv, rx_position=rx_xyz, coords='xyz')
        az,el,r = ecef2aer(xyz[0,:],xyz[1,:],xyz[2,:],rec_lat, rec_lon, rec_alt)
        aer_vector = np.array([az, el, r])
        
        r_new = []
        for i in range(len(el)):
            if el[i] > el0:
                fm = np.sin(np.radians(el[i]))
                r_new.append(ipp_alt / fm)
            else:
                r_new.append(np.nan)
        lla_vector = np.array(aer2geodetic(az, el, r_new, rec_lat, rec_lon, rec_alt))
        
    elif sv[0] == 'R':
        aer_vector = gloSatPosition(navfn=navfn, sv=sv, obstimes=obstimes, rx_position=[rec_lon, rec_lat, rec_alt], cs='aer')
        fm = np.sin(np.radians(aer_vector[1]))
        r_new = ipp_alt / fm
        lla_vector = np.array(aer2geodetic(aer_vector[0], aer_vector[1], r_new, rec_lat, rec_lon, rec_alt))
    else:
        print ('Type in valid sattype initial. "G" for GPS and "R" for GLONASS')
        
    if (cs == 'wsg84'):
        return lla_vector
    elif (cs == 'aer'):
        return aer_vector
    else:
        print ('Enter either "wsg84" or "aer" as coordinate system. "wsg84" is default one.')
Esempio n. 20
0
def RAY_INTERSECT_WGS84(point, ray_dir, t):
    #-----WGS 84 --------------
    dat_a = 6378137  #Meters
    dat_f = 1 / 298.257223563  #flat scale for oblateness
    dat_ep = 1 / ((1 - dat_f) * (1 - dat_f))

    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]

    qa = xd**2 + yd**2 + (zd**2) * dat_ep
    qb = 2 * (xc * xd + yc * yd + zc * zd * dat_ep)
    qc = xc**2 + yc**2 + ((zc**2) * dat_ep) - (dat_a**2)

    ray_roots = np.roots([qa, qb, qc])
    earth_point = []
    earth_point.append([
        xc + ray_roots[0] * xd, yc + ray_roots[0] * yd, zc + ray_roots[0] * zd
    ])
    earth_point.append([
        xc + ray_roots[1] * xd, yc + ray_roots[1] * yd, zc + ray_roots[1] * zd
    ])

    #print(earth_point)
    #6371e3 * np.vstack(ecef)
    #print('--NORMS '+str(np.linalg.norm(earth_point[0]))+'--:--'+str(np.linalg.norm(earth_point[1]))+'\n')

    #print('\n\n ---------- STATE VECTOR 2 NORMAL PROJECTION -------------- \n')
    #print(earth_point)
    #print(6371e3*np.vstack(earth_point[0]))
    earth_point[0] = pm.eci2ecef((earth_point[1]), t)
    #earth_point[0]=6371e3*np.array(earth_point[0])
    # 6371e3 * np.vstack(ecef)
    ecx = -1 * earth_point[0][0]
    ecy = -1 * earth_point[0][1]
    ecz = -1 * earth_point[0][2]
    #print((ecx**2+ecy**2+ecz**2)**0.5)
    #print("LAT(deg) LON(deg) HEIGHT(m) :"+str(pm.ecef2geodetic(ecx,ecy,ecz)))
    #print("LAT(deg) LON(deg) HEIGHT(m) :"+str(ECI_TO_WGS84LLH(-1*np.array(earth_point[0]),t  )))
    #print("LAT(deg) LON(deg) HEIGHT(m) :"+str(ECEF_TO_WGS84LLH(-1*np.array(earth_point[0]))))
    #earth_point[0]=np.array([ecx,ecy,ecz))/1000
    #llh=pm.ecef2geodetic(ecx,ecy,ecz)
    # ecef = pyproj.Proj(proj='geocent', ellps='WGS84', datum='WGS84')
    # lla = pyproj.Proj(proj='latlong', ellps='WGS84', datum='WGS84')
    # lon, lat, alt = pyproj.transform(ecef, lla, ecx, ecy, ecz, radians=False)
    llh = pm.ecef2geodetic(ecx, ecy, ecz)
    #print("LAT(deg) LON(deg) HEIGHT(m) :"+str(llh))
    #print('---------- ------------------------------- -------------- \n')
    #print(llh)
    return (llh)
Esempio n. 21
0
 def ecef2EnuMat(self, origin, scene_origin = np.array([4.40145e+06, 597011, 4.56599e+06])):
     ell = pm3d.EarthEllipsoid(model='wgs84')
     phi, lam, alt = pm3d.ecef2geodetic(origin[0] + scene_origin[0], origin[1] + scene_origin[1], origin[2] + scene_origin[2], ell)
     """ phi is latitude, lam is longitude
         transformation taken from:
         https://gssc.esa.int/navipedia/index.php/Transformations_between_ECEF_and_ENU_coordinates
     """
     pi_2 = np.pi / 2.0
     rx = self.Rx(pi_2 - phi)
     rz = self.Rz(pi_2 + lam)
     return rx.dot(rz)
def cartesian_to_galactic(system, vector):
	vector = unit(vector)
	system = normvec(system)
	ECEF = array(([1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]))
	R = transform_matrix(ECEF, system)
	vector_in_system = around(R.dot(vector), decimals = 3)
	# print(vector_in_system)
	theta, phi = get_theta_phi(vector_in_system)
	if not theta and not phi:
		phi, theta, _ = pm.ecef2geodetic(vector_in_system[0], vector_in_system[1], vector_in_system[2])
		# print(theta, phi)
		phi = 90 - degrees(arccos(scal(ECEF[2], vector_in_system)))
	return theta, phi
Esempio n. 23
0
 def ecef2enu(self, M, origin, scene_origin = np.array([4.40145e+06, 597011, 4.56599e+06])):
     """M is a row-wise atrix of 3D ecef points
        origin is a vector in ecef defining the origin for ENU
        scene_origin will be added to both origin and each point in M before
        the transformation
     """
     ell = pm3d.EarthEllipsoid(model='wgs84')
     lat, lon, alt = pm3d.ecef2geodetic(origin[0] + scene_origin[0], origin[1] + scene_origin[1], origin[2] + scene_origin[2], ell)
     res = []
     for i in range(M.shape[0]):
         e,n,u = pm3d.ecef2enu(M[i,0] + scene_origin[0], M[i,1] + scene_origin[1], M[i,2] + scene_origin[2], lat, lon, alt, ell)
         res.append(np.array([e,n,u]))
     return np.array(res)
Esempio n. 24
0
def test_xarray():
    xarray = pytest.importorskip("xarray")
    xr_lla = xarray.DataArray(list(lla0))

    xyz = pm.geodetic2ecef(*xr_lla)

    assert xyz == approx(xyz0)
    # %%
    xr_xyz = xarray.DataArray(list(xyz0))

    lla = pm.ecef2geodetic(*xr_xyz)

    assert lla == approx(lla0)
Esempio n. 25
0
def test_ellipsoid():

    assert pm.ecef2geodetic(*xyz0, ell=pm.Ellipsoid('wgs84')) == approx([42.014670535, -82.0064785, 276.9136916])
    assert pm.ecef2geodetic(*xyz0, ell=pm.Ellipsoid('grs80')) == approx([42.014670536, -82.0064785, 276.9137385])
    assert pm.ecef2geodetic(*xyz0, ell=pm.Ellipsoid('clarke1866')) == approx([42.01680003, -82.0064785, 313.9026793])
    assert pm.ecef2geodetic(*xyz0, ell=pm.Ellipsoid('mars')) == approx([42.009428417, -82.006479, 2.981246e6])
    assert pm.ecef2geodetic(*xyz0, ell=pm.Ellipsoid('venus')) == approx([41.8233663, -82.0064785, 3.17878159e5])
    assert pm.ecef2geodetic(*xyz0, ell=pm.Ellipsoid('moon')) == approx([41.8233663, -82.0064785, 4.630878e6])
Esempio n. 26
0
    def pPosition(self, h: str):
        """ Write coordaintes in list and convert to geodetic
        """
        try:
            self.position = [float(x) for x in h.split()]
            try:
                from pymap3d import ecef2geodetic
            except ImportError:
                ecef2geodetic = None
            if ecef2geodetic is not None:
                self.positionGeodetic = ecef2geodetic(*self.position)

        except (KeyError, ValueError):
            self.position = None
Esempio n. 27
0
def plotLOSecef(cam,odir):
    fg = figure()

    if odir and skml is not None:
        kml1d = skml.Kml()

    for C in cam:
        if not C.usecam:
            continue

        ax = fg.gca(projection='3d')
        ax.plot(xs=C.x2mz, ys=C.y2mz, zs=C.z2mz, zdir='z', label=str(C.name))
        ax.set_title('LOS to magnetic zenith in ECEF')
        ax.set_xlabel('x [m]')
        ax.set_ylabel('y [m]')
        ax.set_zlabel('z [m]')

        if odir and skml is not None: #Write KML
            #convert LOS ECEF -> LLA
            loslat,loslon,losalt = ecef2geodetic(C.x2mz, C.y2mz, C.z2mz)
            kclr = ['ff5c5ccd','ffff0000']
            #camera location points
            bpnt = kml1d.newpoint(name='HST {}'.format(C.name),
                                  description='camera {} location'.format(C.name),
                                  coords=[(C.lon, C.lat)])
            bpnt.altitudemode = skml.AltitudeMode.clamptoground
            bpnt.style.iconstyle.icon.href = 'http://maps.google.com/mapfiles/kml/paddle/pink-blank.png'
            bpnt.style.iconstyle.scale = 2.0
            #show cam to mag zenith los
            linestr = kml1d.newlinestring(name='')
            #TODO this is only first and last point without middle!
            linestr.coords = [(loslon[0],   loslat[0],  losalt[0]),
                              (loslon[-1], loslat[-1], losalt[-1])]
            linestr.altitudemode = skml.AltitudeMode.relativetoground
            linestr.style.linestyle.color = kclr[C.name]

    ax.legend()
    if C.verbose:
        show()

    if odir and skml is not None:
        kmlfn = odir / 'debug1dcut.kmz'
        print(f'saving {kmlfn}')
        kml1d.savekmz(str(kmlfn))

    if odir:
        ofn = odir / 'ecef_cameras.eps'
        print(f'saving {ofn}')
        fg.savefig(ofn,bbox_inches='tight')
Esempio n. 28
0
    def __make_log(self, rocket):
        self.pos_onlauncer_LLH_log = np.array([
            pm.ned2geodetic(pos_NED[0], pos_NED[1], pos_NED[2],
                            rocket.pos0_LLH[0], rocket.pos0_LLH[1],
                            rocket.pos0_LLH[2])
            for pos_NED in self.pos_onlauncher_NED_log
        ])
        self.downrange_log = np.array([
            pm.vincenty.vdist(rocket.pos0_LLH[0], rocket.pos0_LLH[1], pos[0],
                              pos[1]) for pos in self.pos_LLH_log
        ])[:, 0]
        self.vel_AIR_BODYframe_abs_log = np.array(
            [np.linalg.norm(vel) for vel in self.vel_AIR_BODYframe_log])
        DCM_NED2BODY_log = np.array(
            [coord.DCM_NED2BODY_quat(quat) for quat in self.quat_log])
        self.attitude_log = np.array(
            [coord.quat2euler(DCM) for DCM in DCM_NED2BODY_log])
        self.pos_NED_log = np.array([
            pm.ecef2ned(pos_ECEF[0], pos_ECEF[1], pos_ECEF[2],
                        rocket.pos0_LLH[0], rocket.pos0_LLH[1],
                        rocket.pos0_LLH[2]) for pos_ECEF in self.pos_ECEF_log
        ])

        self.pos_decent_ECEF_log = np.array([
            coord.DCM_ECI2ECEF(t).dot(pos_ECI) for pos_ECI, t in zip(
                self.pos_decent_ECI_log, self.time_decent_log)
        ])
        self.pos_decent_LLH_log = np.array([
            pm.ecef2geodetic(pos[0], pos[1], pos[2])
            for pos in self.pos_decent_ECEF_log
        ])
        self.vel_decent_NED_log = np.array([
            coord.DCM_ECEF2NED(rocket.pos0_LLH).dot(
                coord.vel_ECI2ECEF(vel_eci, coord.DCM_ECI2ECEF(t), pos_eci))
            for vel_eci, t, pos_eci in
            zip(self.vel_decent_ECI_log, self.time_decent_log,
                self.pos_decent_ECI_log)
        ])
        self.downrange_decent_log = np.array([
            pm.vincenty.vdist(rocket.pos0_LLH[0], rocket.pos0_LLH[1], pos[0],
                              pos[1]) for pos in self.pos_decent_LLH_log
        ])[:, 0]

        self.pos_hard_LLH_log = np.r_[self.pos_onlauncer_LLH_log,
                                      self.pos_LLH_log]
        index = np.argmax(self.time_log > self.time_decent_log[0])
        self.pos_soft_LLH_log = np.r_[self.pos_onlauncer_LLH_log,
                                      self.pos_LLH_log[:index, :],
                                      self.pos_decent_LLH_log]
Esempio n. 29
0
def test_xarray():
    xarray = pytest.importorskip('xarray')
    xr_lla = xarray.DataArray(list(lla0))

    xyz = pm.geodetic2ecef(*xr_lla)

    assert xyz == approx(xyz0)
    assert isinstance(xyz[0], xarray.DataArray)
# %%
    xr_xyz = xarray.DataArray(list(xyz0))

    lla = pm.ecef2geodetic(*xr_xyz)

    assert lla == approx(lla0)
    assert isinstance(lla[0], float)  # xarrayness is lost, possibly expensive to keep due to isinstance()
Esempio n. 30
0
    def __get_point(lines):
        m = numpy.zeros([3, 3])
        left = numpy.zeros([3, 3])
        right = numpy.zeros([3])

        for origin, direction in lines:
            m = numpy.identity(3) - \
                numpy.column_stack([numpy.array([direction * direction[0]]).T,
                numpy.array([direction * direction[1]]).T,
                numpy.array([direction * direction[2]]).T])
            left += m
            right += m.dot(origin)

        output = numpy.linalg.inv(left).dot(right)

        return numpy.array(pymap3d.ecef2geodetic(*output))
Esempio n. 31
0
def test_ellipsoid():

    assert pm.ecef2geodetic(*xyz0, ell=pm.Ellipsoid('wgs84')) == approx(
        [42., -82., 200.24339])
    assert pm.ecef2geodetic(*xyz0, ell=pm.Ellipsoid('grs80')) == approx(
        [42., -82., 200.24344])
    assert pm.ecef2geodetic(*xyz0, ell=pm.Ellipsoid('clrk66')) == approx(
        [42.00213, -82., 237.17182])
    assert pm.ecef2geodetic(*xyz0, ell=pm.Ellipsoid('mars')) == approx(
        [41.99476, -82., 2.981169e6])
    assert pm.ecef2geodetic(*xyz0, ell=pm.Ellipsoid('venus')) == approx(
        [41.808706, -82., 3.178069e5])
    assert pm.ecef2geodetic(*xyz0, ell=pm.Ellipsoid('moon')) == approx(
        [41.808706, -82., 4.630807e6])
Esempio n. 32
0
def parachute_dynamics(x, t, rocket):
    pos_ECI = x[0:3]
    vel_ECI = x[3:6]

    DCM_ECI2ECEF = coord.DCM_ECI2ECEF(t)
    pos_ECEF = DCM_ECI2ECEF.dot(pos_ECI)
    pos_LLH = pm.ecef2geodetic(pos_ECEF[0], pos_ECEF[1], pos_ECEF[2])

    altitude = pos_LLH[2]
    DCM_ECEF2NED = coord.DCM_ECEF2NED(rocket.pos0_LLH)
    vel_ECEF = coord.vel_ECI2ECEF(vel_ECI, DCM_ECI2ECEF, pos_ECI)
    vel_NED = DCM_ECEF2NED.dot(vel_ECEF)
    vel_decent = vel_NED[2]

    g_NED = np.array([0.0, 0.0, env.gravity(altitude)])
    Ta, Pa, rho, Cs = env.std_atmo(altitude)
    if rocket.timer_mode:
        if t > rocket.t_2nd_max or (altitude <= rocket.alt_sepa2
                                    and t > rocket.t_2nd_min):
            CdS = rocket.CdS1 + rocket.CdS2
        else:
            CdS = rocket.CdS1
    else:
        CdS = rocket.CdS1 + rocket.CdS2 if altitude <= rocket.alt_sepa2 else rocket.CdS1

    drag_NED = np.array(
        [0, 0, -0.5 * rho * vel_decent * np.abs(vel_decent) * CdS])
    acc_NED = drag_NED / rocket.m_burnout + g_NED
    acc_ECI = DCM_ECI2ECEF.transpose().dot(
        DCM_ECEF2NED.transpose().dot(acc_NED))

    wind_NED = env.Wind_NED(rocket.wind_speed(altitude),
                            rocket.wind_direction(altitude))
    vel_NED = vel_NED + wind_NED
    vel_ecef = DCM_ECEF2NED.transpose().dot(vel_NED)
    vel_ECI = coord.vel_ECEF2ECI(vel_ecef, DCM_ECI2ECEF, pos_ECI)

    dx = np.zeros(6)
    dx[0:3] = vel_ECI
    dx[3:6] = acc_ECI

    return dx
Esempio n. 33
0
def test_ecef2geodetic(xyz, lla):
    assert pm.ecef2geodetic(*xyz) == approx(lla)
Esempio n. 34
0
def test_somenan():
    xyz = np.stack((xyz0, (nan, nan, nan)))

    lat, lon, alt = pm.ecef2geodetic(xyz[:, 0], xyz[:, 1], xyz[:, 2])
    assert (lat[0], lon[0], alt[0]) == approx(lla0)
Esempio n. 35
0
def obsheader2(f: TextIO,
               useindicators: bool = False,
               meas: Sequence[str] = None) -> Dict[str, Any]:
    """
    End users should use rinexheader()
    """
    if isinstance(f, (str, Path)):
        with opener(f, header=True) as h:
            return obsheader2(h, useindicators, meas)

    f.seek(0)
# %% selection
    if isinstance(meas, str):
        meas = [meas]

    if not meas or not meas[0].strip():
        meas = None

    hdr = rinexinfo(f)
    Nobs = 0  # not None due to type checking

    for ln in f:
        if "END OF HEADER" in ln:
            break

        h = ln[60:80].strip()
        c = ln[:60]
# %% measurement types
        if '# / TYPES OF OBSERV' in h:
            if Nobs == 0:
                Nobs = int(c[:6])
                hdr[h] = c[6:].split()
            else:
                hdr[h] += c[6:].split()
        elif h not in hdr:  # Header label
            hdr[h] = c  # string with info
        else:  # concatenate
            hdr[h] += " " + c
# %% useful values
    try:
        hdr['systems'] = hdr['RINEX VERSION / TYPE'][40]
    except KeyError:
        pass

    hdr['Nobs'] = Nobs
    # 5 observations per line (incorporating LLI, SSI)
    hdr['Nl_sv'] = ceil(hdr['Nobs'] / 5)
# %% list with receiver location in x,y,z cartesian ECEF (OPTIONAL)
    try:
        hdr['position'] = [float(j) for j in hdr['APPROX POSITION XYZ'].split()]
        if ecef2geodetic is not None:
            hdr['position_geodetic'] = ecef2geodetic(*hdr['position'])
    except (KeyError, ValueError):
        pass
# %% observation types
    try:
        hdr['fields'] = hdr['# / TYPES OF OBSERV']
        if Nobs != len(hdr['fields']):
            raise ValueError(f'{f.name} header read incorrectly')

        if isinstance(meas, (tuple, list, np.ndarray)):
            ind = np.zeros(len(hdr['fields']), dtype=bool)
            for m in meas:
                for i, f in enumerate(hdr['fields']):
                    if f.startswith(m):
                        ind[i] = True

            hdr['fields_ind'] = np.nonzero(ind)[0]
        else:
            ind = slice(None)
            hdr['fields_ind'] = np.arange(Nobs)

        hdr['fields'] = np.array(hdr['fields'])[ind].tolist()
    except KeyError:
        pass

    hdr['Nobsused'] = hdr['Nobs']
    if useindicators:
        hdr['Nobsused'] *= 3

# %%
    try:
        hdr['# OF SATELLITES'] = int(hdr['# OF SATELLITES'][:6])
    except (KeyError, ValueError):
        pass
# %% time
    try:
        hdr['t0'] = _timehdr(hdr['TIME OF FIRST OBS'])
    except (KeyError, ValueError):
        pass

    try:
        hdr['t1'] = _timehdr(hdr['TIME OF LAST OBS'])
    except (KeyError, ValueError):
        pass

    try:  # This key is OPTIONAL
        hdr['interval'] = float(hdr['INTERVAL'][:10])
    except (KeyError, ValueError):
        pass

    return hdr
Esempio n. 36
0
def navtimeseries(nav: xarray.Dataset):
    if not isinstance(nav, xarray.Dataset):
        return

    svs = nav.sv.values

    if cartopy is not None:
        ax = figure().gca(projection=cartopy.crs.PlateCarree())

        ax.add_feature(cpf.LAND)
        ax.add_feature(cpf.OCEAN)
        ax.add_feature(cpf.COASTLINE)
        ax.add_feature(cpf.BORDERS, linestyle=':')
    else:
        ax = figure().gca()

    for sv in svs:
        if sv[0] == 'S':
            lat, lon, alt = pm.ecef2geodetic(nav.sel(sv=sv)['X'].dropna(dim='time', how='all'),
                                             nav.sel(sv=sv)['Y'].dropna(
                dim='time', how='all'),
                nav.sel(sv=sv)['Z'].dropna(dim='time', how='all'))

            if ((alt < 35.7e6) | (alt > 35.9e6)).any():
                logging.warning('unrealistic geostationary satellite altitudes')

            if ((lat < -1) | (lat > 1)).any():
                logging.warning('unrealistic geostationary satellite latitudes')

        elif sv[0] == 'R':
            lat, lon, alt = pm.ecef2geodetic(nav.sel(sv=sv)['X'].dropna(dim='time', how='all'),
                                             nav.sel(sv=sv)['Y'].dropna(
                dim='time', how='all'),
                nav.sel(sv=sv)['Z'].dropna(dim='time', how='all'))

            if ((alt < 19.0e6) | (alt > 19.4e6)).any():
                logging.warning('unrealistic GLONASS satellite altitudes')

            if ((lat < -67) | (lat > 67)).any():
                logging.warning('GLONASS inclination ~ 65 degrees')

        elif sv[0] == 'G':
            ecef = keplerian2ecef(nav.sel(sv=sv))
            lat, lon, alt = pm.ecef2geodetic(*ecef)

            if ((alt < 19.4e6) | (alt > 21.0e6)).any():
                logging.warning('unrealistic GPS satellite altitudes')

            if ((lat < -57) | (lat > 57)).any():
                logging.warning('GPS inclination ~ 55 degrees')
        elif sv[0] == 'E':
            ecef = keplerian2ecef(nav.sel(sv=sv))
            lat, lon, alt = pm.ecef2geodetic(*ecef)

            if ((alt < 23e6) | (alt > 24e6)).any():
                logging.warning('unrealistic Galileo satellite altitudes')

            if ((lat < -57) | (lat > 57)).any():
                logging.warning('Galileo inclination ~ 56 degrees')

        else:
            continue

        ax.plot(lon, lat, label=sv)
Esempio n. 37
0
def obsheader3(f: TextIO,
               use: Sequence[str] = None,
               meas: Sequence[str] = None) -> Dict[str, Any]:
    """
    get RINEX 3 OBS types, for each system type
    optionally, select system type and/or measurement type to greatly
    speed reading and save memory (RAM, disk)
    """
    if isinstance(f, (str, Path)):
        with opener(f, header=True) as h:
            return obsheader3(h, use, meas)

    fields = {}
    Fmax = 0

# %% first line
    hdr = rinexinfo(f)

    for ln in f:
        if "END OF HEADER" in ln:
            break

        h = ln[60:80]
        c = ln[:60]
        if 'SYS / # / OBS TYPES' in h:
            k = c[0]
            fields[k] = c[6:60].split()
            N = int(c[3:6])
# %% maximum number of fields in a file, to allow fast Numpy parse.
            Fmax = max(N, Fmax)

            n = N-13
            while n > 0:  # Rinex 3.03, pg. A6, A7
                ln = f.readline()
                assert 'SYS / # / OBS TYPES' in ln[60:]
                fields[k] += ln[6:60].split()
                n -= 13

            assert len(fields[k]) == N

            continue

        if h.strip() not in hdr:  # Header label
            hdr[h.strip()] = c  # don't strip for fixed-width parsers
            # string with info
        else:  # concatenate to the existing string
            hdr[h.strip()] += " " + c

# %% list with x,y,z cartesian (OPTIONAL)
    try:
        hdr['position'] = [float(j) for j in hdr['APPROX POSITION XYZ'].split()]
        if ecef2geodetic is not None:
            hdr['position_geodetic'] = ecef2geodetic(*hdr['position'])
    except (KeyError, ValueError):
        pass
# %% time
    try:
        t0s = hdr['TIME OF FIRST OBS']
        # NOTE: must do second=int(float()) due to non-conforming files
        hdr['t0'] = datetime(year=int(t0s[:6]), month=int(t0s[6:12]), day=int(t0s[12:18]),
                             hour=int(t0s[18:24]), minute=int(t0s[24:30]), second=int(float(t0s[30:36])),
                             microsecond=int(float(t0s[30:43]) % 1 * 1000000))
    except (KeyError, ValueError):
        pass

    try:
        hdr['interval'] = float(hdr['INTERVAL'][:10])
    except (KeyError, ValueError):
        pass
# %% select specific satellite systems only (optional)
    if use is not None:
        if not set(fields.keys()).intersection(use):
            raise KeyError(f'system type {use} not found in RINEX file')

        fields = {k: fields[k] for k in use if k in fields}

    # perhaps this could be done more efficiently, but it's probably low impact on overall program.
    # simple set and frozenset operations do NOT preserve order, which would completely mess up reading!
    sysind = {}
    if isinstance(meas, (tuple, list, np.ndarray)):
        for sk in fields:  # iterate over each system
            # ind = np.isin(fields[sk], meas)  # boolean vector
            ind = np.zeros(len(fields[sk]), dtype=bool)
            for m in meas:
                for i, f in enumerate(fields[sk]):
                    if f.startswith(m):
                        ind[i] = True

            fields[sk] = np.array(fields[sk])[ind].tolist()
            sysind[sk] = np.empty(Fmax*3, dtype=bool)  # *3 due to LLI, SSI
            for j, i in enumerate(ind):
                sysind[sk][j*3:j*3+3] = i
    else:
        sysind = {k: slice(None) for k in fields}

    hdr['fields'] = fields
    hdr['fields_ind'] = sysind
    hdr['Fmax'] = Fmax

    return hdr