Пример #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 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
Пример #3
0
    def find_orbit(self, p, plane_change_flag):

        r = self.vessel.position(self.ref_frame)
        v = self.vessel.velocity(self.ref_frame)

        rt = self.conn.space_center.target_vessel.position(self.ref_frame)
        vt = self.conn.space_center.target_vessel.velocity(self.ref_frame)

        rt2, vt2 = um.cse_rv(rt, vt, p, self.moon.gravitational_parameter)

        if plane_change_flag:
            v1 = np.sqrt(self.moon.gravitational_parameter *
                         (2 / um.magnitude(r) - 2 /
                          (um.magnitude(r) + um.magnitude(rt))))

            v1 *= um.normalize(np.cross(np.cross(r, v), r))
        else:
            v1, v2 = um.cse_rr(r, rt2, p, -1,
                               self.moon.gravitational_parameter)

        delta_velocity = v1 - v

        uk.burn(self.conn,
                self.ui,
                self.ref_frame,
                delta_velocity,
                stopping_time=(0.1, 0.5, 0.1))
Пример #4
0
    def descent_orbit(self):
        target_time = self.calculate_descent_orbit_time()
        self.conn.space_center.warp_to(self.conn.space_center.ut +
                                       target_time - 15)

        position = np.array(self.vessel.position(self.ref_frame))
        velocity = np.array(self.vessel.velocity(self.ref_frame))

        speed = np.sqrt(self.moon.gravitational_parameter *
                        (2 / np.linalg.norm(position) - 2 /
                         (np.linalg.norm(position) +
                          self.moon.equatorial_radius + self.periapsis)))
        direction = um.normalize(
            np.cross(
                np.cross(np.array(self.vessel.position(self.ref_frame)),
                         np.array(self.vessel.velocity(self.ref_frame))),
                np.array(self.vessel.position(self.ref_frame))))

        delta_velocity = speed * direction - velocity

        uk.burn(self.conn,
                self.ui,
                self.ref_frame,
                delta_velocity,
                stopping_time=(0.1, 0.5, 0.1))
Пример #5
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
Пример #6
0
def guide(tg, dt, r, v, l, mission):
    cgx = um.normalize(l)
    cgy = um.normalize(
        np.cross(
            l, r - l - mission.k *
            (v - np.cross(mission.body_rotation, r)) * tg / 4))
    cgz = um.normalize(np.cross(cgx, cgy))

    cg = np.array([cgx, cgy, cgz])
    rg = np.matmul(cg, r - l)
    vg = np.matmul(cg, v - np.cross(mission.body_rotation, r))

    a = mission.target[3][2]
    b = 6 * mission.target[2][2]
    c = 18 * mission.target[1][2] + 6 * vg[2]
    d = 24 * (mission.target[0][2] - rg[2])
    tg += dt

    while True:
        dt = -(a * tg**3 + b * tg**2 + c * tg + d) / (3 * a * tg**2 +
                                                      2 * b * tg + c)
        if abs(dt) > 60:
            dt *= 60 / abs(dt)
        tg = tg + dt
        if abs(dt) < 1 / 128:
            break

    tp = tg + mission.leadtime
    a = (3 * (tp / tg)**2 - 2 * (tp / tg)) * 12 / tg**2
    b = (4 * (tp / tg)**2 - 3 * (tp / tg)) * 6 / tg
    c = (2 * (tp / tg)**2 - (tp / tg)) * 6 / tg
    d = (6 * (tp / tg)**2 - 6 * (tp / tg) + 1)
    acg1 = a * (mission.target[0] - rg)
    acg2 = b * mission.target[1]
    acg3 = c * vg
    acg4 = d * mission.target[2]

    acg = acg1 + acg2 + acg3 + acg4
    g = -mission.gravitational_parameter / um.magnitude(r)**3 * r
    afcp = np.matmul(np.transpose(cg), acg) - g

    return afcp, tg, rg, vg
Пример #7
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
Пример #8
0
    def match_speed(self, d, v):
        while um.magnitude(self.target.position(
                self.vessel.reference_frame)) > d:
            pass

        cv = np.array(self.vessel.velocity(self.ref_frame)) - np.array(
            self.target.velocity(self.ref_frame))
        cp = np.array(self.vessel.position(self.ref_frame)) - np.array(
            self.target.position(self.ref_frame))
        desv = um.normalize(-cp) * v

        delta_velocity = desv - cv

        uk.burn(self.conn,
                self.ui,
                self.ref_frame,
                delta_velocity,
                stopping_time=(0.25, 0.5, 0.25))
