Beispiel #1
0
def check_trajectory_collision(robot, trajectory, bodies):
    # TODO: each new addition makes collision checking more expensive
    #offset = 4
    movable_joints = get_movable_joints(robot)
    #for q in trajectory[offset:-offset]:
    collisions = [False for _ in range(len(bodies))] # TODO: batch collision detection
    for q in trajectory:
        set_joint_positions(robot, movable_joints, q)
        for i, body in enumerate(bodies):
            if not collisions[i]:
                collisions[i] |= pairwise_collision(robot, body)
    return collisions
Beispiel #2
0
def display_trajectories(assembly_network,
                         process_trajs,
                         extrusion_time_step=0.075,
                         transition_time_step=0.1):
    disconnect()
    assert (process_trajs)

    connect(use_gui=True)
    floor, robot = load_world()
    camera_base_pt = assembly_network.get_end_points(0)[0]
    camera_pt = np.array(camera_base_pt) + np.array([0.1, 0, 0.05])
    set_camera_pose(tuple(camera_pt), camera_base_pt)

    movable_joints = get_movable_joints(robot)
    #element_bodies = dict(zip(elements, create_elements(node_points, elements)))
    #for body in element_bodies.values():
    #    set_color(body, (1, 0, 0, 0))
    # connected = set(ground_nodes)
    for seq_id, unit_proc in sorted(process_trajs.items()):
        #     if isinstance(trajectory, PrintTrajectory):
        #         print(trajectory, trajectory.n1 in connected, trajectory.n2 in connected,
        #               is_ground(trajectory.element, ground_nodes), len(trajectory.path))
        #         connected.add(trajectory.n2)
        #     #wait_for_interrupt()
        #     #set_color(element_bodies[element], (1, 0, 0, 1))
        last_point = None
        handles = []

        if 'transition' in unit_proc and unit_proc['transition']:
            for conf in unit_proc['transition']:
                set_joint_positions(robot, movable_joints, conf)
                wait_for_duration(transition_time_step)
        else:
            print(
                'seq #{} does not have transition traj found!'.format(seq_id))

        for conf in unit_proc['print']:
            set_joint_positions(robot, movable_joints, conf)
            # if isinstance(trajectory, PrintTrajectory):
            current_point = point_from_pose(
                get_link_pose(robot, link_from_name(robot, TOOL_FRAME)))
            if last_point is not None:
                color = (
                    0, 0, 1
                )  #if is_ground(trajectory.element, ground_nodes) else (1, 0, 0)
                handles.append(add_line(last_point, current_point,
                                        color=color))
            last_point = current_point
            wait_for_duration(extrusion_time_step)

    print('simulation done.')
    wait_for_user()
    disconnect()
Beispiel #3
0
def direct_ladder_graph_solve(robot, assembly_network, element_seq, seq_poses, obstacles):
    dof = len(get_movable_joints(robot))
    graph_list = []
    built_obstacles = obstacles
    disabled_collisions = get_disabled_collisions(robot)

    for i in element_seq.keys():
           e_id = element_seq[i]
           p1, p2 = assembly_network.get_end_points(e_id)

           collision_fn = get_collision_fn(robot, get_movable_joints(robot), built_obstacles,
                                           attachments=[], self_collisions=SELF_COLLISIONS,
                                           disabled_collisions=disabled_collisions,
                                           custom_limits={} )
           st_time = time.time()
           while True:
               ee_dir = random.choice(seq_poses[i])
               rot_angle = random.uniform(-np.pi, np.pi)
               way_poses = generate_way_point_poses(p1, p2, ee_dir.phi, ee_dir.theta, rot_angle, WAYPOINT_DISC_LEN)
               graph = generate_ladder_graph_from_poses(robot, dof, way_poses, collision_fn)
               if graph is not None:
                   # print(graph)
                   graph_list.append(graph)
                   break
               if time.time() - st_time > 5:
                   break
           built_obstacles.append(assembly_network.get_element_body(e_id))

    unified_graph = LadderGraph(dof)
    for g in graph_list:
        unified_graph = append_ladder_graph(unified_graph, g)

    dag_search = DAGSearch(unified_graph)
    dag_search.run()
    graph_sizes = [g.size for g in graph_list]
    tot_traj = dag_search.shortest_path()
    return tot_traj, graph_sizes
