Beispiel #1
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
Beispiel #2
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]
Beispiel #3
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
Beispiel #4
0
def _dynamics(pos_ECI, vel_ECI, omega_BODY, quat, t, rocket):

    date_current = rocket.launch_date + datetime.timedelta(seconds=t)

    # Translation coordinate
    DCM_NED2BODY = coord.DCM_NED2BODY_quat(quat)
    DCM_BODY2NED = DCM_NED2BODY.transpose()
    DCM_ECEF2NED = coord.DCM_ECEF2NED(rocket.pos0_LLH)
    DCM_NED2ECEF = DCM_ECEF2NED.transpose()
    DCM_ECI2ECEF = coord.DCM_ECI2ECEF(t)
    DCM_ECEF2ECI = DCM_ECI2ECEF.transpose()
    DCM_BODY2ECI = DCM_ECEF2ECI.dot(DCM_NED2ECEF.dot(DCM_BODY2NED))

    pos_ECEF = DCM_ECI2ECEF.dot(pos_ECI)
    pos_LLH = pm.ecef2geodetic(pos_ECEF[0], pos_ECEF[1], pos_ECEF[2])
    # pos_LLH = pm.eci2geodetic(pos_ECI, date_current)

    vel_ECEF = coord.vel_ECI2ECEF(vel_ECI, DCM_ECI2ECEF, pos_ECI)
    vel_NED = DCM_ECEF2NED.dot(vel_ECEF)

    altitude = pos_LLH[2]
    g0 = 9.80665

    # alpha beta vel_Air
    wind_NED = env.Wind_NED(rocket.wind_speed(altitude),
                            rocket.wind_direction(altitude))
    vel_AIR_BODYframe = DCM_NED2BODY.dot(vel_NED - wind_NED)
    vel_AIR_BODYframe_abs = np.linalg.norm(vel_AIR_BODYframe)
    if vel_AIR_BODYframe_abs <= 0.0 or np.abs(vel_AIR_BODYframe[0]) <= 0.0:
        alpha = 0.0
        beta = 0.0
    else:
        alpha = np.arctan2(vel_AIR_BODYframe[2], vel_AIR_BODYframe[0])
        beta = np.arcsin(-vel_AIR_BODYframe[1] / vel_AIR_BODYframe_abs)

    # Air Condition
    Ta0, Pa0, rho0, Cs0 = env.std_atmo(0.0)
    Ta, Pa, rho, Cs = env.std_atmo(altitude)
    Mach = vel_AIR_BODYframe_abs / Cs
    dynamic_pressure = 0.5 * rho * vel_AIR_BODYframe_abs**2

    # Mass
    if rocket.thrust(t) <= 0.0:
        thrust = 0.0
        Isp = 0.0
        mdot_p = 0.0
        mdot_f = 0.0
        mdot_ox = 0.0
    else:
        mdot_p = rocket.mdot_p(t)
        mdot_f = rocket.mdot_f(t)
        mdot_ox = rocket.mdot_ox(t)
        pressure_thrust = (Pa0 - Pa) * rocket.Ae
        thrust = rocket.thrust(t) + pressure_thrust
        Isp = rocket.Isp + pressure_thrust / (mdot_p * g0)

    mf = rocket.mf(t)
    mox = rocket.mox(t)
    mp = mf + mox
    m = rocket.ms + mp

    # Aero Force
    drag = dynamic_pressure * rocket.Cd(Mach) * rocket.A
    normal = dynamic_pressure * rocket.CNa(Mach) * rocket.A
    F_aero_WIND = np.array([-drag, 0, 0])
    F_aero_BODY = coord.DCM_WIND2BODY(alpha, beta).dot(F_aero_WIND) + np.array(
        [0, normal * beta, -normal * alpha])
    F_aero_WIND = coord.DCM_WIND2BODY(alpha, beta).transpose().dot(F_aero_BODY)

    # Newton Equation
    g_NED = np.array([0.0, 0.0, env.gravity(altitude)])
    force_BODY = F_aero_BODY + np.array([thrust, 0, 0])
    acc_BODY = force_BODY / m + DCM_NED2BODY.dot(g_NED)
    acc_ECI = DCM_BODY2ECI.dot(acc_BODY)

    # Center of Gravity
    Lcg_p = rocket.Lcg_p(t)
    Lcg = rocket.Lcg(t)
    Lcp = rocket.Lcp(Mach)
    moment_arm = np.array([Lcg - Lcp, 0, 0])

    # Inertia Moment
    Ij_pitch = rocket.Ij_pitch(t)
    Ij_roll = rocket.Ij_roll(t)
    Ij = np.array([Ij_roll, Ij_pitch, Ij_pitch])

    Ijdot_f_pitch = rocket.Ijdot_f_pitch(t)
    Ijdot_f_roll = rocket.Ijdot_f_roll(t)
    Ijdot_f = np.array([Ijdot_f_roll, Ijdot_f_pitch, Ijdot_f_pitch])

    # Aero Moment
    moment_aero = np.cross(F_aero_BODY, moment_arm)

    # Aero Dumping Moment
    moment_aero_dumping = np.zeros(3)
    moment_aero_dumping[
        0] = dynamic_pressure * rocket.Clp * rocket.A * rocket.d**2 * 0.5 / vel_AIR_BODYframe_abs * omega_BODY[
            0]
    moment_aero_dumping[
        1] = dynamic_pressure * rocket.Cmq * rocket.A * rocket.L**2 * 0.5 / vel_AIR_BODYframe_abs * omega_BODY[
            1]
    moment_aero_dumping[
        2] = dynamic_pressure * rocket.Cnr * rocket.A * rocket.L**2 * 0.5 / vel_AIR_BODYframe_abs * omega_BODY[
            2]

    # Jet Dumping Moment
    moment_jet_dumping = np.zeros(3)
    moment_jet_dumping[0] = (-Ijdot_f[0] + mdot_p * 0.5 *
                             (0.25 * rocket.de**2)) * omega_BODY[0]
    moment_jet_dumping[1] = (-Ijdot_f[1] + mdot_p *
                             ((Lcg - Lcg_p)**2 -
                              (rocket.L - Lcg_p)**2)) * omega_BODY[1]
    moment_jet_dumping[2] = (-Ijdot_f[2] + mdot_p *
                             ((Lcg - Lcg_p)**2 -
                              (rocket.L - Lcg_p)**2)) * omega_BODY[2]
    # moment_jet_dumping[0] = -(mdot_p * 0.5 * (0.25 * rocket.de ** 2)) * omega_BODY[0]
    # moment_jet_dumping[0] = 0.0
    # moment_jet_dumping[1] = -(mdot_p * ((Lcg - Lcg_p) ** 2 - (rocket.L - Lcg_p) ** 2)) * omega_BODY[1]
    # moment_jet_dumping[2] = -(mdot_p * ((Lcg - Lcg_p) ** 2 - (rocket.L - Lcg_p) ** 2)) * omega_BODY[2]

    # Euler Equation
    moment = moment_aero + moment_aero_dumping + moment_jet_dumping
    p = omega_BODY[0]
    q = omega_BODY[1]
    r = omega_BODY[2]
    omegadot = np.zeros(3)
    omegadot[0] = ((Ij[1] - Ij[2]) * q * r + moment[0]) / Ij[0]
    omegadot[1] = ((Ij[2] - Ij[0]) * p * r + moment[1]) / Ij[1]
    omegadot[2] = ((Ij[0] - Ij[1]) * p * q + moment[2]) / Ij[2]

    # Kinematic Equation
    tersor_0 = [0.0, r, -q, p]
    tersor_1 = [-r, 0.0, p, q]
    tersor_2 = [q, -p, 0.0, r]
    tersor_3 = [-p, -q, -r, 0.0]
    tersor = np.array([tersor_0, tersor_1, tersor_2, tersor_3])
    quatdot = 0.5 * tersor.dot(quat)

    output_data = [
        date_current, pos_ECEF, pos_LLH, vel_ECEF, vel_NED, vel_AIR_BODYframe,
        alpha, beta, Ta, Pa, rho, Cs, Mach, dynamic_pressure, mdot_p, mdot_f,
        mdot_ox, thrust, Isp, mf, mox, mp, m, drag, normal, F_aero_WIND,
        F_aero_BODY, g_NED, force_BODY, acc_BODY, acc_ECI, Lcg_p, Lcg, Lcp, Ij,
        Ijdot_f, moment_aero, moment_aero_dumping, moment_jet_dumping, moment
    ]

    return vel_ECI, acc_ECI, omegadot, quatdot, output_data
