예제 #1
0
 def __init__(self,
              end_effector,
              element_bodies,
              node_points,
              ground_nodes,
              element,
              reverse,
              max_directions=INF):
     # TODO: more directions for ground collisions
     self.end_effector = end_effector
     self.element = element
     self.reverse = reverse
     self.max_directions = max_directions
     self.element_pose = get_pose(element_bodies[element])
     n1, n2 = element
     length = get_distance(node_points[n1], node_points[n2])
     self.translation_path = np.append(
         np.arange(-length / 2, length / 2, STEP_SIZE), [length / 2])
     if ORTHOGONAL_GROUND and is_ground(element, ground_nodes):
         # TODO: orthogonal to the ground
         self.direction_generator = cycle(
             [Pose(euler=Euler(roll=0, pitch=0))])
     else:
         self.direction_generator = get_direction_generator(
             self.end_effector, use_halton=False)
     self.trajectories = []
예제 #2
0
def draw_model(elements, node_points, ground_nodes, color=None):
    handles = []
    with LockRenderer():
        for element in elements:
            if color is None:
                element_color = BLUE if is_ground(element,
                                                  ground_nodes) else RED
            else:
                element_color = color
            handles.append(
                draw_element(node_points, element, color=element_color))
    return handles
예제 #3
0
 def add_successors(printed, position, conf):
     only_ground = printed <= ground_elements
     num_remaining = len(printed) - 1
     #assert 0 <= num_remaining
     for element in randomize(printed):
         if not (outgoing_from_element[element] & printed) and implies(
                 is_ground(element, ground_nodes), only_ground):
             for directed in get_directions(element):
                 visits = 0
                 bias = heuristic_fn(printed, directed, position, conf)
                 priority = (num_remaining, bias, random.random())
                 heapq.heappush(queue,
                                (visits, priority, printed, directed, conf))
예제 #4
0
def display_trajectories(node_points,
                         ground_nodes,
                         trajectories,
                         animate=True,
                         time_step=0.02,
                         video=False):
    if trajectories is None:
        return
    set_extrusion_camera(node_points)
    planned_elements = recover_sequence(trajectories)
    colors = sample_colors(len(planned_elements))
    # if not animate:
    #     draw_ordered(planned_elements, node_points)
    #     wait_for_user()
    #     disconnect()
    #     return

    video_saver = None
    if video:
        handles = draw_model(planned_elements, node_points,
                             ground_nodes)  # Allows user to adjust the camera
        wait_for_user()
        remove_all_debug()
        wait_for_duration(0.1)
        video_saver = VideoSaver('video.mp4')  # has_gui()
        time_step = 0.001
    else:
        wait_for_user()

    #element_bodies = dict(zip(planned_elements, create_elements(node_points, planned_elements)))
    #for body in element_bodies.values():
    #    set_color(body, (1, 0, 0, 0))
    connected_nodes = set(ground_nodes)
    printed_elements = []
    print('Trajectories:', len(trajectories))
    for i, trajectory in enumerate(trajectories):
        #wait_for_user()
        #set_color(element_bodies[element], (1, 0, 0, 1))
        last_point = None
        handles = []

        for _ in trajectory.iterate():
            # TODO: the robot body could be different
            if isinstance(trajectory, PrintTrajectory):
                current_point = point_from_pose(
                    trajectory.end_effector.get_tool_pose())
                if last_point is not None:
                    # color = BLUE if is_ground(trajectory.element, ground_nodes) else RED
                    color = colors[len(printed_elements)]
                    handles.append(
                        add_line(last_point,
                                 current_point,
                                 color=color,
                                 width=LINE_WIDTH))
                last_point = current_point
            if time_step is None:
                wait_for_user()
            else:
                wait_for_duration(time_step)

        if isinstance(trajectory, PrintTrajectory):
            if not trajectory.path:
                color = colors[len(printed_elements)]
                handles.append(
                    draw_element(node_points, trajectory.element, color=color))
                #wait_for_user()
            is_connected = (trajectory.n1 in connected_nodes
                            )  # and (trajectory.n2 in connected_nodes)
            print('{}) {:9} | Connected: {} | Ground: {} | Length: {}'.format(
                i, str(trajectory), is_connected,
                is_ground(trajectory.element, ground_nodes),
                len(trajectory.path)))
            if not is_connected:
                wait_for_user()
            connected_nodes.add(trajectory.n2)
            printed_elements.append(trajectory.element)

    if video_saver is not None:
        video_saver.restore()
    wait_for_user()
