class TestDistanceToFacesCubeOutsideRandom():
    """Ranom location that is always outside the cube
    """
    pt_out=np.array([1, np.random.uniform(-0.4, 0.4), 0])
    v_cube, f_cube=wavefront.read_obj('./integration/cube.obj')
    ast = asteroid.Asteroid('castalia', 256, 'mat')
    ast = ast.loadmesh(v_cube, f_cube, 'cube')
    edge_vertex_map=ast.asteroid_grav['edge_vertex_map']
    edge_face_map=ast.asteroid_grav['edge_face_map']
    normal_face=ast.asteroid_grav['normal_face']
    vf_map=ast.asteroid_grav['vertex_face_map']

    D, P, V, E, F=wavefront.distance_to_faces(pt_out, v_cube, f_cube,
                                                   normal_face,
                                                   edge_vertex_map,
                                                   edge_face_map,
                                                   vf_map)
    def test_distance(self):
        np.testing.assert_allclose(np.isfinite(self.D), True)
    def test_point(self):
        np.testing.assert_allclose(len(self.P) >= 3, True)
    def test_vertex(self):
        np.testing.assert_allclose(np.isfinite(self.V), True)
    def test_edge(self):
        np.testing.assert_allclose(np.isfinite(self.E), True)
    def test_face(self):
        np.testing.assert_allclose(self.F.size >= 1, True)
class TestDistanceToEdgesCubeOutsideEdge():

    pt_out = np.array([0.6, 0.6, 0.6])
    v_cube, f_cube = wavefront.read_obj('./integration/cube.obj')
    ast = asteroid.Asteroid('castalia', 256, 'mat')
    ast = ast.loadmesh(v_cube, f_cube, 'cube')

    edge_vertex_map = ast.asteroid_grav['edge_vertex_map']
    edge_face_map = ast.asteroid_grav['edge_face_map']
    normal_face = ast.asteroid_grav['normal_face']
    vf_map = ast.asteroid_grav['vertex_face_map']

    D, P, V, E, F = wavefront.distance_to_edges(pt_out, v_cube, f_cube,
                                                normal_face, edge_vertex_map,
                                                edge_face_map, vf_map)
    D_exp = P_exp = E_exp = F_exp = []

    def test_distance(self):
        np.testing.assert_allclose(self.D, self.D_exp)

    def test_point(self):
        np.testing.assert_allclose(self.P, np.empty(shape=(0, 3)))

    def test_vertex(self):
        np.testing.assert_allclose(self.V, np.empty(shape=(0, 2)))

    def test_edge(self):
        np.testing.assert_allclose(self.E, np.empty(shape=(0, 2)))

    def test_face(self):
        np.testing.assert_allclose(self.F, self.F_exp)
class TestDistanceToEdgesCubeSurfaceSingle():

    pt_out = np.array([0.5, 0.4, 0.3])
    v_cube, f_cube = wavefront.read_obj('./integration/cube.obj')
    ast = asteroid.Asteroid('castalia', 256, 'mat')
    ast = ast.loadmesh(v_cube, f_cube, 'cube')

    edge_vertex_map = ast.asteroid_grav['edge_vertex_map']
    edge_face_map = ast.asteroid_grav['edge_face_map']
    normal_face = ast.asteroid_grav['normal_face']
    vf_map = ast.asteroid_grav['vertex_face_map']

    D, P, V, E, F = wavefront.distance_to_edges(pt_out, v_cube, f_cube,
                                                normal_face, edge_vertex_map,
                                                edge_face_map, vf_map)
    D_exp = 0.1 / 2 * np.sqrt(2)
    P_exp = np.array([0.5, 0.35, 0.35])
    V_exp = np.array([4, 7])
    E_exp = np.array([4, 7])
    F_exp = np.array([6, 7])

    def test_distance(self):
        np.testing.assert_allclose(self.D, self.D_exp)

    def test_point(self):
        np.testing.assert_allclose(self.P, self.P_exp)

    def test_vertex(self):
        np.testing.assert_allclose(self.V, self.V_exp)

    def test_edge(self):
        np.testing.assert_allclose(self.E, self.E_exp)

    def test_face(self):
        np.testing.assert_allclose(self.F, self.F_exp)
class TestDistanceToEdgesCubeInside():

    pt_out = np.array([0.4, 0.4, 0.2])
    v_cube, f_cube = wavefront.read_obj('./integration/cube.obj')
    ast = asteroid.Asteroid('castalia', 256, 'mat')
    ast = ast.loadmesh(v_cube, f_cube, 'cube')
    edge_vertex_map = ast.asteroid_grav['edge_vertex_map']
    edge_face_map = ast.asteroid_grav['edge_face_map']
    normal_face = ast.asteroid_grav['normal_face']
    vf_map = ast.asteroid_grav['vertex_face_map']

    D, P, V, E, F = wavefront.distance_to_edges(pt_out, v_cube, f_cube,
                                                normal_face, edge_vertex_map,
                                                edge_face_map, vf_map)
    D_exp = -0.1 * np.sqrt(2) * np.ones_like(D)
    P_exp = np.array([[0.5, 0.5, 0.2], [0.5, 0.5, 0.2]])
    V_exp = np.array([[6, 7], [7, 6]])
    E_exp = np.array([[6, 7], [7, 6]])
    F_exp = np.array([[4, 6], [4, 6]])

    def test_distance(self):
        np.testing.assert_allclose(self.D, self.D_exp)

    def test_point(self):
        np.testing.assert_allclose(self.P, self.P_exp)

    def test_vertex(self):
        np.testing.assert_allclose(self.V, self.V_exp)

    def test_edge(self):
        for E, E_exp in zip(self.E, self.E_exp):
            np.testing.assert_allclose(E, E_exp)

    def test_face(self):
        np.testing.assert_allclose(self.F, self.F_exp)
