mp_yam_code / source /bimanual /yam /tasks /bar_pull.py
yqi19's picture
YAM bimanual task suite: env, solvers, tasks, converters
7399b6f verified
Raw
History Blame Contribute Delete
2.5 kB
"""Constrained pull: draw a wooden bar straight out of a slotted block (drawer-like motion).
The bar starts most of the way inside a through-channel with only its end sticking out. The
channel caps it top and sides, so the only motion that gets it free is a straight pull along
+x -- lift it or turn it and it binds. That constraint is the whole point of the task.
"""
from ..registry import register_task
from ..envs import YamTaskEnv
from ..solvers import pull
from .. import conditions as C
@register_task("bar_pull")
class BarPullTask(YamTaskEnv):
title = "PULL THE BAR OUT OF THE BLOCK"
tags = ["constrained-motion", "pull", "primitive"]
instruction = {"default": "Pull the wooden bar out of the block."}
sleeve_xy = (-0.06, 0.02)
sleeve_length = 0.10
bar_length = 0.15 # must match the CuboidCfg registered in the env
pull_distance = 0.14
# a light clamp: the bar is a small dry cuboid, and squeezing hard wedges it in the channel
gripper_effort, gripper_damping = 62, 85
def _load_scene(self):
s = self.scene.build_sleeve({"name": "sleeve", "xy": self.sleeve_xy,
"length": self.sleeve_length, "width": 0.046, "height": 0.046,
"xy_jitter": (0.015, 0.020)})
# slide the bar in so it is flush at the -x end: the overhang at +x is what we grab
self._overhang = self.bar_length-self.sleeve_length
self._placed = [self.scene.place_object({
"name": "bar",
"xy": (s["xy"][0]+self._overhang/2.0, s["xy"][1]),
# vary how deep it starts in the slot
"xy_jitter": (0.010, 0.0),
# ride on the channel floor, not the table
"z_offset": s["channel_z"]-0.45+0.002,
})]
def solve(self):
# grab the MIDDLE OF THE EXPOSED STUB, not the centroid: the centroid is buried in the
# housing, and the very tip leaves too little bar between the jaws
grip_x = self.bar_length/2.0-self._overhang/2.0
return pull.solve(self, obj="bar", direction=(1.0, 0.0), distance=self.pull_distance,
grasp_offset=(grip_x, 0.0), max_gap=0.05)
def evaluate(self):
return self.check(
C.labelled("bar drawn clear of the block",
C.object_clear_of("bar", "sleeve", extent=self.bar_length/2.0, margin=0.02)),
C.labelled("bar stayed flat", C.object_level("bar", 25.0)))