yqi19's picture
YAM bimanual task suite: env, solvers, tasks, converters
7399b6f verified
Raw
History Blame Contribute Delete
2.44 kB
"""Peg-in-hole: grasp near the top, align over the socket, insert straight down."""
import numpy as np
from ..motion.arm import OPEN, CLOSE, fillet
from ..envs.scene import TABLE_TOP
from .base import approach_and_grasp
def solve(env, obj, target, arm="right", grasp_top=0.03, max_gap=0.03):
a = env.arms[arm]
rec = env.recorder
res, ext = approach_and_grasp(env, a, obj, grasp_top=grasp_top, max_gap=max_gap)
if not res.ok:
rec.phase = "ABORT: no grasp"
return {"grasped": False, "reason": res.reason}
reg = env.scene.regions[target]
above = a.to_root(np.array([reg["xy"][0], reg["xy"][1], TABLE_TOP+0.20], np.float32))
# the peg was grasped while standing on the table, so returning the fingers to that height
# puts its base back at table level -- fully seated, since the hole's floor IS the table
seat = np.array([above[0], above[1], float(res.hold_pose[2])], np.float32)
rec.phase = "4. CARRY + ALIGN over the hole"
a.flow(fillet([a._seg_start(), res.hold_pose+np.array([0, 0, 0.16], np.float32), above])[1:], CLOSE)
# VISUAL-SERVO the correction: the part slips in the jaws during the carry, so the gripper
# being over the hole is not the same as the PART being over it. Measure the part's live xy
# and shift the descent by the residual -- without this the ring lands beside the post.
live = env.scene.object_pos(obj)
delta = np.array([reg["xy"][0]-float(live[0]), reg["xy"][1]-float(live[1])], float)
if float(np.linalg.norm(delta)) > 0.002:
rec.phase = "4b. FINE-ALIGN on the part's own pose"
above = above+np.array([delta[0], delta[1], 0.0], np.float32)
seat = seat+np.array([delta[0], delta[1], 0.0], np.float32)
a.move_to(above, CLOSE, tol=0.005, max_steps=90)
print(f"[solver] fine-align: part was off by {np.round(delta,4)} m", flush=True)
rec.phase = "5. INSERT"
err = a.move_to(seat, CLOSE, tol=0.006, max_steps=170)
rec.phase = "6. RELEASE"
a.move_to(seat, OPEN, tol=0.02, max_steps=45)
rec.phase = "7. RETREAT"
a.flow([seat+np.array([0, 0, 0.16], np.float32)], OPEN)
fin = env.scene.object_pos(obj)
miss = float(np.hypot(fin[0]-reg["xy"][0], fin[1]-reg["xy"][1]))
print(f"[solver] {obj} settled at ({fin[0]:+.3f},{fin[1]:+.3f},{fin[2]:.3f}), "
f"{miss:.3f} m from {target}", flush=True)
return {"grasped": True, "insert_err": err, "miss": miss}