예제 #5
0
    def gen_fn(node1, element, extruded=[], trajectories=[]):  # fluents=[]):
        start_time = time.time()
        assert not is_reversed(element_bodies, element)
        idle_time = 0
        reverse = is_end(node1, element)
        if disable or (len(extruded) < SKIP_PERCENTAGE *
                       len(element_bodies)):  # For quick visualization
            path, tool_path = [], []
            traj = PrintTrajectory(end_effector, get_movable_joints(robot),
                                   path, tool_path, element, reverse)
            command = Command([traj])
            yield (command, )
            return
        directed = reverse_element(element) if reverse else element
        extrusion = extrusions[directed]

        n1, n2 = reverse_element(element) if reverse else element
        neighboring_elements = node_neighbors[n1] & node_neighbors[n2]

        supporters = []  # TODO: can also do according to levels
        retrace_supporters(element, incoming_supporters, supporters)
        element_obstacles = {
            element_bodies[e]
            for e in supporters + list(extruded)
        }
        obstacles = set(fixed_obstacles) | element_obstacles
        if not collisions:
            obstacles = set()
            #obstacles = set(fixed_obstacles)

        elements_order = [
            e for e in element_bodies if (e != element) and (
                e not in removed) and (element_bodies[e] not in obstacles)
        ]
        collision_fn = get_element_collision_fn(robot, obstacles)
        #print(len(fixed_obstacles), len(element_obstacles), len(elements_order))

        trajectories = list(trajectories)
        for num in irange(INF):
            for attempt, tool_traj in enumerate(
                    islice(extrusion.generator(), max_directions)):
                # TODO: is this slower now for some reason?
                #tool_traj.safe_from_body = {} # Disables caching
                if not tool_traj.is_safe(obstacles):
                    continue
                for _ in range(max_attempts):
                    if max_time <= elapsed_time(start_time):
                        return
                    nearby_conf = initial_conf if random.random(
                    ) < p_nearby else None
                    command = compute_direction_path(tool_traj,
                                                     collision_fn,
                                                     ee_only=ee_only,
                                                     initial_conf=nearby_conf,
                                                     **kwargs)
                    if command is None:
                        continue

                    command.update_safe(extruded)
                    if precompute_collisions:
                        bodies_order = [
                            element_bodies[e] for e in elements_order
                        ]
                        colliding = command_collision(end_effector, command,
                                                      bodies_order)
                        for element2, unsafe in zip(elements_order, colliding):
                            if unsafe:
                                command.set_unsafe(element2)
                            else:
                                command.set_safe(element2)
                    if not is_ground(element, ground_nodes) and (
                            neighboring_elements <= command.colliding):
                        continue  # If all neighbors collide

                    trajectories.append(command)
                    if precompute_collisions:
                        prune_dominated(trajectories)
                    if command not in trajectories:
                        continue
                    print(
                        '{}) {}->{} | EE: {} | Supporters: {} | Attempts: {} | Trajectories: {} | Colliding: {}'
                        .format(num, n1, n2, ee_only, len(supporters), attempt,
                                len(trajectories),
                                sorted(len(t.colliding)
                                       for t in trajectories)))
                    temp_time = time.time()
                    yield (command, )

                    idle_time += elapsed_time(temp_time)
                    if precompute_collisions:
                        if len(command.colliding) == 0:
                            #print('Reevaluated already non-colliding trajectory!')
                            return
                        elif len(command.colliding) == 1:
                            [colliding_element] = command.colliding
                            obstacles.add(element_bodies[colliding_element])
                    break
                else:
                    if allow_failures:
                        yield None
            else:
                print(
                    '{}) {}->{} | EE: {} | Supporters: {} | Attempts: {} | Max attempts exceeded!'
                    .format(num, n1, n2, ee_only, len(supporters),
                            max_directions))
                return