Esempio n. 5
0
class TestInertialTransform():

    inertial_pos = np.array([1, 1, 1])
    inertial_vel = np.random.rand(3)
    R_sc2int = att.rot2(np.pi / 2)
    body_ang_vel = np.random.rand(3)

    time = np.array([0])
    ast = asteroid.Asteroid(name='castalia', num_faces=64)
    dum = dumbbell.Dumbbell()

    input_state = np.hstack(
        (inertial_pos, inertial_vel, R_sc2int.reshape(9), body_ang_vel))
    inertial_state = transform.eoms_inertial_to_inertial(
        time, input_state, ast, dum)

    def test_eoms_inertial_to_inertial_scalar_pos(self):
        np.testing.assert_almost_equal(self.inertial_pos,
                                       self.inertial_state[0:3])

    def test_eoms_inertial_to_inertial_scalar_vel(self):
        np.testing.assert_almost_equal(self.inertial_vel,
                                       self.inertial_state[3:6])

    def test_eoms_inertial_to_inertial_scalar_att(self):
        np.testing.assert_almost_equal(self.R_sc2int.reshape(9),
                                       self.inertial_state[6:15])

    def test_eoms_inertial_to_inertial_scalar_ang_vel(self):
        np.testing.assert_almost_equal(self.R_sc2int.dot(self.body_ang_vel),
                                       self.inertial_state[15:18])
Esempio n. 6
0
def load_data(inertial_filename, relative_filename, mode):
    """Load saved data and extract out the states

    """
    with np.load(inertial_filename, allow_pickle=True) as data:
        inertial_state = data['state']
        inertial_time = data['time']
        inertial_KE = data['KE']
        inertial_PE = data['PE']
        ast_name = data['ast_name'][()]
        num_faces = data['num_faces'][()]
        tf = data['tf'][()]
        num_steps = data['num_steps'][()]

    with np.load(relative_filename, allow_pickle=True) as data:
        relative_state = data['state']
        relative_time = data['time']
        relative_KE = data['KE']
        relative_PE = data['PE']
        relative_ast_name = data['ast_name'][()]
        relative_num_faces = data['num_faces'][()]
        relative_tf = data['tf'][()]
        relative_num_steps = data['num_steps'][()]

    # make sure we're dealing with the same simulation results or else the comparison is meaningless
    np.testing.assert_string_equal(relative_ast_name, ast_name)
    np.testing.assert_allclose(relative_num_faces, num_faces)
    np.testing.assert_allclose(relative_tf, tf)
    np.testing.assert_allclose(relative_num_steps, num_steps)
    np.testing.assert_allclose(relative_state.shape, inertial_state.shape)

    ast = asteroid.Asteroid(ast_name, num_faces)
    dum = dumbbell.Dumbbell()

    return relative_time, inertial_time, relative_state, inertial_state, ast, dum
Esempio n. 7
0
def inertial_frame_comparison(ast_name='castalia',
                              num_faces=64,
                              tf=1e5,
                              num_steps=1e6):
    """Compare EOMs in the inertial frame

    """
    initial_w = np.array([0.01, 0.0, 0.0])
    print("Running inertial EOMS")
    i_time, i_state = idriver.inertial_eoms_driver(ast_name, num_faces, tf,
                                                   num_steps, initial_w)

    print("Running asteroid EOMs")
    r_time, r_state = rdriver.relative_eoms_driver(ast_name, num_faces, tf,
                                                   num_steps, initial_w)

    ast = asteroid.Asteroid(ast_name, num_faces)
    dum = dumbbell.Dumbbell()

    # also compute and compare the energy behavior
    print("Computing inertial energy")
    i_KE, i_PE = dum.inertial_energy(i_time, i_state, ast)

    print("Computing asteroid energy")
    r_KE, r_PE = dum.relative_energy(r_time, r_state, ast)

    plotting.plot_energy(i_time, i_KE, i_PE)
    # also look at the animation of both and the converted form as well

    print("Plot comparison in the inertial frame")
    plotting.plot_inertial_comparison(r_time, i_time, r_state, i_state, ast,
                                      dum)

    return 0
class TestDistanceToEdgesCubeOutsideFixedSingle():

    pt_out = np.array([1, 0.5, 0.5])
    ast = asteroid.Asteroid('castalia', 256, 'mat')
    v, f = wavefront.read_obj('./integration/cube.obj')
    ast = ast.loadmesh(v, f, 'cube')

    edge_vertex_map = ast.asteroid_grav['edge_vertex_map']
    edge_face_map = ast.asteroid_grav['edge_face_map']
    normal_face = ast.asteroid_grav['normal_face']
    vf_map = ast.asteroid_grav['vertex_face_map']

    D, P, V, E, F = wavefront.distance_to_edges(pt_out, v, f, normal_face,
                                                edge_vertex_map, edge_face_map,
                                                vf_map)
    D_exp = 0.5
    P_exp = np.array([0.5, 0.5, 0.5])
    V_exp = [7, 4]
    E_exp = [7, 4]
    F_exp = [6, 7]

    def test_distance(self):
        np.testing.assert_allclose(self.D, self.D_exp)

    def test_point(self):
        np.testing.assert_array_almost_equal(self.P, self.P_exp)

    def test_vertex(self):
        np.testing.assert_allclose(self.V, self.V_exp)

    def test_edge(self):
        np.testing.assert_allclose(self.E, self.E_exp)

    def test_face(self):
        np.testing.assert_allclose(self.F, self.F_exp)
class TestDistanceToFacesCubeSurfaceSingle():

    pt_out=np.array([0.51, -0.1, 0.0])
    v_cube, f_cube=wavefront.read_obj('./integration/cube.obj')
    ast = asteroid.Asteroid('castalia', 256, 'mat')
    ast = ast.loadmesh(v_cube, f_cube, 'cube')
    edge_vertex_map=ast.asteroid_grav['edge_vertex_map']
    edge_face_map=ast.asteroid_grav['edge_face_map']
    normal_face=ast.asteroid_grav['normal_face']
    vf_map=ast.asteroid_grav['vertex_face_map']

    D, P, V, E, F=wavefront.distance_to_faces(pt_out, v_cube, f_cube,
                                                   normal_face,
                                                   edge_vertex_map,
                                                   edge_face_map,
                                                   vf_map)
    D_exp = np.array(0.01)
    P_exp = np.array([0.5, -0.1, 0])
    V_exp = np.array([4, 7, 5])
    E_exp = np.array([[7, 4],
                      [5, 7],
                      [4, 5]])
    F_exp = np.array(7)

    def test_distance(self):
        np.testing.assert_allclose(self.D, self.D_exp)
    def test_point(self):
        np.testing.assert_allclose(self.P, self.P_exp)
    def test_vertex(self):
        np.testing.assert_allclose(self.V, self.V_exp)
    def test_edge(self):
        for E, E_exp in zip(self.E, self.E_exp):
            np.testing.assert_allclose(E, E_exp)
    def test_face(self):
        np.testing.assert_allclose(self.F, self.F_exp)
