Exemple #1
0
def get_null_space(robot, joints, custom_limits={}):
    rest_positions = get_joint_positions(robot, joints)
    lower, upper = get_custom_limits(robot, joints, custom_limits)
    lower = np.maximum(lower, -10 * np.ones(len(joints)))
    upper = np.minimum(upper, +10 * np.ones(len(joints)))
    joint_ranges = 10 * np.ones(len(joints))
    return NullSpace(list(lower), list(upper), list(joint_ranges),
                     list(rest_positions))
Exemple #2
0
def get_sample_fn(body, joints, custom_limits={}, **kwargs):
    lower_limits, upper_limits = get_custom_limits(
        body, joints, custom_limits, circular_limits=CIRCULAR_LIMITS)
    generator = interval_generator(lower_limits, upper_limits, **kwargs)

    def fn():
        return tuple(next(generator))

    return fn
def get_sample_fn(body, joints, custom_limits={}, **kwargs):
    generator = unit_generator(len(joints), **kwargs)
    lower_limits, upper_limits = get_custom_limits(
        body, joints, custom_limits, circular_limits=CIRCULAR_LIMITS)
    limits_extents = np.array(upper_limits) - np.array(lower_limits)

    def fn():
        return tuple(next(generator) * limits_extents + np.array(lower_limits))

    return fn
def get_collision_fn(body,
                     joints,
                     obstacles,
                     attachments,
                     self_collisions,
                     disabled_collisions,
                     custom_limits={},
                     **kwargs):
    from pybullet_planning.interfaces.robots.collision import pairwise_collision, pairwise_link_collision
    from pybullet_planning.interfaces.robots.joint import set_joint_positions

    # TODO: convert most of these to keyword arguments
    check_link_pairs = get_self_link_pairs(body, joints, disabled_collisions) \
        if self_collisions else []
    moving_links = frozenset(get_moving_links(body, joints))
    attached_bodies = [attachment.child for attachment in attachments]
    moving_bodies = [(body, moving_links)] + attached_bodies
    #moving_bodies = [body] + [attachment.child for attachment in attachments]
    check_body_pairs = list(product(
        moving_bodies, obstacles))  # + list(combinations(moving_bodies, 2))
    lower_limits, upper_limits = get_custom_limits(body, joints, custom_limits)

    # TODO: maybe prune the link adjacent to the robot
    # TODO: test self collision with the holding
    def collision_fn(q):
        if not all_between(lower_limits, q, upper_limits):
            #print('Joint limits violated')
            return True
        set_joint_positions(body, joints, q)
        for attachment in attachments:
            attachment.assign()
        for link1, link2 in check_link_pairs:
            # Self-collisions should not have the max_distance parameter
            if pairwise_link_collision(body, link1, body,
                                       link2):  #, **kwargs):
                #print(get_body_name(body), get_link_name(body, link1), get_link_name(body, link2))
                return True
        for body1, body2 in check_body_pairs:
            if pairwise_collision(body1, body2, **kwargs):
                #print(get_body_name(body1), get_body_name(body2))
                return True
        return False

    return collision_fn
