Download source/bimanual/yam/solvers/insert.py from yqi19/mp_yam_code: direct link, hf CLI and curl.
- Browser
- Download file 2.44 kB
-
https://huggingface.co/yqi19/mp_yam_code/resolve/main/source/bimanual/yam/solvers/insert.py
- Command line
-
hf download hf://yqi19/mp_yam_code/source/bimanual/yam/solvers/insert.py
-
curl -L -o insert.py https://huggingface.co/yqi19/mp_yam_code/resolve/main/source/bimanual/yam/solvers/insert.py
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} | |