| """Run a registered YAM task: build scene -> solve -> evaluate -> video. |
| |
| python scripts/yam_task.py --list |
| python scripts/yam_task.py --task grape_box --seed 0 |
| python scripts/yam_task.py --task pot_dual_lift --seed 4 --no-randomize |
| |
| One Python file per task under source/bimanual/yam/tasks/, in the shape ManiSkill uses: a |
| registered class with _load_scene / _initialize_episode / solve / evaluate. |
| """ |
| import argparse, json, os, sys |
| from pathlib import Path |
|
|
| REPO = Path(__file__).resolve().parent.parent |
| sys.path.insert(0, str(REPO/"source")) |
|
|
|
|
| def main(): |
| ap = argparse.ArgumentParser() |
| ap.add_argument("--task") |
| ap.add_argument("--list", action="store_true") |
| ap.add_argument("--seed", type=int, default=0) |
| ap.add_argument("--no-randomize", action="store_true") |
| ap.add_argument("--episode", type=int, default=-1) |
| ap.add_argument("--video", default="") |
| ap.add_argument("--set", action="append", default=[], metavar="KEY=VALUE", |
| help="override a task parameter, on top of tasks/configs/<task>.yaml") |
| ap.add_argument("--first-frame", default="", |
| help="build the scene, save ONE frame here, and exit without solving") |
| args, unknown = ap.parse_known_args() |
|
|
| from bimanual.yam import registry |
| import bimanual.yam.tasks |
|
|
| if args.list or not args.task: |
| rows = registry.list_tasks() |
| w = max([len(r["name"]) for r in rows]+[4]) |
| print(f"{'name'.ljust(w)} {'class'.ljust(20)} tags") |
| for r in rows: |
| print(f"{r['name'].ljust(w)} {r['class'].ljust(20)} {r['tags']}") |
| print(f"\n{len(rows)} task(s) registered") |
| return 0 |
|
|
| cls = registry.REGISTRY.get(args.task) |
| if cls is None: |
| raise SystemExit(f"unknown task {args.task!r}. Registered: {sorted(registry.REGISTRY)}") |
|
|
| |
| |
| |
| from bimanual.yam.envs import config as taskcfg |
| overrides = dict(taskcfg.load(args.task)) |
| overrides.update(taskcfg.parse_cli(args.set)) |
|
|
| |
| for k, v in cls.env_vars(overrides).items(): |
| os.environ[k] = v |
| print(f"[run] {k}={v}", flush=True) |
| os.environ.setdefault("OMNI_KIT_ACCEPT_EULA", "YES") |
|
|
| from isaaclab.app import AppLauncher |
| ap2 = argparse.ArgumentParser(); AppLauncher.add_app_launcher_args(ap2) |
| largs = ap2.parse_args(unknown); largs.headless = True; largs.enable_cameras = True |
| app = AppLauncher(largs).app |
|
|
| import gymnasium as gym |
| import bimanual.tasks.manager_based.yam |
| from isaaclab_tasks.utils import parse_env_cfg |
|
|
| cfg = parse_env_cfg("Template-YAM-Play-v0", device="cuda:0", num_envs=1) |
| |
| |
| cfg.episode_length_s = 1.0e6 |
| try: |
| cfg.terminations.time_out = None |
| except Exception as e: |
| print("[run] time_out disable failed:", e) |
| try: |
| cfg.viewer.eye = tuple(cls.viewer_eye); cfg.viewer.lookat = tuple(cls.viewer_lookat) |
| cfg.viewer.resolution = (720, 540) |
| except Exception as e: |
| print("[run] viewer cfg:", e) |
|
|
| env = gym.make("Template-YAM-Play-v0", cfg=cfg, render_mode="rgb_array") |
| env.reset() |
| origin = env.unwrapped.scene.env_origins[0].cpu().numpy() |
|
|
| task = cls(seed=args.seed, randomize=not args.no_randomize, episode=args.episode, |
| video=args.video, overrides=taskcfg.parse_cli(args.set)) |
| task.build(env, origin) |
| if args.first_frame: |
| |
| |
| import imageio.v2 as _iio |
| |
| |
| |
| frame = None |
| for _ in range(60): |
| task.step() |
| img = env.render() |
| if img is not None: |
| frame = img |
| os.makedirs(os.path.dirname(args.first_frame) or ".", exist_ok=True) |
| _iio.imwrite(args.first_frame, frame) |
| print(f"[run] first frame -> {args.first_frame} {frame.shape}", flush=True) |
| env.close(); app.close() |
| print("YAM_TASK_DONE", flush=True) |
| return 0 |
| |
| |
| |
| task._start_joints = task._joint_state() |
| info = task.solve() |
| print(f"[run] solver: {json.dumps(info, default=str)}", flush=True) |
| result = task.evaluate() |
| task.save_video(args.video or None) |
| env.close(); app.close() |
| print("YAM_TASK_DONE", flush=True) |
| return 0 if result.get("success") else 1 |
|
|
|
|
| if __name__ == "__main__": |
| sys.exit(main() or 0) |
|
|