Unverified Commit 64681ea9 authored by peterd-NV's avatar peterd-NV Committed by GitHub

Adds parameter to specify number of rerenders after environment reset (#3818)

# Description

<!--
Thank you for your interest in sending a pull request. Please make sure
to check the contribution guidelines.

Link:
https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html

💡 Please try to keep PRs small and focused. Large PRs are harder to
review and merge.
-->

Adds a new parameter to ManagerBasedEnv and DirectRLEnv to give users
better control over rerender on reset behaviour. The new parameter
`num_rerenders_on_reset` allows users to explicitly define the number of
re-render steps after an env reset. When using DLSS, this allows for the
elimination of artifacts/ghosting that are present after a single
rendering step.

Add a deprecation warning for the old parameter `rerender_on_reset`.
Functionality of old parameter is preserved.

Updates the existing visuomotor envs to use new rerendering API together
with DLAA for high quality rendering.

Fixes # (issue)

Non-DLSS denoising is not supported on aarch64. There are also future
plans from the rendering team to disable use of non-DLSS antialiasing
for all platforms in the future. This causes an issue for visuomotor
envs which suffer from image ghosting/artifacts when using DLSS. The new
rerendering API allows for users of visuomotor envs to enable DLSS/DLAA
while preserving image integrity.

## Type of change

<!-- As you go through the list, delete the ones that are not
applicable. -->

- New feature (non-breaking change which adds functionality)

## Screenshots

Please attach before and after screenshots of the change if applicable.

<!--
Example:

| Before | After |
| ------ | ----- |
| _gif/png before_ | _gif/png after_ |

To upload images to a PR -- simply drag and drop an image while in edit
mode and it should upload the image directly. You can then paste that
source into the above before/after sections.
-->

## Checklist

- [x] I have read and understood the [contribution
guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html)
- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./isaaclab.sh --format`
- [ ] 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
- [x] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [x] 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: 's avatarKelly Guo <kellyg@nvidia.com>
Co-authored-by: 's avatarKelly Guo <kellyg@nvidia.com>
parent f4982455
......@@ -91,8 +91,6 @@ Other notable limitations with respect to Isaac Lab include...
#. Multi-node training may require direct connections between Spark machines or additional network configurations.
#. :ref:`Isaac Lab Mimic <generating-additional-demonstrations>` data generation and policy inference for visuomotor environments are not supported on DGX Spark due to a lack of non-DLSS image denoiser on aarch64.
#. :ref:`Running Cosmos Transfer1 <running-cosmos>` is not currently supported on the DGX Spark.
Troubleshooting
......
......@@ -59,6 +59,7 @@ import argparse
# Third-party imports
import gymnasium as gym
import h5py
import importlib
import json
import numpy as np
import os
......@@ -369,7 +370,18 @@ def main(args: argparse.Namespace):
f" Please check that the gym registry has the entry point: '{cfg_entry_point_key}'."
)
with open(cfg_entry_point_file) as f:
# resolve module path if needed
if ":" in cfg_entry_point_file:
mod_name, file_name = cfg_entry_point_file.split(":")
mod = importlib.import_module(mod_name)
if mod.__file__ is None:
raise ValueError(f"Could not find module file for: '{mod_name}'")
mod_path = os.path.dirname(mod.__file__)
config_file = os.path.join(mod_path, file_name)
else:
config_file = cfg_entry_point_file
with open(config_file) as f:
ext_cfg = json.load(f)
config = config_factory(ext_cfg["algo_name"])
# update config with external json - this will throw errors if
......
[package]
# Note: Semantic Versioning is used: https://semver.org/
version = "0.47.9"
version = "0.47.10"
# Description
title = "Isaac Lab framework for Robot Learning"
......
Changelog
---------
0.47.10 (2025-11-06)
~~~~~~~~~~~~~~~~~~~~
Added
^^^^^
* Added ``num_rerenders_on_reset`` parameter to ManagerBasedEnvCfg and DirectRLEnvCfg to configure the number
of render steps to perform after reset. This enables more control over DLSS rendering behavior after reset.
Changed
^^^^^^^
* Added deprecation warning for ``rerender_on_reset`` parameter in ManagerBasedEnv and DirectRLEnv.
0.47.9 (2025-11-05)
~~~~~~~~~~~~~~~~~~~
......
......@@ -11,6 +11,7 @@ import inspect
import math
import numpy as np
import torch
import warnings
import weakref
from abc import abstractmethod
from collections.abc import Sequence
......@@ -219,6 +220,20 @@ class DirectRLEnv(gym.Env):
# video matches the simulation
self.metadata["render_fps"] = 1 / self.step_dt
# show deprecation message for rerender_on_reset
if self.cfg.rerender_on_reset:
msg = (
"\033[93m\033[1m[DEPRECATION WARNING] DirectRLEnvCfg.rerender_on_reset is deprecated. Use"
" DirectRLEnvCfg.num_rerenders_on_reset instead.\033[0m"
)
warnings.warn(
msg,
FutureWarning,
stacklevel=2,
)
if self.cfg.num_rerenders_on_reset == 0:
self.cfg.num_rerenders_on_reset = 1
# print the environment information
print("[INFO]: Completed setting up the environment...")
......@@ -300,8 +315,9 @@ class DirectRLEnv(gym.Env):
self.sim.forward()
# if sensors are added to the scene, make sure we render to reflect changes in reset
if self.sim.has_rtx_sensors() and self.cfg.rerender_on_reset:
self.sim.render()
if self.sim.has_rtx_sensors() and self.cfg.num_rerenders_on_reset > 0:
for _ in range(self.cfg.num_rerenders_on_reset):
self.sim.render()
if self.cfg.wait_for_textures and self.sim.has_rtx_sensors():
while SimulationManager.assets_loading():
......@@ -377,8 +393,9 @@ class DirectRLEnv(gym.Env):
if len(reset_env_ids) > 0:
self._reset_idx(reset_env_ids)
# if sensors are added to the scene, make sure we render to reflect changes in reset
if self.sim.has_rtx_sensors() and self.cfg.rerender_on_reset:
self.sim.render()
if self.sim.has_rtx_sensors() and self.cfg.num_rerenders_on_reset > 0:
for _ in range(self.cfg.num_rerenders_on_reset):
self.sim.render()
# post-step: step interval event
if self.cfg.events:
......
......@@ -222,6 +222,22 @@ class DirectRLEnvCfg:
to reflect the latest states from the reset. This comes at a cost of performance as an additional render
step will be performed after each time an environment is reset.
.. deprecated:: 2.3.1
This attribute is deprecated and will be removed in the future. Please use
:attr:`num_rerenders_on_reset` instead.
To get the same behaviour as setting this parameter to ``True`` or ``False``, set
:attr:`num_rerenders_on_reset` to 1 or 0, respectively.
"""
num_rerenders_on_reset: int = 0
"""Number of render steps to perform after reset. Defaults to 0, which means no render step will be performed after reset.
* When this is 0, no render step will be performed after reset. Data collected from sensors after performing reset will be stale and will not reflect the
latest states in simulation caused by the reset.
* When this is greater than 0, the specified number of extra render steps will be performed to update the sensor data
to reflect the latest states from the reset. This comes at a cost of performance as additional render
steps will be performed after each time an environment is reset.
"""
wait_for_textures: bool = True
......
......@@ -5,6 +5,7 @@
import builtins
import torch
import warnings
from collections.abc import Sequence
from typing import Any
......@@ -190,6 +191,20 @@ class ManagerBasedEnv:
if self.cfg.export_io_descriptors:
self.export_IO_descriptors()
# show deprecation message for rerender_on_reset
if self.cfg.rerender_on_reset:
msg = (
"\033[93m\033[1m[DEPRECATION WARNING] ManagerBasedEnvCfg.rerender_on_reset is deprecated. Use"
" ManagerBasedEnvCfg.num_rerenders_on_reset instead.\033[0m"
)
warnings.warn(
msg,
FutureWarning,
stacklevel=2,
)
if self.cfg.num_rerenders_on_reset == 0:
self.cfg.num_rerenders_on_reset = 1
def __del__(self):
"""Cleanup for the environment."""
self.close()
......@@ -353,8 +368,9 @@ class ManagerBasedEnv:
self.scene.write_data_to_sim()
self.sim.forward()
# if sensors are added to the scene, make sure we render to reflect changes in reset
if self.sim.has_rtx_sensors() and self.cfg.rerender_on_reset:
self.sim.render()
if self.sim.has_rtx_sensors() and self.cfg.num_rerenders_on_reset > 0:
for _ in range(self.cfg.num_rerenders_on_reset):
self.sim.render()
# trigger recorder terms for post-reset calls
self.recorder_manager.record_post_reset(env_ids)
......@@ -413,8 +429,9 @@ class ManagerBasedEnv:
self.sim.forward()
# if sensors are added to the scene, make sure we render to reflect changes in reset
if self.sim.has_rtx_sensors() and self.cfg.rerender_on_reset:
self.sim.render()
if self.sim.has_rtx_sensors() and self.cfg.num_rerenders_on_reset > 0:
for _ in range(self.cfg.num_rerenders_on_reset):
self.sim.render()
# trigger recorder terms for post-reset calls
self.recorder_manager.record_post_reset(env_ids)
......
......@@ -115,6 +115,22 @@ class ManagerBasedEnvCfg:
to reflect the latest states from the reset. This comes at a cost of performance as an additional render
step will be performed after each time an environment is reset.
.. deprecated:: 2.3.1
This attribute is deprecated and will be removed in the future. Please use
:attr:`num_rerenders_on_reset` instead.
To get the same behaviour as setting this parameter to ``True`` or ``False``, set
:attr:`num_rerenders_on_reset` to 1 or 0, respectively.
"""
num_rerenders_on_reset: int = 0
"""Number of render steps to perform after reset. Defaults to 0, which means no render step will be performed after reset.
* When this is 0, no render step will be performed after reset. Data collected from sensors after performing reset will be stale and will not reflect the
latest states in simulation caused by the reset.
* When this is greater than 0, the specified number of extra render steps will be performed to update the sensor data
to reflect the latest states from the reset. This comes at a cost of performance as additional render
steps will be performed after each time an environment is reset.
"""
wait_for_textures: bool = True
......
......@@ -222,8 +222,9 @@ class ManagerBasedRLEnv(ManagerBasedEnv, gym.Env):
self._reset_idx(reset_env_ids)
# if sensors are added to the scene, make sure we render to reflect changes in reset
if self.sim.has_rtx_sensors() and self.cfg.rerender_on_reset:
self.sim.render()
if self.sim.has_rtx_sensors() and self.cfg.num_rerenders_on_reset > 0:
for _ in range(self.cfg.num_rerenders_on_reset):
self.sim.render()
# trigger recorder terms for post-reset calls
self.recorder_manager.record_post_reset(reset_env_ids)
......
[package]
# Note: Semantic Versioning is used: https://semver.org/
version = "0.11.7"
version = "0.11.8"
# Description
title = "Isaac Lab Environments"
......
Changelog
---------
0.11.8 (2025-11-06)
~~~~~~~~~~~~~~~~~~~~
Changed
^^^^^^^
* Changed to use of ``num_rerenders_on_reset`` and ``DLAA`` in visuomotor imitation learning environments.
0.11.7 (2025-10-22)
~~~~~~~~~~~~~~~~~~~~
......
......@@ -323,9 +323,9 @@ class ExhaustPipeGR1T2BaseEnvCfg(ManagerBasedRLEnvCfg):
self.sim.dt = 1 / 100
self.sim.render_interval = 2
# # Set settings for camera rendering
self.rerender_on_reset = True
self.sim.render.antialiasing_mode = "OFF" # disable dlss
# Set settings for camera rendering
self.num_rerenders_on_reset = 3
self.sim.render.antialiasing_mode = "DLAA" # Use DLAA for higher quality rendering
# List of image observations in policy observations
self.image_obs_list = ["robot_pov_cam"]
......@@ -359,8 +359,8 @@ class NutPourGR1T2BaseEnvCfg(ManagerBasedRLEnvCfg):
self.sim.render_interval = 2
# Set settings for camera rendering
self.rerender_on_reset = True
self.sim.render.antialiasing_mode = "OFF" # disable dlss
self.num_rerenders_on_reset = 3
self.sim.render.antialiasing_mode = "DLAA" # Use DLAA for higher quality rendering
# List of image observations in policy observations
self.image_obs_list = ["robot_pov_cam"]
......@@ -54,7 +54,7 @@ gym.register(
entry_point="isaaclab.envs:ManagerBasedRLEnv",
kwargs={
"env_cfg_entry_point": f"{__name__}.stack_ik_rel_visuomotor_env_cfg:FrankaCubeStackVisuomotorEnvCfg",
"robomimic_bc_cfg_entry_point": f"{agents.__name__}:robomimic/bc_rnn_image_84.json",
"robomimic_bc_cfg_entry_point": f"{agents.__name__}:robomimic/bc_rnn_image_200.json",
},
disable_env_checker=True,
)
......
......@@ -196,8 +196,8 @@
},
"obs_randomizer_class": "CropRandomizer",
"obs_randomizer_kwargs": {
"crop_height": 76,
"crop_width": 76,
"crop_height": 181,
"crop_width": 181,
"num_crops": 1,
"pos_enc": false
}
......
......@@ -153,8 +153,8 @@ class FrankaCubeStackVisuomotorCosmosEnvCfg(stack_ik_rel_visuomotor_env_cfg.Fran
)
# Set settings for camera rendering
self.rerender_on_reset = True
self.sim.render.antialiasing_mode = "OFF" # disable dlss
self.num_rerenders_on_reset = 1
self.sim.render.antialiasing_mode = "OFF"
# List of image observations in policy observations
self.image_obs_list = ["table_cam", "wrist_cam"]
......@@ -204,8 +204,8 @@ class FrankaCubeStackVisuomotorEnvCfg(stack_joint_pos_env_cfg.FrankaCubeStackEnv
self.scene.wrist_cam = CameraCfg(
prim_path="{ENV_REGEX_NS}/Robot/panda_hand/wrist_cam",
update_period=0.0,
height=84,
width=84,
height=200,
width=200,
data_types=["rgb", "distance_to_image_plane"],
spawn=sim_utils.PinholeCameraCfg(
focal_length=24.0, focus_distance=400.0, horizontal_aperture=20.955, clipping_range=(0.1, 2)
......@@ -219,8 +219,8 @@ class FrankaCubeStackVisuomotorEnvCfg(stack_joint_pos_env_cfg.FrankaCubeStackEnv
self.scene.table_cam = CameraCfg(
prim_path="{ENV_REGEX_NS}/table_cam",
update_period=0.0,
height=84,
width=84,
height=200,
width=200,
data_types=["rgb", "distance_to_image_plane"],
spawn=sim_utils.PinholeCameraCfg(
focal_length=24.0, focus_distance=400.0, horizontal_aperture=20.955, clipping_range=(0.1, 2)
......@@ -231,8 +231,8 @@ class FrankaCubeStackVisuomotorEnvCfg(stack_joint_pos_env_cfg.FrankaCubeStackEnv
)
# Set settings for camera rendering
self.rerender_on_reset = True
self.sim.render.antialiasing_mode = "OFF" # disable dlss
self.num_rerenders_on_reset = 3
self.sim.render.antialiasing_mode = "DLAA" # Use DLAA for higher quality rendering
# List of image observations in policy observations
self.image_obs_list = ["table_cam", "wrist_cam"]
......@@ -271,8 +271,8 @@ class RmpFlowGalbotLeftArmCubeStackVisuomotorEnvCfg(RmpFlowGalbotLeftArmCubeStac
)
# Set settings for camera rendering
self.rerender_on_reset = True
self.sim.render.antialiasing_mode = "OFF" # disable dlss
self.num_rerenders_on_reset = 3
self.sim.render.antialiasing_mode = "DLAA" # Use DLAA for higher quality rendering
# List of image observations in policy observations
self.image_obs_list = ["ego_cam", "left_wrist_cam", "right_wrist_cam"]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment