Exemple #1
0
def plan_water_motion(body,
                      joints,
                      end_conf,
                      attachment,
                      obstacles=None,
                      attachments=[],
                      self_collisions=True,
                      disabled_collisions=set(),
                      max_distance=MAX_DISTANCE,
                      weights=None,
                      resolutions=None,
                      reference_pose=unit_pose(),
                      custom_limits={},
                      **kwargs):
    assert len(joints) == len(end_conf)
    sample_fn = get_sample_fn(body, joints, custom_limits=custom_limits)
    distance_fn = get_distance_fn(body, joints, weights=weights)
    extend_fn = get_extend_fn(body, joints, resolutions=resolutions)
    collision_fn = get_collision_fn(body,
                                    joints,
                                    obstacles, {attachment} | set(attachments),
                                    self_collisions,
                                    disabled_collisions,
                                    max_distance=max_distance,
                                    custom_limits=custom_limits)

    def water_test(q):
        if attachment is None:
            return False
        set_joint_positions(body, joints, q)
        attachment.assign()
        attachment_pose = get_pose(attachment.child)
        pose = multiply(attachment_pose,
                        reference_pose)  # TODO: confirm not inverted
        roll, pitch, _ = euler_from_quat(quat_from_pose(pose))
        violation = (MAX_ROTATION < abs(roll)) or (MAX_ROTATION < abs(pitch))
        #if violation: # TODO: check whether different confs can be waypoints for each object
        #    print(q, violation)
        #    wait_for_user()
        return violation

    invalid_fn = lambda q, **kwargs: water_test(q) or collision_fn(q, **kwargs)
    start_conf = get_joint_positions(body, joints)
    if not check_initial_end(start_conf, end_conf, invalid_fn):
        return None
    return birrt(start_conf, end_conf, distance_fn, sample_fn, extend_fn,
                 invalid_fn, **kwargs)
Exemple #2
0
def plan_workspace(world,
                   tool_path,
                   obstacles,
                   randomize=True,
                   teleport=False):
    # Assuming that pairs of fixed things aren't in collision at this point
    moving_links = get_moving_links(world.robot, world.arm_joints)
    robot_obstacle = (world.robot, frozenset(moving_links))
    distance_fn = get_distance_fn(world.robot, world.arm_joints)
    if randomize:
        sample_fn = get_sample_fn(world.robot, world.arm_joints)
        set_joint_positions(world.robot, world.arm_joints, sample_fn())
    else:
        world.carry_conf.assign()
    arm_path = []
    for i, tool_pose in enumerate(tool_path):
        #set_joint_positions(world.kitchen, [door_joint], door_path[i])
        tolerance = INF if i == 0 else NEARBY_PULL
        full_arm_conf = world.solve_inverse_kinematics(
            tool_pose, nearby_tolerance=tolerance)
        if full_arm_conf is None:
            # TODO: this fails when teleport=True
            if PRINT_FAILURES: print('Workspace kinematic failure')
            return None
        if any(pairwise_collision(robot_obstacle, b) for b in obstacles):
            if PRINT_FAILURES: print('Workspace collision failure')
            return None
        arm_conf = get_joint_positions(world.robot, world.arm_joints)
        if arm_path and not teleport:
            distance = distance_fn(arm_path[-1], arm_conf)
            if MAX_CONF_DISTANCE < distance:
                if PRINT_FAILURES:
                    print(
                        'Workspace proximity failure (distance={:.5f})'.format(
                            distance))
                return None
        arm_path.append(arm_conf)
        # wait_for_user()
    return arm_path
Exemple #3
0
def compute_motion(robot, fixed_obstacles, element_bodies,
                   printed_elements, start_conf, end_conf,
                   collisions=True, max_time=INF, buffer=0.1, smooth=100):
    # TODO: can also just plan to initial conf and then shortcut
    joints = get_movable_joints(robot)
    assert len(joints) == len(end_conf)
    weights = JOINT_WEIGHTS
    resolutions = np.divide(RESOLUTION * np.ones(weights.shape), weights)
    disabled_collisions = get_disabled_collisions(robot)
    custom_limits = {}
    #element_from_body = {b: e for e, b in element_bodies.items()}

    hulls, obstacles = {}, []
    if collisions:
        element_obstacles = {element_bodies[e] for e in printed_elements}
        obstacles = set(fixed_obstacles) | element_obstacles
        #hulls, obstacles = decompose_structure(fixed_obstacles, element_bodies, printed_elements)
    #print(hulls)
    #print(obstacles)
    #wait_for_user()

    #printed_elements = set(element_bodies)
    bounding = None
    if printed_elements:
        # TODO: pass in node_points
        bounding = create_bounding_mesh(printed_elements, element_bodies=element_bodies, node_points=None,
                                        buffer=0.01) # buffer=buffer)
        #wait_for_user()

    sample_fn = get_sample_fn(robot, joints, custom_limits=custom_limits)
    distance_fn = get_distance_fn(robot, joints, weights=weights)
    extend_fn = get_extend_fn(robot, joints, resolutions=resolutions)
    #collision_fn = get_collision_fn(robot, joints, obstacles, attachments={}, self_collisions=SELF_COLLISIONS,
    #                                disabled_collisions=disabled_collisions, custom_limits=custom_limits, max_distance=0.)
    collision_fn = get_element_collision_fn(robot, obstacles)

    fine_extend_fn = get_extend_fn(robot, joints, resolutions=1e-1*resolutions) #, norm=INF)

    def test_bounding(q):
        set_joint_positions(robot, joints, q)
        collision = (bounding is not None) and pairwise_collision(robot, bounding, max_distance=buffer) # body_collision
        return q, collision

    def dynamic_extend_fn(q_start, q_end):
        # TODO: retime trajectories to be move more slowly around the structure
        for (q1, c1), (q2, c2) in get_pairs(map(test_bounding, extend_fn(q_start, q_end))):
            # print(c1, c2, len(list(fine_extend_fn(q1, q2))))
            # set_joint_positions(robot, joints, q2)
            # wait_for_user()
            if c1 and c2:
                for q in fine_extend_fn(q1, q2):
                    # set_joint_positions(robot, joints, q)
                    # wait_for_user()
                    yield q
            else:
                yield q2

    def element_collision_fn(q):
        if collision_fn(q):
            return True
        #for body in get_bodies_in_region(get_aabb(robot)): # Perform per link?
        #    if (element_from_body.get(body, None) in printed_elements) and pairwise_collision(robot, body):
        #        return True
        for hull, bodies in hulls.items():
            if pairwise_collision(robot, hull) and any(pairwise_collision(robot, body) for body in bodies):
                return True
        return False

    path = None
    if check_initial_end(start_conf, end_conf, collision_fn):
        path = birrt(start_conf, end_conf, distance_fn, sample_fn, dynamic_extend_fn, element_collision_fn,
                     restarts=50, iterations=100, smooth=smooth, max_time=max_time)
    # path = plan_joint_motion(robot, joints, end_conf, obstacles=obstacles,
    #                          self_collisions=SELF_COLLISIONS, disabled_collisions=disabled_collisions,
    #                          weights=weights, resolutions=resolutions,
    #                          restarts=50, iterations=100, smooth=100)

    # if (bounding is not None) and (path is not None):
    #     for i, q in enumerate(path):
    #         print('{}/{}'.format(i, len(path)))
    #         set_joint_positions(robot, joints, q)
    #         wait_for_user()

    if bounding is not None:
        remove_body(bounding)
    for hull in hulls:
        remove_body(hull)
    if path is None:
        print('Failed to find a motion plan!')
        return None
    return MotionTrajectory(robot, joints, path)
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-c', '--cfree', action='store_true',
                        help='When enabled, disables collision checking.')
    # parser.add_argument('-p', '--problem', default='test_pour', choices=sorted(problem_fn_from_name),
    #                     help='The name of the problem to solve.')
    parser.add_argument('--holonomic', action='store_true', # '-h',
                        help='')
    parser.add_argument('-l', '--lock', action='store_false',
                        help='')
    parser.add_argument('-s', '--seed', default=None, type=int,
                        help='The random seed to use.')
    parser.add_argument('-v', '--viewer', action='store_false',
                        help='')
    args = parser.parse_args()
    connect(use_gui=args.viewer)

    seed = args.seed
    #seed = 0
    #seed = time.time()
    set_random_seed(seed=seed) # None: 2147483648 = 2**31
    set_numpy_seed(seed=seed)
    print('Random seed:', get_random_seed(), random.random())
    print('Numpy seed:', get_numpy_seed(), np.random.random())

    #########################

    robot, base_limits, goal_conf, obstacles = problem1()
    draw_base_limits(base_limits)
    custom_limits = create_custom_base_limits(robot, base_limits)
    base_joints = joints_from_names(robot, BASE_JOINTS)
    base_link = link_from_name(robot, BASE_LINK_NAME)
    if args.cfree:
        obstacles = []
    # for obstacle in obstacles:
    #     draw_aabb(get_aabb(obstacle)) # Updates automatically
    resolutions = None
    #resolutions = np.array([0.05, 0.05, math.radians(10)])
    set_all_static() # Doesn't seem to affect

    region_aabb = AABB(lower=-np.ones(3), upper=+np.ones(3))
    draw_aabb(region_aabb)
    step_simulation() # Need to call before get_bodies_in_region
    #update_scene() # TODO: https://github.com/bulletphysics/bullet3/pull/3331
    bodies = get_bodies_in_region(region_aabb)
    print(len(bodies), bodies)
    # https://github.com/bulletphysics/bullet3/search?q=broadphase
    # https://github.com/bulletphysics/bullet3/search?p=1&q=getCachedOverlappingObjects&type=&utf8=%E2%9C%93
    # https://andysomogyi.github.io/mechanica/bullet.html
    # http://www.cs.kent.edu/~ruttan/GameEngines/lectures/Bullet_User_Manual

    #draw_pose(get_link_pose(robot, base_link), length=0.5)
    for conf in [get_joint_positions(robot, base_joints), goal_conf]:
        draw_pose(pose_from_pose2d(conf, z=DRAW_Z), length=DRAW_LENGTH)
    aabb = get_aabb(robot)
    #aabb = get_subtree_aabb(robot, base_link)
    draw_aabb(aabb)

    for link in [BASE_LINK, base_link]:
        print(link, get_collision_data(robot, link), pairwise_link_collision(robot, link, robot, link))

    #########################

    saver = WorldSaver()
    start_time = time.time()
    profiler = Profiler(field='tottime', num=50) # tottime | cumtime | None
    profiler.save()
    with LockRenderer(lock=args.lock):
        path = plan_motion(robot, base_joints, goal_conf, holonomic=args.holonomic, obstacles=obstacles,
                           custom_limits=custom_limits, resolutions=resolutions,
                           use_aabb=True, cache=True, max_distance=0.,
                           restarts=2, iterations=20, smooth=20) # 20 | None
        saver.restore()
    #wait_for_duration(duration=1e-3)
    profiler.restore()

    #########################

    solved = path is not None
    length = INF if path is None else len(path)
    cost = sum(get_distance_fn(robot, base_joints, weights=resolutions)(*pair) for pair in get_pairs(path))
    print('Solved: {} | Length: {} | Cost: {:.3f} | Runtime: {:.3f} sec'.format(
        solved, length, cost, elapsed_time(start_time)))
    if path is None:
        disconnect()
        return
    iterate_path(robot, base_joints, path)
    disconnect()
