示例#1
0
 def _initialize_ik(self, urdf_path):
     if not USE_TRACK_IK:
         self.ik_solver = None
         return
     from trac_ik_python.trac_ik import IK  # killall -9 rosmaster
     base_link = get_link_name(
         self.robot, parent_link_from_joint(self.robot, self.arm_joints[0]))
     tip_link = get_link_name(self.robot,
                              child_link_from_joint(self.arm_joints[-1]))
     # limit effort and velocities are required
     # solve_type: Speed, Distance, Manipulation1, Manipulation2
     # TODO: fast solver and slow solver
     self.ik_solver = IK(base_link=str(base_link),
                         tip_link=str(tip_link),
                         timeout=0.01,
                         epsilon=1e-5,
                         solve_type="Speed",
                         urdf_string=read(urdf_path))
     if not CONSERVITIVE_LIMITS:
         return
     lower, upper = self.ik_solver.get_joint_limits()
     buffer = JOINT_LIMITS_BUFFER * np.ones(len(self.ik_solver.joint_names))
     lower, upper = lower + buffer, upper - buffer
     lower[6] = -MAX_FRANKA_JOINT7
     upper[6] = +MAX_FRANKA_JOINT7
     self.ik_solver.set_joint_limits(lower, upper)
示例#2
0
def get_handle_grasps(world, joint, pull=True, pre_distance=APPROACH_DISTANCE):
    pre_direction = pre_distance * get_unit_vector([0, 0, 1])
    #half_extent = 1.0*FINGER_EXTENT[2] # Collides
    half_extent = 1.05 * FINGER_EXTENT[2]

    grasps = []
    for link in get_link_subtree(world.kitchen, joint):
        if 'handle' in get_link_name(world.kitchen, link):
            # TODO: can adjust the position and orientation on the handle
            for yaw in [0, np.pi]:  # yaw=0 DOESN'T WORK WITH LULA
                handle_grasp = (Point(z=-half_extent),
                                quat_from_euler(
                                    Euler(roll=np.pi, pitch=np.pi / 2,
                                          yaw=yaw)))
                #if not pull:
                #    handle_pose = get_link_pose(world.kitchen, link)
                #    for distance in np.arange(0., 0.05, step=0.001):
                #        pregrasp = multiply(([0, 0, -distance], unit_quat()), handle_grasp)
                #        tool_pose = multiply(handle_pose, invert(pregrasp))
                #        set_tool_pose(world, tool_pose)
                #        # TODO: check collisions
                #        wait_for_user()
                handle_pregrasp = multiply((pre_direction, unit_quat()),
                                           handle_grasp)
                grasps.append(HandleGrasp(link, handle_grasp, handle_pregrasp))
    return grasps
示例#3
0
def test_clone_arm(pr2):
    first_joint_name = PR2_GROUPS['left_arm'][0]
    first_joint = joint_from_name(pr2, first_joint_name)
    parent_joint = get_link_parent(pr2, first_joint)
    print(get_link_name(pr2, parent_joint), parent_joint, first_joint_name,
          first_joint)
    print(get_link_descendants(pr2,
                               first_joint))  # TODO: least common ancestor
    links = [first_joint] + get_link_descendants(pr2, first_joint)
    new_arm = clone_body(pr2, links=links, collision=False)
    dump_world()
    set_base_values(pr2, (-2, 0, 0))
    wait_for_interrupt()
示例#4
0
 def test(at, o, wp):
     if not collisions:
         return True
     # TODO: check door collisions
     # TODO: still need to check static links at least once
     if isinstance(wp, SurfaceDist):
         return True  # TODO: perform this probabilistically
     wp.assign()
     state = at.context.copy()
     state.assign()
     all_bodies = {
         body
         for command in at.commands for body in command.bodies
     }
     for command in at.commands:
         obstacles = get_link_obstacles(world, o) - all_bodies
         # TODO: why did I previously remove o at p?
         #obstacles = get_link_obstacles(world, o) - command.bodies  # - p.bodies # Doesn't include o at p
         if not obstacles:
             continue
         if isinstance(command, DoorTrajectory):
             [door_joint] = command.door_joints
             surface_name = get_link_name(world.kitchen,
                                          child_link_from_joint(door_joint))
             if wp.support == surface_name:
                 return True
         for _ in command.iterate(state):
             state.derive()
             #for attachment in state.attachments.values():
             #    if any(pairwise_collision(attachment.child, obst) for obst in obstacles):
             #        return False
             # TODO: just check collisions with moving links
             if any(
                     pairwise_collision(world.robot, obst)
                     for obst in obstacles):
                 #print(at, o, p)
                 #wait_for_user()
                 return False
     return True
