Esempio n. 1
0
    def execute(self):
        # Get the bottle pose from the camera.

        square = 0.1175
        curr = t.current_robot_pose('global_xyz_link', 'gripper_endpoint')
        for i in range(6):
            for j in range(7):
                m.move_to_global(curr.position.x + square * i,
                                 curr.position.y + square * j, curr.position.z,
                                 'gripper')
                rospy.sleep(4)
Esempio n. 2
0
    def execute(self):
        # Get the bottle pose from the camera.
        rospy.loginfo('Moveing to view')
        m.move_to_named_pose('whole_arm', 'view_checkerboard')

        rospy.sleep(4)

        poses = []
        qt = tf.transformations.quaternion_from_euler(0.0, 0.0,
                                                      -3.141592653 / 2)

        for i in range(16):
            rospy.loginfo('GET OBJECT POSE')
            b_req = cartesian_calibration.srv.GetACoorRequest()
            b_req.data_set = "measured"
            b_req.object_idx = i
            b_res = self.pose_service.call(b_req)
            p = b_res.object_pose.pose
            # p.orientation.x = qt[0]
            # p.orientation.y = qt[1]
            # p.orientation.z = qt[2]
            # p.orientation.w = qt[3]

            object_global = t.convert_pose(p, self.camera_reference_frame,
                                           'global_xyz_link')
            # object_global.position.z = min(0.80,p.position.z)
            poses.append(object_global)

        m.move_to_named_pose('realsense', 'tool_change_position')
        m.move_to_named_pose('wrist_only', 'sucker')

        for p in poses:

            if p.position.x == 0 and p.position.y == 0 and p.position.z == 0:
                rospy.logerr('Failed to find an object. %s' % i)
                # return 'failed'
                continue

            print("MOVE SUCKER TO ABOVE OBJECT")
            p = t.align_pose_orientation_to_frame(p, 'global_xyz_link',
                                                  'sucker_endpoint')

            t.publish_pose_as_transform(p, 'global_xyz_link', 'MOVE HERE', 0.5)
            res = m.move_to_global(p.position.x - 0.02,
                                   p.position.y + 0.01,
                                   p.position.z - 0.02,
                                   'sucker',
                                   orientation=p.orientation)

            rospy.sleep(4)
Esempio n. 3
0
    def execute(self, userdata):
        suction.pump_off()

        curr = t.current_robot_pose('global_xyz_link', 'realsense_endpoint')

        rospy.loginfo('MOVE UP TO SAFE POSITION')
        res = m.move_to_global(curr.position.x, curr.position.y, 0.505,
                               'realsense')
        if not res:
            rospy.logerr('Failed to move to safe position.')
            return 'failed'

        rospy.sleep(10.0)

        return 'succeeded'
Esempio n. 4
0
    def execute(self, userdata):
        rospy.loginfo('MOVE TO SAFE HEIGHT')
        curr = t.current_robot_pose('global_xyz_link', 'realsense_endpoint')
        res = m.move_to_global(curr.position.x,
                               min(curr.position.y, TOOL_CHANGE_SAFE_Y),
                               TOOL_CHANGE_REALSENSE_GLOBAL_Z, 'realsense')
        if not res:
            return 'failed'

        rospy.loginfo('TESTING THAT THE WRIST MOVES')
        res = m.move_to_named_pose('wrist_only', 'test_joints')
        if not res:
            rospy.logerr('Wrist Failed to Move')
            return 'failed'

        return 'succeeded'
Esempio n. 5
0
    def execute(self, userdata):
        gripper.open_gripper
        rospy.loginfo('TOOL CHANGE')

        rospy.loginfo('\tMove up to safe height')
        curr = t.current_robot_pose('global_xyz_link', 'realsense_endpoint')
        res = m.move_to_global(curr.position.x, curr.position.y, 0.505,
                               'realsense')
        if not res:
            rospy.logerr('Failed to move to safe position.')
            return 'failed'

        rospy.loginfo('\tMove to tool change position')
        res = m.move_to_named_pose('realsense', 'tool_change_position')
        if not res:
            rospy.logerr('Failed to move to tool_change_position')
            return 'failed'

        if self.tool == 'gripper':
            rospy.loginfo('\tSelect Gripper')
            tool_change_named_pose = 'tool_change_gripper'

        elif self.tool == 'sucker':
            rospy.loginfo('\tSelect Sucker')
            tool_change_named_pose = 'tool_change_sucker'

        elif self.tool == 'neutral':
            # Allow us to select neutral
            rospy.loginfo('\tSelect Neutral')
            tool_change_named_pose = 'tool_change_neutral'

        else:
            rospy.logerr('Incorrect tool name for tool change')
            return 'failed'

        res = m.move_to_named_pose('whole_arm', tool_change_named_pose)
        if not res:
            rospy.logerr('Failed to move to %s' % tool_change_named_pose)
            return 'failed'
        return 'succeeded'
Esempio n. 6
0
    def execute(self, userdata):
        suction.set_suck_level(0)
        suction.pump_off()
        gripper.open_gripper()
        rospy.sleep(0.5)

        userdata.data['move_objects_mode'] = False
        userdata.data['move_objects_between_bins_mode'] = None

        rospy.loginfo('MOVE TO TOOL CHANGE HEIGHT')
        curr = t.current_robot_pose('global_xyz_link', 'realsense_endpoint')

        # Don't hit the top bar.
        if curr.position.y >= TOOL_CHANGE_SAFE_Y:
            curr.position.y = TOOL_CHANGE_SAFE_Y

        # Don't hit the down bars.
        if curr.position.y >= TOOL_CHANGE_DANGEROUS_Y:
            # We might hit the front frame so move away from it.
            if curr.position.x >= TOOL_CHANGE_X_MAX:
                curr.position.x = TOOL_CHANGE_X_MAX
            if curr.position.x <= TOOL_CHANGE_X_MIN:
                curr.position.x = TOOL_CHANGE_X_MIN

        res = m.move_to_global(curr.position.x,
                               min(curr.position.y, TOOL_CHANGE_SAFE_Y),
                               TOOL_CHANGE_REALSENSE_GLOBAL_Z, 'realsense')
        if not res:
            return 'failed'

        rospy.loginfo('CHANGE TO NEUTRAL WRIST NEUTRAL')
        res = m.move_to_named_pose('wrist_only', 'neutral')
        if not res:
            return 'failed'

        return 'succeeded'
Esempio n. 7
0
    def execute(self, userdata):

        if userdata.data['task'] == 'stow':
            if userdata.data['empty_space_capture'].get('storage_A') is None:
                # We need to update storage_A
                res = m.move_to_named_pose('realsense',
                                           'realsense_above_storage_system_A')
                if not res:
                    return 'failed'

                pc, pose = self.get_point_cloud_and_position('storage_A')
                if pc is None and pose is None:
                    return 'failed'
                userdata.data['empty_space_capture']['storage_A'] = {
                    'point_cloud': pc,
                    'pose': pose
                }

            if userdata.data['empty_space_capture'].get('storage_B') is None:
                # We need to update storage_A
                res = m.move_to_named_pose('realsense',
                                           'realsense_above_storage_system_B')
                if not res:
                    return 'failed'

                pc, pose = self.get_point_cloud_and_position('storage_B')
                if pc is None and pose is None:
                    return 'failed'
                userdata.data['empty_space_capture']['storage_B'] = {
                    'point_cloud': pc,
                    'pose': pose
                }

        elif userdata.data['task'] == 'pick':
            for b in boxes:
                if userdata.data['empty_space_capture'].get(b) is None:
                    bd = boxes[b]
                    # Find centre of box in x direction
                    x_pos = (bd['right'] + bd['left']) / 2
                    x_pos = min(x_pos, REALSENSE_MAX_GLOBAL_X)
                    x_pos = max(x_pos, REALSENSE_MIN_GLOBAL_X)

                    y_pos = 0.819  # This stops us hitting the gripper on the frame.

                    res = m.move_to_global(x_pos, y_pos, 0.575, 'realsense')
                    if not res:
                        return 'failed'

                    rospy.set_param('/storage_specs/%s/h_high' % b, 180)
                    rospy.set_param('/storage_specs/%s/h_inside' % b, True)
                    rospy.set_param('/storage_specs/%s/h_low' % b, 0)
                    rospy.set_param('/storage_specs/%s/s_high' % b, 255)
                    rospy.set_param('/storage_specs/%s/s_low' % b, 0)
                    rospy.set_param('/storage_specs/%s/v_high' % b, 255)
                    rospy.set_param('/storage_specs/%s/v_low' % b, 0)

                    rospy.set_param('/storage_specs/%s/x_max' % b,
                                    (x_pos - bd['right']) + 0.02)
                    rospy.set_param('/storage_specs/%s/x_min' % b,
                                    (x_pos - bd['left']) - 0.02)
                    rospy.set_param('/storage_specs/%s/y_max' % b,
                                    (y_pos - bd['bottom']) + 0.02)
                    rospy.set_param('/storage_specs/%s/y_min' % b,
                                    (y_pos - bd['top']) - 0.04)
                    rospy.set_param('/storage_specs/%s/z_max' % b, 1000)
                    rospy.set_param('/storage_specs/%s/z_min' % b, 0.4)

                    pc, pose = self.get_point_cloud_and_position(b)
                    if pc is None and pose is None:
                        return 'failed'
                    userdata.data['empty_space_capture'][b] = {
                        'point_cloud': pc,
                        'pose': pose
                    }
                    self.pc_pub.publish(pc)

        return 'succeeded'