Beispiel #4
0
    def __init__(self, robot, dof, assembly_network, element_seq, seq_poses, static_obstacles=[]):
        """seq_poses = {e_id: [(phi, theta)], ..}"""
        assert(isinstance(assembly_network, AssemblyNetwork))
        assert(isinstance(dof, int))
        self.dof = dof
        self.cap_rungs = []
        self.robot = robot
        disabled_collisions = get_disabled_collisions(robot)
        built_obstacles = copy(static_obstacles)

        seq = set()
        for i in sorted(element_seq.keys()):
            e_id = element_seq[i]
            # TODO: temporal fix, this should be consistent with the seq search!!!
            if not assembly_network.is_element_grounded(e_id):
                ngbh_e_ids = seq.intersection(assembly_network.get_element_neighbor(e_id))
                shared_node = set()
                for n_e in ngbh_e_ids:
                    shared_node.update([assembly_network.get_shared_node_id(e_id, n_e)])
                shared_node = list(shared_node)
            else:
                shared_node = [v_id for v_id in assembly_network.get_element_end_point_ids(e_id)
                               if assembly_network.assembly_joints[v_id].is_grounded]
            assert(shared_node)

            e_ns = set(assembly_network.get_element_end_point_ids(e_id))
            e_ns.difference_update([shared_node[0]])
            way_points = interpolate_straight_line_pts(assembly_network.get_node_point(shared_node[0]),
                                                       assembly_network.get_node_point(e_ns.pop()),
                                                       WAYPOINT_DISC_LEN)

            e_body = assembly_network.get_element_body(e_id)
            cap_rung = CapRung()
            cap_rung.path_pts = way_points

            assert(seq_poses[i])
            cap_rung.ee_dirs = seq_poses[i]
            cap_rung.collision_fn = get_collision_fn(robot, get_movable_joints(robot), built_obstacles,
                                        attachments=[], self_collisions=SELF_COLLISIONS,
                                        disabled_collisions=disabled_collisions,
                                        custom_limits={})
            self.cap_rungs.append(cap_rung)
            built_obstacles.append(e_body)
            seq.update([e_id])
Beispiel #5
0
def display_trajectories(assembly_network, trajectories, time_step=0.075):
    disconnect()
    if trajectories is None:
        return
    connect(use_gui=True)
    floor, robot = load_world()
    camera_base_pt = assembly_network.get_end_points(0)[0]
    camera_pt = np.array(camera_base_pt) + np.array([0.1, 0, 0.05])
    set_camera_pose(tuple(camera_pt), camera_base_pt)
    # wait_for_interrupt()

    movable_joints = get_movable_joints(robot)
    #element_bodies = dict(zip(elements, create_elements(node_points, elements)))
    #for body in element_bodies.values():
    #    set_color(body, (1, 0, 0, 0))
    # connected = set(ground_nodes)
    for trajectory in trajectories:
        #     if isinstance(trajectory, PrintTrajectory):
        #         print(trajectory, trajectory.n1 in connected, trajectory.n2 in connected,
        #               is_ground(trajectory.element, ground_nodes), len(trajectory.path))
        #         connected.add(trajectory.n2)
        #     #wait_for_interrupt()
        #     #set_color(element_bodies[element], (1, 0, 0, 1))
        last_point = None
        handles = []
        for conf in trajectory:  #.path:
            set_joint_positions(robot, movable_joints, conf)
            # if isinstance(trajectory, PrintTrajectory):
            current_point = point_from_pose(
                get_link_pose(robot, link_from_name(robot, TOOL_FRAME)))
            if last_point is not None:
                color = (
                    0, 0, 1
                )  #if is_ground(trajectory.element, ground_nodes) else (1, 0, 0)
                handles.append(add_line(last_point, current_point,
                                        color=color))
            last_point = current_point
            wait_for_duration(time_step)
        # wait_for_interrupt()

    wait_for_interrupt()
    disconnect()