示例#5
0
def collect_place(world, object_name, surface_name, grasp_type, args):
    date = get_date()
    #set_seed(args.seed)

    #dump_body(world.robot)
    surface_pose = get_surface_reference_pose(world.kitchen, surface_name) # TODO: assumes the drawer is open
    stable_gen_fn = get_stable_gen(world, z_offset=Z_EPSILON, visibility=False,
                                   learned=False, collisions=not args.cfree)
    grasp_gen_fn = get_grasp_gen(world)
    ik_ir_gen = get_pick_gen_fn(world, learned=False, collisions=not args.cfree, teleport=args.teleport)

    stable_gen = stable_gen_fn(object_name, surface_name)
    grasps = list(grasp_gen_fn(object_name, grasp_type))

    robot_name = get_body_name(world.robot)
    path = get_place_path(robot_name, surface_name, grasp_type)
    print(SEPARATOR)
    print('Robot name: {} | Object name: {} | Surface name: {} | Grasp type: {} | Filename: {}'.format(
        robot_name, object_name, surface_name, grasp_type, path))

    entries = []
    start_time = time.time()
    failures = 0
    while (len(entries) < args.num_samples) and \
            (elapsed_time(start_time) < args.max_time): #and (failures <= max_failures):
        (rel_pose,) = next(stable_gen)
        if rel_pose is None:
            break
        (grasp,) = random.choice(grasps)
        with LockRenderer(lock=True):
            result = next(ik_ir_gen(object_name, rel_pose, grasp), None)
        if result is None:
            print('Failure! | {} / {} [{:.3f}]'.format(
                len(entries), args.num_samples, elapsed_time(start_time)))
            failures += 1
            continue
        # TODO: ensure an arm motion exists
        bq, aq, at = result
        rel_pose.assign()
        bq.assign()
        aq.assign()
        base_pose = get_link_pose(world.robot, world.base_link)
        object_pose = rel_pose.get_world_from_body()
        tool_pose = multiply(object_pose, invert(grasp.grasp_pose))
        entries.append({
            'tool_from_base': multiply(invert(tool_pose), base_pose),
            'surface_from_object': multiply(invert(surface_pose), object_pose),
            'base_from_object': multiply(invert(base_pose), object_pose),
        })
        print('Success! | {} / {} [{:.3f}]'.format(
            len(entries), args.num_samples, elapsed_time(start_time)))
        if has_gui():
            wait_for_user()
    #visualize_database(tool_from_base_list)
    if not entries:
        safe_remove(path)
        return None

    # Assuming the kitchen is fixed but the objects might be open world
    data = {
        'date': date,
        'robot_name': robot_name, # get_name | get_body_name | get_base_name | world.robot_name
        'base_link': get_link_name(world.robot, world.base_link),
        'tool_link': get_link_name(world.robot, world.tool_link),
        'kitchen_name': get_body_name(world.kitchen),
        'surface_name': surface_name,
        'object_name': object_name,
        'grasp_type': grasp_type,
        'entries': entries,
        'failures': failures,
        'successes': len(entries),
    }

    write_json(path, data)
    print('Saved', path)
    return data