Exemple #5
0
def plan_cartesian_motion(robot,
                          first_joint,
                          target_link,
                          waypoint_poses,
                          max_iterations=200,
                          custom_limits={},
                          get_sub_conf=False,
                          **kwargs):
    """Compute a joint trajectory for a given sequence of workspace poses. Only joint limit is considered.
    Collision checking using `get_collision_fn` is often performed on the path computed by this function.

    Parameters
    ----------
    robot : int
        robot body index
    first_joint : int
        the first joint index in the kinematics chain.
    target_link : int
        end effector link index.
    waypoint_poses : a list of Pose
        a list of end effector workspace poses in the world coord.
    max_iterations : int, optional
        [description], by default 200
    custom_limits : dict, optional
        [description], by default {}
    get_sub_conf : bool, optional
        return sub-kinematics chain configuration if set to True, by default False

    Returns
    -------
    [type]
        [description]

    Example
    -------
    ```
    ik_joints = joints_from_names(robot_uid, ik_joint_names)
    ik_tool_link = link_from_name(robot_uid, tool_link_name)
    cart_conf_vals = plan_cartesian_motion(robot_uid, ik_joints[0], ik_tool_link, world_from_ee_poses)
    ```
    """
    from pybullet_planning.interfaces.env_manager.pose_transformation import all_between
    from pybullet_planning.interfaces.robots.link import get_link_subtree, prune_fixed_joints
    from pybullet_planning.interfaces.kinematics import inverse_kinematics_helper, is_pose_close

    # TODO: fix stationary joints
    # TODO: pass in set of movable joints and take least common ancestor
    # TODO: update with most recent bullet updates
    # https://github.com/bulletphysics/bullet3/blob/master/examples/pybullet/examples/inverse_kinematics.py
    # https://github.com/bulletphysics/bullet3/blob/master/examples/pybullet/examples/inverse_kinematics_husky_kuka.py
    # TODO: plan a path without needing to following intermediate waypoints

    lower_limits, upper_limits = get_custom_limits(robot,
                                                   get_movable_joints(robot),
                                                   custom_limits)
    selected_links = get_link_subtree(
        robot, first_joint)  # TODO: child_link_from_joint?
    selected_movable_joints = prune_fixed_joints(robot, selected_links)
    assert (target_link in selected_links)
    selected_target_link = selected_links.index(target_link)
    sub_robot = clone_body(robot,
                           links=selected_links,
                           visual=False,
                           collision=False)  # TODO: joint limits
    sub_movable_joints = get_movable_joints(sub_robot)
    #null_space = get_null_space(robot, selected_movable_joints, custom_limits=custom_limits)
    null_space = None

    solutions = []
    for target_pose in waypoint_poses:
        for iteration in range(max_iterations):
            sub_kinematic_conf = inverse_kinematics_helper(
                sub_robot,
                selected_target_link,
                target_pose,
                null_space=null_space)
            if sub_kinematic_conf is None:
                remove_body(sub_robot)
                return None
            set_joint_positions(sub_robot, sub_movable_joints,
                                sub_kinematic_conf)
            if is_pose_close(get_link_pose(sub_robot, selected_target_link),
                             target_pose, **kwargs):
                set_joint_positions(robot, selected_movable_joints,
                                    sub_kinematic_conf)
                kinematic_conf = get_configuration(robot)
                if not all_between(lower_limits, kinematic_conf, upper_limits):
                    #movable_joints = get_movable_joints(robot)
                    #print([(get_joint_name(robot, j), l, v, u) for j, l, v, u in
                    #       zip(movable_joints, lower_limits, kinematic_conf, upper_limits) if not (l <= v <= u)])
                    #print("Limits violated")
                    #wait_for_user()
                    remove_body(sub_robot)
                    return None
                #print("IK iterations:", iteration)
                if not get_sub_conf:
                    solutions.append(kinematic_conf)
                else:
                    solutions.append(sub_kinematic_conf)
                break
        else:
            remove_body(sub_robot)
            return None
    remove_body(sub_robot)
    return solutions