def test_eros_obj():
    # pick a known position
    pos = np.random.uniform(1, 2, (3, ))
    # apply a small perturbation
    deltapos = delta * np.random.uniform(0, 1, pos.shape)
    ast = asteroid.Asteroid('eros', 0, 'obj')
    diff_U, dUdx = finite_difference(pos, deltapos, ast)
    np.testing.assert_almost_equal(dUdx.dot(deltapos), diff_U)
class TestDistanceToVerticesCubeOutsideFixedMultiple():
    """This point is equally close to an entire face of the cube

    So there are 4 vertices equidistant from pt
    """
    pt_out = np.array([1, 0, 0])
    v_cube, f_cube = wavefront.read_obj('./integration/cube.obj')
    ast = asteroid.Asteroid('castalia', 256, 'mat')
    ast = ast.loadmesh(v_cube, f_cube, 'cube')
    edge_vertex_map = ast.asteroid_grav['edge_vertex_map']
    edge_face_map = ast.asteroid_grav['edge_face_map']
    normal_face = ast.asteroid_grav['normal_face']
    vf_map = ast.asteroid_grav['vertex_face_map']

    D, P, V, E, F = wavefront.distance_to_vertices(pt_out, v_cube, f_cube,
                                                   normal_face,
                                                   edge_vertex_map,
                                                   edge_face_map, vf_map)

    D_exp = np.ones_like(D) * 0.5 * np.sqrt(3)
    P_exp = np.array([[0.5, -0.5, -0.5], [0.5, -0.5, 0.5], [0.5, 0.5, -0.5],
                      [0.5, 0.5, 0.5]])
    V_exp = np.array([4, 5, 6, 7])
    E_exp = np.array([
        np.array([[6, 4], [7, 4], [4, 0], [4, 6], [5, 4], [0, 4], [4, 7],
                  [4, 5]]),
        np.array([[5, 0], [5, 1], [5, 7], [5, 4], [1, 5], [7, 5], [4, 5],
                  [0, 5]]),
        np.array([[6, 0], [6, 4], [4, 6], [6, 2], [6, 7], [7, 6], [0, 6],
                  [2, 6]]),
        np.array([[7, 2], [7, 4], [7, 1], [6, 7], [7, 3], [7, 6], [5, 7],
                  [7, 5], [3, 7], [2, 7], [4, 7], [1, 7]])
    ])
    F_exp = np.array([
        list([0, 6, 7, 8]),
        list([7, 8, 9, 10]),
        list([0, 1, 4, 6]),
        list([4, 5, 6, 7, 10, 11])
    ])

    def test_distance(self):
        np.testing.assert_allclose(np.absolute(self.D), self.D_exp)

    def test_point(self):
        np.testing.assert_allclose(self.P, self.P_exp)

    def test_vertex(self):
        np.testing.assert_allclose(self.V, self.V_exp)

    def test_edge(self):
        for E, E_exp in zip(self.E, self.E_exp):
            np.testing.assert_allclose(E, E_exp)

    def test_face(self):
        for F, F_exp in zip(self.F, self.F_exp):
            np.testing.assert_allclose(F, F_exp)
Esempio n. 12
0
def test_asteroid():
    # plot the asteroid as a triangular mesh

    ast = asteroid.Asteroid('castalia', 64)

    V = ast.asteroid_grav.get('V') * 1e5
    F = ast.asteroid_grav.get('F')
    F = F.astype(int)
    surface = mlab.pipeline.triangular_mesh_source(V[:, 0], V[:, 1], V[:, 2],
                                                   F - 1)
    # numpy array of points which define the vertices of the surface
    points = np.array([[0, 0, 0], [1, 0, 0], [1, 1, 0]])
    # numpy array defining the triangle which connects those points
    element = np.array([[0, 1, 2], [0, 1, 2]])
Esempio n. 13
0
def initialize():
    """Initialize all the things for the simulation
    """
    logger = logging.getLogger(__name__)
    logger.info('Initialize asteroid and dumbbell objects')

    ast = asteroid.Asteroid('castalia', 4092, 'obj')
    dum = dumbbell.Dumbbell(m1=500, m2=500, l=0.003)
    des_att_func = controller.random_sweep_attitude
    des_tran_func = controller.inertial_fixed_state
    AbsTol = 1e-9
    RelTol = 1e-9

    return ast, dum, des_att_func, des_tran_func, AbsTol, RelTol
Esempio n. 14
0
def create_plots(plot_flags):
    # load the h5py file with all the imagery and simulation data
    with h5py.File('./data/itokawa_landing/cycles_high_7200.hdf5', 'r') as sim_data:
        sim_data.visit(printname)
        K = sim_data['K']
        i_state = sim_data['i_state']
        time = sim_data['time']
        images = sim_data['landing']
        RT_vector = sim_data['RT']
        R_bcam2i_vector = sim_data['R_i2bcam'] # the name is incorrect - actually it's bcamera to inertial frame
        R_ast2int = sim_data['Rast2inertial']

        # define the asteroid and dumbbell objects like the simulation driver
        ast_name = 'itokawa'
        num_faces = 64
        ast = asteroid.Asteroid(ast_name,num_faces)
        dum = dumbbell.Dumbbell(m1=500, m2=500, l=0.003)

        # draw some of the features from an example image
        if plot_flags.feature_matching:
            sift_flann_matching_image(images[:, :, :, 3000],
                                      images[:, :, :, 3200], ratio=0.3, 
                                      plot=True, 
                                      filename='/tmp/itokawa_feature_matching.png',
                                      save_fig=plot_flags.save_plots)    


        # draw the true and estimated trajectory
        if plot_flags.simulation_plots:
            plotting.plot_controlled_blender_inertial(time, 
                                                      i_state, 
                                                      ast, 
                                                      dum, 
                                                      plot_flags.save_plots, 
                                                      1, 
                                                      controller.traverse_then_land_vertically,
                                                      controller.body_fixed_pointing_attitude)

        # create animation
        if plot_flags.animation:
            plotting.animate_inertial_trajectory(time, i_state, ast, dum, 3600, plot_flags.save_plots)

        if plot_flags.keyframe:
            # plot_keyframe_trajectory(time, i_state, R_ast2int, R_bcam2i_vector, 
            #                          plot_flags.save_plots, fwidth=1, 
            #                          filename='/tmp/keyframe_estimate.eps')
            plot_keyframe_original(time, i_state, R_ast2int, R_bcam2i_vector,
                                   plot_flags.save_plots, fwidth=1,
                                   filename='/tmp/keyframe_estimate.eps')