Beispiel #6
0
def main(precompute=False):
    parser = argparse.ArgumentParser()
    # four-frame | simple_frame | djmm_test_block | mars_bubble | sig_artopt-bunny | topopt-100 | topopt-205 | topopt-310 | voronoi
    parser.add_argument('-p',
                        '--problem',
                        default='simple_frame',
                        help='The name of the problem to solve')
    parser.add_argument(
        '-sm',
        '--search_method',
        default='b',
        help='csp search method, b for backward, f for forward.')
    parser.add_argument(
        '-vom',
        '--value_order_method',
        default='sp',
        help=
        'value ordering method, sp for special heuristic, random for random value ordering'
    )
    parser.add_argument('-l',
                        '--use_layer',
                        action='store_true',
                        help='use layer info in the search.')
    # parser.add_argument('-c', '--cfree', action='store_true', help='Disables collisions with obstacles')
    # parser.add_argument('-m', '--motions', action='store_true', help='Plans motions between each extrusion')
    parser.add_argument('-v',
                        '--viewer',
                        action='store_true',
                        help='Enables the viewer during planning (slow!)')
    parser.add_argument(
        '-s',
        '--parse_seq',
        action='store_true',
        help=
        'parse sequence planning result from a file and proceed to motion planning'
    )
    parser.add_argument('-d',
                        '--debug',
                        action='store_true',
                        help='Debug mode.')
    args = parser.parse_args()
    print('Arguments:', args)

    elements, node_points, ground_nodes, file_path = load_extrusion(
        args.problem, parse_layers=True)
    node_order = list(range(len(node_points)))

    # vert indices sanity check
    ground_nodes = [n for n in ground_nodes if n in node_order]
    elements = [
        element for element in elements
        if all(n in node_order for n in element.node_ids)
    ]

    connect(use_gui=args.viewer)
    floor, robot = load_world()

    # TODO: import other static obstacles
    static_obstacles = [floor]
    movable_joints = get_movable_joints(robot)
    disabled_collisions = get_disabled_collisions(robot)
    initial_conf = get_joint_positions(robot, movable_joints)

    camera_pt = np.array(node_points[10]) + np.array([0.1, 0, 0.05])
    target_camera_pt = node_points[0]

    # create collision bodies
    bodies = create_elements(node_points,
                             [tuple(e.node_ids) for e in elements])
    for e, b in zip(elements, bodies):
        e.element_body = b
        # draw_pose(get_pose(b), length=0.004)

    assembly_network = AssemblyNetwork(node_points, elements, ground_nodes)
    assembly_network.compute_traversal_to_ground_dist()

    sc = stiffness_checker(json_file_path=file_path, verbose=False)
    # sc.set_self_weight_load(True)
    print('test stiffness check on the whole structure: {0}'.format(
        sc.solve()))

    if has_gui():
        pline_handle = draw_model(assembly_network, draw_tags=False)
        set_camera_pose(tuple(camera_pt), target_camera_pt)
        wait_for_user()

    use_seq_existing_plan = args.parse_seq
    if not use_seq_existing_plan:
        with LockRenderer():
            search_method = SEARCH_METHODS[args.search_method]
            element_seq, seq_poses = plan_sequence(
                robot,
                static_obstacles,
                assembly_network,
                stiffness_checker=sc,
                search_method=search_method,
                value_ordering_method=args.value_order_method,
                use_layer=args.use_layer,
                file_name=args.problem)
        write_seq_json(assembly_network, element_seq, seq_poses, args.problem)
    else:
        element_seq, seq_poses = read_seq_json(args.problem)

    # TODO: sequence direction routing (if real fab)
    ####################
    # sequence planning completed
    if has_gui():
        # wait_for_interrupt('Press a key to visualize the plan...')
        # map(p.removeUserDebugItem, pline_handle)
        remove_all_debug()
        # draw_assembly_sequence(assembly_network, element_seq, seq_poses, time_step=1)

    if USE_MESHCAT:
        print('Visualizing assembly seq in meshcat...')
        vis = meshcat.Visualizer()
        try:
            vis.open()
        except:
            vis.url()
        meshcat_visualize_assembly_sequence(vis,
                                            assembly_network,
                                            element_seq,
                                            seq_poses,
                                            scale=3,
                                            time_step=0.5,
                                            direction_len=0.025)

    # motion planning phase
    # assume that the robot's dof is all included in the ikfast model
    print('start sc motion planning.')
    with LockRenderer():
        # tot_traj, graph_sizes = direct_ladder_graph_solve(robot, assembly_network, element_seq, seq_poses, static_obstacles)
        sg = SparseLadderGraph(robot, len(get_movable_joints(robot)),
                               assembly_network, element_seq, seq_poses,
                               static_obstacles)
        sg.find_sparse_path(max_time=SPARSE_LADDER_GRAPH_SOLVE_TIMEOUT)
        tot_traj, graph_sizes = sg.extract_solution()

    process_trajs = {}
    for seq_id, print_jt_list in enumerate(
            list(divide_list_chunks(tot_traj, graph_sizes))):
        process_trajs[seq_id] = {}
        process_trajs[seq_id]['print'] = print_jt_list

    # TODO: a separate function
    # transition planning
    print('start transition planning.')
    moving_obstacles = {}
    for seq_id, e_id in sorted(element_seq.items()):
        print('transition planning # {} - E#{}'.format(seq_id, e_id))
        # print('moving obs: {}'.format([get_name(mo) for mo in moving_obstacles.values()]))
        # print('static obs: {}'.format([get_name(so) for so in static_obstacles]))
        print('---')

        if seq_id != 0:
            set_joint_positions(robot, movable_joints,
                                process_trajs[seq_id - 1]['print'][-1])
        else:
            set_joint_positions(robot, movable_joints, initial_conf)

        transition_traj = plan_joint_motion(robot,
                                            movable_joints,
                                            process_trajs[seq_id]['print'][0],
                                            obstacles=static_obstacles +
                                            list(moving_obstacles.values()),
                                            self_collisions=SELF_COLLISIONS)

        if not transition_traj:
            add_line(*assembly_network.get_end_points(e_id))

            cfn = get_collision_fn_diagnosis(
                robot,
                movable_joints,
                obstacles=static_obstacles + list(moving_obstacles.values()),
                attachments=[],
                self_collisions=SELF_COLLISIONS,
                disabled_collisions=disabled_collisions)

            st_conf = get_joint_positions(robot, movable_joints)
            print('start extrusion pose:')
            cfn(st_conf)

            end_conf = process_trajs[seq_id]['print'][0]
            print('end extrusion pose:')
            cfn(end_conf)

        process_trajs[seq_id]['transition'] = transition_traj

        e_body = assembly_network.get_element_body(e_id)
        moving_obstacles[seq_id] = e_body

    print('transition planning done! proceed to simulation?')
    wait_for_user()

    display_trajectories(assembly_network,
                         process_trajs,
                         extrusion_time_step=0.15,
                         transition_time_step=0.1)
    print('Quit?')
    if has_gui():
        wait_for_user()