Beispiel #5
0
def solve_trajectory(rocket):
    # Initial Attitude #############################
    quat0 = coord.euler2quat(rocket.azimuth0, rocket.elevation0)
    DCM_LAUNCHER2NED = coord.DCM_NED2BODY_quat(quat0).transpose()
    ################################################

    # Initial Position #############################
    pos0_ECEF = pm.geodetic2ecef(rocket.pos0_LLH[0], rocket.pos0_LLH[1],
                                 rocket.pos0_LLH[2])
    pos0_ECI = pm.ecef2eci(pos0_ECEF, rocket.launch_date)
    pos0_NED = DCM_LAUNCHER2NED.dot(np.array([rocket.Lcg0, 0.0, 0.0]))
    ################################################

    # onLauncher Trajectory ##################################################
    # lower launch lugがランチャレール長を越した時点でランチクリア
    # lower lugが抜けた時点での重心各値をメインのソルバへ渡す
    time = np.arange(
        0.0, 0.5 + np.sqrt(
            2.0 * rocket.launcher_rail * rocket.m(0.0) / rocket.ref_thrust),
        0.01)
    x0 = np.zeros(13)
    x0[0:3] = pos0_NED  # Pos_NED
    x0[3:6] = np.zeros((1, 3))  # Vel_NED
    x0[6:9] = np.zeros((1, 3))  # omega
    x0[9:13] = quat0  # quat
    ode_log = odeint(onlauncher_dynamics,
                     x0,
                     time,
                     args=(rocket, DCM_LAUNCHER2NED.transpose()))

    # onLauncher post ######
    pos_LAUNCHER = np.array(
        [DCM_LAUNCHER2NED.transpose().dot(pos) for pos in ode_log[:, 0:3]])
    # ランチクリアまででカット
    index_launch_clear = np.argmax(
        rocket.launcher_rail <= pos_LAUNCHER[:, 0] - rocket.lower_lug)
    # log
    rocket.result.time_onlauncher_log = time[:index_launch_clear + 1]
    rocket.result.pos_onlauncher_NED_log = ode_log[:index_launch_clear + 1,
                                                   0:3]
    rocket.result.vel_onlauncher_NED_log = ode_log[:index_launch_clear + 1,
                                                   3:6]
    rocket.result.omega_onlauncher_log = ode_log[:index_launch_clear + 1, 6:9]
    rocket.result.quat_onlauncher_log = ode_log[:index_launch_clear + 1, 9:13]

    pos_launch_clear_NED = rocket.result.pos_onlauncher_NED_log[-1, :]
    vel_launch_clear_NED = rocket.result.vel_onlauncher_NED_log[-1, :]
    omega_launch_clear = rocket.result.omega_onlauncher_log[-1, :]
    quat_launch_clear = rocket.result.quat_onlauncher_log[-1, :]
    time_launch_clear = rocket.result.time_onlauncher_log[-1]
    altitude_launch_clear = -pos_launch_clear_NED[2]
    DCM_NED2BODY = coord.DCM_NED2BODY_quat(quat_launch_clear)

    # tipoff moment
    if rocket.tipoff_exist:
        mg_tipoff_NED = np.array([
            0, 0,
            rocket.m(time_launch_clear) * env.gravity(altitude_launch_clear)
        ])
        mg_tipoff_BODY = DCM_NED2BODY.dot(mg_tipoff_NED)
        moment_arm_tipoff = np.array(
            [rocket.lower_lug - rocket.Lcg(time_launch_clear), 0, 0])
        moment_tipoff = np.cross(mg_tipoff_BODY, moment_arm_tipoff)
        Ij_pitch = rocket.Ij_pitch(
            time_launch_clear) + rocket.m(time_launch_clear) * np.abs(
                rocket.Lcg(time_launch_clear) - rocket.lower_lug)**2
        Ij_roll = rocket.Ij_roll(time_launch_clear)
        Ij = np.array([Ij_roll, Ij_pitch, Ij_pitch])
        omegadot_tipoff = moment_tipoff / Ij  # 下部ラグを支点とした機体質量でのチップオフ角加速度。あとで角速度に変換する
    else:
        omegadot_tipoff = 0.0
    ################################################

    # Main Trajectory ##################################################
    def estimate_end(total_impulse):
        It = total_impulse
        tf = 2.37 * It**0.37
        tf_order = len(str(int(tf))) - 1
        dt = 10.0**(tf_order - 4)
        return 1.4 * tf, dt

    if rocket.auto_end:
        rocket.end_time, rocket.time_step = estimate_end(rocket.total_impulse)
    start_time = time_launch_clear  # + rocket.time_step
    time = np.arange(start_time, rocket.end_time, rocket.time_step)

    pos_launch_clear_ECEF = pm.ned2ecef(pos_launch_clear_NED[0],
                                        pos_launch_clear_NED[1],
                                        pos_launch_clear_NED[2],
                                        rocket.pos0_LLH[0], rocket.pos0_LLH[1],
                                        rocket.pos0_LLH[2])
    pos_launch_clear_ECI = coord.DCM_ECI2ECEF(
        time_launch_clear).transpose().dot(pos_launch_clear_ECEF)
    DCM_NED2ECEF = coord.DCM_ECEF2NED(rocket.pos0_LLH).transpose()
    DCM_ECI2ECEF = coord.DCM_ECI2ECEF(time_launch_clear)

    x0 = np.zeros(13)
    x0[0:3] = pos_launch_clear_ECI
    x0[3:6] = coord.vel_ECEF2ECI(DCM_NED2ECEF.dot(vel_launch_clear_NED),
                                 DCM_ECI2ECEF, pos_launch_clear_ECI)
    x0[6:9] = omega_launch_clear + omegadot_tipoff * rocket.time_step
    x0[9:13] = quat_launch_clear
    ode_log = odeint(dynamics_odeint, x0, time, args=(rocket, ))

    # Main post ######
    date_array = rocket.launch_date + np.array(
        [datetime.timedelta(seconds=sec) for sec in time])
    pos_ECEF = np.array([
        coord.DCM_ECI2ECEF(t).dot(pos)
        for pos, t in zip(ode_log[:, 0:3], time)
    ])
    pos_LLH = np.array(
        [pm.ecef2geodetic(pos[0], pos[1], pos[2]) for pos in pos_ECEF])

    # 着地後の分をカット
    index_hard_landing = np.argmax(pos_LLH[:, 2] <= 0.0)
    # log
    rocket.result.time_log = time[:index_hard_landing + 1]
    rocket.result.pos_ECI_log = ode_log[:index_hard_landing + 1, 0:3]
    rocket.result.vel_ECI_log = ode_log[:index_hard_landing + 1, 3:6]
    rocket.result.omega_log = ode_log[:index_hard_landing + 1, 6:9]
    rocket.result.quat_log = ode_log[:index_hard_landing + 1, 9:13]
    dynamics_result(rocket)
    ################################################

    # Decent Trajectory ##################################################
    if rocket.timer_mode:
        index_apogee = np.argmax(rocket.result.time_log > rocket.t_1st)
    else:
        index_apogee = np.argmax(pos_LLH[:, 2])
    time_apogee = rocket.result.time_log[index_apogee]
    pos_apogee_ECI = rocket.result.pos_ECI_log[index_apogee]
    vel_apogee_ECI = rocket.result.vel_ECI_log[index_apogee]
    vel_apogee_ned = np.array([
        0, 0,
        coord.DCM_ECEF2NED(rocket.pos0_LLH).dot(
            coord.vel_ECI2ECEF(vel_apogee_ECI, coord.DCM_ECI2ECEF(time_apogee),
                               pos_apogee_ECI))[2]
    ])
    vel_apogee_ECI = coord.vel_ECEF2ECI(
        coord.DCM_ECEF2NED(rocket.pos0_LLH).transpose().dot(vel_apogee_ned),
        coord.DCM_ECI2ECEF(time_apogee), pos_apogee_ECI)

    if rocket.payload_exist:
        rocket.m_burnout -= rocket.payload.mass
        est_landing_payload = pos_LLH[index_apogee, 2] / np.sqrt(
            2.0 * rocket.payload.mass * env.gravity(pos_LLH[index_apogee, 2]) /
            (env.get_std_density(0.0) * rocket.payload.CdS))
    est_landing = pos_LLH[index_apogee, 2] / np.sqrt(
        2.0 * rocket.result.m_log[index_apogee] *
        env.gravity(pos_LLH[index_apogee, 2]) / (env.get_std_density(0.0) *
                                                 (rocket.CdS1 + rocket.CdS2)))
    time = np.arange(time_apogee, time_apogee + 1.2 * est_landing, 0.1)
    x0 = np.zeros(6)
    x0[0:3] = pos_apogee_ECI
    x0[3:6] = vel_apogee_ECI
    ode_log = odeint(parachute_dynamics, x0, time, args=(rocket, ))

    # Decent post ######
    date_array = rocket.launch_date + np.array(
        [datetime.timedelta(seconds=sec) for sec in time])
    pos_ECEF = np.array([
        coord.DCM_ECI2ECEF(t).dot(pos)
        for pos, t in zip(ode_log[:, 0:3], time)
    ])
    pos_LLH = np.array(
        [pm.ecef2geodetic(pos[0], pos[1], pos[2]) for pos in pos_ECEF])

    # 着地後の分をカット
    index_soft_landing = np.argmax(pos_LLH[:, 2] <= 0.0)
    # log
    rocket.result.time_decent_log = time[:index_soft_landing + 1]
    rocket.result.pos_decent_ECI_log = ode_log[:index_soft_landing + 1, 0:3]
    rocket.result.vel_decent_ECI_log = ode_log[:index_soft_landing + 1, 3:6]

    # Payload ####
    if rocket.payload_exist:
        time = np.arange(time_apogee, time_apogee + 1.2 * est_landing_payload,
                         0.01)
        x0 = np.zeros(6)
        x0[0:3] = pos_apogee_ECI
        x0[3:6] = vel_apogee_ECI
        ode_log = odeint(payload_parachute_dynamics, x0, time, args=(rocket, ))

        date_array = rocket.launch_date + np.array(
            [datetime.timedelta(seconds=sec) for sec in time])
        pos_ECEF = np.array([
            coord.DCM_ECI2ECEF(t).dot(pos)
            for pos, t in zip(ode_log[:, 0:3], time)
        ])
        pos_LLH = np.array(
            [pm.ecef2geodetic(pos[0], pos[1], pos[2]) for pos in pos_ECEF])

        # 着地後の分をカット
        index_payload_landing = np.argmax(pos_LLH[:, 2] <= 0.0)
        # log
        rocket.payload.result.time_decent_log = time[:index_payload_landing +
                                                     1]
        rocket.payload.result.pos_decent_LLH_log = pos_LLH[:
                                                           index_payload_landing
                                                           + 1, :]