Esempio n. 15
0
def test_closest_edge_plot_asteroid(pt=np.random.uniform(0.8, 1.5) *
                                    sphere.rand(2)):
    ast = asteroid.Asteroid('itokawa', 0, 'obj')

    v, f = ast.asteroid_grav['V'], ast.asteroid_grav['F']
    edge_vertex_map = ast.asteroid_grav['edge_vertex_map']
    edge_face_map = ast.asteroid_grav['edge_face_map']
    normal_face = ast.asteroid_grav['normal_face']
    vf_map = ast.asteroid_grav['vertex_face_map']

    D, P, V, E, F = wavefront.distance_to_edges(pt, v, f, normal_face,
                                                edge_vertex_map, edge_face_map,
                                                vf_map)
    plot_data(pt, v, f, D, P, V, E, F, 'Closest Edge')
    return D, P, V, E, F
Esempio n. 16
0
def test_closest_edge_plot_cube(pt=np.random.uniform(0.9, 1.5) *
                                sphere.rand(2)):
    ast = asteroid.Asteroid('castalia', 256, 'mat')
    v, f = wavefront.read_obj('./integration/cube.obj')
    ast = ast.loadmesh(v, f, 'cube')

    edge_vertex_map = ast.asteroid_grav['edge_vertex_map']
    edge_face_map = ast.asteroid_grav['edge_face_map']
    normal_face = ast.asteroid_grav['normal_face']
    vf_map = ast.asteroid_grav['vertex_face_map']

    D, P, V, E, F = wavefront.distance_to_edges(pt, v, f, normal_face,
                                                edge_vertex_map, edge_face_map,
                                                vf_map)
    plot_data(pt, v, f, D, P, V, E, F, '')
    return D, P, V, E, F
Esempio n. 17
0
def test_update_raycasting_mesh(): 
    # load a polyhedron
    ast = asteroid.Asteroid('castalia', 0, 'obj')
    v, f = ast.V, ast.F
    nv = ast.rotate_vertices(0)
    nf = f

    # define the raycaster object
    caster = raycaster.RayCaster.loadmesh(v, f, flag='obb', scale=1.0)
    ncaster = raycaster.RayCaster.updatemesh(nv, nf)

    # test methods of caster
    V, F = wavefront.polydatatomesh(caster.polydata)
    nV, nF = wavefront.polydatatomesh(ncaster.polydata)

    np.testing.assert_allclose(V, v)
Esempio n. 18
0
    def test_ensure_asteroid_potential_matching(self):
        # some random numbers for the state
        from dynamics import asteroid as asteroid_python

        ast_python = asteroid_python.Asteroid('castalia', 0, 'obj')

        mesh = mesh_data.MeshData(self.v, self.f)
        ast_cpp = asteroid.Asteroid('castalia', mesh)

        for ii in range(10):
            x = np.random.rand()
            state = np.array([x, 1, 1])

            Up, _, _, _ = ast_python.polyhedron_potential(state)
            ast_cpp.polyhedron_potential(state)

            np.testing.assert_allclose(ast_cpp.get_potential(), Up, 1e-6)
Esempio n. 19
0
def castalia_reconstruction(img_path):
    """Incrementally modify an ellipse into a low resolution verision of castalia
    by adding vertices and modifying the mesh
    """
    surf_area = 0.01
    a = 0.22
    delta = 0.01

    # load a low resolution ellipse to start
    ast = asteroid.Asteroid('castalia', 0, 'obj')
    ellipsoid = surface_mesh.SurfMesh(ast.axes[0], ast.axes[1], ast.axes[2],
                                      10, 0.025, 0.5)

    ve, fe = ellipsoid.verts(), ellipsoid.faces()
    vc, fc = ast.V, ast.F

    # sort the vertices in in order (x component)
    vc = vc[vc[:, 0].argsort()]

    # uncertainty for each vertex in meters (1/variance)
    vert_weight = np.full(ve.shape[0], (np.pi * np.max(ast.axes))**2)
    # calculate maximum angle as function of surface area
    max_angle = wavefront.spherical_surface_area(np.max(ast.axes), surf_area)

    # loop and create many figures
    mfig = graphics.mayavi_figure(offscreen=False)
    mesh = graphics.mayavi_addMesh(mfig, ve, fe)
    ms = mesh.mlab_source
    index = 0

    for ii, pt in enumerate(vc):
        index += 1
        filename = os.path.join(
            img_path, 'castalia_reconstruct_' + str(index).zfill(7) + '.jpg')
        # graphics.mlab.savefig(filename, magnification=4)
        ve, vert_weight = wavefront.spherical_incremental_mesh_update(
            pt, ve, fe, vertex_weight=vert_weight, max_angle=max_angle)

        ms.reset(x=ve[:, 0], y=ve[:, 1], z=ve[:, 2], triangles=fe)
        graphics.mayavi_addPoint(mfig, pt, radius=0.01)

    graphics.mayavi_points3d(mfig, ve, scale_factor=0.01, color=(1, 0, 0))

    return 0
Esempio n. 20
0
def test_closest_face_plot_asteroid(pt=np.random.uniform(0.8, 1.5) *
                                    sphere.rand(2)):
    """Needs to be aligned with a face
    
        i.e. not in the corners
    """

    ast = asteroid.Asteroid('itokawa', 0, 'obj')

    v, f = ast.asteroid_grav['V'], ast.asteroid_grav['F']
    edge_vertex_map = ast.asteroid_grav['edge_vertex_map']
    edge_face_map = ast.asteroid_grav['edge_face_map']
    normal_face = ast.asteroid_grav['normal_face']
    vf_map = ast.asteroid_grav['vertex_face_map']

    D, P, V, E, F = wavefront.distance_to_faces(pt, v, f, normal_face,
                                                edge_vertex_map, edge_face_map,
                                                vf_map)
    plot_data(pt, v, f, D, P, V, E, F, 'Closest Face')

    return D, P, V, E, F