Esempio n. 8
0
    def execute(self, userdata):

        first_attamept = True
        label = userdata.data['item_to_pick']['label']
        suck_level = item_meta[label].get('suction_pressure', 3)
        set_suck_level(suck_level)

        USE_ANGLED = False

        position_limits = POSITION_LIMITS[
            userdata.data['picking_from']]['sucker']

        # Get the tote weight before the pick
        scales_topic = userdata.data['picking_from'] + '_scales/weight'
        if item_meta[userdata.data['item_to_pick']
                     ['label']]['grasp_type'] != 'grip_suck':
            # If we've just tried sucking, then don't re-weigh
            try:
                weight = rospy.wait_for_message(scales_topic, Int16, 2.0)
                userdata.data['weight_before'] = weight.data
            except:
                rospy.logerr('Unable to read weight from %s' % scales_topic)
                userdata.data['weight_before'] = -1
                if item_meta[userdata.data['item_to_pick']
                             ['label']]['grasp_point_type'] == 'rgb_centroid':
                    rospy.logerr(
                        "Aborting RGB Centroid pick because there aren't any scales."
                    )
                    return 'suck_failed'

        for object_global in userdata.data['item_to_pick']['grasp_poses']:

            USE_ANGLED = decide_angled(object_global, position_limits)

            object_global.position.x += 0.015
            object_global.position.y -= 0.03

            if USE_ANGLED:
                rospy.logerr('ANGLED PICK')

                # Make sure we're inside the tote.
                edge_offset = 0.0
                object_global.position.x = max(
                    object_global.position.x,
                    position_limits['x_min'] - edge_offset)
                object_global.position.x = min(
                    object_global.position.x,
                    position_limits['x_max'] + edge_offset)
                object_global.position.y = max(
                    object_global.position.y,
                    position_limits['y_min'] - edge_offset)
                object_global.position.y = min(
                    object_global.position.y,
                    position_limits['y_max'] + edge_offset)

                object_global.position.z -= 0.02  # The endpoint is half way through the suction cup, so move up slightly

                #t.publish_pose_as_transform(object_global, 'global_xyz_link', 'ORIGINAL', seconds=2)

                translation = [
                    object_global.position.x, object_global.position.y,
                    object_global.position.z
                ]
                qm = object_global.orientation
                q = (qm.x, qm.y, qm.z, qm.w)

                R = tft.quaternion_matrix(q)
                P = tft.projection_matrix([0, 0, 0], [0, 0, 1])  # XY plane
                pose_vec = R[:, 2]  # Z portion of matrix.
                proj_vec = np.dot(
                    P,
                    pose_vec)[:3]  # Projected onto XY plane as a unit vector.
                proj_vec_unit = tft.unit_vector(proj_vec)
                y_unit = [0, 1, 0]  # Unit vector in the y-direction.
                yaw_angle = np.arccos(np.dot(
                    proj_vec_unit, y_unit))  # Angle to the grasp around Z.
                pitch_angle = np.arcsin(
                    tft.vector_norm(proj_vec))  # Angle to tilt the suction cup
                if pitch_angle > 1.2:
                    pitch_angle = 1.2

                # Only get absolute angle from above.  Check the direction of the vector.
                if R[0, 2] > 0:
                    yaw_angle = -1 * yaw_angle

                # Create a quaternion with the right angles (note rotations are applied in the rotated frame in zyx order)
                q = tft.quaternion_from_euler(yaw_angle, 0, -1 * pitch_angle,
                                              'rzyx')

                if yaw_angle > 1.571 or yaw_angle < -1.571:
                    # Rotate by 180 to normalise to the sucker workspace.
                    q2 = tft.quaternion_from_euler(0, 0, 3.1415)
                    q = tft.quaternion_multiply(q, q2)

                e = list(tft.euler_from_quaternion(q))
                if e[2] > 1.5:  # Stop gimbal lock and weird joint configurations.
                    e[2] = 1.5
                if e[2] < -1.5:
                    e[2] = -1.5
                q = tft.quaternion_from_euler(e[0], e[1], e[2])

                object_global.orientation.x = q[0]
                object_global.orientation.y = q[1]
                object_global.orientation.z = q[2]
                object_global.orientation.w = q[3]

                R = tft.quaternion_matrix(q)

                t.publish_tf_quaterion_as_transform(translation,
                                                    q,
                                                    'global_xyz_link',
                                                    'MOVE_HERE',
                                                    seconds=0.5)

                # Create a pre-grasp pose away from the object.
                T = tft.translation_matrix(translation)
                T2 = tft.translation_matrix((0, 0, -0.05))
                F = tft.concatenate_matrices(T, R, T2)
                pre_grasp_t = tft.translation_from_matrix(F)
                pre_grasp_q = tft.quaternion_from_matrix(F)

                #t.publish_tf_quaterion_as_transform(pre_grasp_t, pre_grasp_q, 'global_xyz_link', 'PRE', seconds=5.0)

                grasp_orientation = Quaternion()
                grasp_orientation.x = q[0]
                grasp_orientation.y = q[1]
                grasp_orientation.z = q[2]
                grasp_orientation.w = q[3]

                rospy.loginfo('MOVE TO TOOL CHANGE HEIGHT')

                if first_attamept:
                    # Move the whole wrist and then select the sucker.
                    res = m.move_to_global(
                        min(object_global.position.x, REALSENSE_MAX_GLOBAL_X),
                        max(
                            min(object_global.position.y,
                                SUCKER_MAX_Y_STRAIGHT) - 0.02,
                            SUCKER_MIN_GLOBAL_Y + 0.02) -
                        SUCKER_REALSENSE_Y_OFFSET,
                        TOOL_CHANGE_REALSENSE_GLOBAL_Z, 'realsense')
                    if not res:
                        return 'failed'
                    rospy.loginfo('SELECTING SUCKER')
                    res = m.move_to_named_pose('wrist_only', 'sucker')
                    if not res:
                        return 'failed'
                    first_attamept = False
                else:
                    # Straighten up the sucker from the last attempt and move into position
                    straight_q = Quaternion()
                    straight_q.x = 0
                    straight_q.y = 0
                    straight_q.z = 0
                    straight_q.w = 1
                    res = m.move_to_global(
                        min(object_global.position.x, SUCKER_MAX_GLOBAL_X),
                        max(
                            min(object_global.position.y,
                                SUCKER_MAX_Y_STRAIGHT) - 0.02,
                            SUCKER_MIN_GLOBAL_Y + 0.02),
                        TOOL_CHANGE_REALSENSE_GLOBAL_Z + 0.35,
                        'sucker',
                        orientation=straight_q)
                    if not res:
                        return 'failed'

                rospy.loginfo("MOVE TO PRE-GRASP")
                res = m.move_to_global(pre_grasp_t[0],
                                       pre_grasp_t[1],
                                       min(pre_grasp_t[2],
                                           SUCKER_MAX_GLOBAL_Z),
                                       'sucker',
                                       orientation=grasp_orientation,
                                       velo_scale=0.4)
                if not res:
                    return 'failed'

                rospy.loginfo("PUMP ON, MOVING TO OBJECT")
                suction.pump_on()
                (res, stopped,
                 bail) = m.move_to_global_monitor_weight_and_suction(
                     object_global.position.x,
                     object_global.position.y,
                     min(object_global.position.z, SUCKER_MAX_GLOBAL_Z),
                     'sucker',
                     scales_topic,
                     orientation=grasp_orientation,
                     velo_scale=0.3)
                if not res:
                    return 'failed'

            else:
                # Straight Down Suck
                rospy.logerr('STRAIGHT PICK')

                # Make sure we're inside the tote.
                edge_offset = 0.0
                object_global.position.x = max(
                    object_global.position.x,
                    position_limits['x_min'] - edge_offset)
                object_global.position.x = min(
                    object_global.position.x,
                    position_limits['x_max'] + edge_offset)
                object_global.position.y = max(
                    object_global.position.y,
                    position_limits['y_min'] - edge_offset)
                object_global.position.y = min(
                    object_global.position.y,
                    position_limits['y_max'] + edge_offset)
                object_global.position.z = min(object_global.position.z,
                                               position_limits['z_max'])

                t.publish_pose_as_transform(object_global,
                                            'global_xyz_link',
                                            'MOVE_HERE',
                                            seconds=0.5)
                rospy.loginfo('MOVE TO TOOL CHANGE HEIGHT')

                # We only need to select the sucker on the first attempt.
                # Can cause it to break becasue the controllers don't switch properly
                #  if there's no actual movment and we change controllers too quickly. Not sure why, something to do with timing.
                if first_attamept:
                    res = m.move_to_global(
                        object_global.position.x,
                        max(
                            min(object_global.position.y,
                                SUCKER_MAX_Y_STRAIGHT),
                            SUCKER_MIN_Y_STRAIGHT) - SUCKER_REALSENSE_Y_OFFSET,
                        TOOL_CHANGE_REALSENSE_GLOBAL_Z, 'realsense')
                    if not res:
                        return 'failed'
                    rospy.loginfo('SELECTING SUCKER')
                    res = m.move_to_named_pose('wrist_only', 'sucker')
                    if not res:
                        return 'failed'
                    first_attamept = False
                    if item_meta[userdata.data['item_to_pick']
                                 ['label']]['grasp_type'] == 'grip_suck':
                        # Weird async movement bug.
                        rospy.sleep(1.0)
                else:
                    straight_q = Quaternion()
                    straight_q.x = 0
                    straight_q.y = 0
                    straight_q.z = 0
                    straight_q.w = 1
                    res = m.move_to_global(
                        object_global.position.x,
                        max(
                            min(object_global.position.y,
                                SUCKER_MAX_Y_STRAIGHT), SUCKER_MIN_Y_STRAIGHT),
                        TOOL_CHANGE_REALSENSE_GLOBAL_Z + 0.35,
                        'sucker',
                        orientation=straight_q)
                    if not res:
                        return 'failed'

                # Correct the rotation if required.
                pca_yaw = userdata.data['item_to_pick']['pca_yaw']
                q = (pca_yaw.x, pca_yaw.y, pca_yaw.z, pca_yaw.w)
                e = list(tft.euler_from_quaternion(q))
                if e[2] > 1.57:
                    e[2] -= 3.14
                if e[2] < -1.57:
                    e[2] += 3.14
                if e[2] > 1.5:  # Stop gimbal lock and weird joint configurations.
                    e[2] = 1.5
                if e[2] < -1.5:
                    e[2] = -1.5
                q = tft.quaternion_from_euler(0, 0, e[2])
                pca_yaw.x = q[0]
                pca_yaw.y = q[1]
                pca_yaw.z = q[2]
                pca_yaw.w = q[3]

                rospy.loginfo("PUMP ON, MOVING TO OBJECT")
                suction.pump_on()
                v_scale = 0.25
                if item_meta[userdata.data['item_to_pick']
                             ['label']]['grasp_point_type'] == 'rgb_centroid':
                    v_scale = 0.1
                (res, stopped,
                 bail) = m.move_to_global_monitor_weight_and_suction(
                     object_global.position.x,
                     min(object_global.position.y, SUCKER_MAX_Y_STRAIGHT),
                     min(object_global.position.z, SUCKER_MAX_GLOBAL_Z),
                     'sucker',
                     scales_topic,
                     orientation=pca_yaw,
                     velo_scale=v_scale)
                if not res:
                    return 'failed'

            if bail:
                m.move_relative(0, 0, -0.02, 'sucker_endpoint', 'sucker')
                rospy.sleep(0.5)
            elif not suction.check_pressure_sensor():
                # If it's not already on, give it a sec.
                rospy.sleep(1.0)

            suction_state = suction.check_pressure_sensor(
            )  #query pressure sensor for state, has the object been sucked correctly
            rospy.loginfo("PRESSURE SENSOR STATUS: %s" % suction_state)

            if not suction_state and not bail:
                set_suck_level(3)
                # Just move down a touch and double check
                move_amount = 0.02
                if USE_ANGLED:
                    move_amount = 0.035
                if object_global.position.z < (SUCKER_MAX_GLOBAL_Z):
                    move_amount = min(
                        move_amount,
                        SUCKER_MAX_GLOBAL_Z - object_global.position.z)
                    res = m.move_relative(0,
                                          0,
                                          move_amount,
                                          'sucker_endpoint',
                                          'sucker',
                                          plan_time=0.5)
                else:
                    res = True
                if res:
                    rospy.sleep(1.0)
                    suction_state = suction.check_pressure_sensor()

            if suction_state:
                #userdata.data['last_failed'] = None
                return 'succeeded'
            else:
                suction.pump_off()

        # Run out of grasp poses.
        suction.pump_off()
        if item_meta[userdata.data['item_to_pick']
                     ['label']]['grasp_type'] == 'suck_grip':
            return 'try_gripper'
        userdata.data['last_failed'][userdata.data['item_to_pick']
                                     ['label']] = 0
        return 'suck_failed'
    def execute(self, userdata):
        # wait for the specified duration or until we are asked to preempt
        curr = t.current_robot_pose('global_xyz_link', 'gripper_endpoint')
        rospy.loginfo('MOVE UP TO DROP POSITION')

        into_bin = 'B'  # Default
        weight_before = -1

        drop_orientation = Quaternion()  # Default straight
        drop_orientation.x = 0
        drop_orientation.y = 0
        drop_orientation.z = 0
        drop_orientation.w = 1

        x_pos = None
        y_pos = None
        z_pos = None

        if userdata.data['task'] == 'stow':
            #bins = ['storage_B', 'storage_A']
            bins = ['storage_B']  # Only B for finals.

        elif userdata.data['task'] == 'pick':
            if userdata.data['move_objects_between_bins_mode'] is not None:
                bins = [
                    'storage_' +
                    userdata.data['move_objects_between_bins_mode']
                ]
            else:
                l = userdata.data['item_to_pick']['label']
                box_id = None
                for o in userdata.data['order']:
                    if l in o['contents']:
                        box_id = o['size_id']
                bins = [box_id]
                if box_id is None:
                    rospy.logerr("NO BOX FOR ITEM")
                    return 'failed'

        else:
            return 'failed'

        for bin_id in bins:
            # Try and find free space based on the point cloud.
            # Try both bins.
            if bin_id not in userdata.data['empty_space_capture']:
                continue
            pc = userdata.data['empty_space_capture'][bin_id].get(
                'point_cloud', None)
            if pc is None:
                # Make sure we actually have one.
                continue

            req = ObjectPlacementPoseFromCloudRequest()
            req.cropped_cloud = userdata.data['empty_space_capture'][bin_id][
                'point_cloud']
            req.camera_to_world = userdata.data['empty_space_capture'][bin_id][
                'pose']
            l = userdata.data['item_to_pick']['label']

            dimensions = item_meta[l]['dimensions']
            dimensions.sort()
            req.object_longest_side_length.data = dimensions[2]
            req.object_middlest_side_length.data = dimensions[1]
            req.object_shortest_side_length.data = dimensions[0]
            req.resolution.data = 0.01

            res = self.free_space_service.call(req)

            if not res.success.data:
                continue

            x_pos = res.x.data
            y_pos = res.y.data
            z_pos = res.z.data - 0.13

            if res.degrees_to_global_y.data > 89:
                res.degrees_to_global_y.data = 89
            if res.degrees_to_global_y.data < -89:
                res.degrees_to_global_y.data = -89

            tq = tft.quaternion_from_euler(
                0, 0, res.degrees_to_global_y.data * 3.14 / 180.0)
            drop_orientation.x = tq[0]
            drop_orientation.y = tq[1]
            drop_orientation.z = tq[2]
            drop_orientation.w = tq[3]

            t.publish_tf_quaterion_as_transform(
                (x_pos, y_pos, z_pos), tq, 'global_xyz_link', 'DROP_HERE', 0.5)
            userdata.data['empty_space_capture'][bin_id] = None
            break

        if userdata.data['task'] == 'stow':
            into_bin = bin_id[-1]
            if x_pos is None:
                rospy.logerr('Couldn\'t find space to place.')
                x_pos = 0.350
                y_pos = 0.440
                z_pos = 0.900
                into_bin = 'B'
                bin_id = 'storage_B'
                userdata.data['empty_space_capture']['storage_B'] = None
            if item_meta[userdata.data['item_to_pick']['label']].get(
                    'ignore_weight') == True:
                rospy.logerr("Overriding drop point for floppy item")
                x_pos = 0.350
                y_pos = 0.210
                z_pos = 0.800
                into_bin = 'B'
                bin_id = 'storage_B'
                userdata.data['empty_space_capture']['storage_B'] = None

            position_limits = POSITION_LIMITS['storage_' + into_bin]['gripper']
            x_pos = max(x_pos, position_limits['x_min'])
            x_pos = min(x_pos, position_limits['x_max'])
            y_pos = max(y_pos, position_limits['y_min'])
            y_pos = min(y_pos, position_limits['y_max'])

            scales_topic = bin_id + '_scales/weight'
            try:
                weight = rospy.wait_for_message(scales_topic, Int16, 2.0)
                weight_before = weight.data
            except:
                rospy.logerr('Unable to read weight from %s' % scales_topic)
                weight_before = -1

        elif userdata.data['task'] == 'pick' and userdata.data[
                'move_objects_between_bins_mode'] is None:
            if x_pos is None:
                rospy.logerr('Couldn\'t find space to place.')
                box = userdata.data['boxes'][box_id]
                x_pos = (box['left'] + box['right']) / 2
                y_pos = (box['top'] + box['bottom']) / 2
                z_pos = 0.95
                yaw = 0
                userdata.data['empty_space_capture'][box_id] = None
            if item_meta[userdata.data['item_to_pick']['label']].get(
                    'ignore_weight') == True:
                rospy.logerr('Overriding drop point for floppy item')
                box = userdata.data['boxes'][box_id]
                x_pos = (box['left'] + box['right']) / 2
                y_pos = box['top'] - 0.02
                z_pos = 0.9
                yaw = 0
                userdata.data['empty_space_capture'][box_id] = None

            x_pos = max(x_pos, SUCKER_MIN_GLOBAL_X)
            x_pos = min(x_pos, SUCKER_MAX_GLOBAL_X)
            y_pos = min(y_pos, SUCKER_MAX_Y_STRAIGHT)

        elif userdata.data['task'] == 'pick' and userdata.data[
                'move_objects_between_bins_mode'] is not None:
            drop_pos = POSITION_LIMITS[
                'storage_' +
                userdata.data['move_objects_between_bins_mode']]['centre']
            x_pos = drop_pos[0]
            y_pos = drop_pos[1]
            z_pos = 0.9
            into_bin = userdata.data['move_objects_between_bins_mode']

        res = m.move_to_global(x_pos,
                               y_pos,
                               GRIPPER_LIFT_HEIGHT_STRAIGHT + 0.01,
                               'gripper',
                               orientation=drop_orientation)
        if not res:
            rospy.logerr('Failed to move to tote')
            return 'failed'

        curr = t.current_robot_pose('global_xyz_link', 'gripper_endpoint')
        pose = gmsg.Pose()
        pose.position.x = curr.position.x
        pose.position.y = curr.position.y
        pose.position.z = z_pos
        pose.orientation = drop_orientation

        if userdata.data['task'] == 'stow':
            # We can use the scales to check our movement.
            scales_topic = 'storage_%s_scales/weight' % into_bin
            (res, stopped, bail) = m.move_to_global_monitor_weight(
                pose.position.x,
                pose.position.y,
                pose.position.z,
                'gripper',
                scales_topic,
                orientation=pose.orientation,
                velo_scale=0.4)
            if not res:
                return 'failed'
            if bail:
                m.move_relative(0, 0, -0.02, 'gripper_endpoint', 'gripper')

        else:
            # No scales, perform a normal movement
            res = m.move_to_global(pose.position.x,
                                   pose.position.y,
                                   pose.position.z,
                                   'gripper',
                                   orientation=pose.orientation,
                                   velo_scale=0.4)
            if not res:
                rospy.logerr('Failed to perform a move')
                return 'failed'

        res = gripper.open_gripper()
        if not res:
            rospy.logerr('Failed to open gripper')
            return 'failed'

        rospy.sleep(1.0)

        userdata.data['last_drop_bin'] = into_bin

        if weight_before != -1 and userdata.data['task'] == 'stow':
            scales_topic = bin_id + '_scales/weight'
            try:
                weight = rospy.wait_for_message(scales_topic, Int16, 2.0)
                if (weight.data - weight_before) < 5:
                    rospy.logerr('No weight change, we must have dropped it.')
                    userdata.data['last_failed'][userdata.data['item_to_pick']
                                                 ['label']] = 0

                    # Undo an added weight reclassification if it happened.
                    if userdata.data['weight_reclassifications']:
                        if userdata.data['weight_reclassifications'][-1][
                                1] == userdata.data['item_to_pick']['label']:
                            userdata.data[
                                'weight_reclassifications'] = userdata.data[
                                    'weight_reclassifications'][:-1]

                    # Don't update the item locations.
                    return 'succeeded'
                rospy.logerr("SUCCESSFUL DROP")
            except:
                rospy.logerr('Unable to read weight from %s' % scales_topic)

        if userdata.data[
                'task'] == 'pick' and userdata.data['weight_before'] != -1:
            # Make sure the weight in the source storage system is still down.
            scales_topic = userdata.data['picking_from'] + '_scales/weight'
            try:
                weight = rospy.wait_for_message(scales_topic, Int16)
            except:
                rospy.logerr(
                    'Failed to get weight from %s, ignoring weight check')
            else:
                dw = userdata.data['weight_before'] - weight.data
                if dw < 4:
                    # The item must have fallen out before we got to the box.
                    # Don't update the item locations
                    rospy.logerr(
                        'The source storage system didn\'t change weight, we probably dropped the item'
                    )
                    return 'succeeded'

        # Update item locations.
        if userdata.data['task'] == 'stow':
            cur_label = userdata.data['item_to_pick']['label']
            try:
                userdata.data['item_locations']['tote']['contents'].remove(
                    cur_label)
            except ValueError:
                # The item wasn't meant to be in the tote, maybe we thought we already moved it.
                # Amend the list.
                for b in userdata.data['item_locations']['bins']:
                    if cur_label in b['contents']:
                        b['contents'].remove(cur_label)
            for b in userdata.data['item_locations']['bins']:
                if b['bin_id'] == into_bin:
                    b['contents'].append(cur_label)

        elif userdata.data['task'] == 'pick' and userdata.data[
                'move_objects_between_bins_mode'] is None:
            cur_label = userdata.data['item_to_pick']['label']
            for b in userdata.data['item_locations']['bins']:
                if cur_label in b['contents']:
                    b['contents'].remove(cur_label)
            for b in userdata.data['item_locations']['boxes']:
                if b['size_id'] == box_id:
                    b['contents'].append(cur_label)

        elif userdata.data['task'] == 'pick' and userdata.data[
                'move_objects_between_bins_mode'] is not None:
            cur_label = userdata.data['item_to_pick']['label']
            for b in userdata.data['item_locations']['bins']:
                if cur_label in b['contents']:
                    b['contents'].remove(cur_label)
                if b['bin_id'] == userdata.data[
                        'move_objects_between_bins_mode']:
                    b['contents'].append(cur_label)
            userdata.data['move_objects_between_bins_mode'] = None

        json_functions.save_file(userdata.data['task'],
                                 'item_location_file_out.json',
                                 userdata.data['item_locations'])

        return 'succeeded'
    def execute(self, userdata):
        # Only do it once.
        move_objects_mode = userdata.data['move_objects_mode']
        userdata.data['move_objects_mode'] = False

        rospy.loginfo('LIFTING OBJECT WITH SUCKER')
        curr = t.current_robot_pose('global_xyz_link', 'sucker_endpoint')
        # Update current pose with new orientation.

        curr.position.x = min(curr.position.x, SUCKER_MAX_GLOBAL_X - 0.01)
        curr.position.y = min(curr.position.y, SUCKER_MAX_Y_STRAIGHT)
        curr.position.y = max(curr.position.y, SUCKER_MIN_GLOBAL_Y + 0.01)
        suck_height = curr.position.z
        curr.position.z = SUCKER_LIFT_HEIGHT
        #t.publish_pose_as_transform(curr, 'global_xyz_link', 'MOVE HERE', 1.0)

        co = curr.orientation
        q = [co.x, co.y, co.z, co.w]
        e = tft.euler_from_quaternion(q)
        q = tft.quaternion_from_euler(0, 0, e[2])

        qm = gmsg.Quaternion()
        qm.x = 0
        qm.y = 0
        qm.z = 0
        qm.w = 1

        v_scale = 0.3
        if item_meta[userdata.data['item_to_pick']['label']]['weight'] > 0.5:
            # Heavy Item
            v_scale = 0.15

        res = m.move_to_global(curr.position.x, curr.position.y, curr.position.z, 'sucker', orientation=qm, velo_scale=v_scale)
        if not res:
            rospy.logerr('Failed to perform a move')
            return 'failed'

        if not suction.check_pressure_sensor():
            userdata.data['last_failed'][userdata.data['item_to_pick']['label']] = 0
            return 'suck_failed'

        scales_topic = userdata.data['picking_from'] + '_scales/weight'
        if move_objects_mode and userdata.data['move_objects_between_bins_mode'] is None:
            mid_x, mid_y = POSITION_LIMITS[userdata.data['picking_from']]['centre']
            if curr.position.x > mid_x:
                curr.position.x -= 0.15
            else:
                curr.position.x += 0.15
            if curr.position.y > mid_y:
                curr.position.y -= 0.2
            else:
                curr.position.y += 0.2
            res, _, _ = m.move_to_global_monitor_weight(curr.position.x, curr.position.y, suck_height - 0.13, 'sucker', scales_topic, velo_scale=0.2)
            return 'suck_failed'

        if userdata.data['weight_before'] < 0:
            rospy.logerr('No pre-pick weight, ignoring weight check')
            return 'succeeded'

        try:
            weight = rospy.wait_for_message(scales_topic, Int16)
        except:
            rospy.logerr('Failed to get weight from %s, ignoring weight check')
            return 'succeeded'

        userdata.data['weight_after'] = weight.data
        dw = userdata.data['weight_before'] - weight.data

        if item_meta[userdata.data['item_to_pick']['label']].get('weight')*1000.0 < 5:
            # We can't do a weight check.
            return 'succeeded'


        if userdata.data['weight_failures'].get(userdata.data['item_to_pick']['label'], 0) > 3 and (len(userdata.data['visible_objects']) < 6 or userdata.data.get('i_think_im_done')):
            # We've failed weight check on this item heaps of times and we're almost finished so just pick it.
            rospy.logerr('I am ignoring the weight check since it has failed too many times.')
            return 'succeeded'

        if dw < 4:
            # We haven't got anything, go back to the camera position and try again.
            rospy.logerr('No detected change in weight, failed grasp.')
            userdata.data['last_failed'][userdata.data['item_to_pick']['label']] = 0
            return 'suck_failed'

        if item_meta[userdata.data['item_to_pick']['label']].get('ignore_weight') == True:
            return 'succeeded'

        weight_correct, possible_matches = w.weight_matches(userdata.data['item_to_pick']['label'], dw, userdata.data['visible_objects'], 3)
        if not weight_correct:
            rospy.logerr(possible_matches)
            if userdata.data.get('i_think_im_done', False) == True:
                # Don't do weight reclassifications at the end.
                pass
            elif userdata.data['move_objects_between_bins_mode'] is not None:
                pass
            elif len(possible_matches) == 1 and possible_matches[0][0] < 5:
                # There's only one thing it could actually be!
                if userdata.data['task'] == 'stow' or (userdata.data['task'] == 'pick' and possible_matches[0][1] in userdata.data['wanted_items']):
                    rospy.logerr("I'M CHANGING THE OBJECT TO %s" % possible_matches[0][1])
                    userdata.data['weight_reclassifications'].append( (userdata.data['item_to_pick']['label'], possible_matches[0][1]) )
                    userdata.data['item_to_pick']['label'] = possible_matches[0][1]
                    suck_level = item_meta[possible_matches[0][1]].get('suction_pressure', 3)
                    suction.set_suck_level(suck_level)
                    return 'succeeded'

            elif len(possible_matches) > 1 and userdata.data['task'] == 'stow':
                userdata.data['double_check_objects'] = [i[1] for i in possible_matches]
                suck_pos = t.current_robot_pose('global_xyz_link', 'sucker_endpoint')
                suck_pos.position.z = suck_height
                userdata.data['original_pick_position'] = suck_pos
                return 'secondary_check'


            # Put the item back down and bail.
            userdata.data['last_failed'][userdata.data['item_to_pick']['label']] = 0
            if userdata.data['item_to_pick']['label'] not in userdata.data['weight_failures']:
                userdata.data['weight_failures'][userdata.data['item_to_pick']['label']] = 1
            else:
                userdata.data['weight_failures'][userdata.data['item_to_pick']['label']] += 1
            rospy.logerr("WEIGHT DOESN'T MATCH: MEASURED: %s, EXPECTED: %s" % (dw, item_meta[userdata.data['item_to_pick']['label']].get('weight')*1000.0))

            # Move towards the centre.
            mid_x, mid_y = POSITION_LIMITS[userdata.data['picking_from']]['centre']
            if curr.position.x > mid_x:
                curr.position.x -= 0.08
            else:
                curr.position.x += 0.08
            if curr.position.y > mid_y:
                curr.position.y -= 0.08
            else:
                curr.position.y += 0.08

            res, _, _ = m.move_to_global_monitor_weight(curr.position.x, curr.position.y, suck_height - 0.13, 'sucker', scales_topic, velo_scale=0.1)
            if not res:
                rospy.logerr('Failed to perform a move')
                return 'failed'

            return 'suck_failed'

        return 'succeeded'