示例#6
0
def pdddlstream_from_problem(belief,
                             additional_init=[],
                             fixed_base=True,
                             **kwargs):
    world = belief.world  # One world per state
    task = world.task  # One task per world
    print(task)
    domain_pddl = read(get_file_path(__file__, '../pddl/domain.pddl'))
    # TODO: repackage stream outputs to avoid recomputation

    # Despite the base not moving, it could be re-estimated
    init_bq = belief.base_conf
    init_aq = belief.arm_conf
    init_gq = belief.gripper_conf

    carry_aq = world.carry_conf
    init_aq = carry_aq if are_confs_close(init_aq, carry_aq) else init_aq

    # TODO: the following doesn't work. Maybe because carry_conf is used elsewhere
    #carry_aq = init_aq if are_confs_close(init_aq, world.carry_conf) else world.carry_conf
    #calibrate_aq = init_aq if are_confs_close(init_aq, world.calibrate_conf) else world.calibrate_conf

    # Don't need this now that returning to old confs
    #open_gq = init_gq if are_confs_close(init_gq, world.open_gq) else world.open_gq
    #closed_gq = init_gq if are_confs_close(init_gq, world.closed_gq) else world.closed_gq
    open_gq = world.open_gq
    closed_gq = world.closed_gq

    constant_map = {
        '@world': 'world',
        '@gripper': 'gripper',
        '@stove': 'stove',
        '@none': None,
        '@rest_aq': carry_aq,
        #'@calibrate_aq': calibrate_aq,
        '@open_gq': open_gq,
        '@closed_gq': closed_gq,
        '@open': OPEN,
        '@closed': CLOSED,
        '@top': TOP_GRASP,
        '@side': SIDE_GRASP,
        '@bq0': init_bq,
    }
    top_joint = JOINT_TEMPLATE.format(TOP_DRAWER)
    bottom_joint = JOINT_TEMPLATE.format(BOTTOM_DRAWER)

    init = [
        ('BConf', init_bq),
        ('AtBConf', init_bq),
        ('AConf', init_bq, carry_aq),
        #('RestAConf', carry_aq),
        #('AConf', init_bq, calibrate_aq),
        (
            'Stationary', ),
        ('AConf', init_bq, init_aq),
        ('AtAConf', init_aq),
        ('GConf', open_gq),
        ('GConf', closed_gq),
        ('Grasp', None, None),
        ('AtGrasp', None, None),
        ('Above', top_joint, bottom_joint),
        ('Adjacent', top_joint, bottom_joint),
        ('Adjacent', bottom_joint, top_joint),
        ('Calibrated', ),
        ('CanMoveBase', ),
        ('CanMoveArm', ),
        ('CanMoveGripper', ),
    ] + list(task.init) + list(additional_init)
    for action_name, cost in ACTION_COSTS.items():
        function_name = '{}Cost'.format(title_from_snake(action_name))
        function = (function_name, )
        init.append(Equal(function, cost))  # TODO: stove state
    init += [('Stackable', name, surface) for name, surface in task.goal_on.items()] + \
            [('Stackable', name, stove) for name, stove in product(task.goal_cooked, STOVES)] + \
            [('Pressed', name) for name in belief.pressed] + \
            [('Cookable', name) for name in task.goal_cooked] + \
            [('Cooked', name) for name in belief.cooked] + \
            [('Status', status) for status in DOOR_STATUSES] + \
            [('Knob', knob) for knob in KNOBS] + \
            [('Joint', knob) for knob in KNOBS] + \
            [('Liquid', liquid) for _, liquid in task.init_liquid] + \
            [('HasLiquid', cup, liquid) for cup, liquid in belief.liquid] + \
            [('StoveKnob', STOVE_TEMPLATE.format(loc), KNOB_TEMPLATE.format(loc)) for loc in STOVE_LOCATIONS] + \
            [('GraspType', ty) for ty in task.grasp_types]  # TODO: grasp_type per object
    #[('Type', obj_name, 'stove') for obj_name in STOVES] + \
    #[('Camera', name) for name in world.cameras]
    if task.movable_base:
        init.append(('MovableBase', ))
    if fixed_base:
        init.append(('InitBConf', init_bq))
    if task.noisy_base:
        init.append(('NoisyBase', ))

    compute_pose_kin = get_compute_pose_kin(world)
    compute_angle_kin = get_compute_angle_kin(world)

    initial_poses = {}
    for joint_name, init_conf in belief.door_confs.items():
        if joint_name in DRAWER_JOINTS:
            init.append(('Drawer', joint_name))
        if joint_name in CABINET_JOINTS:
            init.append(('Cabinet', joint_name))
        joint = joint_from_name(world.kitchen, joint_name)
        surface_name = surface_from_joint(joint_name)
        init.append(('SurfaceJoint', surface_name, joint_name))
        # Relies on the fact that drawers have identical surface and link names
        link_name = get_link_name(world.kitchen, child_link_from_joint(joint))
        #link_name = str(link_name.decode('UTF-8'))
        #link_name = str(link_name.encode('ascii','ignore'))
        for conf in {
                init_conf, world.open_kitchen_confs[joint],
                world.closed_kitchen_confs[joint]
        }:
            # TODO: return to initial poses?
            world_pose, = compute_angle_kin(link_name, joint_name, conf)
            init.extend([
                ('Joint', joint_name),
                ('Angle', joint_name, conf),
                ('Obstacle', link_name),
                ('AngleKin', link_name, world_pose, joint_name, conf),
                ('WorldPose', link_name, world_pose),
            ])
            if joint in world.kitchen_joints:
                init.extend([
                    ('Sample', world_pose),
                    #('Value', world_pose), # comment out?
                ])
            if conf == init_conf:
                initial_poses[link_name] = world_pose
                init.extend([
                    ('AtAngle', joint_name, conf),
                    ('AtWorldPose', link_name, world_pose),
                ])

    for surface_name in ALL_SURFACES:
        if surface_name in OPEN_SURFACES:
            init.append(('Counter', surface_name))  # Fixed surface
        if surface_name in DRAWERS:
            init.append(('Drawer', surface_name))
        surface = surface_from_name(surface_name)
        surface_link = link_from_name(world.kitchen, surface.link)
        parent_joint = parent_joint_from_link(surface_link)
        if parent_joint not in world.kitchen_joints:
            # TODO: attach to world frame?
            world_pose = RelPose(world.kitchen, surface_link, init=True)
            initial_poses[surface_name] = world_pose
            init += [
                #('RelPose', surface_name, world_pose, 'world'),
                ('WorldPose', surface_name, world_pose),
                #('AtRelPose', surface_name, world_pose, 'world'),
                ('AtWorldPose', surface_name, world_pose),
                ('Sample', world_pose),
                #('Value', world_pose),
            ]
        init.extend([
            ('CheckNearby', surface_name),
            #('InitPose', world_pose),
            ('Localized', surface_name),
        ])
        for grasp_type in task.grasp_types:
            if (surface_name in OPEN_SURFACES) or has_place_database(
                    world.robot_name, surface_name, grasp_type):
                init.append(('AdmitsGraspType', surface_name, grasp_type))

    if belief.grasped is None:
        init.extend([
            ('HandEmpty', ),
            ('GConf', init_gq),
            ('AtGConf', init_gq),
        ])
    else:
        obj_name = belief.grasped.body_name
        assert obj_name not in belief.pose_dists
        grasp = belief.grasped
        init += [
            # Static
            #('Graspable', obj_name),
            ('Grasp', obj_name, grasp),
            ('IsGraspType', obj_name, grasp, grasp.grasp_type),
            # Fluent
            ('AtGrasp', obj_name, grasp),
            ('Holding', obj_name),
            ('Localized', obj_name),
        ]
        init.extend(('ValidGraspType', obj_name, grasp_type)
                    for grasp_type in task.grasp_types
                    if implies(world.is_real(),
                               is_valid_grasp_type(obj_name, grasp_type)))

    for obj_name in world.movable:
        obj_type = type_from_name(obj_name)
        if obj_type in BOWLS:
            init.append(('Bowl', obj_name))
        else:
            init.append(
                ('Obstacle', obj_name))  # TODO: hack to place within bowls
        if obj_type in COOKABLE:
            init.append(('Cookable', obj_name))
        if obj_type in POURABLE:
            init.append(('Pourable', obj_name))
        init += [
            ('Entity', obj_name),
            ('CheckNearby', obj_name),
        ] + [('Stackable', obj_name, counter)
             for counter in set(ALL_SURFACES) & set(COUNTERS)]

    # TODO: track poses over time to produce estimates
    for obj_name, pose_dist in belief.pose_dists.items():
        dist_support = pose_dist.dist.support()
        localized = pose_dist.is_localized()
        graspable = True
        if localized:
            init.append(('Localized', obj_name))
            [rel_pose] = dist_support
            roll, pitch, yaw = euler_from_quat(
                quat_from_pose(rel_pose.get_reference_from_body()))
            if (MAX_ERROR < abs(roll)) or (MAX_ERROR < abs(pitch)):
                graspable = False
                print(
                    '{} has an invalid orientation: roll={:.3f}, pitch={:.3f}'.
                    format(obj_name, roll, pitch))
        if graspable:
            #init.append(('Graspable', obj_name))
            init.extend(('ValidGraspType', obj_name, grasp_type)
                        for grasp_type in task.grasp_types
                        if implies(world.is_real(),
                                   is_valid_grasp_type(obj_name, grasp_type)))

        # Could also fully decompose into points (but many samples)
        # Could immediately add likely points for collision checking
        for rel_pose in (dist_support if localized else pose_dist.decompose()):
            surface_name = rel_pose.support
            if surface_name is None:
                # Treats as obstacle
                # TODO: could temporarily add to fixed
                world_pose = rel_pose
                init += [
                    ('WorldPose', obj_name, world_pose),
                    ('AtWorldPose', obj_name, world_pose),
                ]
                poses = [world_pose]
                #raise RuntimeError(obj_name, supporting)
            else:
                surface_pose = initial_poses[surface_name]
                world_pose, = compute_pose_kin(obj_name, rel_pose,
                                               surface_name, surface_pose)
                init += [
                    # Static
                    ('RelPose', obj_name, rel_pose, surface_name),
                    ('WorldPose', obj_name, world_pose),
                    ('PoseKin', obj_name, world_pose, rel_pose, surface_name,
                     surface_pose),
                    # Fluent
                    ('AtRelPose', obj_name, rel_pose, surface_name),
                    ('AtWorldPose', obj_name, world_pose),
                ]
                if localized:
                    init.append(('On', obj_name, surface_name))
                poses = [rel_pose, world_pose]
            for pose in poses:
                if isinstance(pose, PoseDist):
                    init.append(('Dist', pose))
                else:
                    init.extend([('Sample', pose)])  #, ('Value', pose)])

    #for body, ty in problem.body_types:
    #    init += [('Type', body, ty)]
    #bodies_from_type = get_bodies_from_type(problem)
    #bodies = bodies_from_type[get_parameter_name(ty)] if is_parameter(ty) else [ty]

    goal_formula = get_goal(belief, init)
    stream_pddl, stream_map = get_streams(world,
                                          teleport_base=task.teleport_base,
                                          **kwargs)

    print('Constants:', constant_map)
    print('Init:', sorted(init, key=lambda f: f[0]))
    print('Goal:', goal_formula)
    #print('Streams:', stream_map.keys()) # DEBUG

    return PDDLProblem(domain_pddl, constant_map, stream_pddl, stream_map,
                       init, goal_formula)
