-
Notifications
You must be signed in to change notification settings - Fork 4.2k
fix(envs): handle async vector env compatibility for Libero #3321
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
11d3c76
c0ce2e9
6c4b1ee
e74cac7
bbe47fa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -130,7 +130,21 @@ def env_to_policy_features(env_cfg: EnvConfig) -> dict[str, PolicyFeature]: | |
| return policy_features | ||
|
|
||
|
|
||
| def _has_env_attr(env: gym.vector.VectorEnv, attr: str) -> bool: | ||
| """Check if sub-environments have an attribute, compatible with sync and async vector envs.""" | ||
|
Comment on lines
+133
to
+134
|
||
| if hasattr(env, "envs"): | ||
| return hasattr(env.envs[0], attr) | ||
| try: | ||
| env.call(attr) | ||
| return True | ||
| except Exception: | ||
| return False | ||
|
Comment on lines
+133
to
+141
|
||
|
|
||
|
|
||
| def are_all_envs_same_type(env: gym.vector.VectorEnv) -> bool: | ||
| if not hasattr(env, "envs"): | ||
| # AsyncVectorEnv: cannot inspect subprocess env types directly | ||
| return True | ||
| first_type = type(env.envs[0]) # Get type of first env | ||
| return all(type(e) is first_type for e in env.envs) # Fast type check | ||
|
|
||
|
|
@@ -139,7 +153,7 @@ def check_env_attributes_and_types(env: gym.vector.VectorEnv) -> None: | |
| with warnings.catch_warnings(): | ||
| warnings.simplefilter("once", UserWarning) # Apply filter only in this function | ||
|
|
||
| if not (hasattr(env.envs[0], "task_description") and hasattr(env.envs[0], "task")): | ||
| if not (_has_env_attr(env, "task_description") or _has_env_attr(env, "task")): | ||
| warnings.warn( | ||
| "The environment does not have 'task_description' and 'task'. Some policies require these features.", | ||
| UserWarning, | ||
|
Comment on lines
+156
to
159
|
||
|
|
@@ -155,7 +169,7 @@ def check_env_attributes_and_types(env: gym.vector.VectorEnv) -> None: | |
|
|
||
| def add_envs_task(env: gym.vector.VectorEnv, observation: RobotObservation) -> RobotObservation: | ||
| """Adds task feature to the observation dict with respect to the first environment attribute.""" | ||
| if hasattr(env.envs[0], "task_description"): | ||
| if _has_env_attr(env, "task_description"): | ||
| task_result = env.call("task_description") | ||
|
Comment on lines
+172
to
173
|
||
|
|
||
| if isinstance(task_result, tuple): | ||
|
|
@@ -167,7 +181,7 @@ def add_envs_task(env: gym.vector.VectorEnv, observation: RobotObservation) -> R | |
| raise TypeError("All items in task_description result must be strings") | ||
|
|
||
| observation["task"] = task_result | ||
| elif hasattr(env.envs[0], "task"): | ||
| elif _has_env_attr(env, "task"): | ||
| task_result = env.call("task") | ||
|
Comment on lines
+184
to
185
|
||
|
|
||
| if isinstance(task_result, tuple): | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using
partial(...)meansenv_clsis no longer a class whenuse_async_envs=True. If any downstream code expects class-like behavior (e.g.,isinstance(..., env_cls),env_cls.__name__, type comparisons), this will break. A more robust approach is to keepenv_clsas the class and passcontext='spawn'at the construction site (or branch on async vs sync for instantiation), so the variable’s type stays consistent.