Ejemplo n.º 1
0
class TestDumbbellInertialTranslationalController():

    des_tran_tuple = controller.traverse_then_land_vertically(0, ast)
    u_f = controller.translation_controller(t, state, np.zeros(3), dum, ast,
                                            des_tran_tuple)

    def test_control_force_size(self):
        np.testing.assert_equal(self.u_f.shape, (3, ))
Ejemplo n.º 2
0
def eoms_controlled_blender(t, state, dum, ast):
    """Inertial dumbbell equations of motion about an asteroid 
    
    This method must be used with the scipy.integrate.ode class instead of the
    more convienent scipy.integrate.odeint. In addition, we can control the
    dumbbell given full state feedback. Blender is used to generate imagery
    during the simulation.

    Inputs:
        t - Current simulation time step
        state - (18,) array which defines the state of the vehicle 
            pos - (3,) position of the dumbbell with respect to the
            asteroid center of mass and expressed in the inertial frame
            vel - (3,) velocity of the dumbbell with respect to the
            asteroid center of mass and expressed in the inertial frame
            R - (9,) attitude of the dumbbell with defines the
            transformation of a vector in the dumbbell frame to the
            inertial frame ang_vel - (3,) angular velocity of the dumbbell
            with respect to the inertial frame and represented in the
            dumbbell frame
        ast - Asteroid class object holding the asteroid gravitational
        model and other useful parameters
    """
    # unpack the state
    pos = state[0:3]  # location of the center of mass in the inertial frame
    vel = state[3:6]  # vel of com in inertial frame
    R = np.reshape(state[6:15], (3, 3))  # sc body frame to inertial frame
    ang_vel = state[
        15:
        18]  # angular velocity of sc wrt inertial frame defined in body frame

    Ra = attitude.rot3(ast.omega * t,
                       'c')  # asteroid body frame to inertial frame

    # unpack parameters for the dumbbell
    J = dum.J

    rho1 = dum.zeta1
    rho2 = dum.zeta2

    # position of each mass in the asteroid frame
    z1 = Ra.T.dot(pos + R.dot(rho1))
    z2 = Ra.T.dot(pos + R.dot(rho2))

    z = Ra.T.dot(pos)  # position of COM in asteroid frame

    # compute the potential at this state
    (U1, U1_grad, U1_grad_mat, U1laplace) = ast.polyhedron_potential(z1)
    (U2, U2_grad, U2_grad_mat, U2laplace) = ast.polyhedron_potential(z2)

    F1 = dum.m1 * Ra.dot(U1_grad)
    F2 = dum.m2 * Ra.dot(U2_grad)

    M1 = dum.m1 * attitude.hat_map(rho1).dot(R.T.dot(Ra).dot(U1_grad))
    M2 = dum.m2 * attitude.hat_map(rho2).dot(R.T.dot(Ra).dot(U2_grad))

    # generate image at this current state only at a specifc time
    # blender.driver(pos, R, ast.omega * t, [5, 0, 1], 'test' + str.zfill(str(t), 4))
    # use the imagery to figure out motion and pass to the controller instead
    # of the true state

    # calculate the desired attitude and translational trajectory
    des_att_tuple = controller.body_fixed_pointing_attitude(t, state)
    des_tran_tuple = controller.traverse_then_land_vertically(
        t,
        ast,
        final_pos=[0.550, 0, 0],
        initial_pos=[2.550, 0, 0],
        descent_tf=3600)
    # input trajectory and compute the control inputs
    # compute the control input
    u_m = controller.attitude_controller(t, state, M1 + M2, dum, ast,
                                         des_att_tuple)
    u_f = controller.translation_controller(t, state, F1 + F2, dum, ast,
                                            des_tran_tuple)

    pos_dot = vel
    vel_dot = 1 / (dum.m1 + dum.m2) * (F1 + F2 + u_f)
    R_dot = R.dot(attitude.hat_map(ang_vel)).reshape(9)
    ang_vel_dot = np.linalg.inv(J).dot(-np.cross(ang_vel, J.dot(ang_vel)) +
                                       M1 + M2 + u_m)

    statedot = np.hstack((pos_dot, vel_dot, R_dot, ang_vel_dot))

    return statedot