Esempio n. 11
0
    def execute(self, userdata):
        gripper.open_gripper()

        position_limits = POSITION_LIMITS[userdata.data['picking_from']]['gripper']

        # Get the weight before the pick
        scales_topic = userdata.data['picking_from'] + '_scales/weight'
        if item_meta[userdata.data['item_to_pick']['label']]['grasp_type'] != 'suck_grip':
            # If we've just tried sucking, then don't re-weigh
            try:
                weight = rospy.wait_for_message(scales_topic, Int16, 2.0)
                userdata.data['weight_before'] = weight.data
            except:
                rospy.logerr('Unable to read weight from %s' % scales_topic)
                userdata.data['weight_before'] = -1
                if item_meta[userdata.data['item_to_pick']['label']]['grasp_point_type'] == 'rgb_centroid':
                    rospy.logerr("Aborting RGB Centroid pick because there aren't any scales.")
                    return 'grip_failed'

        # No way to detect failure yet, so just use one grasp point.
        object_global = userdata.data['item_to_pick']['grasp_poses'][0]

        object_global.position.x += 0.015
        object_global.position.y -= 0.03

        object_global.position.x = max(object_global.position.x, position_limits['x_min'])
        object_global.position.x = min(object_global.position.x, position_limits['x_max'])
        object_global.position.y = max(object_global.position.y, position_limits['y_min'])
        object_global.position.y = min(object_global.position.y, position_limits['y_max'])
        object_global.position.z = min(object_global.position.z, position_limits['z_max'])

        t.publish_pose_as_transform(object_global, 'global_xyz_link', 'MOVE HERE', 0.5)

        rospy.loginfo('MOVE TO TOOL CHANGE HEIGHT')
        curr = t.current_robot_pose('global_xyz_link', 'realsense_endpoint')
        # res = m.move_to_global(curr.position.x, curr.position.y, TOOL_CHANGE_REALSENSE_GLOBAL_Z, 'realsense')
        res = m.move_to_global(min(object_global.position.x, REALSENSE_MAX_GLOBAL_X), max(min(object_global.position.y, SUCKER_MAX_Y_STRAIGHT) - 0.02, SUCKER_MIN_GLOBAL_Y + 0.02) - SUCKER_REALSENSE_Y_OFFSET, TOOL_CHANGE_REALSENSE_GLOBAL_Z, 'realsense')
        if not res:
            return 'failed'

        rospy.loginfo('SELECTING GRIPPER')
        res = m.move_to_named_pose('wrist_only', 'gripper')
        if not res:
            return 'failed'

        object_global.position.z += 0.015
        pca_yaw = userdata.data['item_to_pick']['pca_yaw']
        q = (pca_yaw.x, pca_yaw.y, pca_yaw.z, pca_yaw.w)
        e = list(tft.euler_from_quaternion(q))
        if e[2] > 1.57:
            e[2] -= 3.14
        if e[2] < -1.57:
            e[2] += 3.14
        if e[2] > 1.55: # Stop gimbal lock and weird joint configurations.
            e[2] = 1.55
        if e[2] < -1.55:
            e[2] = -1.55

        q = tft.quaternion_from_euler(0, 0, e[2])
        object_global.orientation.x = q[0]
        object_global.orientation.y = q[1]
        object_global.orientation.z = q[2]
        object_global.orientation.w = q[3]

        rospy.loginfo('MOVE GRIPPER TO ABOVE OBJECT')
        res = m.move_to_global(object_global.position.x, object_global.position.y, max(object_global.position.z - 0.2, GRIPPER_MIN_GLOBAL_Z), 'gripper', orientation=object_global.orientation)
        if not res:
            return 'failed'

        rospy.loginfo('MOVING TO OBJECT')
        v_scale = 0.1
        if item_meta[userdata.data['item_to_pick']['label']]['grasp_point_type'] == 'rgb_centroid':
            # Don't trust the depth.
            v_scale = 0.1
        if userdata.data['item_to_pick']['label'] == 'mesh_cup':
            v_scale = 0.05
        (res, stopped, bail) = m.move_to_global_monitor_weight(object_global.position.x, object_global.position.y,
                               min(object_global.position.z, GRIPPER_MAX_GLOBAL_Z), 'gripper', scales_topic, velo_scale=v_scale, orientation=object_global.orientation)
        if not res:
            return 'failed'

        if bail:
            m.move_relative(0, 0, -0.02, 'gripper_endpoint', 'gripper')
        # rospy.sleep(0.5)

        rospy.loginfo('CLOSE THE GRIPPER')
        gripper.close_gripper()
        rospy.sleep(0.5)

        return('succeeded')
    if tool is 'gripper':

        #TOOL CHANGE TO 45 DEGREES

        rospy.init_node('my_ros_node')
        curr = t.current_robot_pose('global_xyz_link', 'gripper_endpoint')
        pose = gmsg.Pose()
        qt = tf.transformations.quaternion_from_euler(0.785398, 0.0, 1.57)
        pose.orientation.x = qt[0]
        pose.orientation.y = qt[1]
        pose.orientation.z = qt[2]
        pose.orientation.w = qt[3]
        rospy.loginfo('MOVE UP TO 45 DEGREES POSITION')
        res = m.move_to_global(curr.position.x,
                               curr.position.y,
                               0.6,
                               'gripper',
                               orientation=pose.orientation)
        if not res:
            rospy.logerr(move_error)
        rospy.loginfo(move_success + str(res))

        #MOVE TO DROP POSITION

        curr = t.current_robot_pose('global_xyz_link', 'gripper_endpoint')
        rospy.loginfo('MOVE UP TO DROP POSITION')
        res = m.move_to_global(0.3,
                               curr.position.y,
                               curr.position.z,
                               'gripper',
                               orientation=None)
