| """Bimanual L-shaped relay push: each arm drives one leg, and neither can do the other's. |
| |
| The route turns a corner on purpose. The right arm's shoulder is at y=-0.2 and the left arm's at |
| y=+0.2, so an arm can only push comfortably AWAY from its own shoulder: the right arm can drive |
| the block in +x, the left arm can drive it in -y. Getting the block from the start to the pad |
| needs both, in that order. |
| |
| A straight-line relay does not work here, and not for a tuning reason: pushing along -y means |
| standing on the block's +y side, which the right arm can only reach by stretching over the block |
| itself -- the approach swipes it off the table. |
| """ |
| from ..registry import register_task |
| from ..envs import YamTaskEnv |
| from ..solvers import push |
| from .. import conditions as C |
|
|
|
|
| @register_task("push_relay") |
| class PushRelayTask(YamTaskEnv): |
| title = "RELAY-PUSH THE BLOCK AROUND THE CORNER" |
| tags = ["bimanual", "push", "no-grasp", "coordination", "primitive"] |
| instruction = {"default": "Push the block onto the pad, using both arms in turn."} |
|
|
| bimanual = True |
| |
| |
| |
| |
| block_spawn = (-0.15, 0.12) |
| spawn_jitter = (0.018, 0.015) |
| corner_xy = (0.02, -0.02) |
| target_xy = (0.18, -0.10) |
| target_size = 0.11 |
| gripper_effort, gripper_damping = 78, 88 |
|
|
| def _load_scene(self): |
| self.scene.build_marker({"name": "corner", "xy": self.corner_xy, "size": 0.085, |
| "color": (0.55, 0.55, 0.58), "xy_jitter": (0.012, 0.012)}) |
| self.scene.build_marker({"name": "target", "xy": self.target_xy, "size": self.target_size, |
| "color": (0.90, 0.68, 0.15), "xy_jitter": (0.012, 0.012)}) |
| self._placed = [self.scene.place_object( |
| {"name": "cube_y", "xy": self.block_spawn, "xy_jitter": self.spawn_jitter})] |
|
|
| def solve(self): |
| return push.relay(self, obj="cube_y", legs=[ |
| {"arm": "left", "target": "corner"}, |
| {"arm": "right", "target": "target"}, |
| ]) |
|
|
| def evaluate(self): |
| return self.check( |
| C.labelled("block reached the pad", C.object_moved_to("cube_y", "target", tol=0.07)), |
| C.labelled("block never left the table", C.object_level("cube_y", 40.0))) |
|
|