Unverified Commit 190fa854 authored by Kelly Guo's avatar Kelly Guo Committed by GitHub

Optimizes interactive scene for homogeneous cloning (#636)

# Description

Previously, we always assumed heterogeneous environment setup, which
performed cloning on a per-actor basis during spawning of actors. In
some direct workflow environments, a redundant cloning call was made at
the end of environment setup to perform cloning on a global scope.

With this change, we determine whether to perform cloning on a per-actor
or global scope based on the `replicate_physics` parameter in
`InteractiveSceneCfg`. When `replicate_physics=True`, homogeneous
environment is assumed and cloning will only happen on a global scope.
This reduces the time required for cloning for homogeneous setups. For
heterogeneous environments, set `replicate_physics=False` and cloning
will happen per-actor.

## Type of change

- Bug fix (non-breaking change which fixes an issue)
- New feature (non-breaking change which adds functionality)
- This change requires a documentation update

## 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
- [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
parent 07f082f5
[package]
# Note: Semantic Versioning is used: https://semver.org/
version = "0.19.1"
version = "0.19.2"
# Description
title = "Isaac Lab framework for Robot Learning"
......
Changelog
---------
0.19.2 (2024-07-05)
~~~~~~~~~~~~~~~~~~~
Changed
^^^^^^^
* Modified cloning scheme based on the attribute :attr:`~omni.isaac.lab.scene.InteractiveSceneCfg.replicate_physics` to determine whether environment is homogeneous or heterogeneous.
0.19.1 (2024-07-05)
~~~~~~~~~~~~~~~~~~~
......
......@@ -30,6 +30,22 @@ class InteractiveScene:
Based on the specified number of environments, it clones the entities and groups them into different
categories (e.g., articulations, sensors, etc.).
Cloning can be performed in two ways:
* For tasks where all environments contain the same assets, a more performant cloning paradigm
can be used to allow for faster environment creation. This is specified by the ``replicate_physics`` flag.
.. code-block:: python
scene = InteractiveScene(cfg=InteractiveSceneCfg(replicate_physics=True))
* For tasks that require having separate assets in the environments, ``replicate_physics`` would have to
be set to False, which will add some costs to the overall startup time.
.. code-block:: python
scene = InteractiveScene(cfg=InteractiveSceneCfg(replicate_physics=False))
Each entity is registered to scene based on its name in the configuration class. For example, if the user
specifies a robot in the configuration class as follows:
......@@ -59,6 +75,14 @@ class InteractiveScene:
# access the robot based on its type
robot = scene.articulations["robot"]
If the :class:`InteractiveSceneCfg` class does not include asset entities, the cloning process
can still be triggered if assets were added to the stage outside of the :class:`InteractiveScene` class:
.. code-block:: python
scene = InteractiveScene(cfg=InteractiveSceneCfg(num_envs=128, replicate_physics=True))
scene.clone_environments()
.. note::
It is important to note that the scene only performs common operations on the entities. For example,
resetting the internal buffers, writing the buffers to the simulation and updating the buffers from the
......@@ -92,18 +116,29 @@ class InteractiveScene:
self.env_prim_paths = self.cloner.generate_paths(f"{self.env_ns}/env", self.cfg.num_envs)
# create source prim
self.stage.DefinePrim(self.env_prim_paths[0], "Xform")
# clone the env xform
env_origins = self.cloner.clone(
source_prim_path=self.env_prim_paths[0],
prim_paths=self.env_prim_paths,
replicate_physics=False,
copy_from_source=True,
)
self._default_env_origins = torch.tensor(env_origins, device=self.device, dtype=torch.float32)
# when replicate_physics=False, we assume heterogeneous environments and clone the xforms first.
# this triggers per-object level cloning in the spawner.
if not self.cfg.replicate_physics:
# clone the env xform
env_origins = self.cloner.clone(
source_prim_path=self.env_prim_paths[0],
prim_paths=self.env_prim_paths,
replicate_physics=False,
copy_from_source=True,
)
self._default_env_origins = torch.tensor(env_origins, device=self.device, dtype=torch.float32)
else:
# otherwise, environment origins will be initialized during cloning at the end of environment creation
self._default_env_origins = None
self._global_prim_paths = list()
if self._is_scene_setup_from_cfg():
# add entities from config
self._add_entities_from_cfg()
# clone environments on a global scope if environment is homogeneous
if self.cfg.replicate_physics:
self.clone_environments(copy_from_source=False)
# replicate physics if we have more than one environment
# this is done to make scene initialization faster at play time
if self.cfg.replicate_physics and self.cfg.num_envs > 1:
......@@ -128,31 +163,47 @@ class InteractiveScene:
If True, clones are independent copies of the source prim and won't reflect its changes (start-up time
may increase). Defaults to False.
"""
self.cloner.clone(
env_origins = self.cloner.clone(
source_prim_path=self.env_prim_paths[0],
prim_paths=self.env_prim_paths,
replicate_physics=self.cfg.replicate_physics,
copy_from_source=copy_from_source,
)
def filter_collisions(self, global_prim_paths: list[str] = []):
# in case of heterogeneous cloning, the env origins is specified at init
if self._default_env_origins is None:
self._default_env_origins = torch.tensor(env_origins, device=self.device, dtype=torch.float32)
def filter_collisions(self, global_prim_paths: list[str] | None = None):
"""Filter environments collisions.
Disables collisions between the environments in ``/World/envs/env_.*`` and enables collisions with the prims
in global prim paths (e.g. ground plane).
Args:
global_prim_paths: The global prim paths to enable collisions with.
global_prim_paths: A list of global prim paths to enable collisions with.
Defaults to None, in which case no global prim paths are considered.
"""
# obtain the current physics scene
physics_scene_prim_path = self.physics_scene_path
# validate paths in global prim paths
if global_prim_paths is None:
global_prim_paths = []
else:
# remove duplicates in paths
global_prim_paths = list(set(global_prim_paths))
# set global prim paths list if not previously defined
if len(self._global_prim_paths) < 1:
self._global_prim_paths += global_prim_paths
# filter collisions within each environment instance
self.cloner.filter_collisions(
physics_scene_prim_path,
"/World/collisions",
self.env_prim_paths,
global_paths=global_prim_paths,
global_paths=self._global_prim_paths,
)
def __str__(self) -> str:
......
......@@ -85,4 +85,15 @@ class InteractiveSceneCfg:
"""
replicate_physics: bool = True
"""Enable/disable replication of physics schemas when using the Cloner APIs. Default is True."""
"""Enable/disable replication of physics schemas when using the Cloner APIs. Default is True.
If True, the simulation will have the same asset instances (USD prims) in all the cloned environments.
Internally, this ensures optimization in setting up the scene and parsing it via the physics stage parser.
If False, the simulation allows having separate asset instances (USD prims) in each environment.
This flexibility comes at a cost of slowdowns in setting up and parsing the scene.
.. note::
Optimized parsing of certain prim types (such as deformable objects) is not currently supported
by the physics engine. In these cases, this flag needs to be set to False.
"""
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