"""Stack two upright cups on a marked target region.""" from ..registry import register_task from ..envs import YamTaskEnv from ..solvers import stack from .. import conditions as C @register_task("stack_cups") class StackCupsTask(YamTaskEnv): title = "STACK TWO CUPS ON THE TARGET" tags = ["stacking", "precision", "robotwin-asset"] instruction = {"default": "Stack the cups on the target.", "specific": "Put one cup on the marked square, then stack the second on top."} rw_objects = {"rw_cupA": "021_cup/base0.usd:0.075:0.08", "rw_cupB": "021_cup/base1.usd:0.075:0.08"} cup_spawns = {"rw_cupA": (-0.05, 0.11), "rw_cupB": (0.05, 0.05)} spawn_jitter = (0.02, 0.015) target_xy = (0.02, -0.22) target_size = 0.12 # RoboTwin cups spawn upside-down; inverted, the rim is at the bottom and the jaws grip a # narrowing taper, so they slip straight out cup_roll = 90 gripper_effort, gripper_damping = 55, 72 def _load_scene(self): self.scene.build_marker({"name": "target", "xy": self.target_xy, "size": self.target_size, "xy_jitter": (0.015, 0.015)}) self._placed = [ self.scene.place_object({"name": n, "xy": xy, "xy_jitter": self.spawn_jitter, "roll": self.cup_roll}) for n, xy in self.cup_spawns.items()] def solve(self): return stack.solve(self, objects=list(self.cup_spawns), target="target") def evaluate(self): return self.check( C.labelled("bottom cup on target", C.object_in_region("rw_cupA", "target", pad=0.04)), C.labelled("top cup on target", C.object_in_region("rw_cupB", "target", pad=0.04)), C.labelled("cups stacked", C.objects_stacked("rw_cupA", "rw_cupB", min_dz=0.03)))