Esempio n. 21
0
def asteroid_frame_comparison():
    """Compare EOMs in the asteroid frame

    """

    ast_name = 'castalia'
    num_faces = 64
    tf = 1e4
    num_steps = 1e5

    initial_w = np.array([0.0, 0.01, 0.0])

    i_time, i_state = id.inertial_eoms_driver(ast_name, num_faces, tf,
                                              num_steps, initial_w)
    r_time, r_state = rd.relative_eoms_driver(ast_name, num_faces, tf,
                                              num_steps, initial_w)

    ast = asteroid.Asteroid(ast_name, num_faces)
    dum = dumbbell.Dumbbell()

    # also compute and compare the energy behavior
    i_KE, i_PE = dum.inertial_energy(i_time, i_state, ast)
    r_KE, r_PE = dum.relative_energy(r_time, r_state, ast)
class TestDistanceToVerticesCubeSurfaceSingle():

    pt_out = np.array([0.5, 0.4, 0.4])
    v_cube, f_cube = wavefront.read_obj('./integration/cube.obj')
    ast = asteroid.Asteroid('castalia', 256, 'mat')
    ast = ast.loadmesh(v_cube, f_cube, 'cube')
    edge_vertex_map = ast.asteroid_grav['edge_vertex_map']
    edge_face_map = ast.asteroid_grav['edge_face_map']
    normal_face = ast.asteroid_grav['normal_face']
    vf_map = ast.asteroid_grav['vertex_face_map']

    D, P, V, E, F = wavefront.distance_to_vertices(pt_out, v_cube, f_cube,
                                                   normal_face,
                                                   edge_vertex_map,
                                                   edge_face_map, vf_map)
    D_exp = -0.1 * np.sqrt(2)
    P_exp = np.array([0.5, 0.5, 0.5])
    V_exp = 7
    E_exp = np.array([[7, 2], [7, 4], [7, 1], [6, 7], [7, 3], [7, 6], [5, 7],
                      [7, 5], [3, 7], [2, 7], [4, 7], [1, 7]])
    F_exp = [4, 5, 6, 7, 10, 11]

    def test_distance(self):
        np.testing.assert_allclose(self.D, self.D_exp)

    def test_point(self):
        np.testing.assert_allclose(self.P, self.P_exp)

    def test_vertex(self):
        np.testing.assert_allclose(self.V, self.V_exp)

    def test_edge(self):
        for E, E_exp in zip(self.E, self.E_exp):
            np.testing.assert_allclose(E, E_exp)

    def test_face(self):
        np.testing.assert_allclose(self.F, self.F_exp)
Esempio n. 23
0
class TestHamiltonRelativeTransform():

    time = np.array([0])
    ast = asteroid.Asteroid(name='castalia', num_faces=64)
    dum = dumbbell.Dumbbell()

    inertial_pos = np.array([1, 1, 1])
    inertial_vel = np.random.rand(3) + att.hat_map(
        ast.omega * np.array([0, 0, 1])).dot(inertial_pos)
    R_sc2int = att.rot2(np.pi / 2)
    R_ast2int = att.rot3(time * ast.omega)
    body_ang_vel = np.random.rand(3)

    initial_lin_mom = (dum.m1 + dum.m2) * (inertial_vel)
    initial_ang_mom = R_sc2int.dot(dum.J).dot(body_ang_vel)
    initial_ham_state = np.hstack(
        (inertial_pos, initial_lin_mom, R_ast2int.dot(R_sc2int).reshape(9),
         initial_ang_mom))

    inertial_state = transform.eoms_hamilton_relative_to_inertial(
        time, initial_ham_state, ast, dum)

    def test_eoms_hamilton_relative_to_inertial_scalar_pos(self):
        np.testing.assert_almost_equal(self.inertial_pos,
                                       self.inertial_state[0:3])

    def test_eoms_hamilton_relative_to_inertial_scalar_vel(self):
        np.testing.assert_almost_equal(self.inertial_vel,
                                       self.inertial_state[3:6])

    def test_eoms_hamilton_relative_to_inertial_scalar_att(self):
        np.testing.assert_almost_equal(self.R_sc2int.reshape(9),
                                       self.inertial_state[6:15])

    def test_eoms_hamilton_relative_to_inertial_scalar_ang_vel(self):
        np.testing.assert_almost_equal(self.R_sc2int.dot(self.body_ang_vel),
                                       self.inertial_state[15:18])
class TestDistanceToEdgesCubeOutsideFixedMultiple():
    """This point is equally close to vertex so hopefully multiple edges
    have equal distance
    """
    pt_out = np.array([1, 0, 0])
    ast = asteroid.Asteroid('castalia', 256, 'mat')
    v, f = wavefront.read_obj('./integration/cube.obj')
    ast = ast.loadmesh(v, f, 'cube')

    edge_vertex_map = ast.asteroid_grav['edge_vertex_map']
    edge_face_map = ast.asteroid_grav['edge_face_map']
    normal_face = ast.asteroid_grav['normal_face']
    vf_map = ast.asteroid_grav['vertex_face_map']

    D, P, V, E, F = wavefront.distance_to_edges(pt_out, v, f, normal_face,
                                                edge_vertex_map, edge_face_map,
                                                vf_map)
    D_exp = np.array([0.5, 0.5])
    P_exp = np.array([[0.5, -0, -0], [0.5, 0, 0]])
    V_exp = np.array([[7, 4], [4, 7]])
    E_exp = np.array([[7, 4], [4, 7]])
    F_exp = np.array([[6, 7], [6, 7]])

    def test_distance(self):
        np.testing.assert_allclose(self.D, self.D_exp)

    def test_point(self):
        np.testing.assert_array_almost_equal(self.P, self.P_exp)

    def test_vertex(self):
        np.testing.assert_allclose(self.V, self.V_exp)

    def test_edge(self):
        np.testing.assert_allclose(self.E, self.E_exp)

    def test_face(self):
        np.testing.assert_allclose(self.F, self.F_exp)
