mp_yam_code / source /bimanual /yam /tasks /drawer_store.py
yqi19's picture
YAM bimanual task suite: env, solvers, tasks, converters
7399b6f verified
Raw
History Blame Contribute Delete
3.38 kB
"""Two-stage articulated task: pull the drawer open, then put a milk carton inside it.
Neither half is interesting alone -- the point is the ORDER. The drawer has to be open before
anything can go in, so the second skill's workspace is created by the first one, and a policy
that gets the order wrong drives the carton into a closed drawer front.
"""
from ..registry import register_task
from ..envs import YamTaskEnv
from ..solvers import articulate, shelf
from .. import conditions as C
@register_task("drawer_store")
class DrawerStoreTask(YamTaskEnv):
title = "OPEN THE DRAWER, PUT THE CARTON IN"
tags = ["articulated", "slider", "sequential", "pick-place", "robotwin-asset"]
instruction = {"default": "Open the drawer and put the milk carton inside."}
rw_articulations = {"rw_cabinet": "036_cabinet/46653_clean.usd:0.20"}
rw_objects = {"rw_carton": "038_milk-box/base0.usd:0.045:0.08"}
body_xy = (-0.02, -0.26)
carton_xy = (0.06, 0.06)
spawn_jitter = (0.020, 0.015)
front_dy = -0.085
grip_z = 0.100
press_down = 0.0
# lean the wrist most of the way to horizontal so the fingers straddle the drawer's lip
grip_tilt = 62.0
pull_distance = 0.14
gripper_effort, gripper_damping = 80, 90
def _load_scene(self):
self.scene.place_articulation({"name": "rw_cabinet", "bbox": [[-0.4283, -0.8033, -0.4334], [0.426, 0.8112, 0.4655]], "scale": 0.2, "xy": self.body_xy, "half": 0.13,
"xy_jitter": (0.015, 0.012)})
self._placed = [self.scene.place_object(
{"name": "rw_carton", "xy": self.carton_xy, "xy_jitter": self.spawn_jitter})]
art = self.scene.articulations.get("rw_cabinet")
if art is not None:
print(f"[task] cabinet joints={list(art.data.joint_names)}", flush=True)
for i, nm in enumerate(art.data.body_names):
print(f"[task] link {i} {nm}: {self.scene.link_pos('rw_cabinet', i).round(3)}",
flush=True)
def solve(self):
bx, by = self.scene.regions["rw_cabinet"]["xy"]
opened = articulate.solve(self, fixture="rw_cabinet", kind="slider",
grip_xy=(bx, by+self.front_dy), grip_z=self.grip_z, press=self.press_down,
grip_tilt=self.grip_tilt, open_jaw=False, jaw="x",
direction=(0.0, -1.0), distance=self.pull_distance,
approach_from=(0.0, -1.0))
if opened["moved"] < 0.04:
self.recorder.phase = "ABORT: the drawer never opened, so nothing can go in"
return {"opened": False, **opened}
# the drawer's mouth is now `moved` metres out in front of the cabinet body
self.scene.regions["drawer_mouth"] = {
"xy": (bx, by+self.front_dy-opened["moved"]*0.45),
"half": 0.05, "shelf_z": self.scene.regions["rw_cabinet"]["top_z"]+self.grip_z-0.02}
put = shelf.solve(self, obj="rw_carton", target="drawer_mouth", standoff=0.14)
return {"opened": True, **opened, **put}
def evaluate(self):
return self.check(
C.labelled("drawer opened", C.joint_driven("rw_cabinet", 0, by=0.05)),
C.labelled("carton went into the drawer",
C.object_moved_to("rw_carton", "drawer_mouth", tol=0.09)))