Пример #9
0
    def change_inclination(self):
        sma_1 = (self.vessel.orbit.semi_major_axis + self.apoapsis +
                 self.moon.equatorial_radius) / 2
        sma_2 = self.apoapsis + self.moon.equatorial_radius
        sma_3 = (self.apoapsis +
                 self.periapsis) / 2 + self.moon.equatorial_radius
        period_1 = 2 * np.pi * (sma_1**3 /
                                self.moon.gravitational_parameter)**0.5
        period_2 = 2 * np.pi * (sma_2**3 /
                                self.moon.gravitational_parameter)**0.5
        period_3 = 2 * np.pi * (sma_3**3 /
                                self.moon.gravitational_parameter)**0.5

        self.lan = self.longitude + (
            period_1 / 2 + period_2 +
            period_3 / 2) / self.moon.orbit.period * 360 + np.degrees(
                self.moon.rotation_angle)

        delta_longitude = um.safe_asin(
            np.tan(np.radians(self.latitude)) / np.tan(self.inclination))

        closest_normal = self.calculate_landing_normal(np.radians(self.lan),
                                                       delta_longitude)

        angle_to_maneuver = self.calculate_angle_to_maneuver(closest_normal)

        self.conn.space_center.warp_to(self.conn.space_center.ut +
                                       angle_to_maneuver /
                                       (2 * np.pi) * self.vessel.orbit.period -
                                       15)

        attitude = um.normalize(
            np.cross(closest_normal,
                     np.array(self.vessel.position(self.ref_frame))))
        delta_velocity = attitude * np.sqrt(
            self.moon.gravitational_parameter *
            (2 / np.linalg.norm(self.vessel.position(self.ref_frame)) -
             1 / sma_1)) - self.vessel.velocity(self.ref_frame)

        uk.burn(self.conn,
                self.ui,
                self.ref_frame,
                delta_velocity,
                stopping_time=(1.0, 0.5, 1.0))
Пример #10
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
Пример #11
0
    def circularize(self):
        self.conn.space_center.warp_to(self.conn.space_center.ut +
                                       self.vessel.orbit.time_to_periapsis -
                                       15)

        circular_speed = np.sqrt(
            self.moon.gravitational_parameter /
            np.linalg.norm(np.array(self.vessel.position(self.ref_frame))))
        circular_direction = um.normalize(
            np.cross(
                np.cross(np.array(self.vessel.position(self.ref_frame)),
                         np.array(self.vessel.velocity(self.ref_frame))),
                np.array(self.vessel.position(self.ref_frame))))
        delta_velocity = circular_speed * circular_direction - np.array(
            self.vessel.velocity(self.ref_frame))

        uk.burn(self.conn,
                self.ui,
                self.ref_frame,
                delta_velocity,
                stopping_time=(1.0, 0.5, 1.0))
Пример #12
0
    def match_speed_mono(self, d, v):
        while um.magnitude(self.target.position(
                self.vessel.reference_frame)) > d:
            pass

        cv = np.array(self.vessel.velocity(self.ref_frame)) - np.array(
            self.target.velocity(self.ref_frame))
        cp = np.array(self.vessel.position(self.ref_frame)) - np.array(
            self.target.position(self.ref_frame))
        desv = um.normalize(-cp) * v

        delta_velocity = desv - cv

        uk.burn(self.conn,
                self.ui,
                self.ref_frame,
                delta_velocity,
                stopping_time=(0.25, 0.5, 0.25),
                main_engine=False,
                specified_thrust=4000,
                specified_isp=240,
                facing=-1)
        self.vessel_attitude()