Exemple #6
0
def get_collision_fn(body,
                     joints,
                     obstacles=[],
                     attachments=[],
                     self_collisions=True,
                     disabled_collisions={},
                     extra_disabled_collisions={},
                     custom_limits={},
                     **kwargs):
    """get collision checking function collision_fn(joint_values) -> bool.

    * Note: This function might be one of the most heavily used function in this suite and
    is very important for planning applications. Backward compatibility (for Caelan's PDDLStream)
    is definitely on top priority.

    Parameters
    ----------
    body : int
        the main moving body (usually the robot). We refer to this body as 'the main body'
        in this function's docstring.
    joints : list of int
        moving joint indices for body
    obstacles : list of int
        body indices for collision objects, by default []
    attachments : list of Attachment, optional
        list of attachment, by default []
    self_collisions : bool, optional
        checking self collisions between links of the body or not, by default True
    disabled_collisions : set of tuples, optional
        list of tuples of two integers, representing the **main body's** link indices pair that is
        ignored in collision checking, by default {}
    extra_disabled_collisions : set of tuples, optional
        list of tuples for specifying disabled collisions, the tuple must be of the following format:
            ((int, int), (int, int)) : (body index, link index), (body index, link index)
        If the body considered is a single-link (floating) body, assign the link index to BASE_LINK.
        reversing the order of the tuples above is also acceptable, by default {}
    custom_limits: dict, optional
        customized joint range, example: {joint index (int) : (-np.pi/2, np.pi/2)}, by default {}

    Returns
    -------
    function handle
        collision_fn: (conf, diagnosis) -> False if no collision found, True otherwise.
        if need diagnosis information for the collision, set diagnosis to True will help you visualize
        which link is colliding to which.
    """
    from pybullet_planning.interfaces.env_manager.pose_transformation import all_between
    from pybullet_planning.interfaces.robots.joint import set_joint_positions, get_custom_limits
    from pybullet_planning.interfaces.robots.link import get_self_link_pairs, get_moving_links
    from pybullet_planning.interfaces.debug_utils.debug_utils import draw_collision_diagnosis
    moving_links = frozenset(get_moving_links(body, joints))
    attached_bodies = [attachment.child for attachment in attachments]
    moving_bodies = [(body, moving_links)] + attached_bodies
    # * main body self-collision link pairs
    self_check_link_pairs = get_self_link_pairs(
        body, joints, disabled_collisions) if self_collisions else []
    # * main body link - attachment body pairs
    attach_check_pairs = []
    for attached in attachments:
        if attached.parent != body:
            continue
        # prune the main body link adjacent to the attachment and the ones in ignored collisions
        # TODO: prune the link that's adjacent to the attach link as well?
        # ? i.e. object attached to ee_tool_link, and ee geometry is attached to ee_base_link
        at_check_links = [
            ml for ml in moving_links if ml != attached.parent_link and (
                (body, ml), (attached.child,
                             BASE_LINK)) not in extra_disabled_collisions and (
                                 (attached.child, BASE_LINK),
                                 (body, ml)) not in extra_disabled_collisions
        ]
        attach_check_pairs.append((at_check_links, attached.child))
    # * body pairs
    check_body_pairs = list(product(
        moving_bodies, obstacles))  # + list(combinations(moving_bodies, 2))
    check_body_link_pairs = []
    for body1, body2 in check_body_pairs:
        body1, links1 = expand_links(body1)
        body2, links2 = expand_links(body2)
        if body1 == body2:
            continue
        bb_link_pairs = product(links1, links2)
        for bb_links in bb_link_pairs:
            bbll_pair = ((body1, bb_links[0]), (body2, bb_links[1]))
            if bbll_pair not in extra_disabled_collisions and bbll_pair[::
                                                                        -1] not in extra_disabled_collisions:
                check_body_link_pairs.append(bbll_pair)
    # print('check pairs: ', check_body_link_pairs)
    # print('extra disabled: ', extra_disabled_collisions)
    # * joint limits
    lower_limits, upper_limits = get_custom_limits(body, joints, custom_limits)

    # TODO: maybe prune the link adjacent to the robot
    def collision_fn(q, diagnosis=False):
        # * joint limit check
        if not all_between(lower_limits, q, upper_limits):
            if diagnosis:
                warnings.warn('joint limit violation!', UserWarning)
                cr = np.less_equal(q, lower_limits), np.less_equal(
                    upper_limits, q)
                print('joint limit violation : {} / {}'.format(cr[0], cr[1]))
                for i, (cr_l, cr_u) in enumerate(zip(cr[0], cr[1])):
                    if cr_l:
                        print('J{}: {} < lower limit {}'.format(
                            i, q[i], lower_limits[i]))
                    if cr_u:
                        print('J{}: {} > upper limit {}'.format(
                            i, q[i], upper_limits[i]))
            return True
        # * set body & attachment positions
        set_joint_positions(body, joints, q)
        for attachment in attachments:
            attachment.assign()
        # * self-collision link check
        for link1, link2 in self_check_link_pairs:
            if pairwise_link_collision(body, link1, body, link2):
                if diagnosis:
                    warnings.warn(
                        'moving body link - moving body link collision!',
                        UserWarning)
                    cr = pairwise_link_collision_info(body, link1, body, link2)
                    draw_collision_diagnosis(cr)
                return True
        # * self link - attachment check
        for body_check_links, attached_body in attach_check_pairs:
            if any_link_pair_collision(body, body_check_links, attached_body,
                                       **kwargs):
                if diagnosis:
                    warnings.warn('moving body link - attachement collision!',
                                  UserWarning)
                    cr = any_link_pair_collision_info(body, body_check_links,
                                                      attached_body, **kwargs)
                    draw_collision_diagnosis(cr)
                return True
        # * body - body check
        for (body1, link1), (body2, link2) in check_body_link_pairs:
            if pairwise_link_collision(body1, link1, body2, link2, **kwargs):
                if diagnosis:
                    warnings.warn('moving body - body collision!', UserWarning)
                    cr = pairwise_link_collision_info(body1, link1, body2,
                                                      link2)
                    draw_collision_diagnosis(cr)
                return True
        return False

    return collision_fn
