Spaces:
Build error
Build error
| """Motion primitives.""" | |
| import numpy as np | |
| from cliport.utils import utils | |
| class PickPlace(): | |
| """Pick and place primitive.""" | |
| def __init__(self, height=0.32, speed=0.01): | |
| self.height, self.speed = height, speed | |
| def __call__(self, movej, movep, ee, pose0, pose1): | |
| """Execute pick and place primitive. | |
| Args: | |
| movej: function to move robot joints. | |
| movep: function to move robot end effector pose. | |
| ee: robot end effector. | |
| pose0: SE(3) picking pose. | |
| pose1: SE(3) placing pose. | |
| Returns: | |
| timeout: robot movement timed out if True. | |
| """ | |
| pick_pose, place_pose = pose0, pose1 | |
| # Execute picking primitive. | |
| prepick_to_pick = ((0, 0, 0.32), (0, 0, 0, 1)) | |
| postpick_to_pick = ((0, 0, self.height), (0, 0, 0, 1)) | |
| prepick_pose = utils.multiply(pick_pose, prepick_to_pick) | |
| postpick_pose = utils.multiply(pick_pose, postpick_to_pick) | |
| timeout = movep(prepick_pose) | |
| # Move towards pick pose until contact is detected. | |
| delta = (np.float32([0, 0, -0.001]), | |
| utils.eulerXYZ_to_quatXYZW((0, 0, 0))) | |
| targ_pose = prepick_pose | |
| while not ee.detect_contact(): # and target_pose[2] > 0: | |
| targ_pose = utils.multiply(targ_pose, delta) | |
| timeout |= movep(targ_pose) | |
| if timeout: | |
| return True | |
| # Activate end effector, move up, and check picking success. | |
| ee.activate() | |
| timeout |= movep(postpick_pose, self.speed) | |
| pick_success = ee.check_grasp() | |
| # Execute placing primitive if pick is successful. | |
| if pick_success: | |
| preplace_to_place = ((0, 0, self.height), (0, 0, 0, 1)) | |
| postplace_to_place = ((0, 0, 0.32), (0, 0, 0, 1)) | |
| preplace_pose = utils.multiply(place_pose, preplace_to_place) | |
| postplace_pose = utils.multiply(place_pose, postplace_to_place) | |
| targ_pose = preplace_pose | |
| while not ee.detect_contact(): | |
| targ_pose = utils.multiply(targ_pose, delta) | |
| timeout |= movep(targ_pose, self.speed) | |
| if timeout: | |
| return True | |
| ee.release() | |
| timeout |= movep(postplace_pose) | |
| # Move to prepick pose if pick is not successful. | |
| else: | |
| ee.release() | |
| timeout |= movep(prepick_pose) | |
| return timeout | |
| def push(movej, movep, ee, pose0, pose1): # pylint: disable=unused-argument | |
| """Execute pushing primitive. | |
| Args: | |
| movej: function to move robot joints. | |
| movep: function to move robot end effector pose. | |
| ee: robot end effector. | |
| pose0: SE(3) starting pose. | |
| pose1: SE(3) ending pose. | |
| Returns: | |
| timeout: robot movement timed out if True. | |
| """ | |
| # Adjust push start and end positions. | |
| pos0 = np.float32((pose0[0][0], pose0[0][1], 0.005)) | |
| pos1 = np.float32((pose1[0][0], pose1[0][1], 0.005)) | |
| vec = np.float32(pos1) - np.float32(pos0) | |
| length = np.linalg.norm(vec) | |
| vec = vec / length | |
| pos0 -= vec * 0.02 | |
| pos1 -= vec * 0.05 | |
| # Align spatula against push direction. | |
| theta = np.arctan2(vec[1], vec[0]) | |
| rot = utils.eulerXYZ_to_quatXYZW((0, 0, theta)) | |
| over0 = (pos0[0], pos0[1], 0.31) | |
| over1 = (pos1[0], pos1[1], 0.31) | |
| # Execute push. | |
| timeout = movep((over0, rot)) | |
| timeout |= movep((pos0, rot)) | |
| n_push = np.int32(np.floor(np.linalg.norm(pos1 - pos0) / 0.01)) | |
| for _ in range(n_push): | |
| target = pos0 + vec * n_push * 0.01 | |
| timeout |= movep((target, rot), speed=0.003) | |
| timeout |= movep((pos1, rot), speed=0.003) | |
| timeout |= movep((over1, rot)) | |
| return timeout | |