Esempio n. 25
0
class TestInertialandRelativeEOMS():
    """Compare the inertial and relative eoms against one another

    """
    RelTol = 1e-9
    AbsTol = 1e-9
    ast_name = 'castalia'
    num_faces = 64
    tf = 1e2
    num_steps = 1e2
    time = np.linspace(0, tf, num_steps)

    periodic_pos = np.array(
        [1.495746722510590, 0.000001002669660, 0.006129720493607])
    periodic_vel = np.array(
        [0.000000302161724, -0.000899607989820, -0.000000013286327])

    ast = asteroid.Asteroid(ast_name, num_faces)
    dum = dumbbell.Dumbbell(m1=500, m2=500, l=0.003)

    # set initial state for inertial EOMs
    initial_pos = periodic_pos  # km for center of mass in body frame
    initial_vel = periodic_vel + att.hat_map(
        ast.omega * np.array([0, 0, 1])).dot(initial_pos)
    initial_R = att.rot2(np.pi / 2).reshape(
        9)  # transforms from dumbbell body frame to the inertial frame
    initial_w = np.array([0.01, 0.01, 0.01])
    initial_state = np.hstack((initial_pos, initial_vel, initial_R, initial_w))

    i_state = integrate.odeint(dum.eoms_inertial,
                               initial_state,
                               time,
                               args=(ast, ),
                               atol=AbsTol,
                               rtol=RelTol)
    # (i_time, i_state) = idriver.eom_inertial_driver(initial_state, time, ast, dum, AbsTol=1e-9, RelTol=1e-9)

    initial_lin_mom = (dum.m1 + dum.m2) * (periodic_vel + att.hat_map(
        ast.omega * np.array([0, 0, 1])).dot(initial_pos))
    initial_ang_mom = initial_R.reshape((3, 3)).dot(dum.J).dot(initial_w)
    initial_ham_state = np.hstack(
        (initial_pos, initial_lin_mom, initial_R, initial_ang_mom))

    rh_state = integrate.odeint(dum.eoms_hamilton_relative,
                                initial_ham_state,
                                time,
                                args=(ast, ),
                                atol=AbsTol,
                                rtol=RelTol)

    # now convert both into the inertial frame
    istate_ham = transform.eoms_hamilton_relative_to_inertial(
        time, rh_state, ast, dum)
    istate_int = transform.eoms_inertial_to_inertial(time, i_state, ast, dum)

    # also convert both into the asteroid frame and compare
    astate_ham = transform.eoms_hamilton_relative_to_asteroid(
        time, rh_state, ast, dum)
    astate_int = transform.eoms_inertial_to_asteroid(time, i_state, ast, dum)

    def test_inertial_frame_comparison_pos(self):
        np.testing.assert_array_almost_equal(self.istate_ham[:, 0:3],
                                             self.istate_int[:, 0:3])

    def test_inertial_frame_comparison_vel(self):
        np.testing.assert_array_almost_equal(self.istate_ham[:, 3:6],
                                             self.istate_int[:, 3:6])

    def test_inertial_frame_comparison_att(self):
        np.testing.assert_array_almost_equal(self.istate_ham[:, 6:15],
                                             self.istate_int[:, 6:15])

    def test_inertial_frame_comparison_ang_vel(self):
        np.testing.assert_array_almost_equal(self.istate_ham[:, 15:18],
                                             self.istate_int[:, 15:18])

    def test_asteroid_frame_comparison_pos(self):
        np.testing.assert_array_almost_equal(self.astate_ham[:, 0:3],
                                             self.astate_int[:, 0:3])

    def test_asteroid_frame_comparison_vel(self):
        np.testing.assert_array_almost_equal(self.astate_ham[:, 3:6],
                                             self.astate_int[:, 3:6])

    def test_asteroid_frame_comparison_att(self):
        np.testing.assert_array_almost_equal(self.astate_ham[:, 6:15],
                                             self.astate_int[:, 6:15])

    def test_asteroid_frame_comparison_ang_vel(self):
        np.testing.assert_array_almost_equal(self.astate_ham[:, 15:18],
                                             self.astate_int[:, 15:18])
Esempio n. 26
0
import relative_driver as rdriver

RelTol = 1e-6
AbsTol = 1e-6
ast_name = 'itokawa'
num_faces = 64
tf = 1e2
num_steps = 1e2
time = np.linspace(0, int(tf), int(num_steps))

periodic_pos = np.array(
    [1.495746722510590, 0.000001002669660, 0.006129720493607])
periodic_vel = np.array(
    [0.000000302161724, -0.000899607989820, -0.000000013286327])

ast = asteroid.Asteroid(ast_name, num_faces)
dum = dumbbell.Dumbbell(m1=500, m2=500, l=0.003)

# set initial state for inertial EOMs
initial_pos = periodic_pos  # km for center of mass in body frame
initial_vel = periodic_vel + attitude.hat_map(
    ast.omega * np.array([0, 0, 1])).dot(initial_pos)
initial_R = attitude.rot2(np.pi / 2).reshape(
    9)  # transforms from dumbbell body frame to the inertial frame
initial_w = np.array([0.01, 0.01, 0.01])
initial_state = np.hstack((initial_pos, initial_vel, initial_R, initial_w))

