Unverified Commit 052c277b authored by David Hoeller's avatar David Hoeller Committed by GitHub

Fixes running environments with a single instance (#355)

# Description

This MR fixes running of single environments (`num_envs=1`). Previously,
in the `InteractiveScene` class, physics cloning happened when the
`replicate_physics` flag was set to True even if there was only one
environment.

Fixes [#199](https://github.com/NVIDIA-Omniverse/orbit/issues/199) and
[#203](https://github.com/NVIDIA-Omniverse/orbit/issues/203)

## Type of change

- Bug fix (non-breaking change which fixes an issue)

## Checklist

- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./orbit.sh --format`
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [ ] I have run all the tests with `./orbit.sh --test` and they pass
- [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 9c3f65f3
[package]
# Note: Semantic Versioning is used: https://semver.org/
version = "0.10.12"
version = "0.10.13"
# Description
title = "ORBIT framework for Robot Learning"
......
Changelog
---------
0.10.13 (2024-01-15)
~~~~~~~~~~~~~~~~~~~~
Fixed
^^^^^
* Fixed running of environments with a single instance even if the :attr:`replicate_physics`` flag is set to True.
0.10.12 (2024-01-10)
~~~~~~~~~~~~~~~~~~~~
......
......@@ -142,7 +142,7 @@ class InteractiveScene:
self._add_entities_from_cfg()
# 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:
if self.cfg.replicate_physics and self.cfg.num_envs > 1:
# in isaac sim 2022.2, this function is private
if isaac_major_version == 2022:
self.cloner._replicate_physics( # pyright: ignore [reportPrivateUsage]
......
......@@ -49,20 +49,48 @@ class TestEnvironments(unittest.TestCase):
# print all existing task names
print(">>> All registered environments:", cls.registered_tasks)
def setUp(self) -> None:
"""
Test fixtures.
"""
def test_multiple_instances_gpu(self):
"""Run all environments with multiple instances and check environments return valid signals."""
# common parameters
self.num_envs = 64
self.use_gpu = True
num_envs = 32
use_gpu = True
# iterate over all registered environments
for task_name in self.registered_tasks:
print(f">>> Running test for environment: {task_name}")
# check environment
self._check_random_actions(task_name, use_gpu, num_envs, num_steps=1000)
# close the environment
print(f">>> Closing environment: {task_name}")
print("-" * 80)
def test_random_actions(self):
"""Run random actions and check environments return valid signals."""
def test_single_instance_gpu(self):
"""Run all environments with single instance and check environments return valid signals."""
# common parameters
num_envs = 1
use_gpu = True
# iterate over all registered environments
for task_name in self.registered_tasks:
print(f">>> Running test for environment: {task_name}")
# check environment
self._check_random_actions(task_name, use_gpu, num_envs, num_steps=1000)
# close the environment
print(f">>> Closing environment: {task_name}")
print("-" * 80)
"""
Helper functions.
"""
def _check_random_actions(self, task_name: str, use_gpu: bool, num_envs: int, num_steps: int = 1000):
"""Run random actions and check environments return valid signals."""
# create a new stage
omni.usd.get_context().new_stage()
# parse configuration
env_cfg: RLTaskEnvCfg = parse_env_cfg(task_name, use_gpu=self.use_gpu, num_envs=self.num_envs)
env_cfg: RLTaskEnvCfg = parse_env_cfg(task_name, use_gpu=use_gpu, num_envs=num_envs)
# create environment
env: RLTaskEnv = gym.make(task_name, cfg=env_cfg)
......@@ -70,10 +98,9 @@ class TestEnvironments(unittest.TestCase):
obs, _ = env.reset()
# check signal
self.assertTrue(self._check_valid_tensor(obs))
# simulate environment for 1000 steps
# simulate environment for num_steps steps
with torch.inference_mode():
for _ in range(1000):
for _ in range(num_steps):
# sample actions from -1 to 1
actions = 2 * torch.rand(env.action_space.shape, device=env.unwrapped.device) - 1
# apply actions
......@@ -83,13 +110,8 @@ class TestEnvironments(unittest.TestCase):
self.assertTrue(self._check_valid_tensor(data), msg=f"Invalid data: {data}")
# close the environment
print(f">>> Closing environment: {task_name}")
env.close()
"""
Helper functions.
"""
@staticmethod
def _check_valid_tensor(data: torch.Tensor | dict) -> bool:
"""Checks if given data does not have corrupted values.
......
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