Beispiel #6
0
    def __post_event(self, rocket):
        # Launch Clear
        self.time_launch_clear = self.time_onlauncher_log[-1]
        self.acc_gauge_launch_clear = rocket.thrust(
            self.time_launch_clear) / rocket.m(
                self.time_launch_clear)  # 本来はDragとかもあるがランチクリア時点では小さいので無視
        self.vel_launch_clear = coord.DCM_NED2BODY_quat(
            self.quat_onlauncher_log[-1, :]).dot(
                self.vel_onlauncher_NED_log[-1, :])[0]

        # Apogee
        index_apogee = np.argmax(self.pos_LLH_log[:, 2])
        self.time_apogee = self.time_log[index_apogee]
        self.alt_apogee = self.pos_LLH_log[index_apogee, 2]
        self.downrange_apogee = self.downrange_log[index_apogee]
        self.vel_apogee = self.vel_AIR_BODYframe_abs_log[index_apogee]

        # Max Q/Drag/Vel
        index = np.argmax(self.dynamic_pressure_log[:index_apogee])
        self.time_maxQ = self.time_log[index]
        self.alt_maxQ = self.pos_LLH_log[index, 2]
        self.maxQ = self.dynamic_pressure_log[index]
        index = np.argmax(self.vel_AIR_BODYframe_log[:index_apogee, 0])
        self.time_vel_max = self.time_log[index]
        self.alt_vel_max = self.pos_LLH_log[index, 2]
        self.vel_max = self.vel_AIR_BODYframe_log[index, 0]
        index = np.argmax(self.Mach_log[:index_apogee])
        self.time_Mach_max = self.time_log[index]
        self.alt_Mach_max = self.pos_LLH_log[index, 2]
        self.Mach_max = self.Mach_log[index]

        # Ballistic Landing
        self.time_hard_landing = self.time_log[-1]
        self.downrange_hard_landing = self.downrange_log[-1]
        self.vel_hard_landing = np.linalg.norm(
            coord.DCM_ECEF2NED(rocket.pos0_LLH).dot(
                coord.vel_ECI2ECEF(self.vel_ECI_log[-1, :],
                                   coord.DCM_ECI2ECEF(self.time_log[-1]),
                                   self.pos_ECI_log[-1, :])))

        # Decent Landing
        self.time_soft_landing = self.time_decent_log[-1]
        self.downrange_soft_landing = self.downrange_decent_log[-1]
        self.vel_soft_landing = coord.DCM_ECEF2NED(rocket.pos0_LLH).dot(
            coord.vel_ECI2ECEF(self.vel_decent_ECI_log[-1, :],
                               coord.DCM_ECI2ECEF(self.time_decent_log[-1]),
                               self.pos_decent_ECI_log[-1, :]))[2]

        # 2nd Separation
        if rocket.timer_mode:
            index_sepa2 = np.min([
                np.argmax(self.time_decent_log > rocket.t_2nd_max),
                np.max([
                    np.argmax(
                        self.pos_decent_LLH_log[:, 2] <= rocket.alt_sepa2),
                    np.argmax(self.time_decent_log > rocket.t_2nd_min)
                ])
            ])
        else:
            index_sepa2 = np.argmax(
                self.pos_decent_LLH_log[:, 2] <= rocket.alt_sepa2)
        self.time_separation_2nd = self.time_decent_log[index_sepa2]
        self.vel_decent_1st = coord.DCM_ECEF2NED(rocket.pos0_LLH).dot(
            coord.vel_ECI2ECEF(
                self.vel_decent_ECI_log[index_sepa2, :],
                coord.DCM_ECI2ECEF(self.time_decent_log[index_sepa2]),
                self.pos_decent_ECI_log[index_sepa2, :]))[2]

        # 1st Separation
        self.time_separation_1st = self.time_decent_log[0]
        self.vel_separation_1st = coord.DCM_ECEF2NED(rocket.pos0_LLH).dot(
            coord.vel_ECI2ECEF(self.vel_decent_ECI_log[0, :],
                               coord.DCM_ECI2ECEF(self.time_decent_log[0]),
                               self.pos_decent_ECI_log[0, :]))[2]