Пример #13
0
    def execute(self):
        ldg.p63_ignition_algorithm(self)
        burn_time = self.time + self.time_initial_ut

        self.vessel.auto_pilot.engage()
        self.vessel.auto_pilot.reference_frame = self.ref_frame

        self.conn.space_center.rails_warp_factor = 4

        while self.conn.space_center.ut < burn_time - 90:
            self.ui.update_phase_current_time(
                int(abs(self.conn.space_center.ut - burn_time)))

        self.conn.space_center.rails_warp_factor = 2
        while self.conn.space_center.ut < burn_time - 30:
            self.ui.update_phase_current_time(
                int(abs(self.conn.space_center.ut - burn_time)))

        self.conn.space_center.rails_warp_factor = 0

        self.ui.update_phase_current('P63')
        self.ui.update_phase_next('P64')

        while True:
            position = np.array(self.vessel.position(self.ref_frame))
            velocity = np.array(self.vessel.velocity(self.ref_frame))
            landing_site = (
                self.moon.equatorial_radius +
                self.inputs[11]) / self.moon.equatorial_radius * np.array(
                    self.moon.surface_position(self.latitude, self.longitude,
                                               self.ref_frame))
            afcp, tg, rg, vg = ldg.guide(self.guide_time, 0, position,
                                         velocity, landing_site, self)
            self.vessel.auto_pilot.target_direction = afcp
            maxafcp = self.vessel.max_thrust / self.vessel.mass
            ts = um.magnitude(afcp) / maxafcp
            if self.conn.space_center.ut > burn_time:
                if ts > 1:
                    ts = 1
                self.vessel.control.throttle = ts
                self.ui.update_phase_current_time(int(abs(tg - self.tbrf)))
            else:
                self.ui.update_phase_current_time(
                    int(abs(self.conn.space_center.ut - burn_time)))
            if tg > self.tbrf:
                break

        print('swap to approach phase')
        self.ui.update_phase_current('P64')
        self.ui.update_phase_next('P66')
        self.target = self.aptg
        self.guidetime = self.tapi
        while tg < self.tapf and self.vessel.flight().surface_altitude > 30:
            self.ui.update_phase_current_time(int(abs(tg - self.tapf)))
            position = np.array(self.vessel.position(self.ref_frame))
            velocity = np.array(self.vessel.velocity(self.ref_frame))
            landing_site = (
                self.moon.equatorial_radius +
                self.inputs[11]) / self.moon.equatorial_radius * np.array(
                    self.moon.surface_position(self.latitude, self.longitude,
                                               self.ref_frame))
            afcp, tg, rg, vg = ldg.guide(self.guide_time, 0, position,
                                         velocity, landing_site, self)
            self.vessel.auto_pilot.target_direction = afcp
            maxafcp = self.vessel.max_thrust / self.vessel.mass
            self.vessel.control.throttle = um.magnitude(afcp) / maxafcp

        self.ui.update_phase_current('P88')
        self.ui.update_phase_next('N/A')
        self.ui.update_phase_current_time(0)
        self.vessel.control.throttle = 0.00

        ref_frame = self.moon.reference_frame

        gm = self.moon.gravitational_parameter
        self.vessel.auto_pilot.engage()
        self.vessel.auto_pilot.reference_frame = ref_frame
        self.vessel.control.gear = True

        while self.vessel.flight().surface_altitude > 1.5:

            r = np.array(self.vessel.position(self.moon.reference_frame))
            vs = np.array(self.vessel.flight(ref_frame).vertical_speed)
            fa = np.array(self.vessel.direction(ref_frame))
            g = -gm / um.magnitude(r)**3 * r
            up = np.array(
                self.conn.space_center.transform_direction(
                    [1, 0, 0], self.vessel.surface_reference_frame,
                    self.moon.reference_frame))
            v = np.array(self.vessel.velocity(self.moon.reference_frame))
            a = um.vector_exclude(up, -v)
            afyz = a / 10
            if self.vessel.flight().surface_altitude > 5:
                if um.magnitude(afyz) > 0.35 * um.magnitude(g):
                    afyz = 0.35 * g * um.normalize(afyz)
                if vs < 0:
                    afx = (((-1.00 - vs) / 1.5) * up - g) / np.cos(
                        um.vector_angle(up, fa))
                else:
                    afx = 0
                afcp = afyz + afx
            else:
                if um.magnitude(afyz) > 0.35 * um.magnitude(g):
                    afyz = 0.35 * g * um.normalize(afyz)
                if vs < 0:
                    afx = (((-0.50 - vs) / 1.5) * up - g) / np.cos(
                        um.vector_angle(up, fa))
                else:
                    afx = 0
                afcp = afyz + afx

            maxafcp = self.vessel.max_thrust / self.vessel.mass
            self.vessel.auto_pilot.target_direction = afcp
            self.vessel.control.throttle = um.magnitude(afcp) / maxafcp

        self.vessel.control.throttle = 0
        self.vessel.auto_pilot.disengage()