Exemplo n.º 1
0
def receive_time(station_id, sc_id, sc_time, max_error=1e-7, **kwargs):
    t2 = sc_time
    if type(sc_id) == int:
        x2 = spice.spkez(sc_id, t2, 'J2000', 'NONE', 399)[0]
    else:
        x2 = sc_id
    x3 = spice.spkez(station_id, t2, 'J2000', 'NONE', 399)[0]
    t3 = t2 + light_time(x2, x3, **kwargs)
    dt = max_error * 2

    while np.abs(dt) > max_error:
        x3 = spice.spkez(station_id, t3, 'J2000', 'NONE', 399)[0]
        df_dt = -1 + np.dot(
            (x3[0:3] - x2[0:3]) / norm(x3[0:3] - x2[0:3]), x3[3:6])
        f = t3 - t2 - light_time(x2, x3, **kwargs)
        dt = -f / df_dt
        t3 += dt

    return t3
Exemplo n.º 2
0
def send_time(station_id, sc_id, sc_time, max_error=1e-7, **kwargs):
    t2 = sc_time
    if type(sc_id) == int:
        x2 = spice.spkez(sc_id, t2, 'J2000', 'NONE', 399)[0]
    else:
        x2 = sc_id
    x1 = spice.spkez(station_id, t2, 'J2000', 'NONE', 399)[0]
    t1 = t2 - light_time(x1, x2, **kwargs)
    dt = max_error * 2

    while np.abs(dt) > max_error:
        x1 = spice.spkez(station_id, t1, 'J2000', 'NONE', 399)[0]
        df_dt = -1 + np.dot(
            (x2[0:3] - x1[0:3]) / norm(x2[0:3] - x1[0:3]), x1[3:6])
        f = t2 - t1 - light_time(x1, x2, **kwargs)
        dt = -f / df_dt
        t1 += dt

    return t1
Exemplo n.º 3
0
def plot_lvlh_covariance(label,
                         count=0,
                         body_id=399,
                         object_id=-5440,
                         pos_vel_axes=None,
                         snapshot_label=None):

    if body_id == 'earth':
        body_id = 399
    elif body_id == 'moon':
        body_id = 301

    if pos_vel_axes is None:
        pos_axes = None
        vel_axes = None
    else:
        pos_axes, vel_axes = pos_vel_axes

    P, time = LinCov.load_covariance(label, count, snapshot_label)

    # Get LVLH frame
    x_inrtl = spice.spkez(object_id, time, 'J2000', 'NONE',
                          body_id)[0] * 1000.0
    T_inrtl_to_lvlh = frames.compute_T_inrtl_to_lvlh(x_inrtl)

    # Transform covariance to LVLH frame
    P_lvlh = T_inrtl_to_lvlh.dot(P[0:6, 0:6]).dot(T_inrtl_to_lvlh.T)

    fig1, pos_axes = error_ellipsoid(P_lvlh[0:3, 0:3],
                                     dof=3,
                                     xlabel='downtrack (m)',
                                     ylabel='crosstrack (m)',
                                     zlabel='radial (m)',
                                     label=label,
                                     axes=pos_axes)
    fig2, vel_axes = error_ellipsoid(P_lvlh[3:6, 3:6],
                                     dof=3,
                                     xlabel='downtrack (m/s)',
                                     ylabel='crosstrack (m/s)',
                                     zlabel='radial (m/s)',
                                     label=label,
                                     axes=vel_axes)

    if label is not None:
        pos_axes[0].legend()
        vel_axes[0].legend()

    return (fig1, fig2), (pos_axes, vel_axes)
Exemplo n.º 4
0
def ltime(t1, id1, dir, x2, gamma=1.0, mu=3.9860043543609598e5):
    x1 = spice.spkez(id1, t1, 'J2000', 'NONE', 399)

    r2 = norm(x2[0:3])
    if dir == '->':
        r1 = norm(x1[0:3])
        r12 = norm(x2[0:3] - x1[0:3])
        tau12 = r12 / C + (1.0 + gamma) * (mu / C**3) * np.log(
            (r1 + r2 + r12) / (r1 + r2 - r12))
        return t1 + tau12, tau12

    elif dir == '<-':
        t3 = t1
        r3 = norm(x1[0:3])
        r23 = norm(x2[0:3] - x1[0:3])
        tau23 = r23 / C + (1.0 + gamma) * (mu / C**3) * np.log(
            (r2 + r3 + r23) / (r2 + r3 - r23))
        return t3 - tau23, tau23

    else:
        raise ValueError("expected '<-' or '->' for dir")
