|
3 | 3 | # |
4 | 4 | # SPDX-License-Identifier: Apache-2.0 |
5 | 5 |
|
6 | | -"""GR00T policy-runner task for the Isaac Lab Arena OSMO workflow. |
7 | | -
|
8 | | -Runs ``policy_runner.py`` with the GR00T remote closed-loop policy against the |
9 | | -GR00T server that shares its OSMO group. Mirrors the eval side of the |
10 | | -``test_gr00t_closedloop_e2e`` CI job in ``.github/workflows/ci.yml``. |
11 | | -""" |
| 6 | +"""GR00T policy-runner task for the Isaac Lab Arena OSMO workflow.""" |
12 | 7 |
|
13 | 8 | import argparse |
14 | | -from typing import Any |
15 | | - |
16 | | -from tasks.gr00t_server_task import GR00T_SERVER_HOST_TOKEN, get_wait_for_server_script |
17 | | -from tasks.policy_runner_task import POLICY_RUNNER_COMMAND, PolicyRunnerTask |
18 | | -from workflows.workflow_constants import EVAL_OUTPUT_SWIFT_URL, OSMO_TASK_OUTPUT_DIR |
19 | 9 |
|
20 | | -# Arena image name |
21 | | -DEFAULT_IMAGE = "nvcr.io/nvstaging/isaac-amr/isaaclab_arena:latest" |
| 10 | +from tasks.policy_runner_task import PolicyRunnerTask |
| 11 | +from workflows.workflow_constants import POLICY_SERVER_PORT |
22 | 12 |
|
23 | | -# GR00T remote closed-loop policy and the policy closed-loop config. |
24 | | -GR00T_POLICY_TYPE = "isaaclab_arena_gr00t.policy.gr00t_remote_closedloop_policy.Gr00tRemoteClosedloopPolicy" |
25 | 13 | DEFAULT_POLICY_CONFIG = "isaaclab_arena_gr00t/policy/config/droid_manip_gr00t_closedloop_config.yaml" |
26 | 14 |
|
27 | | -DEFAULT_POLICY_RUNNER_ARGS = "--num_episodes 2 --headless --enable_cameras --num_envs 4 --record_camera_video" |
28 | | - |
29 | 15 |
|
30 | 16 | class Gr00tPolicyRunnerTask(PolicyRunnerTask): |
31 | 17 | """OSMO task that evaluates the GR00T remote policy via a connection to the GR00T server.""" |
32 | 18 |
|
33 | 19 | def __init__( |
34 | 20 | self, |
35 | | - workflow_args: Any, |
36 | | - task_args: Any, |
37 | | - image: str = DEFAULT_IMAGE, |
| 21 | + workflow_args: argparse.Namespace, |
| 22 | + task_args: argparse.Namespace, |
38 | 23 | lead: bool | None = None, |
39 | 24 | ) -> None: |
40 | | - super().__init__(workflow_args, task_args, image=image, lead=lead) |
41 | | - self.image = getattr(task_args, "arena_image", image) |
| 25 | + super().__init__(workflow_args=workflow_args, task_args=task_args, lead=lead) |
42 | 26 | self.policy_config_yaml_path = task_args.policy_config_yaml_path |
43 | | - |
44 | | - # Tasks in an OSMO group each get their own IP (no shared loopback), so the server is reached |
45 | | - # via the {{host:<task-name>}} token, which OSMO resolves to the server task's IP at runtime. |
46 | 27 | self.remote_host = task_args.remote_host |
47 | | - self.remote_port = task_args.server_port |
48 | 28 |
|
49 | 29 | @staticmethod |
50 | 30 | def add_task_arguments(parser: argparse.ArgumentParser) -> None: |
| 31 | + PolicyRunnerTask.add_task_arguments(parser) |
51 | 32 | group = parser.add_argument_group("gr00t policy runner") |
52 | | - group.add_argument("--arena_image", default=DEFAULT_IMAGE, help="Override the Arena dev image") |
53 | 33 | group.add_argument( |
54 | 34 | "--policy_config_yaml_path", default=DEFAULT_POLICY_CONFIG, help="GR00T closed-loop config YAML" |
55 | 35 | ) |
56 | | - group.add_argument( |
57 | | - "--arena_env_args", |
58 | | - required=True, |
59 | | - help=( |
60 | | - "Arena example-environment name plus its env-related arguments, " |
61 | | - "e.g. 'kitchen_pick_and_place --object cracker_box'" |
62 | | - ), |
63 | | - ) |
| 36 | + # Tasks in an OSMO group each get their own IP, so the server is reached via the |
| 37 | + # {{host:<task-name>}} token, which OSMO resolves to the server task's IP at runtime. |
64 | 38 | group.add_argument( |
65 | 39 | "--remote_host", |
66 | | - default=GR00T_SERVER_HOST_TOKEN, |
67 | | - help="GR00T server host (defaults to the {{host:gr00t_server}}) name", |
| 40 | + default="{{host:gr00t_server}}", |
| 41 | + help="GR00T server host (defaults to {{host:gr00t_server}})", |
68 | 42 | ) |
69 | | - group.add_argument( |
70 | | - "--policy_runner_args", |
71 | | - default=DEFAULT_POLICY_RUNNER_ARGS, |
72 | | - help=( |
73 | | - "Policy-runner related arguments, e.g. '--num_episodes, --headless, --enable_cameras, --num_envs," |
74 | | - " --record_camera_video'" |
75 | | - ), |
76 | | - ) |
77 | | - |
78 | | - @staticmethod |
79 | | - def get_task_name() -> str: |
80 | | - return "gr00t_policy_runner" |
81 | | - |
82 | | - def _get_outputs(self) -> list[dict[str, Any]]: |
83 | | - # Evaluation outputs (videos, per-episode results, report) are uploaded per run. |
84 | | - return [{"url": EVAL_OUTPUT_SWIFT_URL}] |
85 | 43 |
|
86 | 44 | def _get_policy_args(self) -> list[str]: |
87 | 45 | return [ |
88 | 46 | "--policy_type", |
89 | | - GR00T_POLICY_TYPE, |
| 47 | + "isaaclab_arena_gr00t.policy.gr00t_remote_closedloop_policy.Gr00tRemoteClosedloopPolicy", |
90 | 48 | "--policy_config_yaml_path", |
91 | 49 | self.policy_config_yaml_path, |
92 | 50 | "--remote_host", |
93 | 51 | self.remote_host, |
94 | 52 | "--remote_port", |
95 | | - str(self.remote_port), |
| 53 | + str(POLICY_SERVER_PORT), |
96 | 54 | ] |
97 | | - |
98 | | - def _get_run_script(self) -> str: |
99 | | - # Override the base runner: block on the GR00T server coming up before launching the eval. |
100 | | - policy_args_str = " ".join(self._get_policy_args()) |
101 | | - return ( |
102 | | - "set -euxo pipefail\n" |
103 | | - "ldconfig\n" |
104 | | - "nvidia-smi\n" |
105 | | - "cd /workspaces/isaaclab_arena\n" |
106 | | - "[ -e submodules/IsaacLab/_isaac_sim ] || ln -s /isaac-sim/ submodules/IsaacLab/_isaac_sim\n" |
107 | | - "\n" |
108 | | - f"{get_wait_for_server_script(self.remote_host, self.remote_port)}" |
109 | | - "\n" |
110 | | - f"{POLICY_RUNNER_COMMAND} " |
111 | | - f"{policy_args_str} " |
112 | | - # Write evaluation outputs to the OSMO task output mount (uploaded to EVAL_OUTPUT_SWIFT_URL). |
113 | | - f"--output_base_dir {OSMO_TASK_OUTPUT_DIR} " |
114 | | - f"{self.policy_runner_args} " |
115 | | - f"{self.arena_env_args}\n" |
116 | | - ) |
0 commit comments