def compute_cost(robot, joints, path, resolutions=None):
    if path is None:
        return INF
    distance_fn = get_distance_fn(robot, joints,
                                  weights=resolutions)  # TODO: get_duration_fn
    return sum(distance_fn(*pair) for pair in get_pairs(path))
Exemple #6
0
def plan_approach(world,
                  approach_pose,
                  attachments=[],
                  obstacles=set(),
                  teleport=False,
                  switches_only=False,
                  approach_path=not MOVE_ARM,
                  **kwargs):
    # TODO: use velocities in the distance function
    distance_fn = get_distance_fn(world.robot, world.arm_joints)
    aq = world.carry_conf
    grasp_conf = get_joint_positions(world.robot, world.arm_joints)
    if switches_only:
        return [aq.values, grasp_conf]

    # TODO: could extract out collision function
    # TODO: track the full approach motion
    full_approach_conf = world.solve_inverse_kinematics(
        approach_pose, nearby_tolerance=NEARBY_APPROACH)
    if full_approach_conf is None:  # TODO: | {obj}
        if PRINT_FAILURES: print('Pregrasp kinematic failure')
        return None
    moving_links = get_moving_links(world.robot, world.arm_joints)
    robot_obstacle = (world.robot, frozenset(moving_links))
    #robot_obstacle = world.robot
    if any(pairwise_collision(robot_obstacle, b)
           for b in obstacles):  # TODO: | {obj}
        if PRINT_FAILURES: print('Pregrasp collision failure')
        return None
    approach_conf = get_joint_positions(world.robot, world.arm_joints)
    if teleport:
        return [aq.values, approach_conf, grasp_conf]
    distance = distance_fn(grasp_conf, approach_conf)
    if MAX_CONF_DISTANCE < distance:
        if PRINT_FAILURES:
            print('Pregrasp proximity failure (distance={:.5f})'.format(
                distance))
        return None

    resolutions = ARM_RESOLUTION * np.ones(len(world.arm_joints))
    grasp_path = plan_direct_joint_motion(
        world.robot,
        world.arm_joints,
        grasp_conf,
        attachments=attachments,
        obstacles=obstacles,
        self_collisions=SELF_COLLISIONS,
        disabled_collisions=world.disabled_collisions,
        custom_limits=world.custom_limits,
        resolutions=resolutions / 4.)
    if grasp_path is None:
        if PRINT_FAILURES: print('Pregrasp path failure')
        return None
    if not approach_path:
        return grasp_path
    # TODO: plan one with attachment placed and one held
    # TODO: can still use this as a witness that the conf is reachable
    aq.assign()
    approach_path = plan_joint_motion(
        world.robot,
        world.arm_joints,
        approach_conf,
        attachments=attachments,
        obstacles=obstacles,
        self_collisions=SELF_COLLISIONS,
        disabled_collisions=world.disabled_collisions,
        custom_limits=world.custom_limits,
        resolutions=resolutions,
        restarts=2,
        iterations=25,
        smooth=25)
    if approach_path is None:
        if PRINT_FAILURES: print('Approach path failure')
        return None
    return approach_path + grasp_path
Exemple #7
0
def get_cspace_distance(robot, q1, q2):
    #return get_distance(q1, q2)
    joints = get_movable_joints(robot)
    distance_fn = get_distance_fn(robot, joints, weights=JOINT_WEIGHTS)
    return distance_fn(q1, q2)