示例#7
0
def collect_pull(world, joint_name, args):
    date = get_date()
    #set_seed(args.seed)

    robot_name = get_body_name(world.robot)
    if is_press(joint_name):
        press_gen = get_press_gen_fn(world,
                                     collisions=not args.cfree,
                                     teleport=args.teleport,
                                     learned=False)
    else:
        joint = joint_from_name(world.kitchen, joint_name)
        open_conf = Conf(world.kitchen, [joint], [world.open_conf(joint)])
        closed_conf = Conf(world.kitchen, [joint], [world.closed_conf(joint)])
        pull_gen = get_pull_gen_fn(world,
                                   collisions=not args.cfree,
                                   teleport=args.teleport,
                                   learned=False)
        #handle_link, handle_grasp, _ = get_handle_grasp(world, joint)

    path = get_pull_path(robot_name, joint_name)
    print(SEPARATOR)
    print('Robot name {} | Joint name: {} | Filename: {}'.format(
        robot_name, joint_name, path))

    entries = []
    failures = 0
    start_time = time.time()
    while (len(entries) < args.num_samples) and \
            (elapsed_time(start_time) < args.max_time):
        if is_press(joint_name):
            result = next(press_gen(joint_name), None)
        else:
            result = next(pull_gen(joint_name, open_conf, closed_conf),
                          None)  # Open to closed
        if result is None:
            print('Failure! | {} / {} [{:.3f}]'.format(
                len(entries), args.num_samples, elapsed_time(start_time)))
            failures += 1
            continue
        if not is_press(joint_name):
            open_conf.assign()
        joint_pose = get_joint_reference_pose(world.kitchen, joint_name)
        bq, aq1 = result[:2]
        bq.assign()
        aq1.assign()
        #next(at.commands[2].iterate(None, None))
        base_pose = get_link_pose(world.robot, world.base_link)
        #handle_pose = get_link_pose(world.robot, base_link)
        entries.append({
            'joint_from_base':
            multiply(invert(joint_pose), base_pose),
        })
        print('Success! | {} / {} [{:.3f}]'.format(len(entries),
                                                   args.num_samples,
                                                   elapsed_time(start_time)))
        if has_gui():
            wait_for_user()
    if not entries:
        safe_remove(path)
        return None
    #visualize_database(joint_from_base_list)

    # Assuming the kitchen is fixed but the objects might be open world
    # TODO: could store per data point
    data = {
        'date': date,
        'robot_name':
        robot_name,  # get_name | get_body_name | get_base_name | world.robot_name
        'base_link': get_link_name(world.robot, world.base_link),
        'tool_link': get_link_name(world.robot, world.tool_link),
        'kitchen_name': get_body_name(world.kitchen),
        'joint_name': joint_name,
        'entries': entries,
        'failures': failures,
        'successes': len(entries),
    }
    if not is_press(joint_name):
        data.update({
            'open_conf': open_conf.values,
            'closed_conf': closed_conf.values,
        })

    write_json(path, data)
    print('Saved', path)
    return data