Skip to content

Commit 9f1aa4c

Browse files
authored
Adds support for module:task and updates gymnasium to >=1.0 (#2467)
# Description Gymnasium 1.0 introduced support for specifying module:task to automatically import modules instead of pre-importing task modules. This PR adds support for this feature and enforces the gymnasium version to be >= 1.0. ## Type of change - New feature (non-breaking change which adds functionality) ## Checklist - [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with `./isaaclab.sh --format` - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] I have updated the changelog and the corresponding version in the extension's `config/extension.toml` file - [ ] I have added my name to the `CONTRIBUTORS.md` or my name already exists there <!-- As you go through the checklist above, you can mark something as done by putting an x character in it For example, - [x] I have done this task - [ ] I have not done this task --> --------- Signed-off-by: Kelly Guo <[email protected]>
1 parent d63e58f commit 9f1aa4c

File tree

15 files changed

+46
-29
lines changed

15 files changed

+46
-29
lines changed

scripts/imitation_learning/isaaclab_mimic/annotate_demos.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,13 @@ def main():
174174
os.makedirs(output_dir)
175175

176176
if args_cli.task is not None:
177-
env_name = args_cli.task
177+
env_name = args_cli.task.split(":")[-1]
178178
if env_name is None:
179179
raise ValueError("Task/env name was not specified nor found in the dataset.")
180180

181181
env_cfg = parse_env_cfg(env_name, device=args_cli.device, num_envs=1)
182182

183-
env_cfg.env_name = args_cli.task
183+
env_cfg.env_name = env_name
184184

185185
# extract success checking function to invoke manually
186186
success_term = None

scripts/imitation_learning/isaaclab_mimic/consolidated_demo.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ def main():
366366

367367
# get the environment name
368368
if args_cli.task is not None:
369-
env_name = args_cli.task
369+
env_name = args_cli.task.split(":")[-1]
370370
elif args_cli.input_file:
371371
# if the environment name is not specified, try to get it from the dataset file
372372
dataset_file_handler = HDF5DatasetFileHandler()
@@ -406,7 +406,7 @@ def main():
406406
env_cfg.recorders.dataset_export_mode = DatasetExportMode.EXPORT_SUCCEEDED_ONLY
407407

408408
# create environment
409-
env = gym.make(env_name, cfg=env_cfg)
409+
env = gym.make(args_cli.task, cfg=env_cfg)
410410

411411
if not isinstance(env.unwrapped, ManagerBasedRLMimicEnv):
412412
raise ValueError("The environment should be derived from ManagerBasedRLMimicEnv")

scripts/imitation_learning/isaaclab_mimic/generate_dataset.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,10 @@ def main():
8686

8787
# Setup output paths and get env name
8888
output_dir, output_file_name = setup_output_paths(args_cli.output_file)
89-
env_name = args_cli.task or get_env_name_from_dataset(args_cli.input_file)
89+
task_name = args_cli.task
90+
if task_name:
91+
task_name = args_cli.task.split(":")[-1]
92+
env_name = task_name or get_env_name_from_dataset(args_cli.input_file)
9093

9194
# Configure environment
9295
env_cfg, success_term = setup_env_config(

scripts/imitation_learning/robomimic/train.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -359,15 +359,16 @@ def main(args: argparse.Namespace):
359359
if args.task is not None:
360360
# obtain the configuration entry point
361361
cfg_entry_point_key = f"robomimic_{args.algo}_cfg_entry_point"
362+
task_name = args.task.split(":")[-1]
362363

363-
print(f"Loading configuration for task: {args.task}")
364+
print(f"Loading configuration for task: {task_name}")
364365
print(gym.envs.registry.keys())
365366
print(" ")
366-
cfg_entry_point_file = gym.spec(args.task).kwargs.pop(cfg_entry_point_key)
367+
cfg_entry_point_file = gym.spec(task_name).kwargs.pop(cfg_entry_point_key)
367368
# check if entry point exists
368369
if cfg_entry_point_file is None:
369370
raise ValueError(
370-
f"Could not find configuration for the environment: '{args.task}'."
371+
f"Could not find configuration for the environment: '{task_name}'."
371372
f" Please check that the gym registry has the entry point: '{cfg_entry_point_key}'."
372373
)
373374

scripts/reinforcement_learning/rl_games/play.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777

7878
def main():
7979
"""Play with RL-Games agent."""
80+
task_name = args_cli.task.split(":")[-1]
8081
# parse env configuration
8182
env_cfg = parse_env_cfg(
8283
args_cli.task, device=args_cli.device, num_envs=args_cli.num_envs, use_fabric=not args_cli.disable_fabric
@@ -89,7 +90,7 @@ def main():
8990
print(f"[INFO] Loading experiment from directory: {log_root_path}")
9091
# find checkpoint
9192
if args_cli.use_pretrained_checkpoint:
92-
resume_path = get_published_pretrained_checkpoint("rl_games", args_cli.task)
93+
resume_path = get_published_pretrained_checkpoint("rl_games", task_name)
9394
if not resume_path:
9495
print("[INFO] Unfortunately a pre-trained checkpoint is currently unavailable for this task.")
9596
return

scripts/reinforcement_learning/rsl_rl/play.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,18 +71,19 @@
7171

7272
def main():
7373
"""Play with RSL-RL agent."""
74+
task_name = args_cli.task.split(":")[-1]
7475
# parse configuration
7576
env_cfg = parse_env_cfg(
7677
args_cli.task, device=args_cli.device, num_envs=args_cli.num_envs, use_fabric=not args_cli.disable_fabric
7778
)
78-
agent_cfg: RslRlOnPolicyRunnerCfg = cli_args.parse_rsl_rl_cfg(args_cli.task, args_cli)
79+
agent_cfg: RslRlOnPolicyRunnerCfg = cli_args.parse_rsl_rl_cfg(task_name, args_cli)
7980

8081
# specify directory for logging experiments
8182
log_root_path = os.path.join("logs", "rsl_rl", agent_cfg.experiment_name)
8283
log_root_path = os.path.abspath(log_root_path)
8384
print(f"[INFO] Loading experiment from directory: {log_root_path}")
8485
if args_cli.use_pretrained_checkpoint:
85-
resume_path = get_published_pretrained_checkpoint("rsl_rl", args_cli.task)
86+
resume_path = get_published_pretrained_checkpoint("rsl_rl", task_name)
8687
if not resume_path:
8788
print("[INFO] Unfortunately a pre-trained checkpoint is currently unavailable for this task.")
8889
return

scripts/reinforcement_learning/sb3/play.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,14 @@ def main():
8080
)
8181
agent_cfg = load_cfg_from_registry(args_cli.task, "sb3_cfg_entry_point")
8282

83+
task_name = args_cli.task.split(":")[-1]
84+
8385
# directory for logging into
84-
log_root_path = os.path.join("logs", "sb3", args_cli.task)
86+
log_root_path = os.path.join("logs", "sb3", task_name)
8587
log_root_path = os.path.abspath(log_root_path)
8688
# checkpoint and log_dir stuff
8789
if args_cli.use_pretrained_checkpoint:
88-
checkpoint_path = get_published_pretrained_checkpoint("sb3", args_cli.task)
90+
checkpoint_path = get_published_pretrained_checkpoint("sb3", task_name)
8991
if not checkpoint_path:
9092
print("[INFO] Unfortunately a pre-trained checkpoint is currently unavailable for this task.")
9193
return

scripts/reinforcement_learning/skrl/play.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,22 +108,24 @@ def main():
108108
if args_cli.ml_framework.startswith("jax"):
109109
skrl.config.jax.backend = "jax" if args_cli.ml_framework == "jax" else "numpy"
110110

111+
task_name = args_cli.task.split(":")[-1]
112+
111113
# parse configuration
112114
env_cfg = parse_env_cfg(
113115
args_cli.task, device=args_cli.device, num_envs=args_cli.num_envs, use_fabric=not args_cli.disable_fabric
114116
)
115117
try:
116-
experiment_cfg = load_cfg_from_registry(args_cli.task, f"skrl_{algorithm}_cfg_entry_point")
118+
experiment_cfg = load_cfg_from_registry(task_name, f"skrl_{algorithm}_cfg_entry_point")
117119
except ValueError:
118-
experiment_cfg = load_cfg_from_registry(args_cli.task, "skrl_cfg_entry_point")
120+
experiment_cfg = load_cfg_from_registry(task_name, "skrl_cfg_entry_point")
119121

120122
# specify directory for logging experiments (load checkpoint)
121123
log_root_path = os.path.join("logs", "skrl", experiment_cfg["agent"]["experiment"]["directory"])
122124
log_root_path = os.path.abspath(log_root_path)
123125
print(f"[INFO] Loading experiment from directory: {log_root_path}")
124126
# get checkpoint path
125127
if args_cli.use_pretrained_checkpoint:
126-
resume_path = get_published_pretrained_checkpoint("skrl", args_cli.task)
128+
resume_path = get_published_pretrained_checkpoint("skrl", task_name)
127129
if not resume_path:
128130
print("[INFO] Unfortunately a pre-trained checkpoint is currently unavailable for this task.")
129131
return

scripts/tools/record_demos.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ def main():
209209

210210
# parse configuration
211211
env_cfg = parse_env_cfg(args_cli.task, device=args_cli.device, num_envs=1)
212-
env_cfg.env_name = args_cli.task
212+
env_cfg.env_name = args_cli.task.split(":")[-1]
213213

214214
# extract success checking function to invoke in the main loop
215215
success_term = None

scripts/tools/replay_demos.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ def main():
140140
episode_indices_to_replay = list(range(episode_count))
141141

142142
if args_cli.task is not None:
143-
env_name = args_cli.task
143+
env_name = args_cli.task.split(":")[-1]
144144
if env_name is None:
145145
raise ValueError("Task/env name was not specified nor found in the dataset.")
146146

@@ -153,7 +153,7 @@ def main():
153153
env_cfg.terminations = {}
154154

155155
# create environment from loaded config
156-
env = gym.make(env_name, cfg=env_cfg).unwrapped
156+
env = gym.make(args_cli.task, cfg=env_cfg).unwrapped
157157

158158
teleop_interface = Se3Keyboard(pos_sensitivity=0.1, rot_sensitivity=0.1)
159159
teleop_interface.add_callback("N", play_cb)

source/isaaclab/config/extension.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
[package]
22

33
# Note: Semantic Versioning is used: https://semver.org/
4-
version = "0.40.1"
5-
4+
version = "0.40.2"
65

76
# Description
87
title = "Isaac Lab framework for Robot Learning"

source/isaaclab/docs/CHANGELOG.rst

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,22 @@
11
Changelog
22
---------
33

4+
0.40.2 (2025-05-10)
5+
~~~~~~~~~~~~~~~~~~~
6+
7+
Added
8+
^^^^^
9+
10+
* Updated gymnasium to >= 1.0
11+
* Added support for specifying module:task_name as task name to avoid module import for ``gym.make``
12+
13+
414
0.40.1 (2025-06-02)
515
~~~~~~~~~~~~~~~~~~~
616

717
Added
818
^^^^^
19+
920
* Added time observation functions to ~isaaclab.envs.mdp.observations module,
1021
:func:`~isaaclab.envs.mdp.observations.current_time_s` and :func:`~isaaclab.envs.mdp.observations.remaining_time_s`.
1122

@@ -108,9 +119,6 @@ Fixed
108119
0.39.1 (2025-05-14)
109120
~~~~~~~~~~~~~~~~~~~
110121

111-
Added
112-
^^^^^
113-
114122
* Added a new attribute :attr:`articulation_root_prim_path` to the :class:`~isaaclab.assets.ArticulationCfg` class
115123
to allow explicitly specifying the prim path of the articulation root.
116124

source/isaaclab/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
# devices
3333
"hidapi==0.14.0.post2",
3434
# reinforcement learning
35-
"gymnasium",
35+
"gymnasium>=1.0",
3636
# procedural-generation
3737
"trimesh",
3838
"pyglet<2",

source/isaaclab_tasks/isaaclab_tasks/utils/hydra.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,10 @@ def decorator(func):
8383
@functools.wraps(func)
8484
def wrapper(*args, **kwargs):
8585
# register the task to Hydra
86-
env_cfg, agent_cfg = register_task_to_hydra(task_name, agent_cfg_entry_point)
86+
env_cfg, agent_cfg = register_task_to_hydra(task_name.split(":")[-1], agent_cfg_entry_point)
8787

8888
# define the new Hydra main function
89-
@hydra.main(config_path=None, config_name=task_name, version_base="1.3")
89+
@hydra.main(config_path=None, config_name=task_name.split(":")[-1], version_base="1.3")
9090
def hydra_main(hydra_env_cfg: DictConfig, env_cfg=env_cfg, agent_cfg=agent_cfg):
9191
# convert to a native dictionary
9292
hydra_env_cfg = OmegaConf.to_container(hydra_env_cfg, resolve=True)

source/isaaclab_tasks/isaaclab_tasks/utils/parse_cfg.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def load_cfg_from_registry(task_name: str, entry_point_key: str) -> dict | objec
5757
ValueError: If the entry point key is not available in the gym registry for the task.
5858
"""
5959
# obtain the configuration entry point
60-
cfg_entry_point = gym.spec(task_name).kwargs.get(entry_point_key)
60+
cfg_entry_point = gym.spec(task_name.split(":")[-1]).kwargs.get(entry_point_key)
6161
# check if entry point exists
6262
if cfg_entry_point is None:
6363
raise ValueError(
@@ -122,7 +122,7 @@ def parse_env_cfg(
122122
environment configuration.
123123
"""
124124
# load the default configuration
125-
cfg = load_cfg_from_registry(task_name, "env_cfg_entry_point")
125+
cfg = load_cfg_from_registry(task_name.split(":")[-1], "env_cfg_entry_point")
126126

127127
# check that it is not a dict
128128
# we assume users always use a class for the configuration

0 commit comments

Comments
 (0)