Exemplo n.º 5
0
    def __init__(self, time, loader=None, params=None):
        self.loader = loader
        self.params = params
        self.mu_earth = loader.mu_earth * 1e9
        self.mu_moon = loader.mu_moon * 1e9

        # Ensure that ground station locations are loaded
        if len(State.r_station_ecef) == 0:
            for station in State.ground_stations:
                gid = self.ground_stations[station]
                State.r_station_ecef[station] = spice.spkezr(
                    station, self.loader.start, 'ITRF93', 'NONE',
                    'earth')[0][0:3] * 1000.0

        self.eci = spice.spkez(loader.object_id, time, 'J2000', 'NONE',
                               399)[0] * 1000.0
        self.lci = spice.spkez(loader.object_id, time, 'J2000', 'NONE',
                               301)[0] * 1000.0

        self.T_inrtl_to_body = np.identity(
            3)  # FIXME: Add attitude, eventually

        # FIXME: Need measurements here
        self.a_meas_inrtl = np.zeros(3)
        self.w_meas_inrtl = np.zeros(3)

        # Get distance to earth and moon
        self.d_earth = norm(self.eci[0:3])
        self.d_moon = norm(self.lci[0:3])

        # Get angular size of each
        self.earth_angle = 2 * np.arctan(
            self.loader.r_earth[2] * 1000.0 / self.d_earth)
        self.moon_angle = 2 * np.arctan(
            self.loader.r_moon[2] * 1000.0 / self.d_moon)

        self.earth_phase_angle = sun_spacecraft_angle('earth', time,
                                                      loader.object_id)
        self.moon_phase_angle = sun_spacecraft_angle('moon', time,
                                                     loader.object_id)

        # We need to be able to clearly see the planet in order to do
        # horizon detection.
        planet_occult_code = spice.occult('earth', 'ellipsoid', 'ITRF93',
                                          'moon', 'ellipsoid', 'MOON_ME',
                                          'NONE', str(loader.object_id), time)

        self.horizon_moon_enabled = False
        self.horizon_earth_enabled = False

        if planet_occult_code == 0:
            if self.earth_angle < self.params.horizon_fov and self.earth_phase_angle < self.params.horizon_max_phase_angle:
                self.horizon_earth_enabled = True

            if self.moon_angle < self.params.horizon_fov and self.moon_phase_angle < self.params.horizon_max_phase_angle:
                self.horizon_moon_enabled = True
        else:
            self.earth_angle = 0.0
            self.moon_angle = 0.0

        self.elevation_from = {}
        self.visible_from = []
        self.r_station_inrtl = {}
        for ground_name in self.ground_stations:
            obj_str = str(self.loader.object_id)
            moon_occult_code = spice.occult(
                obj_str, 'point', ' ', 'moon', 'ellipsoid', 'MOON_ME', 'NONE',
                str(self.ground_stations[ground_name]), time)

            elevation = float('nan')
            if moon_occult_code >= 0:
                # get spacecraft elevation
                x, lt = spice.spkcpo(obj_str, time, ground_name + '_TOPO',
                                     'OBSERVER', 'NONE',
                                     self.r_station_ecef[ground_name] / 1000.0,
                                     'earth', 'ITRF93')
                r, lon, lat = spice.reclat(x[0:3])

                if lat >= self.params.radiometric_min_elevation:
                    elevation = lat
                    self.visible_from.append(ground_name)

            # store elevation of spacecraft for logging purposes
            self.elevation_from[ground_name] = elevation

        self.range_earth = norm(self.eci[0:3])
        self.range_moon = norm(self.lci[0:3])

        self.time = time
Exemplo n.º 6
0
    def __init__(self, arrival_time):
        # Start with earth parking orbit
        leo = Orbit.circular(PatchedConic.mu_earth, 6378136.6 + 185000.0)

        # Get the state of the moon at arrival so we know how far out
        # we need to go and how fast.
        x_moon_arrive = spice.spkez(301, arrival_time, 'J2000', 'NONE',
                                    399)[0] * 1000.0

        # Produce patched conic
        x, pcx = pc.optimize_deltav(np.array(
            [49.9 * np.pi / 180.0, leo.v + 3200.0]),
                                    1837400.0,
                                    leo.r,
                                    leo.phi,
                                    norm(x_moon_arrive[0:3]),
                                    norm(x_moon_arrive[3:6]),
                                    conjugate=True)

        depart_time = arrival_time - pcx.tof
        free_flight_sweep_angle = pcx.nu1 - pcx.nu0

        # Get state of moon at departure so we can figure out the
        # plane of our trajectory.
        x_moon_depart = spice.spkez(301, depart_time, 'J2000', 'NONE',
                                    399)[0] * 1000.0

        # Get earth--moon frame at SOI arrival time
        rm0 = x_moon_depart[:3]
        rm0hat = rm0 / norm(rm0)
        rm1 = x_moon_arrive[:3]
        rm1hat = rm1 / norm(rm1)
        hhat = np.cross(rm0hat, rm1hat)
        hhat /= norm(hhat)
        T_eci_to_pqw = spice.twovec(rm1hat, 1, hhat, 3)

        # Get directions to initial and final vectors
        r1hat = T_eci_to_pqw.T.dot(
            rotate_z(pcx.gam1).dot(np.array([1.0, 0, 0])))
        r0hat = T_eci_to_pqw.T.dot(
            rotate_z(pcx.gam1 - free_flight_sweep_angle).dot(
                np.array([1.0, 0.0, 0.0])))
        v0hat = np.cross(hhat, r0hat)

        # post delta-v state:
        r0 = r0hat * leo.r
        v0 = v0hat * x[1]
        # pre delta-v state:
        v0m = v0hat * leo.v

        # arrival state:
        # r1 = r1hat * pcx.arrive.r
        # v1 = ?

        self.free_flight_sweep_angle = free_flight_sweep_angle
        self.depart_time = depart_time
        self.arrival_time = arrival_time
        self.x_depart_post = np.hstack((r0, v0))
        self.x_depart_pre = np.hstack((r0, v0m))
        self.x_moon_depart = x_moon_depart
        self.x_moon_arrive = x_moon_arrive
        self.deltav = v0 - v0m