def ecef2eci(x, y, z, dt): #This function takes a position in the ECI-J2000 corrdinate system and returns it #in ECEF. # # Input # x = ECI X-coordinate (m) # y = ECI Y-coordinate (m) # z = ECI Z-coordinate (m) # dt = UTC time (datetime object) # # # Output # # convert datetime object to astropy time object tt = time.Time(dt, format='datetime') # Read the coordinates in the Geocentric Celestial Reference System itrs = ITRS(CartesianRepresentation(x=x * units.km, y=y * units.km, z=z * units.km), obstime=tt) # Convert it to an Earth-fixed frame gcrs = itrs.transform_to(GCRS(obstime=tt)) x = gcrs.cartesian.x y = gcrs.cartesian.y z = gcrs.cartesian.z return x, y, z
def ecef2eci(time,r_ecef,v_ecef,init_gps_weeknum): """Returns a tuple of position and velocity in ECI""" coord_ecef=ITRS(x=r_ecef[0]*u.m, y=r_ecef[1]*u.m, z=r_ecef[2]*u.m, v_x=v_ecef[0]*u.m/u.s, v_y=v_ecef[1]*u.m/u.s, v_z=v_ecef[2]*u.m/u.s, representation_type=CartesianRepresentation, differential_type=CartesianDifferential, obstime=time2astropyTime(time,init_gps_weeknum)) coord_eci= coord_ecef.transform_to(GCRS(obstime=time2astropyTime(time,init_gps_weeknum))) return (coord_eci.cartesian.xyz.to_value(u.m),coord_eci.velocity.d_xyz.to_value(u.m/u.s))
def ECEF2ECI_pos(Pos_ECEF, t): T = Time(t, format='jd', scale='utc') Pos_ECEF_SC = ITRS(x=Pos_ECEF[0] * u.m, y=Pos_ECEF[1] * u.m, z=Pos_ECEF[2] * u.m, obstime=T) Pos_ECI_SC = Pos_ECEF_SC.transform_to(GCRS(obstime=T)) Pos_ECI = np.vstack(Pos_ECI_SC.cartesian.xyz.value) return Pos_ECI
def setup_class(cls): cls.loc = loc = EarthLocation.from_geodetic( np.linspace(0, 360, 6)*u.deg, np.linspace(-90, 90, 6)*u.deg, 100*u.m) cls.obstime = obstime = Time(np.linspace(2000, 2010, 6), format='jyear') # Get comparison via a full transformation. We do not use any methods # of EarthLocation, since those depend on the fast transform. loc_itrs = ITRS(loc.x, loc.y, loc.z, obstime=obstime) zeros = np.broadcast_to(0. * (u.km / u.s), (3,) + loc_itrs.shape, subok=True) loc_itrs.data.differentials['s'] = CartesianDifferential(zeros) loc_gcrs_cart = loc_itrs.transform_to(GCRS(obstime=obstime)).cartesian cls.obsgeoloc = loc_gcrs_cart.without_differentials() cls.obsgeovel = loc_gcrs_cart.differentials['s'].to_cartesian()
def ecef_to_eci(r: np.ndarray, time: Time) -> np.ndarray: """ Converts coordinates in Earth Centered Earth Initial frame to Earth Centered Initial. :param r: position of satellite in ECEF frame. Units [km] :param time: Time of observation """ itrs = ITRS(CartesianRepresentation(r[0] * u.km, r[1] * u.km, r[2] * u.km), obstime=time) gcrs = itrs.transform_to(GCRS(obstime=time)) x_eci = gcrs.cartesian.x.value y_eci = gcrs.cartesian.y.value z_eci = gcrs.cartesian.z.value return np.array([x_eci, y_eci, z_eci])
def ecef2eci(x, y, z, dt): """This function takes a position in the ECEF coordinate system [m] and datetime.object [utc] and returns it in ECI-J2000 [m].""" # # Input # x = ECEF X-coordinate (m) # y = ECEF Y-coordinate (m) # z = ECEF Z-coordinate (m) # dt = UTC time (datetime object) # # # Output # # convert datetime object to astropy time object tt = time.Time(dt, format="datetime") # Read the coordinates in the Earth-fixed frame itrs = ITRS( CartesianRepresentation(x=x * units.m, y=y * units.m, z=z * units.m), obstime=tt ) # Convert it to Geocentric Celestial Reference System # gcrs = itrs.transform_to(itrs(obstime=tt)) gcrs = itrs.transform_to(GCRS(obstime=tt)) x = gcrs.cartesian.x.to_value() y = gcrs.cartesian.y.to_value() z = gcrs.cartesian.z.to_value() return x, y, z
def test_teme_itrf(): """ Test case transform from TEME to ITRF. Test case derives from example on appendix C of Vallado, Crawford, Hujsak & Kelso (2006). See https://celestrak.com/publications/AIAA/2006-6753/AIAA-2006-6753-Rev2.pdf """ v_itrf = CartesianDifferential(-3.225636520, -2.872451450, 5.531924446, unit=u.km / u.s) p_itrf = CartesianRepresentation(-1033.479383, 7901.2952740, 6380.35659580, unit=u.km, differentials={'s': v_itrf}) t = Time("2004-04-06T07:51:28.386") teme = ITRS(p_itrf, obstime=t).transform_to(TEME(obstime=t)) v_teme = CartesianDifferential(-4.746131487, 0.785818041, 5.531931288, unit=u.km / u.s) p_teme = CartesianRepresentation(5094.18016210, 6127.64465050, 6380.34453270, unit=u.km, differentials={'s': v_teme}) assert_allclose(teme.cartesian.without_differentials().xyz, p_teme.without_differentials().xyz, atol=30 * u.cm) assert_allclose(teme.cartesian.differentials['s'].d_xyz, p_teme.differentials['s'].d_xyz, atol=1.0 * u.cm / u.s) # test round trip itrf = teme.transform_to(ITRS(obstime=t)) assert_allclose(itrf.cartesian.without_differentials().xyz, p_itrf.without_differentials().xyz, atol=100 * u.cm) assert_allclose(itrf.cartesian.differentials['s'].d_xyz, p_itrf.differentials['s'].d_xyz, atol=1 * u.cm / u.s)
def ecef_to_itrs(ecef, itrs): """Compute the transformation from ECEF to ITRS coordinates Parameters ---------- ecef : ECEF The initial coordinates in ECEF itrs : ITRS The ITRS frame to transform to Returns ------- ITRS The ITRS frame with transformed coordinates """ if itrs._obstime == ecef._obstime: c = ecef.cartesian else: itrs0 = ITRS(ecef.cartesian, obstime=ecef._obstime) c = itrs0.transform_to(ITRS(obstime=itrs._obstime)).cartesian return itrs.realize_frame(c)
def ecef2eci( x: "ndarray", y: "ndarray", z: "ndarray", time: datetime, *, use_astropy: bool = True ) -> typing.Tuple["ndarray", "ndarray", "ndarray"]: """ Point => Point ECEF => ECI J2000 frame Parameters ---------- x : "ndarray" target x ECEF coordinate y : "ndarray" target y ECEF coordinate z : "ndarray" target z ECEF coordinate time : datetime.datetime time of observation use_astropy: bool, optional use AstroPy (much more accurate) Results ------- x_eci : "ndarray" x ECI coordinate y_eci : "ndarray" y ECI coordinate z_eci : "ndarray" z ECI coordinate """ if use_astropy and Time is not None: itrs = ITRS(CartesianRepresentation(x * u.m, y * u.m, z * u.m), obstime=time) gcrs = itrs.transform_to(GCRS(obstime=time)) eci = EarthLocation(*gcrs.cartesian.xyz) x_eci = eci.x.value y_eci = eci.y.value z_eci = eci.z.value else: x = atleast_1d(x) y = atleast_1d(y) z = atleast_1d(z) gst = atleast_1d(greenwichsrt(juliandate(time))) assert x.shape == y.shape == z.shape assert x.size == gst.size ecef = column_stack((x.ravel(), y.ravel(), z.ravel())) eci = empty((x.size, 3)) for i in range(x.size): eci[i, :] = R3(gst[i]).T @ ecef[i, :] x_eci = eci[:, 0].reshape(x.shape) y_eci = eci[:, 1].reshape(y.shape) z_eci = eci[:, 2].reshape(z.shape) return x_eci, y_eci, z_eci
json_list = [] print('Parsing file and converting to ECI...') with open(sys.argv[1], "r") as f: for line in f: temp = line.split() epoch_utc = Time(temp[4], scale='utc', format='isot') v = CartesianDifferential(list(np.float_(temp[17:20]))*(u.m/u.s)) r = CartesianRepresentation(list(np.float_(temp[14:17]))*u.m, differentials={'s': v}) r_ecef = ITRS(r, obstime=epoch_utc) r_eci_temp = r_ecef.transform_to(GCRS(obstime=epoch_utc)) v_eci = r_eci_temp.cartesian.differentials['s'].d_xyz # this may be off from Jonathan's initial notebook test r_eci = r_eci_temp.cartesian.xyz utc_ms = temp[4][:-3] # FIXME -- orbdetpy can handle 6 digits of precision in time so need to remove this json_object = {"Time": utc_ms + "Z", # add this to maintain ISO8601 format for orbdetpy "PositionVelocity": [ r_eci[0].value, r_eci[1].value, r_eci[2].value, v_eci[0].value*1000, # not sure why this changed to km/s v_eci[1].value*1000, v_eci[2].value*1000 ] } json_list.append(json_object)