Ejemplo n.º 3
0
def eoms_controlled_inertial_refinement_pybind(t, state, true_ast, dum,
                                               complete_controller,
                                               est_ast_rmesh, est_ast,
                                               desired_landing_site):
    """We'll hover over the landing site and look at 
    all the points in view

    This function must be used with scipy.integrate.ode class instead of the 
    more convienent scipe.integrate.odeint. In addition, we can control the 
    dumbbell given full state feedback. This uses several C++ functions which 
    are exposed to Python using PyBind11
    
    Arguments
    ---------
    t : current simulation time step
    state : (18, ) numpy array of the state
        pos - (3,) position of the dumbbell with respect to the
        asteroid center of mass and expressed in the inertial frame
        vel - (3,) velocity of the dumbbell with respect to the
        asteroid center of mass and expressed in the inertial frame
        R - (9,) attitude of the dumbbell with defines the
        transformation of a vector in the dumbbell frame to the
        inertial frame ang_vel - (3,) angular velocity of the dumbbell
        with respect to the inertial frame and represented in the
        dumbbell frame
    ast : asteroid object (from C++ bindings)
    dum : dumbbell object (from Python)
    complete_controller : controller object (from C++)
    """
    # unpack the state
    pos = state[0:3]  # location of the center of mass in the inertial frame
    vel = state[3:6]  # vel of com in inertial frame
    R = np.reshape(state[6:15], (3, 3))  # sc body frame to inertial frame
    ang_vel = state[
        15:
        18]  # angular velocity of sc wrt inertial frame defined in body frame

    Ra = true_ast.rot_ast2int(t)  # asteroid body frame to inertial frame

    # unpack parameters for the dumbbell
    J = dum.J

    rho1 = dum.zeta1
    rho2 = dum.zeta2

    # position of each mass in the asteroid frame
    z1 = Ra.T.dot(pos + R.dot(rho1))
    z2 = Ra.T.dot(pos + R.dot(rho2))

    z = Ra.T.dot(pos)  # position of COM in asteroid frame

    # gradient and potential at this state
    true_ast.polyhedron_potential(z1)
    U1 = true_ast.get_potential()
    U1_grad = true_ast.get_acceleration()

    true_ast.polyhedron_potential(z2)
    U2 = true_ast.get_potential()
    U2_grad = true_ast.get_acceleration()

    F1 = dum.m1 * Ra.dot(U1_grad)
    F2 = dum.m2 * Ra.dot(U2_grad)

    M1 = dum.m1 * attitude.hat_map(rho1).dot(R.T.dot(Ra).dot(U1_grad))
    M2 = dum.m2 * attitude.hat_map(rho2).dot(R.T.dot(Ra).dot(U2_grad))

    # compute the external force and moment using the asteroid estimate
    est_ast.polyhedron_potential(z1)
    U1_est = est_ast.get_potential()
    U1_grad_est = est_ast.get_acceleration()

    est_ast.polyhedron_potential(z2)
    U2_est = est_ast.get_potential()
    U2_grad_est = est_ast.get_acceleration()

    F1_est = dum.m1 * Ra.dot(U1_grad_est)
    F2_est = dum.m2 * Ra.dot(U2_grad_est)

    M1_est = dum.m1 * attitude.hat_map(rho1).dot(R.T.dot(Ra).dot(U1_grad_est))
    M2_est = dum.m2 * attitude.hat_map(rho2).dot(R.T.dot(Ra).dot(U2_grad_est))

    # compute the desired states for exploration
    complete_controller.refinement(t, state, est_ast_rmesh, est_ast,
                                   desired_landing_site)

    # Need to convert to the inertial frame for use in the controller
    des_att_tuple = (Ra.dot(complete_controller.get_Rd()),
                     Ra.dot(complete_controller.get_Rd_dot()),
                     Ra.dot(complete_controller.get_ang_vel_d()),
                     Ra.dot(complete_controller.get_ang_vel_d_dot()))
    des_tran_tuple = (Ra.dot(complete_controller.get_posd()),
                      Ra.dot(complete_controller.get_veld()),
                      Ra.dot(complete_controller.get_acceld()))

    #  need to pass in the estimated external torque and moment
    u_m = controller.attitude_controller(t, state, M1_est + M2_est, dum,
                                         est_ast, des_att_tuple)
    u_f = controller.translation_controller(t, state, F1_est + F2_est, dum,
                                            est_ast, des_tran_tuple)

    pos_dot = vel
    vel_dot = 1 / (dum.m1 + dum.m2) * (F1 + F2 + u_f)
    R_dot = R.dot(attitude.hat_map(ang_vel)).reshape(9)
    ang_vel_dot = np.linalg.inv(J).dot(-np.cross(ang_vel, J.dot(ang_vel)) +
                                       M1 + M2 + u_m)

    state_dot = np.hstack((pos_dot, vel_dot, R_dot, ang_vel_dot))

    return state_dot