Пример #1
0
def state_from_orbit(ra, rp, lat, lng, node_dir, vel_dir, gm):
    inc = lat + (np.pi / 2 - lat) * 0.05

    a = (ra + rp) / 2
    e = (ra - rp) / (ra + rp)

    dt = 2 * np.pi * np.sqrt(a**3 / gm) / 6
    dt = 616.0809208241426

    r = np.array([1, 0, 0])
    r = um.vector_axis_angle(r, np.array([0, 0, 1]), lng)
    r = rp * um.vector_axis_angle(r, np.cross(r, np.array([0, 0, 1])), lat)

    longitude_of_node = lng + node_dir * abs(
        um.safe_asin(np.tan(lat) / np.tan(inc)))

    print('LAN', np.degrees(longitude_of_node))
    print('a', a)
    print('e', e)
    print('dt', dt)

    n = np.array([1, 0, 0])
    n = um.vector_axis_angle(n, np.array([0, 0, 1]), longitude_of_node)
    normal = vel_dir * um.normalize(np.cross(n, r))

    v = np.sqrt((1 + e) / (1 - e) * gm / a) * um.normalize(np.cross(normal, r))

    r, v = um.cse_rv(r, v, -dt, gm)

    return r, v
Пример #2
0
def landing_site(d, lat, lng):

    li = np.array([1, 0, 0])
    li = um.vector_axis_angle(li, np.array([0, 0, 1]), lng)
    li = d * um.vector_axis_angle(li, np.cross(li, np.array([0, 0, 1])), lat)

    return li
Пример #3
0
    def calculate_landing_normal(self, longitude_of_ascending_node,
                                 delta_longitude):
        ref_axis = -np.array(
            self.vessel.orbit.reference_plane_normal(self.ref_frame))
        ref_direction = np.array(
            self.vessel.orbit.reference_plane_direction(self.ref_frame))
        node_1 = um.vector_axis_angle(
            ref_direction, ref_axis,
            longitude_of_ascending_node + delta_longitude)
        node_2 = um.vector_axis_angle(
            ref_direction, ref_axis,
            longitude_of_ascending_node - delta_longitude)
        velocity_1 = um.vector_axis_angle(np.cross(ref_axis, node_1), node_1,
                                          self.inclination)
        velocity_2 = um.vector_axis_angle(np.cross(ref_axis, node_2), node_2,
                                          -self.inclination)

        normal_1p = np.cross(node_1, velocity_1)
        normal_1n = np.cross(node_1, -velocity_1)
        normal_2p = np.cross(node_2, velocity_2)
        normal_2n = np.cross(node_2, -velocity_2)

        angle_1p = um.vector_angle(normal_1p, self.normal)
        angle_1n = um.vector_angle(normal_1n, self.normal)
        angle_2p = um.vector_angle(normal_2p, self.normal)
        angle_2n = um.vector_angle(normal_2n, self.normal)

        angles = [angle_1p, angle_1n, angle_2p, angle_2n]
        normals = [normal_1p, normal_1n, normal_2p, normal_2n]

        return normals[angles.index(min(angles))]
Пример #4
0
 def node_vector(inclination, vessel, ref_frame):
     position = np.array(vessel.position(ref_frame))
     latitude = np.radians(vessel.flight().latitude)
     ref_axis = np.array(vessel.orbit.reference_plane_normal(ref_frame))
     node_vector_projection_delta = um.safe_asin(
         np.tan(latitude) / np.tan(inclination))
     longitude_vector = um.vector_exclude(ref_axis, position)
     return um.vector_axis_angle(
         longitude_vector, ref_axis,
         node_vector_projection_delta), um.vector_axis_angle(
             longitude_vector, ref_axis,
             np.pi - node_vector_projection_delta)
Пример #5
0
def p63_ignition_algorithm(mission):
    t = mission.time_initial
    tg = mission.guide_time_initial
    li = mission.landing_position_initial
    unfcp = -um.normalize(mission.velocity_initial)
    mission.target = mission.brtg

    while True:
        r, v = um.cse_rv(mission.position_initial, mission.velocity_initial, t,
                         mission.gravitational_parameter)
        lt = um.vector_axis_angle(li, np.array([0, 1, 0]),
                                  mission.body_rotation[1] * t)
        for i in range(3):
            v += mission.aftrim * unfcp * mission.ttrim
            afcp, tg, rg, vg = guide(tg, 0, r, v, lt, mission)
            unfcp = um.normalize(afcp)
        dt = np.dot(
            np.array([
                rg[0] - mission.brig[0][0], rg[1]**2,
                rg[2] - mission.brig[0][2],
                um.magnitude(vg) - um.magnitude(mission.brig[1])
            ]), mission.kgt) / (vg[2] + mission.kgt[0] * vg[0])

        if abs(dt) > 1:
            dt *= 1 / abs(dt)
        t -= dt
        if abs(dt) < 1 / 128:
            break

    t -= (mission.tullage + mission.ttrim)
    mission.time = t
    mission.guide_time = tg