i_state = integrate.odeint(dum.eoms_inertial_control,
                           initial_state,
                           time,
                           args=(ast, ),
Esempio n. 27
0
def blender_asteroid_frame_sim(gen_images=False):
    # simulation parameters
    output_path = './visualization/blender'
    asteroid_name = 'itokawa_low'
    # create a HDF5 dataset
    hdf5_path = './data/asteroid_circumnavigate/{}_asteroid_circumnavigate.hdf5'.format(
        datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S"))
    dataset_name = 'landing'
    render = 'BLENDER'
    image_modulus = 1
    RelTol = 1e-6
    AbsTol = 1e-6
    ast_name = 'itokawa'
    num_faces = 64
    t0 = 0
    dt = 1
    tf = 3600 * 1
    num_steps = 3600 * 1

    ast = asteroid.Asteroid(ast_name,num_faces)
    dum = dumbbell.Dumbbell(m1=500, m2=500, l=0.003)

    # instantiate the blender scene once
    camera_obj, camera, lamp_obj, lamp, itokawa_obj, scene = blender.blender_init(render_engine=render, asteroid_name=asteroid_name)

    # get some of the camera parameters
    K = blender_camera.get_calibration_matrix_K_from_blender(camera)

    periodic_pos = np.array([1.495746722510590,0.000001002669660,0.006129720493607])
    periodic_vel = np.array([0.000000302161724,-0.000899607989820,-0.000000013286327])

    # set initial state for inertial EOMs
    # initial_pos = np.array([2.550, 0, 0]) # km for center of mass in body frame
    initial_pos = np.array([3, 0, 0])
    initial_vel = periodic_vel + attitude.hat_map(ast.omega*np.array([0,0,1])).dot(initial_pos)
    initial_R = attitude.rot3(np.pi/2).reshape(9) # transforms from dumbbell body frame to the inertial frame
    initial_w = np.array([0.01, 0.01, 0.01])
    initial_state = np.hstack((initial_pos, initial_vel, initial_R, initial_w))

    # instantiate ode object
    # system = integrate.ode(eoms_controlled_blender)
    system = integrate.ode(eoms.eoms_controlled_relative_blender_ode)
    system.set_integrator('lsoda', atol=AbsTol, rtol=RelTol, nsteps=1000)
    system.set_initial_value(initial_state, t0)
    system.set_f_params(dum, ast)

    i_state = np.zeros((num_steps+1, 18))
    time = np.zeros(num_steps+1)
    i_state[0, :] = initial_state

    with h5py.File(hdf5_path) as image_data:
        # create a dataset
        if gen_images:
            images = image_data.create_dataset(dataset_name, (244, 537, 3,
                                                              num_steps/image_modulus),
                                               dtype='uint8')
            RT_blender = image_data.create_dataset('RT',
                                                   (num_steps/image_modulus,
                                                    12)) 
            R_i2bcam = image_data.create_dataset('R_i2bcam',
                                                 (num_steps/image_modulus, 9))
       
        ii = 1
        while system.successful() and system.t < tf:
            # integrate the system and save state to an array
            time[ii] = (system.t + dt)
            i_state[ii, :] = (system.integrate(system.t + dt))
            # generate the view of the asteroid at this state
            if int(time[ii]) % image_modulus== 0 and gen_images:
                img, RT, R = blender.gen_image_fixed_ast(i_state[ii,0:3], 
                                                         i_state[ii,6:15].reshape((3,3)),
                                                         ast.omega * (time[ii] - 3600),
                                                         camera_obj, camera,
                                                         lamp_obj, lamp,
                                                         itokawa_obj, scene,
                                                         [5, 0, 1], 'test')

                images[:, :, :, ii//image_modulus - 1] = img
                RT_blender[ii//image_modulus -1, :] = RT.reshape(12)
                R_i2bcam[ii//image_modulus -1, :] = R.reshape(9)


            # do some image processing and visual odometry
            print(system.t)
            ii += 1

        image_data.create_dataset('K', data=K)
        image_data.create_dataset('i_state', data=i_state)
        image_data.create_dataset('time', data=time)
Esempio n. 28
0
def incremental_reconstruction(input_filename,
                               output_filename,
                               asteroid_name='castalia'):
    """Incrementally update the mesh

    Now we'll use the radial mesh reconstruction.

    """
    logger = logging.getLogger(__name__)
    # output_filename = './data/raycasting/20180226_castalia_reconstruct_highres_45deg_cone.hdf5'

    logger.info('Loading {}'.format(input_filename))
    data = np.load(input_filename)
    point_cloud = data['point_cloud'][()]

    # define the asteroid and dumbbell objects

    asteroid_faces = 0
    asteroid_type = 'obj'
    m1, m2, l = 500, 500, 0.003

    ellipsoid_min_angle = 10
    ellipsoid_max_radius = 0.03
    ellipsoid_max_distance = 0.5

    surf_area = 0.01

    ast = asteroid.Asteroid(asteroid_name, asteroid_faces, asteroid_type)
    dum = dumbbell.Dumbbell(m1=m1, m2=m2, l=l)

    logger.info('Creating ellipsoid mesh')
    # define a simple mesh to start
    ellipsoid = surface_mesh.SurfMesh(ast.axes[0], ast.axes[1], ast.axes[2],
                                      ellipsoid_min_angle,
                                      ellipsoid_max_radius,
                                      ellipsoid_max_distance)
    v_est, f_est = ellipsoid.verts(), ellipsoid.faces()

    vert_weight = np.full(v_est.shape[0], (np.pi * np.max(ast.axes))**2)

    max_angle = wavefront.spherical_surface_area(np.max(ast.axes), surf_area)

    # extract out all the points in the asteroid frame
    time = point_cloud['time'][::1]
    ast_ints = point_cloud['ast_ints'][::1]
    logger.info('Create HDF5 file {}'.format(output_filename))
    with h5py.File(output_filename, 'w') as fout:
        # store some extra data about teh simulation
        v_group = fout.create_group('reconstructed_vertex')
        f_group = fout.create_group('reconstructed_face')
        w_group = fout.create_group('reconstructed_weight')

        sim_data = fout.create_group('simulation_data')
        sim_data.attrs['asteroid_name'] = np.string_(asteroid_name)
        sim_data.attrs['asteroid_faces'] = asteroid_faces
        sim_data.attrs['asteroid_type'] = np.string_(asteroid_type)
        sim_data.attrs['m1'] = dum.m1
        sim_data.attrs['m2'] = dum.m2
        sim_data.attrs['l'] = dum.l

        sim_data.attrs['ellipsoid_axes'] = ast.axes
        sim_data.attrs['ellipsoid_min_angle'] = ellipsoid_min_angle
        sim_data.attrs['ellipsoid_max_radius'] = ellipsoid_max_radius
        sim_data.attrs['ellipsoid_max_distance'] = ellipsoid_max_distance
        sim_data.attrs['surf_area'] = surf_area

        sim_data.attrs['max_angle'] = max_angle

        fout.create_dataset('truth_vertex', data=ast.V)
        fout.create_dataset('truth_faces', data=ast.F)
        fout.create_dataset('estimate_faces', data=f_est)

        fout.create_dataset('initial_vertex', data=v_est)
        fout.create_dataset('initial_faces', data=f_est)
        fout.create_dataset('initial_weight', data=vert_weight)

        logger.info('Starting loop over point cloud')
        for ii, (t, points) in enumerate(zip(time, ast_ints)):
            # check if points is empty
            logger.info('Current : t = {} with {} points'.format(
                t, len(points)))
            for pt in points:
                # incremental update for each point in points
                # check to make sure each pt is not nan
                if not np.any(np.isnan(pt)):
                    v_est, vert_weight = wavefront.spherical_incremental_mesh_update(
                        pt,
                        v_est,
                        f_est,
                        vertex_weight=vert_weight,
                        max_angle=max_angle)

            # use HD5PY instead
            # save every so often and delete v_array,f_array to save memory
            if (ii % 1) == 0:
                logger.info('Saving data to HDF5. ii = {}, t = {}'.format(
                    ii, t))
                v_group.create_dataset(str(ii), data=v_est)
                f_group.create_dataset(str(ii), data=f_est)
                w_group.create_dataset(str(ii), data=vert_weight)

    logger.info('Completed the reconstruction')

    return 0
Esempio n. 29
0
def asteroid_reconstruct_generate_data(output_filename,
                                       asteroid_name='castalia'):
    """Generate all the data for an example for reconstructing asteroid 
    """
    asteroid_type = 'obj'
    asteroid_faces = 0

    if asteroid_name == 'castalia':
        ellipsoid_min_angle = 10
        ellipsoid_max_radius = 0.03
        ellipsoid_max_distance = 0.5
        step = 1
        surf_area = 0.01
    elif asteroid_name == 'itokawa':
        ellipsoid_min_angle = 10
        ellipsoid_max_radius = 0.003
        ellipsoid_max_distance = 0.5
        step = 1
        surf_area = 0.0001

    # load asteroid castalia
    ast = asteroid.Asteroid(asteroid_name, asteroid_faces, asteroid_type)
    ellipsoid = surface_mesh.SurfMesh(ast.axes[0], ast.axes[1], ast.axes[2],
                                      ellipsoid_min_angle,
                                      ellipsoid_max_radius,
                                      ellipsoid_max_distance)
    ve, fe = ellipsoid.verts(), ellipsoid.faces()
    vc, fc = ast.V, ast.F

    # cort the truth vertices in increasing order of x component
    vc = vc[vc[:, 0].argsort()]
    vc = vc[::step, :]
    # np.random.shuffle(vc)

    # define initial uncertainty for our estimate
    vert_weight = np.full(ve.shape[0], (np.pi * np.max(ast.axes))**2)

    # calculate the maximum angle as a function of desired surface area
    max_angle = wavefront.spherical_surface_area(np.max(ast.axes), surf_area)

    # generate a mesh and reconstruct object from c++
    mesh = mesh_data.MeshData(ve, fe)
    rmesh = reconstruct.ReconstructMesh(ve, fe, vert_weight)

    # loop over all the points and save the data
    output_path = os.path.join(output_filename)

    with h5py.File(output_path, 'w') as fout:
        reconstructed_vertex = fout.create_group('reconstructed_vertex')
        reconstructed_weight = fout.create_group('reconstructed_weight')
        reconstructed_vertex.attrs['asteroid_name'] = np.string_(asteroid_name)
        reconstructed_vertex.attrs['asteroid_faces'] = asteroid_faces
        reconstructed_vertex.attrs['asteroid_type'] = np.string_(asteroid_type)
        reconstructed_vertex.attrs['ellipsoid_axes'] = ast.axes
        reconstructed_vertex.attrs['ellipsoid_min_angle'] = ellipsoid_min_angle
        reconstructed_vertex.attrs[
            'ellipsoid_max_radius'] = ellipsoid_max_radius
        reconstructed_vertex.attrs[
            'ellipsoid_max_distance'] = ellipsoid_max_distance
        reconstructed_vertex.attrs['surf_area'] = surf_area

        fout.create_dataset('truth_vertex', data=vc)
        fout.create_dataset('truth_faces', data=fc)
        fout.create_dataset('estimate_faces', data=fe)

        fout.create_dataset('initial_vertex', data=ve)
        fout.create_dataset('initial_faces', data=fe)
        fout.create_dataset('initial_weight', data=vert_weight)

        for ii, pt in enumerate(vc):
            # ve, vert_weight = wavefront.spherical_incremental_mesh_update(pt, ve, fe,
            #                                                               vertex_weight=vert_weight,
            #                                                               max_angle=max_angle)
            rmesh.update(pt, max_angle)
            ve = rmesh.get_verts()
            vert_weight = np.squeeze(rmesh.get_weights())
            # save the current array and weight to htpy
            reconstructed_vertex.create_dataset(str(ii),
                                                data=ve,
                                                compression='lzf')
            reconstructed_weight.create_dataset(str(ii),
                                                data=vert_weight,
                                                compression='lzf')

    print('Finished generating data. Saved to {}'.format(output_path))

    return 0
                        help='String - Filename for npz archive',
                        type=str)
    parser.add_argument(
        "-m",
        "--mode",
        type=int,
        choices=[0, 1],
        help=
        "Choose which inertial energy mode to run. 0 - inertial energy, 1 - \Delta E behavior"
    )
    args = parser.parse_args()

    print("Starting the simulation...")

    # instantiate the asteroid and dumbbell objects
    ast = asteroid.Asteroid(args.ast_name, args.num_faces)
    dum = dumbbell.Dumbbell(m1=500, m2=500, l=0.003)

    # initialize simulation parameters
    time = np.linspace(0, args.tf, args.num_steps)
    initial_pos = periodic_pos  # km for center of mass in body frame
    initial_vel = periodic_vel + attitude.hat_map(
        ast.omega * np.array([0, 0, 1])).dot(initial_pos)
    initial_R = attitude.rot2(0).reshape(
        9)  # transforms from dumbbell body frame to the inertial frame
    initial_w = np.array([0.01, 0.01, 0.01])
    initial_state = np.hstack((initial_pos, initial_vel, initial_R, initial_w))

    # echo back all the input parameters
    print("This will run a long simulation with the following parameters!")
    print("     ast_name  - %s" % args.ast_name)