Exemple #7
0
def plan_cartesian_motion(robot,
                          first_joint,
                          target_link,
                          waypoint_poses,
                          max_iterations=200,
                          custom_limits={},
                          **kwargs):
    from pybullet_planning.interfaces.env_manager.pose_transformation import all_between
    from pybullet_planning.interfaces.robots.link import get_link_subtree, prune_fixed_joints
    from pybullet_planning.interfaces.kinematics import inverse_kinematics_helper, is_pose_close

    # TODO: fix stationary joints
    # TODO: pass in set of movable joints and take least common ancestor
    # TODO: update with most recent bullet updates
    # https://github.com/bulletphysics/bullet3/blob/master/examples/pybullet/examples/inverse_kinematics.py
    # https://github.com/bulletphysics/bullet3/blob/master/examples/pybullet/examples/inverse_kinematics_husky_kuka.py
    # TODO: plan a path without needing to following intermediate waypoints

    lower_limits, upper_limits = get_custom_limits(robot,
                                                   get_movable_joints(robot),
                                                   custom_limits)
    selected_links = get_link_subtree(
        robot, first_joint)  # TODO: child_link_from_joint?
    selected_movable_joints = prune_fixed_joints(robot, selected_links)
    assert (target_link in selected_links)
    selected_target_link = selected_links.index(target_link)
    sub_robot = clone_body(robot,
                           links=selected_links,
                           visual=False,
                           collision=False)  # TODO: joint limits
    sub_movable_joints = get_movable_joints(sub_robot)
    #null_space = get_null_space(robot, selected_movable_joints, custom_limits=custom_limits)
    null_space = None

    solutions = []
    for target_pose in waypoint_poses:
        for iteration in range(max_iterations):
            sub_kinematic_conf = inverse_kinematics_helper(
                sub_robot,
                selected_target_link,
                target_pose,
                null_space=null_space)
            if sub_kinematic_conf is None:
                remove_body(sub_robot)
                return None
            set_joint_positions(sub_robot, sub_movable_joints,
                                sub_kinematic_conf)
            if is_pose_close(get_link_pose(sub_robot, selected_target_link),
                             target_pose, **kwargs):
                set_joint_positions(robot, selected_movable_joints,
                                    sub_kinematic_conf)
                kinematic_conf = get_configuration(robot)
                if not all_between(lower_limits, kinematic_conf, upper_limits):
                    #movable_joints = get_movable_joints(robot)
                    #print([(get_joint_name(robot, j), l, v, u) for j, l, v, u in
                    #       zip(movable_joints, lower_limits, kinematic_conf, upper_limits) if not (l <= v <= u)])
                    #print("Limits violated")
                    #wait_for_user()
                    remove_body(sub_robot)
                    return None
                #print("IK iterations:", iteration)
                solutions.append(kinematic_conf)
                break
        else:
            remove_body(sub_robot)
            return None
    remove_body(sub_robot)
    return solutions