Beispiel #7
0
def main(precompute=False):
    parser = argparse.ArgumentParser()
    # four-frame | simple_frame | djmm_test_block | mars_bubble | sig_artopt-bunny | topopt-100 | topopt-205 | topopt-310 | voronoi
    parser.add_argument('-p',
                        '--problem',
                        default='simple_frame',
                        help='The name of the problem to solve')
    # parser.add_argument('-c', '--cfree', action='store_true', help='Disables collisions with obstacles')
    # parser.add_argument('-m', '--motions', action='store_true', help='Plans motions between each extrusion')
    parser.add_argument('-v',
                        '--viewer',
                        action='store_true',
                        help='Enables the viewer during planning (slow!)')
    # parser.add_argument('-s', '--parse_seq', action='store_true', help='parse sequence planning result from a file and proceed to motion planning')
    parser.add_argument('-d',
                        '--debug',
                        action='store_true',
                        help='Debug mode.')
    args = parser.parse_args()
    print('Arguments:', args)

    elements, node_points, ground_nodes, file_path = load_extrusion(
        args.problem, parse_layers=True)
    node_order = list(range(len(node_points)))

    # vert indices sanity check
    ground_nodes = [n for n in ground_nodes if n in node_order]
    elements = [
        element for element in elements
        if all(n in node_order for n in element.node_ids)
    ]

    connect(use_gui=args.viewer)
    floor, robot = load_world()
    # static obstacles
    obstacles = [floor]
    # initial_conf = get_joint_positions(robot, get_movable_joints(robot))
    # dump_body(robot)

    camera_pt = np.array(node_points[10]) + np.array([0.1, 0, 0.05])
    target_camera_pt = node_points[0]

    # create collision bodies
    bodies = create_elements(node_points,
                             [tuple(e.node_ids) for e in elements])
    for e, b in zip(elements, bodies):
        e.element_body = b
        # draw_pose(get_pose(b), length=0.004)

    if has_gui():
        pline_handle = draw_model(assembly_network, draw_tags=False)
        set_camera_pose(tuple(camera_pt), target_camera_pt)
        wait_for_interrupt('Continue?')

    use_seq_existing_plan = args.parse_seq

    ####################
    # sequence planning completed
    if has_gui():
        # wait_for_interrupt('Press a key to visualize the plan...')
        map(p.removeUserDebugItem, pline_handle)
        # draw_assembly_sequence(assembly_network, element_seq, seq_poses, time_step=1)

    # print('Visualizing assembly seq in meshcat...')
    # vis = meshcat.Visualizer()
    # try:
    #     vis.open()
    # except:
    #     vis.url()
    # meshcat_visualize_assembly_sequence(vis, assembly_network, element_seq, seq_poses,
    #                                     scale=3, time_step=0.5, direction_len=0.025)

    # motion planning phase
    # assume that the robot's dof is all included in the ikfast model
    print('start sc motion planning.')

    with LockRenderer():
        # tot_traj, graph_sizes = direct_ladder_graph_solve(robot, assembly_network, element_seq, seq_poses, obstacles)
        sg = SparseLadderGraph(robot, len(get_movable_joints(robot)),
                               assembly_network, element_seq, seq_poses,
                               obstacles)
        sg.find_sparse_path(max_time=2)
        tot_traj, graph_sizes = sg.extract_solution()

    trajectories = list(divide_list_chunks(tot_traj, graph_sizes))

    # if args.viewer:
    # display_trajectories(assembly_network, trajectories, time_step=0.15)
    print('Quit?')
    if has_gui():
        wait_for_interrupt()