Пример #6
0
    def calculate_descent_orbit_time(self):
        ref_axis = np.array(
            self.vessel.orbit.reference_plane_normal(self.ref_frame))
        normal = um.normalize(
            np.cross(self.vessel.position(self.ref_frame),
                     self.vessel.velocity(self.ref_frame)))
        node = np.cross(normal, ref_axis)
        landing_site = self.moon.surface_position(self.latitude,
                                                  self.longitude,
                                                  self.ref_frame)

        angle_dir = 1
        if np.dot(node, landing_site) > 0:
            angle_dir = -1
            node = -node

        theta = um.safe_asin(
            np.sin(np.radians(self.latitude)) / np.sin(self.inclination))
        target = um.vector_axis_angle(node, normal, theta * angle_dir)
        target_angle = um.vector_angle(self.vessel.position(self.ref_frame),
                                       target)
        delta_direction = np.dot(
            normal, np.cross(target, self.vessel.position(self.ref_frame)))

        if delta_direction > 0:
            target_angle = 2 * np.pi - target_angle

        target_time = target_angle * self.vessel.orbit.period / (2 * np.pi)
        return target_time
Пример #7
0
    def burn_wait(self, angle_burn):
        vessel_angle = self.vessel.orbit.true_anomaly + self.vessel.orbit.argument_of_periapsis
        while vessel_angle > 2 * np.pi:
            vessel_angle -= 2 * np.pi
        while angle_burn > 2 * np.pi:
            angle_burn -= 2 * np.pi
        if angle_burn < vessel_angle:
            delta_true_anomaly = 2 * np.pi + angle_burn - vessel_angle
        else:
            delta_true_anomaly = angle_burn - vessel_angle

        position = np.array(self.vessel.position(self.ref_frame))
        velocity = np.array(self.vessel.velocity(self.ref_frame))
        normal = np.cross(position, velocity)
        attitude = um.normalize(np.cross(normal, position))
        attitude = um.vector_axis_angle(attitude, normal, delta_true_anomaly)

        time_wait = delta_true_anomaly / (2 * np.pi) * self.vessel.orbit.period
        return attitude, time_wait
Пример #8
0
    def node_delta(self, inclination, longitude_of_ascending_node, vessel,
                   ref_frame):
        ref_axis = np.array(vessel.orbit.reference_plane_normal(ref_frame))
        ref_direction = np.array(
            vessel.orbit.reference_plane_direction(ref_frame))

        node_north, node_south = self.node_vector(inclination, vessel,
                                                  ref_frame)
        target_node = um.vector_axis_angle(ref_direction, ref_axis,
                                           -longitude_of_ascending_node)

        node_delta_north = um.vector_angle(node_north, target_node)
        node_delta_south = um.vector_angle(node_south, target_node)
        delta_direction_north = np.dot(ref_axis,
                                       np.cross(target_node, node_north))
        delta_direction_south = np.dot(ref_axis,
                                       np.cross(target_node, node_south))

        if delta_direction_north < 0:
            node_delta_north = 2 * np.pi - node_delta_north
        if delta_direction_south < 0:
            node_delta_south = 2 * np.pi - node_delta_south

        return node_delta_north, node_delta_south
Пример #9
0
def simulate(mission, target, time_limit, delta_time, afcp_limit,
             guide_time_flag):
    mission.target = target
    t0 = mission.time
    rg_out = []
    thrott_out = []
    while True:
        lt = um.vector_axis_angle(mission.landing_position_initial,
                                  np.array([0, 1, 0]),
                                  mission.body_rotation[1] * mission.time)
        afcp, mission.guide_time, rg, vg = guide(mission.guide_time,
                                                 delta_time, mission.position,
                                                 mission.velocity, lt, mission)
        maxafcp = mission.maxthrust / mission.mass
        if afcp_limit == -1:
            if um.magnitude(afcp) > maxafcp * mission.minthrottle:
                afcp = um.normalize(afcp) * maxafcp
            elif not mission.throttflag:
                mission.throttflag = True
                mission.throtta = mission.guide_time
        else:
            afcp = um.normalize(afcp) * afcp_limit
        mission.position, mission.velocity = runge_kutta(
            mission.position, mission.velocity, afcp, delta_time,
            mission.gravitational_parameter)
        mission.mass -= um.magnitude(
            afcp) * mission.mass / mission.vexh * delta_time
        mission.time += delta_time

        rg_out.append(rg)
        thrott_out.append([mission.guide_time, um.magnitude(afcp) / maxafcp])
        if guide_time_flag and mission.guide_time > time_limit:
            break
        if not guide_time_flag and mission.time - t0 > time_limit:
            break
    return rg_out, thrott_out