Esempio n. 13
0
    def execute(self, userdata):
        # Only do it once.
        move_objects_mode = userdata.data['move_objects_mode']
        userdata.data['move_objects_mode'] = False

        # Lift the gripper up slowly so that it gets a good grip.
        curr = t.current_robot_pose('global_xyz_link', 'gripper_endpoint')
        res = m.move_to_global(curr.position.x,
                               curr.position.y,
                               max(curr.position.z - 0.05,
                                   GRIPPER_MIN_GLOBAL_Z),
                               'gripper',
                               velo_scale=0.02)

        curr = t.current_robot_pose('global_xyz_link', 'gripper_endpoint')
        # Update current pose with new orientation.
        grip_height = curr.position.z
        curr.position.z = GRIPPER_LIFT_HEIGHT_STRAIGHT
        #t.publish_pose_as_transform(curr, 'global_xyz_link', 'MOVE HERE', 1.0)
        res = m.move_to_global(curr.position.x,
                               curr.position.y,
                               curr.position.z,
                               'gripper',
                               orientation=curr.orientation,
                               velo_scale=0.5)
        if not res:
            rospy.logerr('Failed to perform a move (lift object gripper)')
            return 'failed'

        hold_gripper()

        scales_topic = userdata.data['picking_from'] + '_scales/weight'

        if move_objects_mode and userdata.data[
                'move_objects_between_bins_mode'] is None:
            mid_x, mid_y = POSITION_LIMITS[
                userdata.data['picking_from']]['centre']
            if curr.position.x > mid_x:
                curr.position.x -= 0.15
            else:
                curr.position.x += 0.15
            if curr.position.y > mid_y:
                curr.position.y -= 0.15
            else:
                curr.position.y += 0.15
            res, _, _ = m.move_to_global_monitor_weight(curr.position.x,
                                                        curr.position.y,
                                                        grip_height - 0.13,
                                                        'gripper',
                                                        scales_topic,
                                                        velo_scale=0.1)
            return 'grip_failed'

        if userdata.data['weight_before'] == -1:
            rospy.logerr('No pre-pick weight, ignoring weight check')
            return 'succeeded'

        try:
            weight = rospy.wait_for_message(scales_topic, Int16)
        except:
            rospy.logerr('Failed to get weight from %s, ignoring weight check')
            return 'succeeded'

        userdata.data['weight_after'] = weight.data
        dw = userdata.data['weight_before'] - weight.data

        if item_meta[userdata.data['item_to_pick']['label']].get(
                'weight') * 1000.0 < 5:
            # We can't do a weight check.
            return 'succeeded'

        if userdata.data['weight_failures'].get(
                userdata.data['item_to_pick']['label'],
                0) > 3 and (len(userdata.data['visible_objects']) < 6
                            or userdata.data.get('i_think_im_done')):
            # We've failed weight check on this item heaps of times and we're almost finished so just pick it.
            return 'succeeded'

        if dw < 4:
            # We haven't got anything, go back to the camera position and try again.
            rospy.logerr('No detected change in weight, failed grasp.')
            if item_meta[userdata.data['item_to_pick']
                         ['label']]['grasp_type'] == 'grip_suck':
                return 'try_sucker'
            userdata.data['last_failed'][userdata.data['item_to_pick']
                                         ['label']] = 0
            return 'grip_failed'

        if item_meta[userdata.data['item_to_pick']['label']].get(
                'ignore_weight') == True:
            return 'succeeded'

        weight_correct, possible_matches = w.weight_matches(
            userdata.data['item_to_pick']['label'], dw,
            userdata.data['visible_objects'], 3)
        if not weight_correct:
            rospy.logerr(possible_matches)
            if userdata.data.get('i_think_im_done', False) == True:
                # Don't do weight reclassifications at the end.
                pass
            elif userdata.data['move_objects_between_bins_mode'] is not None:
                pass
            elif len(possible_matches) == 1 and possible_matches[0][0] < 5:
                # There's only one thing it could actually be!
                if userdata.data['task'] == 'stow' or (
                        userdata.data['task'] == 'pick'
                        and possible_matches[0][1]
                        in userdata.data['wanted_items']):
                    rospy.logerr("I'M CHANGING THE OBJECT TO %s" %
                                 possible_matches[0][1])
                    userdata.data['weight_reclassifications'].append(
                        (userdata.data['item_to_pick']['label'],
                         possible_matches[0][1]))
                    userdata.data['item_to_pick']['label'] = possible_matches[
                        0][1]
                    return 'succeeded'

            # Put the item back down and bail.
            if userdata.data['item_to_pick']['label'] not in userdata.data[
                    'weight_failures']:
                userdata.data['weight_failures'][userdata.data['item_to_pick']
                                                 ['label']] = 1
            else:
                userdata.data['weight_failures'][userdata.data['item_to_pick']
                                                 ['label']] += 1
            userdata.data['last_failed'][userdata.data['item_to_pick']
                                         ['label']] = 0
            rospy.logerr("WEIGHT DOESN'T MATCH: MEASURED: %s, EXPECTED: %s" %
                         (dw, item_meta[userdata.data['item_to_pick']
                                        ['label']].get('weight') * 1000.0))

            # Move towards the centre.
            mid_x, mid_y = POSITION_LIMITS[
                userdata.data['picking_from']]['centre']
            if curr.position.x > mid_x:
                curr.position.x -= 0.08
            else:
                curr.position.x += 0.08
            if curr.position.y > mid_y:
                curr.position.y -= 0.08
            else:
                curr.position.y += 0.08

            res, _, _ = m.move_to_global_monitor_weight(curr.position.x,
                                                        curr.position.y,
                                                        grip_height - 0.13,
                                                        'gripper',
                                                        scales_topic,
                                                        velo_scale=0.1)
            if not res:
                rospy.logerr('Failed to perform a move')
                return 'failed'

            return 'grip_failed'

        return 'succeeded'
    def execute(self, userdata):

        rospy.loginfo('MOVE TO DOUBLE CHECK POSITION')
        res = m.move_to_global(0.579, 0.608, 0.630, 'sucker')
        if not res:
            return 'failed'

        try:
            img_msg = rospy.wait_for_message('/realsense/rgb_hd/image_raw',
                                             Image, 5.0)
        except rospy.ROSException:
            # Don't reset vision, this is a different camera.
            return 'classification_failed'

        img = self.cb.imgmsg_to_cv2(img_msg, 'rgb8')
        img = img[155:155 + 540, 340:340 + 960, :]  # Crop
        img = cv2.resize(img, (640, 360))

        img_msg = self.cb.cv2_to_imgmsg(img)

        visible_objects = userdata.data['double_check_objects']
        rospy.loginfo(visible_objects)
        visible_objects_ros = [String(s) for s in visible_objects]

        visible_objects_ros.append(String('tote'))
        class_res = self.refinenet_segmentation_service.call(
            visible_objects_ros, img_msg, img_msg, img_msg)

        self.overlay_pub.publish(class_res.overlay_img)

        labels = [l.data for l in class_res.label]
        segment_certainties = [i.data for i in class_res.segment_certainties]

        print(labels)
        print(segment_certainties)

        if len(labels):

            top_certainty, top_label = max(zip(segment_certainties, labels))

            try:
                if top_label != 'tote':
                    if top_certainty > 10:
                        if userdata.data['task'] == 'stow' or (
                                userdata.data['task'] == 'pick' and top_label
                                in userdata.data['wanted_items']):
                            rospy.logerr("I'M CHANGING THE OBJECT TO %s" %
                                         top_label)
                            userdata.data['item_to_pick']['label'] = top_label
                            suck_level = item_meta[top_label].get(
                                'suction_pressure', 3)
                            suction.set_suck_level(suck_level)
                            return 'succeeded'
            except:
                pass

        mid_x, mid_y = POSITION_LIMITS[userdata.data['picking_from']]['centre']
        orig = userdata.data['original_pick_position']
        if orig.position.x > mid_x:
            orig.position.x -= 0.08
        else:
            orig.position.x += 0.08
        if orig.position.y > mid_y:
            orig.position.y -= 0.08
        else:
            orig.position.y += 0.08

        orig.position.y = min(orig.position.y, SUCKER_MAX_Y_STRAIGHT)

        res = m.move_to_global(orig.position.x, orig.position.y,
                               SUCKER_LIFT_HEIGHT + 0.01, 'sucker')
        if not res:
            rospy.logerr('Failed to perform a move')
            return 'failed'

        scales_topic = userdata.data['picking_from'] + '_scales/weight'
        res, _, _ = m.move_to_global_monitor_weight(orig.position.x,
                                                    orig.position.y,
                                                    orig.position.z - 0.13,
                                                    'sucker',
                                                    scales_topic,
                                                    velo_scale=0.2)
        if not res:
            rospy.logerr('Failed to perform a move')
            return 'failed'

        return 'classification_failed'