Beispiel #8
0
        def exist_valid_ee_pose(self, var, val, assignment):
            # will printing edge #val collide with any assigned element?
            # if var in assignment.keys():
            #     return False
            # else:
            if sum(self.cmaps[val]) == 0:
                return False
            else:
                val_cmap = copy(self.cmaps[val])
                built_obstacles = self.obstacles

                success = False
                # forward search
                if self.search_method == 'forward':
                    built_obstacles = built_obstacles + [
                        self.net.get_element_body(assignment[i])
                        for i in assignment.keys() if i != var
                    ]
                    # check against all existing edges except itself
                    for k in assignment.keys():
                        if k == var:
                            continue
                        exist_e_id = assignment[k]
                        # TODO: check print nodal direction n1 -> n2
                        val_cmap = update_collision_map(
                            self.net, self.ee_body, val, exist_e_id, val_cmap,
                            self.obstacles)
                        if sum(val_cmap) == 0:
                            success = False
                            self.constr_check_time['exist_valid_ee_pose'][
                                success] += 1
                            return success
                # backward search
                elif self.search_method == 'backward':
                    # all unassigned values are assumed to be collision objects
                    # TODO: only check current layer's value?
                    # TODO: these set difference stuff should use domain value
                    unassigned_vals = list(
                        set(range(len(self.variables))).difference(
                            assignment.values()))
                    if not self.net.is_element_grounded(val):
                        ngbh_e_ids = set(self.net.get_element_neighbor(
                            val)).intersection(unassigned_vals)
                        shared_node = set()
                        for n_e in ngbh_e_ids:
                            shared_node.update(
                                [self.net.get_shared_node_id(val, n_e)])
                        shared_node = list(shared_node)
                    else:
                        shared_node = [
                            v_id
                            for v_id in self.net.get_element_end_point_ids(val)
                            if self.net.assembly_joints[v_id].is_grounded
                        ]
                    assert (shared_node)

                    # everytime we start fresh
                    # val_cmap = np.ones(PHI_DISC * THETA_DISC, dtype=int)

                    # print('checking #{0}-e{1}, before pruning, cmaps sum: {2}'.format(var, val, sum(val_cmap)))
                    # print('checking print #{} collision against: '.format(val))
                    # print(sorted(unassigned_vals))
                    # print('static obstables: {}'.format(built_obstacles))

                    built_obstacles = built_obstacles + [
                        self.net.get_element_body(unass_val)
                        for unass_val in unassigned_vals
                    ]
                    val_cmap = update_collision_map_batch(
                        self.net,
                        self.ee_body,
                        print_along_e_id=val,
                        print_along_cmap=val_cmap,
                        printed_nodes=shared_node,
                        bodies=built_obstacles)

                    # print('after pruning, cmaps sum: {}'.format(sum(val_cmap)))
                    # print('-----')

                    if sum(val_cmap) < 5:  #== 0:
                        success = False
                        self.constr_check_time['exist_valid_ee_pose'][
                            success] += 1
                        return success

                collision_fn = get_collision_fn(
                    self.robot,
                    get_movable_joints(self.robot),
                    built_obstacles,
                    attachments=[],
                    self_collisions=SELF_COLLISIONS,
                    disabled_collisions=self.disabled_collisions,
                    custom_limits={})
                success = check_exist_valid_kinematics(self.net, val,
                                                       self.robot, val_cmap,
                                                       collision_fn)
                self.constr_check_time['exist_valid_ee_pose'][success] += 1
                return success