Esempio n. 15
0
    def execute(self, userdata):

        into_bin = 'B'
        weight_before = -1

        drop_orientation = Quaternion()
        drop_orientation.x = 0
        drop_orientation.y = 0
        drop_orientation.z = 0
        drop_orientation.w = 1
        drop_velo_scale = 0.5

        x_pos = None
        y_pos = None
        z_pos = None

        if userdata.data['task'] == 'stow':
            #bins = ['storage_B', 'storage_A']
            bins = ['storage_B']  # Only B for finals.

        elif userdata.data['task'] == 'pick':
            if userdata.data['move_objects_between_bins_mode'] is not None:
                bins = ['storage_' + userdata.data['move_objects_between_bins_mode']]
            else:
                l = userdata.data['item_to_pick']['label']
                box_id = None
                for o in userdata.data['order']:
                    if l in o['contents']:
                        box_id = o['size_id']
                bins = [box_id]
                if box_id is None:
                    rospy.logerr("NO BOX FOR ITEM")
                    return 'failed'

        else:
            return 'failed'

        for bin_id in bins:
            if bin_id not in userdata.data['empty_space_capture']:
                continue
            pc = userdata.data['empty_space_capture'][bin_id].get('point_cloud', None)
            if pc is None:
                # Make sure we actually have one.
                continue

            req = ObjectPlacementPoseFromCloudRequest()
            req.cropped_cloud = userdata.data['empty_space_capture'][bin_id]['point_cloud']
            req.camera_to_world = userdata.data['empty_space_capture'][bin_id]['pose']
            l = userdata.data['item_to_pick']['label']

            dimensions = item_meta[l]['dimensions']
            dimensions.sort()
            req.object_longest_side_length.data = dimensions[2]
            req.object_middlest_side_length.data = dimensions[1]
            req.object_shortest_side_length.data = dimensions[0]

            req.resolution.data = 0.01

            if max(item_meta[l]['dimensions']) > 0.12:
                drop_velo_scale = 0.15

            res = self.free_space_service.call(req)

            if not res.success.data:
                continue

            x_pos = res.x.data
            y_pos = res.y.data
            z_pos = res.z.data - 0.13

            if res.degrees_to_global_y.data == 90 and (x_pos < 0.75 or y_pos < 0.75):
                res.degrees_to_global_y.data = -90  # Rotate away from the vacuum hose, unless we're in the to left coner.

            if res.degrees_to_global_y.data > 89: # Stops the robot doing weird gimbal lock things.
                res.degrees_to_global_y.data = 89
            if res.degrees_to_global_y.data < -89:
                res.degrees_to_global_y.data = -89

            tq = tft.quaternion_from_euler(0, 0, res.degrees_to_global_y.data * 3.14/180.0)
            drop_orientation.x = tq[0]
            drop_orientation.y = tq[1]
            drop_orientation.z = tq[2]
            drop_orientation.w = tq[3]

            t.publish_tf_quaterion_as_transform((x_pos, y_pos, z_pos), tq, 'global_xyz_link', 'DROP_HERE', 0.5)
            userdata.data['empty_space_capture'][bin_id] = None
            break

        if userdata.data['task'] == 'stow':
            into_bin = bin_id[-1]
            if x_pos is None:
                rospy.logerr('Couldn\'t find space to place.')
                x_pos = 0.350
                y_pos = 0.440
                z_pos = 0.900
                into_bin = 'B'
                bin_id = 'storage_B'
                userdata.data['empty_space_capture']['storage_B'] = None
            if item_meta[userdata.data['item_to_pick']['label']].get('ignore_weight') == True:
                rospy.logerr("Overriding drop point for floppy item")
                x_pos = 0.350
                y_pos = 0.210
                z_pos = 0.800
                into_bin = 'B'
                bin_id = 'storage_B'
                userdata.data['empty_space_capture']['storage_B'] = None

            position_limits = POSITION_LIMITS[bin_id]['sucker']
            x_pos = max(x_pos, position_limits['x_min'])
            x_pos = min(x_pos, position_limits['x_max'])
            y_pos = max(y_pos, position_limits['y_min'])
            y_pos = min(y_pos, position_limits['y_max'])

            scales_topic = bin_id + '_scales/weight'
            try:
                weight = rospy.wait_for_message(scales_topic, Int16, 2.0)
                weight_before = weight.data
            except:
                rospy.logerr('Unable to read weight from %s' % scales_topic)
                weight_before = -1

        elif userdata.data['task'] == 'pick' and userdata.data['move_objects_between_bins_mode'] is None:
            if x_pos is None:
                rospy.logerr('Couldn\'t find space to place.')
                box = userdata.data['boxes'][box_id]
                x_pos = (box['left'] + box['right'])/2
                y_pos = (box['top'] + box['bottom'])/2
                z_pos = 0.95
                yaw = 0
                userdata.data['empty_space_capture'][box_id] = None
            if item_meta[userdata.data['item_to_pick']['label']].get('ignore_weight') == True:
                rospy.logerr('Overriding drop point for floppy item')
                box = userdata.data['boxes'][box_id]
                x_pos = (box['left'] + box['right'])/2
                y_pos = box['top'] - 0.02
                z_pos = 0.9
                yaw = 0
                userdata.data['empty_space_capture'][box_id] = None

            x_pos = max(x_pos, SUCKER_MIN_GLOBAL_X)
            x_pos = min(x_pos, SUCKER_MAX_GLOBAL_X)
            y_pos = min(y_pos, SUCKER_MAX_Y_STRAIGHT)

        elif userdata.data['task'] == 'pick' and userdata.data['move_objects_between_bins_mode'] is not None:
            drop_pos = POSITION_LIMITS['storage_' + userdata.data['move_objects_between_bins_mode']]['centre']
            x_pos = drop_pos[0]
            y_pos = drop_pos[1]
            if userdata.data['move_objects_between_bins_mode'] == 'A':
                x_pos += 0.08
            elif userdata.data['move_objects_between_bins_mode'] == 'B':
                x_pos -= 0.08
            z_pos = 0.9
            into_bin = userdata.data['move_objects_between_bins_mode']

        move_velo_scale = 1.0
        if item_meta[userdata.data['item_to_pick']['label']]['weight'] > 0.5:
            # Heavy Item
            move_velo_scale = 0.5

        curr = t.current_robot_pose('global_xyz_link', 'sucker_endpoint')
        res = m.move_to_global(x_pos, y_pos, curr.position.z + 0.01, 'sucker', orientation=drop_orientation, velo_scale=move_velo_scale)
        if not res:
            rospy.logerr('Failed to move to drop point')
            return 'failed'

        # if suction.check_pressure_sensor() == False:
        #     rospy.logerr('No suction pressure, we probably dropped it')
        #     # Undo an added weight reclassification if it happened.
        #     if userdata.data['weight_reclassifications']:
        #         if userdata.data['weight_reclassifications'][-1][1] == userdata.data['item_to_pick']['label']:
        #             userdata.data['weight_reclassifications'] = userdata.data['weight_reclassifications'][:-1]
        #     return 'succeeded'

        if userdata.data['task'] == 'stow':
            # We can use the scales to check our movement
            scales_topic = 'storage_%s_scales/weight' % into_bin
            res, stopped, bail = m.move_to_global_monitor_weight(x_pos, y_pos, z_pos, 'sucker', scales_topic, velo_scale=drop_velo_scale)
            if not res:
                rospy.logerr('Failed to perform a move')
                #return 'failed'  # Don't fail, just continue because the item will probably end up in the storage system.
            if bail:
                m.move_relative(0, 0, -0.04, 'sucker_endpoint', 'sucker')

        else:
            # No scales for pick task, just normal move.
            res = m.move_to_global(x_pos, y_pos, z_pos, 'sucker', velo_scale=0.2)
            if not res:
                rospy.logerr('Failed to perform a move')
                return 'failed'

        set_suck_level(0)
        suction.pump_off()
        rospy.sleep(1.0)

        userdata.data['last_drop_bin'] = into_bin

        if weight_before != -1 and userdata.data['task'] == 'stow':
            scales_topic = bin_id + '_scales/weight'
            try:
                weight = rospy.wait_for_message(scales_topic, Int16, 2.0)
                if (weight.data - weight_before) < 5:
                    rospy.logerr('No weight change, we must have dropped it.')
                    # Don't update the item locations.
                    if userdata.data['weight_reclassifications']:
                        if userdata.data['weight_reclassifications'][-1][1] == userdata.data['item_to_pick']['label']:
                            userdata.data['weight_reclassifications'] = userdata.data['weight_reclassifications'][:-1]
                    return 'succeeded'
                rospy.logerr("SUCCESSFUL DROP")
            except:
                rospy.logerr('Unable to read weight from %s' % scales_topic)

        if userdata.data['task'] == 'pick' and userdata.data['weight_before'] != -1:
            # Make sure the weight in the source storage system is still down.
            scales_topic = userdata.data['picking_from'] + '_scales/weight'
            try:
                weight = rospy.wait_for_message(scales_topic, Int16)
            except:
                rospy.logerr('Failed to get weight from %s, ignoring weight check')
            else:
                dw = userdata.data['weight_before'] - weight.data
                if dw < 4:
                    # The item must have fallen out before we got to the box.
                    # Don't update the item locations
                    rospy.logerr('The source storage system didn\'t change weight, we probably dropped the item')
                    return 'succeeded'


        # Update item locations.
        if userdata.data['task'] == 'stow':
            cur_label = userdata.data['item_to_pick']['label']
            try:
                userdata.data['item_locations']['tote']['contents'].remove(cur_label)
            except ValueError:
                # The item wasn't meant to be in the tote, maybe we thought we already moved it.
                # Amend the list.
                for b in userdata.data['item_locations']['bins']:
                    if cur_label in b['contents']:
                        b['contents'].remove(cur_label)
            for b in userdata.data['item_locations']['bins']:
                if b['bin_id'] == into_bin:
                    b['contents'].append(cur_label)

        elif userdata.data['task'] == 'pick' and userdata.data['move_objects_between_bins_mode'] is None:
            cur_label = userdata.data['item_to_pick']['label']
            for b in userdata.data['item_locations']['bins']:
                if cur_label in b['contents']:
                    b['contents'].remove(cur_label)
            for b in userdata.data['item_locations']['boxes']:
                if b['size_id'] == box_id:
                    b['contents'].append(cur_label)

        elif userdata.data['task'] == 'pick' and userdata.data['move_objects_between_bins_mode'] is not None:
            cur_label = userdata.data['item_to_pick']['label']
            for b in userdata.data['item_locations']['bins']:
                if cur_label in b['contents']:
                    b['contents'].remove(cur_label)
                if b['bin_id'] == userdata.data['move_objects_between_bins_mode']:
                    b['contents'].append(cur_label)
            userdata.data['move_objects_between_bins_mode'] = None

        # Update the output file.
        json_functions.save_file(userdata.data['task'], 'item_location_file_out.json', userdata.data['item_locations'])

        return 'succeeded'