Unverified Commit 71c81cbf authored by AutonomousHansen's avatar AutonomousHansen Committed by GitHub

Drops support for Isaac Sim 2022.2.2 and earlier (#431)

# Description

Fully deprecates Isaac 2022.2 and Python3.7. Removes all
checks/accommodations for 2022.2, defaults to 2023.1 behavior. Also
changes `.env` to default to `ISAACSIM_VERSION` 2023.1.1.

Fixes #393 

## Type of change

- Breaking change (fix or feature that would cause existing
functionality to not work as expected)

## Checklist

- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./orbit.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 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

<!--
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 avatarAutonomousHansen <50837800+AutonomousHansen@users.noreply.github.com>
Signed-off-by: 's avatarMayank Mittal <12863862+Mayankm96@users.noreply.github.com>
Co-authored-by: 's avatarMayank Mittal <12863862+Mayankm96@users.noreply.github.com>
Co-authored-by: 's avatarMayank Mittal <mittalma@leggedrobotics.com>
parent 203cbefe
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# Orbit # Orbit
[![IsaacSim](https://img.shields.io/badge/IsaacSim-2023.1.0--hotfix.1-silver.svg)](https://docs.omniverse.nvidia.com/isaacsim/latest/overview.html) [![IsaacSim](https://img.shields.io/badge/IsaacSim-2023.1.1-silver.svg)](https://docs.omniverse.nvidia.com/isaacsim/latest/overview.html)
[![Python](https://img.shields.io/badge/python-3.10-blue.svg)](https://docs.python.org/3/whatsnew/3.10.html) [![Python](https://img.shields.io/badge/python-3.10-blue.svg)](https://docs.python.org/3/whatsnew/3.10.html)
[![Linux platform](https://img.shields.io/badge/platform-linux--64-orange.svg)](https://releases.ubuntu.com/20.04/) [![Linux platform](https://img.shields.io/badge/platform-linux--64-orange.svg)](https://releases.ubuntu.com/20.04/)
[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://pre-commit.com/) [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://pre-commit.com/)
......
# Accept the NVIDIA Omniverse EULA by default # Accept the NVIDIA Omniverse EULA by default
ACCEPT_EULA=Y ACCEPT_EULA=Y
# NVIDIA Isaac Sim version to use (e.g. 2022.2.1) # NVIDIA Isaac Sim version to use (e.g. 2023.1.1, 2023.1.0-hotfix.1)
ISAACSIM_VERSION=2023.1.0-hotfix.1 ISAACSIM_VERSION=2023.1.1
# Derived from the default path in the NVIDIA provided Isaac Sim container # Derived from the default path in the NVIDIA provided Isaac Sim container
DOCKER_ISAACSIM_PATH=/isaac-sim DOCKER_ISAACSIM_PATH=/isaac-sim
# Docker user directory - by default this is the root user's home directory # Docker user directory - by default this is the root user's home directory
......
...@@ -222,7 +222,7 @@ html_theme_options = { ...@@ -222,7 +222,7 @@ html_theme_options = {
{ {
"name": "Isaac Sim", "name": "Isaac Sim",
"url": "https://developer.nvidia.com/isaac-sim", "url": "https://developer.nvidia.com/isaac-sim",
"icon": "https://img.shields.io/badge/IsaacSim-2023.1.0-silver.svg", "icon": "https://img.shields.io/badge/IsaacSim-2023.1.1-silver.svg",
"type": "url", "type": "url",
}, },
{ {
......
Installation Guide Installation Guide
=================== ===================
.. image:: https://img.shields.io/badge/IsaacSim-2023.1.0--hotfix.1-silver.svg .. image:: https://img.shields.io/badge/IsaacSim-2023.1.1-silver.svg
:target: https://developer.nvidia.com/isaac-sim :target: https://developer.nvidia.com/isaac-sim
:alt: IsaacSim 2023.1.0 :alt: IsaacSim 2023.1.1
.. image:: https://img.shields.io/badge/python-3.10-blue.svg .. image:: https://img.shields.io/badge/python-3.10-blue.svg
:target: https://www.python.org/downloads/release/python-31013/ :target: https://www.python.org/downloads/release/python-31013/
...@@ -20,9 +20,8 @@ Installing Isaac Sim ...@@ -20,9 +20,8 @@ Installing Isaac Sim
.. caution:: .. caution::
While the framework contains some backwards compatibility for Isaac Sim 2022.2.1, we recommend using We have dropped support for Isaac Sim versions 2022.2 and below. We recommend using the latest Isaac Sim
the latest Isaac Sim 2023.1 release. This release contains various improvements on the 2023.1 releases (``2023.1.0-hotfix.1`` or ``2023.1.1``).
simulation side, and is the recommended version to use with Orbit.
For more information, please refer to the For more information, please refer to the
`Isaac Sim release notes <https://docs.omniverse.nvidia.com/isaacsim/latest/release_notes.html>`__. `Isaac Sim release notes <https://docs.omniverse.nvidia.com/isaacsim/latest/release_notes.html>`__.
......
...@@ -75,7 +75,7 @@ custom arguments and those from :class:`~app.AppLauncher`. ...@@ -75,7 +75,7 @@ custom arguments and those from :class:`~app.AppLauncher`.
[INFO] Using python from: /isaac-sim/python.sh [INFO] Using python from: /isaac-sim/python.sh
[INFO][AppLauncher]: The argument 'width' will be used to configure the SimulationApp. [INFO][AppLauncher]: The argument 'width' will be used to configure the SimulationApp.
[INFO][AppLauncher]: The argument 'height' will be used to configure the SimulationApp. [INFO][AppLauncher]: The argument 'height' will be used to configure the SimulationApp.
usage: launch_app.py [-h] [--size SIZE] [--width WIDTH] [--height HEIGHT] [--headless] [--livestream {0,1,2,3}] [--ros {0,1,2}] usage: launch_app.py [-h] [--size SIZE] [--width WIDTH] [--height HEIGHT] [--headless] [--livestream {0,1,2,3}]
[--offscreen_render] [--offscreen_render]
Tutorial on running IsaacSim via the AppLauncher. Tutorial on running IsaacSim via the AppLauncher.
...@@ -90,7 +90,6 @@ custom arguments and those from :class:`~app.AppLauncher`. ...@@ -90,7 +90,6 @@ custom arguments and those from :class:`~app.AppLauncher`.
--headless Force display off at all times. --headless Force display off at all times.
--livestream {0,1,2,3} --livestream {0,1,2,3}
Force enable livestreaming. Mapping corresponds to that for the "LIVESTREAM" environment variable. Force enable livestreaming. Mapping corresponds to that for the "LIVESTREAM" environment variable.
--ros {0,1,2} Enable ROS middleware. Mapping corresponds to that for the "ROS_ENABLED" environment variable
--offscreen_render Enable offscreen rendering when running without a GUI. --offscreen_render Enable offscreen rendering when running without a GUI.
This readout details the ``--size``, ``--height``, and ``--width`` arguments defined in the script directly, This readout details the ``--size``, ``--height``, and ``--width`` arguments defined in the script directly,
...@@ -106,7 +105,7 @@ for more examples. ...@@ -106,7 +105,7 @@ for more examples.
Using environment variables Using environment variables
^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
As noted in the help message, the :class:`~app.AppLauncher` arguments (``--livestream``, ``--ros``) As noted in the help message, the :class:`~app.AppLauncher` arguments (``--livestream``, ``--headless``)
have corresponding environment variables (envar) as well. These are detailed in :mod:`omni.isaac.orbit.app` have corresponding environment variables (envar) as well. These are detailed in :mod:`omni.isaac.orbit.app`
documentation. Providing any of these arguments through CLI is equivalent to running the script in a shell documentation. Providing any of these arguments through CLI is equivalent to running the script in a shell
environment where the corresponding envar is set. environment where the corresponding envar is set.
......
[package] [package]
# Note: Semantic Versioning is used: https://semver.org/ # Note: Semantic Versioning is used: https://semver.org/
version = "0.10.28" version = "0.11.0"
# Description # Description
title = "ORBIT framework for Robot Learning" title = "ORBIT framework for Robot Learning"
......
Changelog Changelog
--------- ---------
0.11.0 (2024-02-27)
~~~~~~~~~~~~~~~~~~~
Removed
^^^^^^^
* Dropped support for Isaac Sim<=2022.2. As part of this, removed the components of :class:`omni.isaac.orbit.app.AppLauncher`
which handled ROS extension loading. We no longer need them in Isaac Sim>=2023.1 to control the load order to avoid crashes.
* Upgraded Dockerfile to use ISAACSIM_VERSION=2023.1.1 by default.
0.10.28 (2024-02-29) 0.10.28 (2024-02-29)
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
......
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
"""Sub-package with the utility class to configure the :class:`omni.isaac.kit.SimulationApp`. """Sub-package with the utility class to configure the :class:`omni.isaac.kit.SimulationApp`.
Based on the desired functionality, this class parses environment variables and input CLI arguments Based on the desired functionality, this class parses environment variables and input CLI arguments
to launch the simulator in various different modes. This includes with or without GUI, switching between to launch the simulator in various different modes. This includes with or without GUI and switching between
different Omniverse remote clients, and enabling particular ROS bridges. Some of these require the different Omniverse remote clients. Some of these require the
extensions to be loaded in a specific order, otherwise a segmentation fault occurs. extensions to be loaded in a specific order, otherwise a segmentation fault occurs.
The launched `SimulationApp`_ instance is accessible via the :attr:`AppLauncher.app` property. The launched `SimulationApp`_ instance is accessible via the :attr:`AppLauncher.app` property.
...@@ -31,18 +31,6 @@ The following details the behavior of the class based on the environment variabl ...@@ -31,18 +31,6 @@ The following details the behavior of the class based on the environment variabl
* ``LIVESTREAM=3`` enables streaming via the `WebRTC Livestream`_ extension. This allows users to * ``LIVESTREAM=3`` enables streaming via the `WebRTC Livestream`_ extension. This allows users to
connect in a browser using the WebRTC protocol. connect in a browser using the WebRTC protocol.
* **Loading ROS Bridge**: If the environment variable ``ROS_ENABLED`` is set to non-zero, then the
following behavior happens:
* ``ROS_ENABLED=1``: Enables the ROS1 Noetic bridge in Isaac Sim.
* ``ROS_ENABLED=2``: Enables the ROS2 Foxy bridge in Isaac Sim.
.. caution::
In Isaac Sim 2022.2.1, loading ``omni.isaac.ros_bridge`` before ``omni.kit.livestream.native``
causes a segfault. Thus, to work around this issue, we enable the ROS-bridge extensions after the
livestreaming extensions.
* **Offscreen Render**: If the environment variable ``OFFSCREEN_RENDER`` is set to 1, then the * **Offscreen Render**: If the environment variable ``OFFSCREEN_RENDER`` is set to 1, then the
offscreen-render pipeline is enabled. This is useful for running the simulator without a GUI but offscreen-render pipeline is enabled. This is useful for running the simulator without a GUI but
still rendering the viewport and camera images. still rendering the viewport and camera images.
...@@ -168,7 +156,7 @@ class AppLauncher: ...@@ -168,7 +156,7 @@ class AppLauncher:
ValueError: If combination of ``launcher_args`` and ``kwargs`` are missing the necessary arguments ValueError: If combination of ``launcher_args`` and ``kwargs`` are missing the necessary arguments
that are needed by the AppLauncher to resolve the desired app configuration. that are needed by the AppLauncher to resolve the desired app configuration.
ValueError: If incompatible or undefined values are assigned to relevant environment values, ValueError: If incompatible or undefined values are assigned to relevant environment values,
such as ``LIVESTREAM`` and ``ROS_ENABLED``. such as ``LIVESTREAM``.
.. _argparse.Namespace: https://docs.python.org/3/library/argparse.html?highlight=namespace#argparse.Namespace .. _argparse.Namespace: https://docs.python.org/3/library/argparse.html?highlight=namespace#argparse.Namespace
.. _SimulationApp: https://docs.omniverse.nvidia.com/py/isaacsim/source/extensions/omni.isaac.kit/docs/index.html .. _SimulationApp: https://docs.omniverse.nvidia.com/py/isaacsim/source/extensions/omni.isaac.kit/docs/index.html
...@@ -183,7 +171,7 @@ class AppLauncher: ...@@ -183,7 +171,7 @@ class AppLauncher:
# and will be passed directly to the SimulationApp initialization. # and will be passed directly to the SimulationApp initialization.
# #
# We could potentially require users to enter each argument they want passed here # We could potentially require users to enter each argument they want passed here
# as a kwarg, but this would require them to pass livestream, headless, ros, and # as a kwarg, but this would require them to pass livestream, headless, and
# any other options we choose to add here explicitly, and with the correct keywords. # any other options we choose to add here explicitly, and with the correct keywords.
# #
# @hunter: I feel that this is cumbersome and could introduce error, and would prefer to do # @hunter: I feel that this is cumbersome and could introduce error, and would prefer to do
...@@ -207,7 +195,6 @@ class AppLauncher: ...@@ -207,7 +195,6 @@ class AppLauncher:
# Define config members that are read from env-vars or keyword args # Define config members that are read from env-vars or keyword args
self._headless: bool # 0: GUI, 1: Headless self._headless: bool # 0: GUI, 1: Headless
self._livestream: Literal[0, 1, 2, 3] # 0: Disabled, 1: Native, 2: Websocket, 3: WebRTC self._livestream: Literal[0, 1, 2, 3] # 0: Disabled, 1: Native, 2: Websocket, 3: WebRTC
self._ros: Literal[0, 1, 2] # 0: Disabled, 1: ROS1, 2: ROS2
self._offscreen_render: bool # 0: Disabled, 1: Enabled self._offscreen_render: bool # 0: Disabled, 1: Enabled
# Integrate env-vars and input keyword args into simulation app config # Integrate env-vars and input keyword args into simulation app config
...@@ -252,9 +239,6 @@ class AppLauncher: ...@@ -252,9 +239,6 @@ class AppLauncher:
* ``livestream`` (int): If one of {0, 1, 2, 3}, then livestreaming and headless mode is enabled. The values * ``livestream`` (int): If one of {0, 1, 2, 3}, then livestreaming and headless mode is enabled. The values
map the same as that for the ``LIVESTREAM`` environment variable. If :obj:`-1`, then livestreaming is map the same as that for the ``LIVESTREAM`` environment variable. If :obj:`-1`, then livestreaming is
determined by the ``LIVESTREAM`` environment variable. determined by the ``LIVESTREAM`` environment variable.
* ``ros`` (int): If one of {0, 1, 2}, then the corresponding ROS bridge is enabled. The values
map the same as that for the ``ROS_ENABLED`` environment variable. If :obj:`-1`, then ROS bridge is
determined by the ``ROS_ENABLED`` environment variable.
* ``offscreen_render`` (bool): If True, the app will be launched in offscreen-render mode. The values * ``offscreen_render`` (bool): If True, the app will be launched in offscreen-render mode. The values
map the same as that for the ``OFFSCREEN_RENDER`` environment variable. If False, then offscreen-render map the same as that for the ``OFFSCREEN_RENDER`` environment variable. If False, then offscreen-render
mode is determined by the ``OFFSCREEN_RENDER`` environment variable. mode is determined by the ``OFFSCREEN_RENDER`` environment variable.
...@@ -308,13 +292,6 @@ class AppLauncher: ...@@ -308,13 +292,6 @@ class AppLauncher:
choices={0, 1, 2, 3}, choices={0, 1, 2, 3},
help="Force enable livestreaming. Mapping corresponds to that for the `LIVESTREAM` environment variable.", help="Force enable livestreaming. Mapping corresponds to that for the `LIVESTREAM` environment variable.",
) )
arg_group.add_argument(
"--ros",
type=int,
default=AppLauncher._APPLAUNCHER_CFG_INFO["ros"][1],
choices={0, 1, 2},
help="Enable ROS middleware. Mapping corresponds to that for the `ROS_ENABLED` environment variable",
)
arg_group.add_argument( arg_group.add_argument(
"--offscreen_render", "--offscreen_render",
action="store_true", action="store_true",
...@@ -335,7 +312,6 @@ class AppLauncher: ...@@ -335,7 +312,6 @@ class AppLauncher:
_APPLAUNCHER_CFG_INFO: dict[str, tuple[list[type], Any]] = { _APPLAUNCHER_CFG_INFO: dict[str, tuple[list[type], Any]] = {
"headless": ([bool], False), "headless": ([bool], False),
"livestream": ([int], -1), "livestream": ([int], -1),
"ros": ([int], -1),
"offscreen_render": ([bool], False), "offscreen_render": ([bool], False),
} }
"""A dictionary of arguments added manually by the :meth:`AppLauncher.add_app_launcher_args` method. """A dictionary of arguments added manually by the :meth:`AppLauncher.add_app_launcher_args` method.
...@@ -497,32 +473,6 @@ class AppLauncher: ...@@ -497,32 +473,6 @@ class AppLauncher:
# Headless needs to be passed to the SimulationApp so we keep it here # Headless needs to be passed to the SimulationApp so we keep it here
launcher_args["headless"] = self._headless launcher_args["headless"] = self._headless
# --ROS logic--
#
ros_env = int(os.environ.get("ROS_ENABLED", 0))
ros_arg = int(launcher_args.pop("ros", AppLauncher._APPLAUNCHER_CFG_INFO["ros"][1]))
ros_valid_vals = {0, 1, 2}
# Value checking on LIVESTREAM
if ros_env not in ros_valid_vals:
raise ValueError(
f"Invalid value for environment variable `ROS_ENABLED`: {ros_env} . Expected: {ros_valid_vals}."
)
# We allow livestream kwarg to supersede LIVESTREAM envvar
if ros_arg >= 0:
if ros_arg in ros_valid_vals:
self._ros = ros_arg
# print info that we overrode the env-var
print(
f"[INFO][AppLauncher]: Input keyword argument `ros={ros_arg}` has overridden"
f" the environment variable `ROS_ENABLED={ros_env}`."
)
else:
raise ValueError(
f"Invalid value for input keyword argument `ros`: {ros_arg} . Expected: {ros_valid_vals}."
)
else:
self._ros = ros_env
# --OFFSCREEN_RENDER logic-- # --OFFSCREEN_RENDER logic--
# #
# off-screen rendering # off-screen rendering
...@@ -577,10 +527,7 @@ class AppLauncher: ...@@ -577,10 +527,7 @@ class AppLauncher:
# These have to be loaded after SimulationApp is initialized # These have to be loaded after SimulationApp is initialized
import carb import carb
from omni.isaac.core.utils.extensions import enable_extension from omni.isaac.core.utils.extensions import enable_extension
from omni.isaac.version import get_version
# Read isaac sim version (this includes build tag, release tag etc.)
isaacsim_version = get_version()
# Retrieve carb settings for modification # Retrieve carb settings for modification
carb_settings_iface = carb.settings.get_settings() carb_settings_iface = carb.settings.get_settings()
...@@ -613,17 +560,6 @@ class AppLauncher: ...@@ -613,17 +560,6 @@ class AppLauncher:
else: else:
carb_settings_iface.set_bool("/app/livestream/enabled", False) carb_settings_iface.set_bool("/app/livestream/enabled", False)
# As of IsaacSim 2022.1.1, the ros extension has to be loaded
# after the streaming extension or it will cause a segfault
# Note: Only one ROS bridge extension can be enabled at a time
if self._ros != 0:
if self._ros == 1:
enable_extension("omni.isaac.ros_bridge")
elif self._ros == 2:
enable_extension("omni.isaac.ros2_bridge")
else:
raise ValueError(f"Invalid value for ros: {self._ros}. Expected: 1, 2 .")
# set carb setting to indicate orbit's offscreen_render pipeline should be enabled # set carb setting to indicate orbit's offscreen_render pipeline should be enabled
# this flag is used by the SimulationContext class to enable the offscreen_render pipeline # this flag is used by the SimulationContext class to enable the offscreen_render pipeline
# when the render() method is called. # when the render() method is called.
...@@ -656,9 +592,8 @@ class AppLauncher: ...@@ -656,9 +592,8 @@ class AppLauncher:
# enable animation recording extension # enable animation recording extension
enable_extension("omni.kit.stagerecorder.core") enable_extension("omni.kit.stagerecorder.core")
# set the nucleus directory manually to the 2023.1.0 version # set the nucleus directory manually to the latest published Nucleus
# TODO: Remove this once the 2023.1.0 version is released # note: this is done to ensure prior versions of Isaac Sim still use the latest assets
if int(isaacsim_version[2]) == 2023:
carb_settings_iface.set_string( carb_settings_iface.set_string(
"/persistent/isaac/asset_root/default", "/persistent/isaac/asset_root/default",
"http://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/2023.1.1", "http://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/2023.1.1",
......
...@@ -15,7 +15,6 @@ import omni.isaac.core.utils.prims as prim_utils ...@@ -15,7 +15,6 @@ import omni.isaac.core.utils.prims as prim_utils
import omni.kit import omni.kit
from omni.isaac.core.materials import PhysicsMaterial from omni.isaac.core.materials import PhysicsMaterial
from omni.isaac.core.prims import GeometryPrim from omni.isaac.core.prims import GeometryPrim
from omni.isaac.version import get_version
from pxr import Gf, PhysxSchema, UsdPhysics, UsdShade from pxr import Gf, PhysxSchema, UsdPhysics, UsdShade
...@@ -102,10 +101,7 @@ def create_ground_plane( ...@@ -102,10 +101,7 @@ def create_ground_plane(
# Warning: This is specific to the default grid plane asset. # Warning: This is specific to the default grid plane asset.
ambient_light = kwargs.get("ambient_light", True) ambient_light = kwargs.get("ambient_light", True)
if ambient_light: if ambient_light:
# check isaacsim version to determine the attribute name
attributes = {"intensity": 600.0} attributes = {"intensity": 600.0}
isaacsim_version = get_version()
if int(isaacsim_version[2]) > 2022:
attributes = {f"inputs:{k}": v for k, v in attributes.items()} attributes = {f"inputs:{k}": v for k, v in attributes.items()}
# create light prim # create light prim
prim_utils.create_prim(f"{prim_path}/AmbientLight", "DistantLight", attributes=attributes) prim_utils.create_prim(f"{prim_path}/AmbientLight", "DistantLight", attributes=attributes)
......
...@@ -14,7 +14,6 @@ import carb ...@@ -14,7 +14,6 @@ import carb
import omni.usd import omni.usd
from omni.isaac.cloner import GridCloner from omni.isaac.cloner import GridCloner
from omni.isaac.core.prims import XFormPrimView from omni.isaac.core.prims import XFormPrimView
from omni.isaac.version import get_version
from pxr import PhysxSchema from pxr import PhysxSchema
import omni.isaac.orbit.sim as sim_utils import omni.isaac.orbit.sim as sim_utils
...@@ -103,11 +102,6 @@ class InteractiveScene: ...@@ -103,11 +102,6 @@ class InteractiveScene:
def __init__(self, cfg: InteractiveSceneCfg): def __init__(self, cfg: InteractiveSceneCfg):
"""Initializes the scene. """Initializes the scene.
.. note::
In Isaac Sim 2022.2, we do not have a way to copy the prim from source. It is always inherited.
Thus, it is not possible to have a scene with multiple environments with different assets (or
as we call heterogeneous environments). This limitation is fixed in Isaac Sim 2023.1.
Args: Args:
cfg: The configuration class for the scene. cfg: The configuration class for the scene.
""" """
...@@ -121,17 +115,7 @@ class InteractiveScene: ...@@ -121,17 +115,7 @@ class InteractiveScene:
self.env_prim_paths = self.cloner.generate_paths(f"{self.env_ns}/env", self.cfg.num_envs) self.env_prim_paths = self.cloner.generate_paths(f"{self.env_ns}/env", self.cfg.num_envs)
# create source prim # create source prim
self.stage.DefinePrim(self.env_prim_paths[0], "Xform") self.stage.DefinePrim(self.env_prim_paths[0], "Xform")
# obtain major isaac sim version
isaac_major_version = int(get_version()[2])
# clone the env xform # clone the env xform
# in isaac sim 2022.2, we do not have a way to copy the prim from source. it is always inherited.
if isaac_major_version == 2022:
env_origins = self.cloner.clone(
source_prim_path=self.env_prim_paths[0],
prim_paths=self.env_prim_paths,
replicate_physics=False,
)
else:
env_origins = self.cloner.clone( env_origins = self.cloner.clone(
source_prim_path=self.env_prim_paths[0], source_prim_path=self.env_prim_paths[0],
prim_paths=self.env_prim_paths, prim_paths=self.env_prim_paths,
...@@ -144,15 +128,6 @@ class InteractiveScene: ...@@ -144,15 +128,6 @@ class InteractiveScene:
# replicate physics if we have more than one environment # replicate physics if we have more than one environment
# this is done to make scene initialization faster at play time # this is done to make scene initialization faster at play time
if self.cfg.replicate_physics and self.cfg.num_envs > 1: 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]
source_prim_path=self.env_prim_paths[0],
prim_paths=self.env_prim_paths,
base_env_path=self.env_ns,
root_path=self.env_regex_ns.replace(".*", ""),
)
else:
self.cloner.replicate_physics( self.cloner.replicate_physics(
source_prim_path=self.env_prim_paths[0], source_prim_path=self.env_prim_paths[0],
prim_paths=self.env_prim_paths, prim_paths=self.env_prim_paths,
......
...@@ -88,8 +88,4 @@ class InteractiveSceneCfg: ...@@ -88,8 +88,4 @@ class InteractiveSceneCfg:
replicate_physics: bool = True 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.
Note:
In Isaac Sim 2022.2.0, domain randomization of material properties is not supported when
``replicate_physics`` is set to True.
""" """
...@@ -12,7 +12,6 @@ import omni ...@@ -12,7 +12,6 @@ import omni
import omni.kit.commands import omni.kit.commands
import omni.usd import omni.usd
from omni.isaac.core.utils.extensions import enable_extension from omni.isaac.core.utils.extensions import enable_extension
from omni.isaac.version import get_version
from pxr import Gf, Usd, UsdGeom, UsdPhysics, UsdUtils from pxr import Gf, Usd, UsdGeom, UsdPhysics, UsdUtils
from omni.isaac.orbit.sim.converters.asset_converter_base import AssetConverterBase from omni.isaac.orbit.sim.converters.asset_converter_base import AssetConverterBase
...@@ -93,22 +92,11 @@ class MeshConverter(AssetConverterBase): ...@@ -93,22 +92,11 @@ class MeshConverter(AssetConverterBase):
# Open converted USD stage # Open converted USD stage
# note: This opens a new stage and does not use the stage created earlier by the user # note: This opens a new stage and does not use the stage created earlier by the user
# TODO: Fix this in Isaac 2023 using Usd.Stage.Open and update MovePrim commands to take in opened stage
isaacsim_major_version = int(get_version()[2])
if isaacsim_major_version == 2022:
omni.usd.get_context().open_stage(self.usd_path)
stage = omni.usd.get_context().get_stage()
# we do not need to cache as we use opened stage
stage_id = None
# no kwargs for 2022
stage_kwargs = {}
stage_or_context_kwargs = {}
else:
# create a new stage # create a new stage
stage = Usd.Stage.Open(self.usd_path) stage = Usd.Stage.Open(self.usd_path)
# add USD to stage cache # add USD to stage cache
stage_id = UsdUtils.StageCache.Get().Insert(stage) stage_id = UsdUtils.StageCache.Get().Insert(stage)
# need to make kwargs for compatibility with 2022 # need to make kwargs for compatibility with 2023
stage_kwargs = {"stage": stage} stage_kwargs = {"stage": stage}
stage_or_context_kwargs = {"stage_or_context": stage} stage_or_context_kwargs = {"stage_or_context": stage}
# FIXME: we need to hack this into command because Kit 105 has a bug. # FIXME: we need to hack this into command because Kit 105 has a bug.
......
...@@ -10,7 +10,6 @@ import os ...@@ -10,7 +10,6 @@ import os
import omni.kit.commands import omni.kit.commands
import omni.usd import omni.usd
from omni.isaac.core.utils.extensions import enable_extension from omni.isaac.core.utils.extensions import enable_extension
from omni.isaac.version import get_version
from pxr import Usd from pxr import Usd
from .asset_converter_base import AssetConverterBase from .asset_converter_base import AssetConverterBase
...@@ -106,14 +105,7 @@ class UrdfConverter(AssetConverterBase): ...@@ -106,14 +105,7 @@ class UrdfConverter(AssetConverterBase):
Returns: Returns:
The constructed ``ImportConfig`` object containing the desired settings. The constructed ``ImportConfig`` object containing the desired settings.
""" """
# check if the urdf importer extension is available # Enable urdf extension
# note: the urdf importer's name changed in 2023.1 onwards
isaacsim_version = get_version()
if int(isaacsim_version[2]) == 2022:
enable_extension("omni.isaac.urdf")
from omni.isaac.urdf import _urdf as omni_urdf
else:
enable_extension("omni.importer.urdf") enable_extension("omni.importer.urdf")
from omni.importer.urdf import _urdf as omni_urdf from omni.importer.urdf import _urdf as omni_urdf
......
...@@ -59,10 +59,6 @@ class PhysxCfg: ...@@ -59,10 +59,6 @@ class PhysxCfg:
Each physics actor in Omniverse specifies its own solver iteration count. The solver takes Each physics actor in Omniverse specifies its own solver iteration count. The solver takes
the number of iterations specified by the actor with the highest iteration and clamps it to the number of iterations specified by the actor with the highest iteration and clamps it to
the range ``[min_position_iteration_count, max_position_iteration_count]``. the range ``[min_position_iteration_count, max_position_iteration_count]``.
.. versionchanged:: 2022.2
In Isaac Sim 2022.2.0, this parameter is used for setting both position and velocity iterations count.
""" """
max_position_iteration_count: int = 255 max_position_iteration_count: int = 255
...@@ -73,10 +69,6 @@ class PhysxCfg: ...@@ -73,10 +69,6 @@ class PhysxCfg:
Each physics actor in Omniverse specifies its own solver iteration count. The solver takes Each physics actor in Omniverse specifies its own solver iteration count. The solver takes
the number of iterations specified by the actor with the highest iteration and clamps it to the number of iterations specified by the actor with the highest iteration and clamps it to
the range ``[min_position_iteration_count, max_position_iteration_count]``. the range ``[min_position_iteration_count, max_position_iteration_count]``.
.. versionchanged:: 2022.2
In Isaac Sim 2022.2.0, this parameter is used for setting both position and velocity iterations count.
""" """
min_velocity_iteration_count: int = 0 min_velocity_iteration_count: int = 0
...@@ -87,10 +79,6 @@ class PhysxCfg: ...@@ -87,10 +79,6 @@ class PhysxCfg:
Each physics actor in Omniverse specifies its own solver iteration count. The solver takes Each physics actor in Omniverse specifies its own solver iteration count. The solver takes
the number of iterations specified by the actor with the highest iteration and clamps it to the number of iterations specified by the actor with the highest iteration and clamps it to
the range ``[min_velocity_iteration_count, max_velocity_iteration_count]``. the range ``[min_velocity_iteration_count, max_velocity_iteration_count]``.
.. versionadded:: 2023.1
This parameter is introduced in 2023.1.0. For older versions, please use :obj:`min_position_iteration_count`.
""" """
max_velocity_iteration_count: int = 255 max_velocity_iteration_count: int = 255
...@@ -101,10 +89,6 @@ class PhysxCfg: ...@@ -101,10 +89,6 @@ class PhysxCfg:
Each physics actor in Omniverse specifies its own solver iteration count. The solver takes Each physics actor in Omniverse specifies its own solver iteration count. The solver takes
the number of iterations specified by the actor with the highest iteration and clamps it to the number of iterations specified by the actor with the highest iteration and clamps it to
the range ``[min_velocity_iteration_count, max_velocity_iteration_count]``. the range ``[min_velocity_iteration_count, max_velocity_iteration_count]``.
.. versionadded:: 2023.1
This parameter is introduced in 2023.1.0. For older versions, please use :obj:`max_position_iteration_count`.
""" """
enable_ccd: bool = False enable_ccd: bool = False
...@@ -223,18 +207,6 @@ class SimulationCfg: ...@@ -223,18 +207,6 @@ class SimulationCfg:
Note: Note:
When enabled, the GUI will not update the physics parameters in real-time. To enable real-time When enabled, the GUI will not update the physics parameters in real-time. To enable real-time
updates, please set this flag to :obj:`False`. updates, please set this flag to :obj:`False`.
.. versionadded:: 2023.1
This flag is introduced in 2023.1.0. For older versions, please use :obj:`use_flatcache` instead.
"""
use_flatcache: bool = True
"""Enable/disable reading of physics buffers directly. Default is True.
.. deprecated:: 2023.1
This flag is deprecated and will be removed in the future. Please use :obj:`use_fabric` instead.
""" """
disable_contact_processing: bool = False disable_contact_processing: bool = False
......
...@@ -515,12 +515,6 @@ class SimulationContext(_SimulationContext): ...@@ -515,12 +515,6 @@ class SimulationContext(_SimulationContext):
physics_scene.CreateGravityDirectionAttr(Gf.Vec3f(*gravity_direction)) physics_scene.CreateGravityDirectionAttr(Gf.Vec3f(*gravity_direction))
physics_scene.CreateGravityMagnitudeAttr(gravity_magnitude) physics_scene.CreateGravityMagnitudeAttr(gravity_magnitude)
# simulation iteration count
if self.get_version()[0] == 2022:
# position and velocity iteration counts
physx_scene_api.CreateMinIterationCountAttr(self.cfg.physx.min_position_iteration_count)
physx_scene_api.CreateMaxIterationCountAttr(self.cfg.physx.max_position_iteration_count)
else:
# position iteration count # position iteration count
physx_scene_api.CreateMinPositionIterationCountAttr(self.cfg.physx.min_position_iteration_count) physx_scene_api.CreateMinPositionIterationCountAttr(self.cfg.physx.min_position_iteration_count)
physx_scene_api.CreateMaxPositionIterationCountAttr(self.cfg.physx.max_position_iteration_count) physx_scene_api.CreateMaxPositionIterationCountAttr(self.cfg.physx.max_position_iteration_count)
...@@ -537,20 +531,7 @@ class SimulationContext(_SimulationContext): ...@@ -537,20 +531,7 @@ class SimulationContext(_SimulationContext):
bind_physics_material(self.cfg.physics_prim_path, material_path) bind_physics_material(self.cfg.physics_prim_path, material_path)
def _load_fabric_interface(self): def _load_fabric_interface(self):
"""Loads the flatcache/fabric interface if enabled.""" """Loads the fabric interface if enabled."""
# check isaac sim version
# note: flatcache is called fabric in isaac sim 2023.x
# in isaac sim 2022.x, we use physx-flatcache module
# in isaac sim 2023.x, we use physx-fabric module
if self.get_version()[0] == 2022:
# check if flatcache is enabled
if self.cfg.use_flatcache:
from omni.physxflatcache import get_physx_flatcache_interface
# acquire flatcache interface
self._fabric_iface = get_physx_flatcache_interface()
else:
# check if fabric is enabled
if self.cfg.use_fabric: if self.cfg.use_fabric:
from omni.physxfabric import get_physx_fabric_interface from omni.physxfabric import get_physx_fabric_interface
......
...@@ -10,7 +10,6 @@ from typing import TYPE_CHECKING ...@@ -10,7 +10,6 @@ from typing import TYPE_CHECKING
import carb import carb
import omni.isaac.core.utils.prims as prim_utils import omni.isaac.core.utils.prims as prim_utils
import omni.kit.commands import omni.kit.commands
from omni.isaac.version import get_version
from pxr import Gf, Sdf, Usd from pxr import Gf, Sdf, Usd
from omni.isaac.orbit.sim import converters, schemas from omni.isaac.orbit.sim import converters, schemas
...@@ -166,12 +165,6 @@ def spawn_ground_plane( ...@@ -166,12 +165,6 @@ def spawn_ground_plane(
# Change the color of the plane # Change the color of the plane
# Warning: This is specific to the default grid plane asset. # Warning: This is specific to the default grid plane asset.
if cfg.color is not None: if cfg.color is not None:
# obtain isaac sim version
isaac_sim_version = int(get_version()[2])
# check the property name based on isaac sim version
if isaac_sim_version == 2022:
prop_path = f"{prim_path}/Looks/theGrid.inputs:diffuse_tint"
else:
prop_path = f"{prim_path}/Looks/theGrid/Shader.inputs:diffuse_tint" prop_path = f"{prim_path}/Looks/theGrid/Shader.inputs:diffuse_tint"
# change the color # change the color
omni.kit.commands.execute( omni.kit.commands.execute(
......
...@@ -8,7 +8,6 @@ from __future__ import annotations ...@@ -8,7 +8,6 @@ from __future__ import annotations
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import omni.isaac.core.utils.prims as prim_utils import omni.isaac.core.utils.prims as prim_utils
from omni.isaac.version import get_version
from pxr import Usd, UsdLux from pxr import Usd, UsdLux
from omni.isaac.orbit.sim.utils import clone, safe_set_attribute_on_usd_prim from omni.isaac.orbit.sim.utils import clone, safe_set_attribute_on_usd_prim
...@@ -50,8 +49,6 @@ def spawn_light( ...@@ -50,8 +49,6 @@ def spawn_light(
# create the prim # create the prim
prim = prim_utils.create_prim(prim_path, prim_type=cfg.prim_type, translation=translation, orientation=orientation) prim = prim_utils.create_prim(prim_path, prim_type=cfg.prim_type, translation=translation, orientation=orientation)
# obtain isaac sim version
isaac_sim_version = int(get_version()[2])
# convert to dict # convert to dict
cfg = cfg.to_dict() cfg = cfg.to_dict()
# delete spawner func specific parameters # delete spawner func specific parameters
...@@ -72,11 +69,6 @@ def spawn_light( ...@@ -72,11 +69,6 @@ def spawn_light(
light_prim.CreateTextureFormatAttr(value) light_prim.CreateTextureFormatAttr(value)
else: else:
raise ValueError(f"Unsupported texture attribute: '{attr_name}'.") raise ValueError(f"Unsupported texture attribute: '{attr_name}'.")
else:
# there was a change in the USD API for setting attributes for lights
# USD 22.1 onwards, we need to set the attribute on the inputs namespace
if isaac_sim_version <= 2022:
prim_prop_name = attr_name
else: else:
prim_prop_name = f"inputs:{attr_name}" prim_prop_name = f"inputs:{attr_name}"
# set the attribute # set the attribute
......
...@@ -17,7 +17,6 @@ import carb ...@@ -17,7 +17,6 @@ import carb
import omni.isaac.core.utils.stage as stage_utils import omni.isaac.core.utils.stage as stage_utils
import omni.kit.commands import omni.kit.commands
from omni.isaac.cloner import Cloner from omni.isaac.cloner import Cloner
from omni.isaac.version import get_version
from pxr import PhysxSchema, Sdf, Semantics, Usd, UsdGeom, UsdPhysics, UsdShade from pxr import PhysxSchema, Sdf, Semantics, Usd, UsdGeom, UsdPhysics, UsdShade
from omni.isaac.orbit.utils.string import to_camel_case from omni.isaac.orbit.utils.string import to_camel_case
...@@ -272,14 +271,8 @@ def clone(func: Callable) -> Callable: ...@@ -272,14 +271,8 @@ def clone(func: Callable) -> Callable:
# clone asset using cloner API # clone asset using cloner API
if len(prim_paths) > 1: if len(prim_paths) > 1:
cloner = Cloner() cloner = Cloner()
# clone the prim based on isaac-sim version # clone the prim
isaac_major_version = int(get_version()[2]) cloner.clone(prim_paths[0], prim_paths[1:], replicate_physics=False, copy_from_source=cfg.copy_from_source)
if isaac_major_version <= 2022:
cloner.clone(prim_paths[0], prim_paths[1:], replicate_physics=False)
else:
cloner.clone(
prim_paths[0], prim_paths[1:], replicate_physics=False, copy_from_source=cfg.copy_from_source
)
# return the source prim # return the source prim
return prim return prim
......
...@@ -28,7 +28,7 @@ INSTALL_REQUIRES = [ ...@@ -28,7 +28,7 @@ INSTALL_REQUIRES = [
"gymnasium==0.29.0", "gymnasium==0.29.0",
# procedural-generation # procedural-generation
"trimesh", "trimesh",
"pyglet", "pyglet<2",
] ]
# Installation operation # Installation operation
......
...@@ -22,23 +22,27 @@ from __future__ import annotations ...@@ -22,23 +22,27 @@ from __future__ import annotations
"""Launch Isaac Sim Simulator first.""" """Launch Isaac Sim Simulator first."""
import argparse import argparse
import traceback
import carb
# omni-isaac-orbit # omni-isaac-orbit
from omni.isaac.kit import SimulationApp from omni.isaac.orbit.app import AppLauncher
# add argparse arguments # add argparse arguments
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="This script shows the issue with renderer in Isaac Sim that affects episodic resets." description="This script shows the issue with renderer in Isaac Sim that affects episodic resets."
) )
parser.add_argument("--headless", action="store_true", default=False, help="Force display off at all times.")
parser.add_argument("--gpu", action="store_true", default=False, help="Use GPU device for camera rendering output.") parser.add_argument("--gpu", action="store_true", default=False, help="Use GPU device for camera rendering output.")
parser.add_argument("--scenario", type=str, default="anymal", help="Scenario to load.", choices=["anymal", "cube"]) parser.add_argument("--scenario", type=str, default="anymal", help="Scenario to load.", choices=["anymal", "cube"])
# append AppLauncher cli args
AppLauncher.add_app_launcher_args(parser)
# parse the arguments
args_cli = parser.parse_args() args_cli = parser.parse_args()
# launch omniverse app # launch omniverse app
config = {"headless": args_cli.headless} app_launcher = AppLauncher(args_cli)
simulation_app = SimulationApp(config) simulation_app = app_launcher.app
"""Rest everything follows.""" """Rest everything follows."""
...@@ -191,7 +195,7 @@ def main(): ...@@ -191,7 +195,7 @@ def main():
break break
# If simulation is paused, then skip. # If simulation is paused, then skip.
if not world.is_playing(): if not world.is_playing():
world.step(render=not args_cli.headless) world.step(render=False)
continue continue
# Reset on intervals # Reset on intervals
if count % 25 == 0: if count % 25 == 0:
...@@ -246,7 +250,13 @@ def main(): ...@@ -246,7 +250,13 @@ def main():
if __name__ == "__main__": if __name__ == "__main__":
# Runs the main function try:
# Run the main function
main() main()
# Close the simulator except Exception as err:
carb.log_error(err)
carb.log_error(traceback.format_exc())
raise
finally:
# close sim app
simulation_app.close() simulation_app.close()
...@@ -16,13 +16,12 @@ from __future__ import annotations ...@@ -16,13 +16,12 @@ from __future__ import annotations
import argparse import argparse
from omni.isaac.kit import SimulationApp from omni.isaac.orbit.app import AppLauncher
# add argparse arguments # add argparse arguments
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="This script shows the issue in Isaac Sim with GPU simulation of floating robots." description="This script shows the issue in Isaac Sim with GPU simulation of floating robots."
) )
parser.add_argument("--headless", action="store_true", default=False, help="Force display off at all times.")
parser.add_argument("--num_robots", type=int, default=128, help="Number of robots to spawn.") parser.add_argument("--num_robots", type=int, default=128, help="Number of robots to spawn.")
parser.add_argument( parser.add_argument(
"--asset", "--asset",
...@@ -30,18 +29,21 @@ parser.add_argument( ...@@ -30,18 +29,21 @@ parser.add_argument(
default="orbit", default="orbit",
help="The asset source location for the robot. Can be: orbit, oige, custom asset path.", help="The asset source location for the robot. Can be: orbit, oige, custom asset path.",
) )
# append AppLauncher cli args
AppLauncher.add_app_launcher_args(parser)
# parse the arguments
args_cli = parser.parse_args() args_cli = parser.parse_args()
# launch omniverse app # launch omniverse app
config = {"headless": args_cli.headless} app_launcher = AppLauncher(args_cli)
simulation_app = SimulationApp(config) simulation_app = app_launcher.app
"""Rest everything follows.""" """Rest everything follows."""
import os import os
import torch import torch
import traceback
import carb import carb
import omni.isaac.core.utils.nucleus as nucleus_utils import omni.isaac.core.utils.nucleus as nucleus_utils
...@@ -167,7 +169,7 @@ def main(): ...@@ -167,7 +169,7 @@ def main():
break break
# If simulation is paused, then skip. # If simulation is paused, then skip.
if not world.is_playing(): if not world.is_playing():
world.step(render=not args_cli.headless) world.step(render=False)
continue continue
# perform step # perform step
world.step() world.step()
...@@ -176,7 +178,13 @@ def main(): ...@@ -176,7 +178,13 @@ def main():
if __name__ == "__main__": if __name__ == "__main__":
try:
# Run the main function # Run the main function
main() main()
# Close the simulator except Exception as err:
carb.log_error(err)
carb.log_error(traceback.format_exc())
raise
finally:
# close sim app
simulation_app.close() simulation_app.close()
...@@ -26,18 +26,20 @@ from __future__ import annotations ...@@ -26,18 +26,20 @@ from __future__ import annotations
import argparse import argparse
# omni-isaac-orbit # omni-isaac-orbit
from omni.isaac.kit import SimulationApp from omni.isaac.orbit.app import AppLauncher
# add argparse arguments # add argparse arguments
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="This script shows how to use replicator to randomly change the textures of a USD scene." description="This script shows how to use replicator to randomly change the textures of a USD scene."
) )
parser.add_argument("--headless", action="store_true", default=False, help="Force display off at all times.") # append AppLauncher cli args
AppLauncher.add_app_launcher_args(parser)
# parse the arguments
args_cli = parser.parse_args() args_cli = parser.parse_args()
# launch omniverse app # launch omniverse app
config = {"headless": args_cli.headless} app_launcher = AppLauncher(args_cli)
simulation_app = SimulationApp(config) simulation_app = app_launcher.app
"""Rest everything follows.""" """Rest everything follows."""
...@@ -45,7 +47,9 @@ simulation_app = SimulationApp(config) ...@@ -45,7 +47,9 @@ simulation_app = SimulationApp(config)
import numpy as np import numpy as np
import torch import torch
import traceback
import carb
import omni.isaac.core.utils.prims as prim_utils import omni.isaac.core.utils.prims as prim_utils
import omni.replicator.core as rep import omni.replicator.core as rep
from omni.isaac.cloner import GridCloner from omni.isaac.cloner import GridCloner
...@@ -143,7 +147,7 @@ def main(): ...@@ -143,7 +147,7 @@ def main():
break break
# If simulation is paused, then skip. # If simulation is paused, then skip.
if not sim.is_playing(): if not sim.is_playing():
sim.step(render=not args_cli.headless) sim.step()
continue continue
# Reset the scene # Reset the scene
if step_count % 500 == 0: if step_count % 500 == 0:
...@@ -159,7 +163,13 @@ def main(): ...@@ -159,7 +163,13 @@ def main():
if __name__ == "__main__": if __name__ == "__main__":
# Runs the main function try:
# Run the main function
main() main()
# Close the simulator except Exception as err:
carb.log_error(err)
carb.log_error(traceback.format_exc())
raise
finally:
# close sim app
simulation_app.close() simulation_app.close()
...@@ -15,10 +15,11 @@ It is possible to add additional callbacks to it for user-defined operations. ...@@ -15,10 +15,11 @@ It is possible to add additional callbacks to it for user-defined operations.
"""Launch Isaac Sim Simulator first.""" """Launch Isaac Sim Simulator first."""
from omni.isaac.kit import SimulationApp from omni.isaac.orbit.app import AppLauncher
# launch the simulator # launch omniverse app
simulation_app = SimulationApp({"headless": False}) app_launcher = AppLauncher()
simulation_app = app_launcher.app
"""Rest everything follows.""" """Rest everything follows."""
......
...@@ -7,17 +7,20 @@ from __future__ import annotations ...@@ -7,17 +7,20 @@ from __future__ import annotations
"""Launch Isaac Sim Simulator first.""" """Launch Isaac Sim Simulator first."""
from omni.isaac.kit import SimulationApp from omni.isaac.orbit.app import AppLauncher
# launch omniverse app # launch omniverse app
config = {"headless": True} app_launcher = AppLauncher()
simulation_app = SimulationApp(config) simulation_app = app_launcher.app
"""Rest everything follows.""" """Rest everything follows."""
import traceback
import unittest import unittest
from collections import namedtuple from collections import namedtuple
import carb
from omni.isaac.orbit.envs.mdp import NullCommandCfg from omni.isaac.orbit.envs.mdp import NullCommandCfg
...@@ -50,4 +53,12 @@ class TestNullCommandTerm(unittest.TestCase): ...@@ -50,4 +53,12 @@ class TestNullCommandTerm(unittest.TestCase):
if __name__ == "__main__": if __name__ == "__main__":
try:
unittest.main() unittest.main()
except Exception as err:
carb.log_error(err)
carb.log_error(traceback.format_exc())
raise
finally:
# close sim app
simulation_app.close()
...@@ -7,18 +7,21 @@ from __future__ import annotations ...@@ -7,18 +7,21 @@ from __future__ import annotations
"""Launch Isaac Sim Simulator first.""" """Launch Isaac Sim Simulator first."""
from omni.isaac.kit import SimulationApp from omni.isaac.orbit.app import AppLauncher
# launch omniverse app # launch omniverse app
config = {"headless": True} config = {"headless": True}
simulation_app = SimulationApp(config) simulation_app = AppLauncher(config).app
"""Rest everything follows.""" """Rest everything follows."""
import torch import torch
import traceback
import unittest import unittest
from collections import namedtuple from collections import namedtuple
import carb
from omni.isaac.orbit.managers import ManagerTermBase, ObservationGroupCfg, ObservationManager, ObservationTermCfg from omni.isaac.orbit.managers import ManagerTermBase, ObservationGroupCfg, ObservationManager, ObservationTermCfg
from omni.isaac.orbit.utils import configclass from omni.isaac.orbit.utils import configclass
...@@ -297,5 +300,12 @@ class TestObservationManager(unittest.TestCase): ...@@ -297,5 +300,12 @@ class TestObservationManager(unittest.TestCase):
if __name__ == "__main__": if __name__ == "__main__":
try:
unittest.main() unittest.main()
except Exception as err:
carb.log_error(err)
carb.log_error(traceback.format_exc())
raise
finally:
# close sim app
simulation_app.close() simulation_app.close()
...@@ -7,17 +7,20 @@ from __future__ import annotations ...@@ -7,17 +7,20 @@ from __future__ import annotations
"""Launch Isaac Sim Simulator first.""" """Launch Isaac Sim Simulator first."""
from omni.isaac.kit import SimulationApp from omni.isaac.orbit.app import AppLauncher
# launch omniverse app # launch omniverse app
config = {"headless": True} config = {"headless": True}
simulation_app = SimulationApp(config) simulation_app = AppLauncher(config).app
"""Rest everything follows.""" """Rest everything follows."""
import traceback
import unittest import unittest
from collections import namedtuple from collections import namedtuple
import carb
from omni.isaac.orbit.managers import RewardManager, RewardTermCfg from omni.isaac.orbit.managers import RewardManager, RewardTermCfg
from omni.isaac.orbit.utils import configclass from omni.isaac.orbit.utils import configclass
...@@ -168,5 +171,12 @@ class TestRewardManager(unittest.TestCase): ...@@ -168,5 +171,12 @@ class TestRewardManager(unittest.TestCase):
if __name__ == "__main__": if __name__ == "__main__":
try:
unittest.main() unittest.main()
except Exception as err:
carb.log_error(err)
carb.log_error(traceback.format_exc())
raise
finally:
# close sim app
simulation_app.close() simulation_app.close()
...@@ -8,11 +8,11 @@ from __future__ import annotations ...@@ -8,11 +8,11 @@ from __future__ import annotations
"""Launch Isaac Sim Simulator first.""" """Launch Isaac Sim Simulator first."""
from omni.isaac.kit import SimulationApp from omni.isaac.orbit.app import AppLauncher
# launch omniverse app # launch omniverse app
config = {"headless": True} config = {"headless": True}
simulation_app = SimulationApp(config) simulation_app = AppLauncher(config).app
"""Rest everything follows.""" """Rest everything follows."""
......
...@@ -18,17 +18,20 @@ from __future__ import annotations ...@@ -18,17 +18,20 @@ from __future__ import annotations
import argparse import argparse
from omni.isaac.kit import SimulationApp from omni.isaac.orbit.app import AppLauncher
# add argparse arguments # add argparse arguments
parser = argparse.ArgumentParser(description="Contact Sensor Test Script") parser = argparse.ArgumentParser(description="Contact Sensor Test Script")
parser.add_argument("--headless", action="store_true", default=False, help="Force display off at all times.")
parser.add_argument("--num_robots", type=int, default=64, help="Number of robots to spawn.") parser.add_argument("--num_robots", type=int, default=64, help="Number of robots to spawn.")
# append AppLauncher cli args
AppLauncher.add_app_launcher_args(parser)
# parse the arguments
args_cli = parser.parse_args() args_cli = parser.parse_args()
# launch omniverse app # launch omniverse app
config = {"headless": args_cli.headless} app_launcher = AppLauncher(args_cli)
simulation_app = SimulationApp(config) simulation_app = app_launcher.app
"""Rest everything follows.""" """Rest everything follows."""
...@@ -135,7 +138,7 @@ def main(): ...@@ -135,7 +138,7 @@ def main():
break break
# If simulation is paused, then skip. # If simulation is paused, then skip.
if not sim.is_playing(): if not sim.is_playing():
sim.step(render=not args_cli.headless) sim.step(render=False)
continue continue
# reset # reset
if count % 1000 == 0: if count % 1000 == 0:
...@@ -153,7 +156,7 @@ def main(): ...@@ -153,7 +156,7 @@ def main():
# write commands to sim # write commands to sim
robot.write_data_to_sim() robot.write_data_to_sim()
# perform step # perform step
sim.step(render=not args_cli.headless) sim.step()
# fetch data # fetch data
robot.update(physics_dt) robot.update(physics_dt)
# update sim-time # update sim-time
......
...@@ -18,11 +18,10 @@ from __future__ import annotations ...@@ -18,11 +18,10 @@ from __future__ import annotations
import argparse import argparse
from omni.isaac.kit import SimulationApp from omni.isaac.orbit.app import AppLauncher
# add argparse arguments # add argparse arguments
parser = argparse.ArgumentParser(description="Ray Caster Test Script") parser = argparse.ArgumentParser(description="Ray Caster Test Script")
parser.add_argument("--headless", action="store_true", default=False, help="Force display off at all times.")
parser.add_argument("--num_envs", type=int, default=128, help="Number of environments to clone.") parser.add_argument("--num_envs", type=int, default=128, help="Number of environments to clone.")
parser.add_argument( parser.add_argument(
"--terrain_type", "--terrain_type",
...@@ -30,11 +29,14 @@ parser.add_argument( ...@@ -30,11 +29,14 @@ parser.add_argument(
default="generator", default="generator",
help="Type of terrain to import. Can be 'generator' or 'usd' or 'plane'.", help="Type of terrain to import. Can be 'generator' or 'usd' or 'plane'.",
) )
# append AppLauncher cli args
AppLauncher.add_app_launcher_args(parser)
# parse the arguments
args_cli = parser.parse_args() args_cli = parser.parse_args()
# launch omniverse app # launch omniverse app
config = {"headless": args_cli.headless} app_launcher = AppLauncher(args_cli)
simulation_app = SimulationApp(config) simulation_app = app_launcher.app
"""Rest everything follows.""" """Rest everything follows."""
...@@ -155,7 +157,7 @@ def main(): ...@@ -155,7 +157,7 @@ def main():
break break
# If simulation is paused, then skip. # If simulation is paused, then skip.
if not sim.is_playing(): if not sim.is_playing():
sim.step(render=not args_cli.headless) sim.step(render=False)
continue continue
# Reset the scene # Reset the scene
if step_count % 500 == 0: if step_count % 500 == 0:
......
...@@ -78,7 +78,7 @@ class TestSimulationContext(unittest.TestCase): ...@@ -78,7 +78,7 @@ class TestSimulationContext(unittest.TestCase):
sim = SimulationContext() sim = SimulationContext()
version = sim.get_version() version = sim.get_version()
self.assertTrue(len(version) > 0) self.assertTrue(len(version) > 0)
self.assertTrue(version[0] >= 2022) self.assertTrue(version[0] >= 2023)
def test_carb_setting(self): def test_carb_setting(self):
"""Test setting carb settings.""" """Test setting carb settings."""
......
...@@ -20,7 +20,6 @@ import omni.isaac.core.utils.prims as prim_utils ...@@ -20,7 +20,6 @@ import omni.isaac.core.utils.prims as prim_utils
import omni.isaac.core.utils.stage as stage_utils import omni.isaac.core.utils.stage as stage_utils
from omni.isaac.core.simulation_context import SimulationContext from omni.isaac.core.simulation_context import SimulationContext
from omni.isaac.core.utils.extensions import get_extension_path_from_name from omni.isaac.core.utils.extensions import get_extension_path_from_name
from omni.isaac.version import get_version
import omni.isaac.orbit.sim as sim_utils import omni.isaac.orbit.sim as sim_utils
from omni.isaac.orbit.utils.assets import ISAAC_ORBIT_NUCLEUS_DIR from omni.isaac.orbit.utils.assets import ISAAC_ORBIT_NUCLEUS_DIR
...@@ -37,8 +36,6 @@ class TestSpawningFromFiles(unittest.TestCase): ...@@ -37,8 +36,6 @@ class TestSpawningFromFiles(unittest.TestCase):
self.dt = 0.1 self.dt = 0.1
# Load kit helper # Load kit helper
self.sim = SimulationContext(physics_dt=self.dt, rendering_dt=self.dt, backend="numpy") self.sim = SimulationContext(physics_dt=self.dt, rendering_dt=self.dt, backend="numpy")
# Isaac Sim version
self.isaacsim_version_year = int(get_version()[2])
# Wait for spawning # Wait for spawning
stage_utils.update_stage() stage_utils.update_stage()
...@@ -67,9 +64,6 @@ class TestSpawningFromFiles(unittest.TestCase): ...@@ -67,9 +64,6 @@ class TestSpawningFromFiles(unittest.TestCase):
def test_spawn_urdf(self): def test_spawn_urdf(self):
"""Test loading prim from URDF file.""" """Test loading prim from URDF file."""
# retrieve path to urdf importer extension # retrieve path to urdf importer extension
if self.isaacsim_version_year == 2022:
extension_path = get_extension_path_from_name("omni.isaac.urdf")
else:
extension_path = get_extension_path_from_name("omni.importer.urdf") extension_path = get_extension_path_from_name("omni.importer.urdf")
# Spawn franka from URDF # Spawn franka from URDF
cfg = sim_utils.UrdfFileCfg( cfg = sim_utils.UrdfFileCfg(
......
...@@ -156,9 +156,7 @@ class TestSpawningLights(unittest.TestCase): ...@@ -156,9 +156,7 @@ class TestSpawningLights(unittest.TestCase):
raise ValueError(f"Unknown texture attribute: '{attr_name}'") raise ValueError(f"Unknown texture attribute: '{attr_name}'")
else: else:
# convert attribute name in prim to cfg name # convert attribute name in prim to cfg name
prim_prop_name = to_camel_case(attr_name, to="cC") prim_prop_name = f"inputs:{to_camel_case(attr_name, to='cC')}"
if self.isaac_sim_version > 2022:
prim_prop_name = f"inputs:{prim_prop_name}"
# configured value # configured value
configured_value = prim.GetAttribute(prim_prop_name).Get() configured_value = prim.GetAttribute(prim_prop_name).Get()
# validate the values # validate the values
......
...@@ -7,11 +7,11 @@ from __future__ import annotations ...@@ -7,11 +7,11 @@ from __future__ import annotations
"""Launch Isaac Sim Simulator first.""" """Launch Isaac Sim Simulator first."""
from omni.isaac.kit import SimulationApp from omni.isaac.orbit.app import AppLauncher
# launch omniverse app # launch omniverse app
config = {"headless": True} config = {"headless": True}
simulation_app = SimulationApp(config) simulation_app = AppLauncher(config).app
"""Rest everything follows.""" """Rest everything follows."""
...@@ -27,7 +27,6 @@ import omni.isaac.core.utils.stage as stage_utils ...@@ -27,7 +27,6 @@ import omni.isaac.core.utils.stage as stage_utils
from omni.isaac.core.articulations import ArticulationView from omni.isaac.core.articulations import ArticulationView
from omni.isaac.core.simulation_context import SimulationContext from omni.isaac.core.simulation_context import SimulationContext
from omni.isaac.core.utils.extensions import get_extension_path_from_name from omni.isaac.core.utils.extensions import get_extension_path_from_name
from omni.isaac.version import get_version
from omni.isaac.orbit.sim.converters import UrdfConverter, UrdfConverterCfg from omni.isaac.orbit.sim.converters import UrdfConverter, UrdfConverterCfg
...@@ -39,12 +38,7 @@ class TestUrdfConverter(unittest.TestCase): ...@@ -39,12 +38,7 @@ class TestUrdfConverter(unittest.TestCase):
"""Create a blank new stage for each test.""" """Create a blank new stage for each test."""
# Create a new stage # Create a new stage
stage_utils.create_new_stage() stage_utils.create_new_stage()
# Isaac Sim version
self.isaacsim_version_year = int(get_version()[2])
# retrieve path to urdf importer extension # retrieve path to urdf importer extension
if self.isaacsim_version_year == 2022:
extension_path = get_extension_path_from_name("omni.isaac.urdf")
else:
extension_path = get_extension_path_from_name("omni.importer.urdf") extension_path = get_extension_path_from_name("omni.importer.urdf")
# default configuration # default configuration
self.config = UrdfConverterCfg( self.config = UrdfConverterCfg(
......
...@@ -7,11 +7,11 @@ from __future__ import annotations ...@@ -7,11 +7,11 @@ from __future__ import annotations
"""Launch Isaac Sim Simulator first.""" """Launch Isaac Sim Simulator first."""
from omni.isaac.kit import SimulationApp from omni.isaac.orbit.app import AppLauncher
# launch omniverse app # launch omniverse app
config = {"headless": True} config = {"headless": True}
simulation_app = SimulationApp(config) simulation_app = AppLauncher(config).app
"""Rest everything follows.""" """Rest everything follows."""
......
...@@ -7,26 +7,35 @@ from __future__ import annotations ...@@ -7,26 +7,35 @@ from __future__ import annotations
"""Launch Isaac Sim Simulator first.""" """Launch Isaac Sim Simulator first."""
import argparse
import os import os
import traceback
parser = argparse.ArgumentParser(description="Generate terrains using trimesh")
parser.add_argument(
"--headless", action="store_true", default=False, help="Don't create a window to display each output."
)
args_cli = parser.parse_args()
from omni.isaac.orbit.app import AppLauncher from omni.isaac.orbit.app import AppLauncher
# launch omniverse app # launch omniverse app
# note: we only need to do this because of `TerrainImporter` which uses Omniverse functions # note: we only need to do this because of `TerrainImporter` which uses Omniverse functions
app_experience = f"{os.environ['EXP_PATH']}/omni.isaac.sim.python.gym.headless.kit" app_experience = f"{os.environ['EXP_PATH']}/omni.isaac.sim.python.gym.headless.kit"
app_launcher = AppLauncher(headless=True, experience=app_experience) app_launcher = AppLauncher(experience=app_experience)
simulation_app = app_launcher.app simulation_app = app_launcher.app
"""Rest everything follows.""" """Rest everything follows."""
import argparse
import trimesh import trimesh
import carb
import omni.isaac.orbit.terrains.height_field as hf_gen import omni.isaac.orbit.terrains.height_field as hf_gen
from omni.isaac.orbit.terrains.utils import color_meshes_by_height from omni.isaac.orbit.terrains.utils import color_meshes_by_height
def test_random_uniform_terrain(difficulty: float): def test_random_uniform_terrain(difficulty: float, output_dir: str, headless: bool):
# parameters for the terrain # parameters for the terrain
cfg = hf_gen.HfRandomUniformTerrainCfg( cfg = hf_gen.HfRandomUniformTerrainCfg(
size=(8.0, 8.0), size=(8.0, 8.0),
...@@ -56,7 +65,7 @@ def test_random_uniform_terrain(difficulty: float): ...@@ -56,7 +65,7 @@ def test_random_uniform_terrain(difficulty: float):
trimesh.viewer.SceneViewer(scene=scene, caption="Random Uniform Terrain") trimesh.viewer.SceneViewer(scene=scene, caption="Random Uniform Terrain")
def test_pyramid_sloped_terrain(difficulty: float, inverted: bool): def test_pyramid_sloped_terrain(difficulty: float, inverted: bool, output_dir: str, headless: bool):
# parameters for the terrain # parameters for the terrain
cfg = hf_gen.HfPyramidSlopedTerrainCfg( cfg = hf_gen.HfPyramidSlopedTerrainCfg(
size=(8.0, 8.0), size=(8.0, 8.0),
...@@ -93,7 +102,7 @@ def test_pyramid_sloped_terrain(difficulty: float, inverted: bool): ...@@ -93,7 +102,7 @@ def test_pyramid_sloped_terrain(difficulty: float, inverted: bool):
trimesh.viewer.SceneViewer(scene=scene, caption=caption) trimesh.viewer.SceneViewer(scene=scene, caption=caption)
def test_pyramid_stairs_terrain(difficulty: float, inverted: bool): def test_pyramid_stairs_terrain(difficulty: float, inverted: bool, output_dir: str, headless: bool):
# parameters for the terrain # parameters for the terrain
cfg = hf_gen.HfPyramidStairsTerrainCfg( cfg = hf_gen.HfPyramidStairsTerrainCfg(
size=(8.0, 8.0), size=(8.0, 8.0),
...@@ -131,7 +140,7 @@ def test_pyramid_stairs_terrain(difficulty: float, inverted: bool): ...@@ -131,7 +140,7 @@ def test_pyramid_stairs_terrain(difficulty: float, inverted: bool):
trimesh.viewer.SceneViewer(scene=scene, caption=caption) trimesh.viewer.SceneViewer(scene=scene, caption=caption)
def test_discrete_obstacles_terrain(difficulty: float, obstacle_height_mode: str): def test_discrete_obstacles_terrain(difficulty: float, obstacle_height_mode: str, output_dir: str, headless: bool):
# parameters for the terrain # parameters for the terrain
cfg = hf_gen.HfDiscreteObstaclesTerrainCfg( cfg = hf_gen.HfDiscreteObstaclesTerrainCfg(
size=(8.0, 8.0), size=(8.0, 8.0),
...@@ -172,7 +181,7 @@ def test_discrete_obstacles_terrain(difficulty: float, obstacle_height_mode: str ...@@ -172,7 +181,7 @@ def test_discrete_obstacles_terrain(difficulty: float, obstacle_height_mode: str
trimesh.viewer.SceneViewer(scene=scene, caption=caption) trimesh.viewer.SceneViewer(scene=scene, caption=caption)
def test_wave_terrain(difficulty: float): def test_wave_terrain(difficulty: float, output_dir: str, headless: bool):
# parameters for the terrain # parameters for the terrain
cfg = hf_gen.HfWaveTerrainCfg( cfg = hf_gen.HfWaveTerrainCfg(
size=(8.0, 8.0), size=(8.0, 8.0),
...@@ -201,7 +210,7 @@ def test_wave_terrain(difficulty: float): ...@@ -201,7 +210,7 @@ def test_wave_terrain(difficulty: float):
trimesh.viewer.SceneViewer(scene=scene, caption="Wave Terrain") trimesh.viewer.SceneViewer(scene=scene, caption="Wave Terrain")
def test_stepping_stones_terrain(difficulty: float): def test_stepping_stones_terrain(difficulty: float, output_dir: str, headless: bool):
# parameters for the terrain # parameters for the terrain
cfg = hf_gen.HfSteppingStonesTerrainCfg( cfg = hf_gen.HfSteppingStonesTerrainCfg(
size=(8.0, 8.0), size=(8.0, 8.0),
...@@ -233,28 +242,38 @@ def test_stepping_stones_terrain(difficulty: float): ...@@ -233,28 +242,38 @@ def test_stepping_stones_terrain(difficulty: float):
trimesh.viewer.SceneViewer(scene=scene, caption="Stepping Stones Terrain") trimesh.viewer.SceneViewer(scene=scene, caption="Stepping Stones Terrain")
if __name__ == "__main__": def main():
# Create argparse for headless mode
parser = argparse.ArgumentParser(description="Generate terrains using trimesh")
parser.add_argument("--headless", action="store_true", default=False, help="Run in headless mode")
args = parser.parse_args()
# Read headless mode
headless = args.headless
# Create directory to dump results # Create directory to dump results
test_dir = os.path.dirname(os.path.abspath(__file__)) test_dir = os.path.dirname(os.path.abspath(__file__))
output_dir = os.path.join(test_dir, "output", "terrains", "height_field") output_dir = os.path.join(test_dir, "output", "terrains", "height_field")
if not os.path.exists(output_dir): if not os.path.exists(output_dir):
os.makedirs(output_dir, exist_ok=True) os.makedirs(output_dir, exist_ok=True)
# Read headless mode
headless = args_cli.headless
# generate terrains # generate terrains
test_random_uniform_terrain(difficulty=0.25) test_random_uniform_terrain(difficulty=0.25, output_dir=output_dir, headless=headless)
test_pyramid_sloped_terrain(difficulty=0.25, inverted=False) test_pyramid_sloped_terrain(difficulty=0.25, inverted=False, output_dir=output_dir, headless=headless)
test_pyramid_sloped_terrain(difficulty=0.25, inverted=True) test_pyramid_sloped_terrain(difficulty=0.25, inverted=True, output_dir=output_dir, headless=headless)
test_pyramid_stairs_terrain(difficulty=0.25, inverted=False) test_pyramid_stairs_terrain(difficulty=0.25, inverted=False, output_dir=output_dir, headless=headless)
test_pyramid_stairs_terrain(difficulty=0.25, inverted=True) test_pyramid_stairs_terrain(difficulty=0.25, inverted=True, output_dir=output_dir, headless=headless)
test_discrete_obstacles_terrain(difficulty=0.25, obstacle_height_mode="choice") test_discrete_obstacles_terrain(
test_discrete_obstacles_terrain(difficulty=0.25, obstacle_height_mode="fixed") difficulty=0.25, obstacle_height_mode="choice", output_dir=output_dir, headless=headless
test_wave_terrain(difficulty=0.25) )
test_stepping_stones_terrain(difficulty=1.0) test_discrete_obstacles_terrain(
difficulty=0.25, obstacle_height_mode="fixed", output_dir=output_dir, headless=headless
)
test_wave_terrain(difficulty=0.25, output_dir=output_dir, headless=headless)
test_stepping_stones_terrain(difficulty=1.0, output_dir=output_dir, headless=headless)
# close the app
if __name__ == "__main__":
try:
# Run the main function
main()
except Exception as err:
carb.log_error(err)
carb.log_error(traceback.format_exc())
raise
finally:
# close sim app
simulation_app.close() simulation_app.close()
...@@ -7,7 +7,15 @@ from __future__ import annotations ...@@ -7,7 +7,15 @@ from __future__ import annotations
"""Launch Isaac Sim Simulator first.""" """Launch Isaac Sim Simulator first."""
import argparse
import os import os
import traceback
parser = argparse.ArgumentParser(description="Generate terrains using trimesh")
parser.add_argument(
"--headless", action="store_true", default=False, help="Don't create a window to display each output."
)
args_cli = parser.parse_args()
from omni.isaac.orbit.app import AppLauncher from omni.isaac.orbit.app import AppLauncher
...@@ -22,11 +30,13 @@ simulation_app = app_launcher.app ...@@ -22,11 +30,13 @@ simulation_app = app_launcher.app
import argparse import argparse
import trimesh import trimesh
import carb
import omni.isaac.orbit.terrains.trimesh as mesh_gen import omni.isaac.orbit.terrains.trimesh as mesh_gen
from omni.isaac.orbit.terrains.utils import color_meshes_by_height from omni.isaac.orbit.terrains.utils import color_meshes_by_height
def test_flat_terrain(difficulty: float): def test_flat_terrain(difficulty: float, output_dir: str, headless: bool):
# parameters for the terrain # parameters for the terrain
cfg = mesh_gen.MeshPlaneTerrainCfg(size=(8.0, 8.0)) cfg = mesh_gen.MeshPlaneTerrainCfg(size=(8.0, 8.0))
# generate the terrain # generate the terrain
...@@ -48,7 +58,7 @@ def test_flat_terrain(difficulty: float): ...@@ -48,7 +58,7 @@ def test_flat_terrain(difficulty: float):
trimesh.viewer.SceneViewer(scene=scene, caption="Flat Terrain") trimesh.viewer.SceneViewer(scene=scene, caption="Flat Terrain")
def test_pyramid_stairs_terrain(difficulty: float, holes: bool): def test_pyramid_stairs_terrain(difficulty: float, holes: bool, output_dir: str, headless: bool):
# parameters for the terrain # parameters for the terrain
cfg = mesh_gen.MeshPyramidStairsTerrainCfg( cfg = mesh_gen.MeshPyramidStairsTerrainCfg(
size=(8.0, 8.0), size=(8.0, 8.0),
...@@ -84,7 +94,7 @@ def test_pyramid_stairs_terrain(difficulty: float, holes: bool): ...@@ -84,7 +94,7 @@ def test_pyramid_stairs_terrain(difficulty: float, holes: bool):
trimesh.viewer.SceneViewer(scene=scene, caption=caption) trimesh.viewer.SceneViewer(scene=scene, caption=caption)
def test_inverted_pyramid_stairs_terrain(difficulty: float, holes: bool): def test_inverted_pyramid_stairs_terrain(difficulty: float, holes: bool, output_dir: str, headless: bool):
# parameters for the terrain # parameters for the terrain
cfg = mesh_gen.MeshInvertedPyramidStairsTerrainCfg( cfg = mesh_gen.MeshInvertedPyramidStairsTerrainCfg(
size=(8.0, 8.0), size=(8.0, 8.0),
...@@ -120,7 +130,7 @@ def test_inverted_pyramid_stairs_terrain(difficulty: float, holes: bool): ...@@ -120,7 +130,7 @@ def test_inverted_pyramid_stairs_terrain(difficulty: float, holes: bool):
trimesh.viewer.SceneViewer(scene=scene, caption=caption) trimesh.viewer.SceneViewer(scene=scene, caption=caption)
def test_random_grid_terrain(difficulty: float, holes: bool): def test_random_grid_terrain(difficulty: float, holes: bool, output_dir: str, headless: bool):
# parameters for the terrain # parameters for the terrain
cfg = mesh_gen.MeshRandomGridTerrainCfg( cfg = mesh_gen.MeshRandomGridTerrainCfg(
size=(8.0, 8.0), size=(8.0, 8.0),
...@@ -155,7 +165,7 @@ def test_random_grid_terrain(difficulty: float, holes: bool): ...@@ -155,7 +165,7 @@ def test_random_grid_terrain(difficulty: float, holes: bool):
trimesh.viewer.SceneViewer(scene=scene, caption=caption) trimesh.viewer.SceneViewer(scene=scene, caption=caption)
def test_rails_terrain(difficulty: float): def test_rails_terrain(difficulty: float, output_dir: str, headless: bool):
# parameters for the terrain # parameters for the terrain
cfg = mesh_gen.MeshRailsTerrainCfg( cfg = mesh_gen.MeshRailsTerrainCfg(
size=(8.0, 8.0), size=(8.0, 8.0),
...@@ -182,7 +192,7 @@ def test_rails_terrain(difficulty: float): ...@@ -182,7 +192,7 @@ def test_rails_terrain(difficulty: float):
trimesh.viewer.SceneViewer(scene=scene, caption="Rail Terrain") trimesh.viewer.SceneViewer(scene=scene, caption="Rail Terrain")
def test_pit_terrain(difficulty: float, double_pit: bool): def test_pit_terrain(difficulty: float, double_pit: bool, output_dir: str, headless: bool):
# parameters for the terrain # parameters for the terrain
cfg = mesh_gen.MeshPitTerrainCfg( cfg = mesh_gen.MeshPitTerrainCfg(
size=(8.0, 8.0), platform_width=1.5, pit_depth_range=(0.05, 1.1), double_pit=double_pit size=(8.0, 8.0), platform_width=1.5, pit_depth_range=(0.05, 1.1), double_pit=double_pit
...@@ -213,7 +223,7 @@ def test_pit_terrain(difficulty: float, double_pit: bool): ...@@ -213,7 +223,7 @@ def test_pit_terrain(difficulty: float, double_pit: bool):
trimesh.viewer.SceneViewer(scene=scene, caption=caption) trimesh.viewer.SceneViewer(scene=scene, caption=caption)
def test_box_terrain(difficulty: float, double_box: bool): def test_box_terrain(difficulty: float, double_box: bool, output_dir: str, headless: bool):
# parameters for the terrain # parameters for the terrain
cfg = mesh_gen.MeshBoxTerrainCfg( cfg = mesh_gen.MeshBoxTerrainCfg(
size=(8.0, 8.0), size=(8.0, 8.0),
...@@ -247,7 +257,7 @@ def test_box_terrain(difficulty: float, double_box: bool): ...@@ -247,7 +257,7 @@ def test_box_terrain(difficulty: float, double_box: bool):
trimesh.viewer.SceneViewer(scene=scene, caption=caption) trimesh.viewer.SceneViewer(scene=scene, caption=caption)
def test_gap_terrain(difficulty: float): def test_gap_terrain(difficulty: float, output_dir: str, headless: bool):
# parameters for the terrain # parameters for the terrain
cfg = mesh_gen.MeshGapTerrainCfg( cfg = mesh_gen.MeshGapTerrainCfg(
size=(8.0, 8.0), size=(8.0, 8.0),
...@@ -273,7 +283,7 @@ def test_gap_terrain(difficulty: float): ...@@ -273,7 +283,7 @@ def test_gap_terrain(difficulty: float):
trimesh.viewer.SceneViewer(scene=scene, caption="Gap Terrain") trimesh.viewer.SceneViewer(scene=scene, caption="Gap Terrain")
def test_floating_ring_terrain(difficulty: float): def test_floating_ring_terrain(difficulty: float, output_dir: str, headless: bool):
# parameters for the terrain # parameters for the terrain
cfg = mesh_gen.MeshFloatingRingTerrainCfg( cfg = mesh_gen.MeshFloatingRingTerrainCfg(
size=(8.0, 8.0), size=(8.0, 8.0),
...@@ -301,7 +311,7 @@ def test_floating_ring_terrain(difficulty: float): ...@@ -301,7 +311,7 @@ def test_floating_ring_terrain(difficulty: float):
trimesh.viewer.SceneViewer(scene=scene, caption="Floating Ring Terrain") trimesh.viewer.SceneViewer(scene=scene, caption="Floating Ring Terrain")
def test_star_terrain(difficulty: float): def test_star_terrain(difficulty: float, output_dir: str, headless: bool):
# parameters for the terrain # parameters for the terrain
cfg = mesh_gen.MeshStarTerrainCfg( cfg = mesh_gen.MeshStarTerrainCfg(
size=(8.0, 8.0), size=(8.0, 8.0),
...@@ -329,7 +339,9 @@ def test_star_terrain(difficulty: float): ...@@ -329,7 +339,9 @@ def test_star_terrain(difficulty: float):
trimesh.viewer.SceneViewer(scene=scene, caption="Star Terrain") trimesh.viewer.SceneViewer(scene=scene, caption="Star Terrain")
def test_repeated_objects_terrain(difficulty: float, object_type: str, provide_as_string: bool = False): def test_repeated_objects_terrain(
difficulty: float, object_type: str, output_dir: str, headless: bool, provide_as_string: bool = False
):
# parameters for the terrain # parameters for the terrain
if object_type == "pyramid": if object_type == "pyramid":
cfg = mesh_gen.MeshRepeatedPyramidsTerrainCfg( cfg = mesh_gen.MeshRepeatedPyramidsTerrainCfg(
...@@ -393,38 +405,39 @@ def test_repeated_objects_terrain(difficulty: float, object_type: str, provide_a ...@@ -393,38 +405,39 @@ def test_repeated_objects_terrain(difficulty: float, object_type: str, provide_a
trimesh.viewer.SceneViewer(scene=scene, caption=f"Repeated Objects Terrain: {object_type}") trimesh.viewer.SceneViewer(scene=scene, caption=f"Repeated Objects Terrain: {object_type}")
if __name__ == "__main__": def main():
# Create argparse for headless mode
parser = argparse.ArgumentParser(description="Generate terrains using trimesh")
parser.add_argument("--headless", action="store_true", default=False, help="Run in headless mode")
args = parser.parse_args()
# Read headless mode
headless = args.headless
# Create directory to dump results # Create directory to dump results
test_dir = os.path.dirname(os.path.abspath(__file__)) test_dir = os.path.dirname(os.path.abspath(__file__))
output_dir = os.path.join(test_dir, "output", "terrains", "trimesh") output_dir = os.path.join(test_dir, "output", "terrains", "trimesh")
if not os.path.exists(output_dir): if not os.path.exists(output_dir):
os.makedirs(output_dir, exist_ok=True) os.makedirs(output_dir, exist_ok=True)
# Read headless mode
headless = args_cli.headless
# generate terrains # generate terrains
test_flat_terrain(difficulty=0.0) test_flat_terrain(difficulty=0.0, output_dir=output_dir, headless=headless)
test_pyramid_stairs_terrain(difficulty=0.75, holes=False) test_pyramid_stairs_terrain(difficulty=0.75, holes=False, output_dir=output_dir, headless=headless)
test_pyramid_stairs_terrain(difficulty=0.75, holes=True) test_pyramid_stairs_terrain(difficulty=0.75, holes=True, output_dir=output_dir, headless=headless)
test_inverted_pyramid_stairs_terrain(difficulty=0.75, holes=False) test_inverted_pyramid_stairs_terrain(difficulty=0.75, holes=False, output_dir=output_dir, headless=headless)
test_inverted_pyramid_stairs_terrain(difficulty=0.75, holes=True) test_inverted_pyramid_stairs_terrain(difficulty=0.75, holes=True, output_dir=output_dir, headless=headless)
test_random_grid_terrain(difficulty=0.75, holes=False) test_random_grid_terrain(difficulty=0.75, holes=False, output_dir=output_dir, headless=headless)
test_random_grid_terrain(difficulty=0.75, holes=True) test_random_grid_terrain(difficulty=0.75, holes=True, output_dir=output_dir, headless=headless)
test_rails_terrain(difficulty=0.75) test_star_terrain(difficulty=0.75, output_dir=output_dir, headless=headless)
test_pit_terrain(difficulty=0.75, double_pit=False) test_repeated_objects_terrain(difficulty=0.75, object_type="pyramid", output_dir=output_dir, headless=headless)
test_pit_terrain(difficulty=0.75, double_pit=True) test_repeated_objects_terrain(difficulty=0.75, object_type="cylinder", output_dir=output_dir, headless=headless)
test_box_terrain(difficulty=0.75, double_box=False) test_repeated_objects_terrain(difficulty=0.75, object_type="box", output_dir=output_dir, headless=headless)
test_box_terrain(difficulty=0.75, double_box=True) test_repeated_objects_terrain(
test_gap_terrain(difficulty=0.75) difficulty=0.75, object_type="cylinder", provide_as_string=True, output_dir=output_dir, headless=headless
test_floating_ring_terrain(difficulty=0.75) )
test_star_terrain(difficulty=0.75)
test_repeated_objects_terrain(difficulty=0.75, object_type="pyramid")
test_repeated_objects_terrain(difficulty=0.75, object_type="cylinder") if __name__ == "__main__":
test_repeated_objects_terrain(difficulty=0.75, object_type="box") try:
test_repeated_objects_terrain(difficulty=0.75, object_type="cylinder", provide_as_string=True) # Run the main function
main()
# close the app except Exception as err:
carb.log_error(err)
carb.log_error(traceback.format_exc())
raise
finally:
# close sim app
simulation_app.close() simulation_app.close()
...@@ -7,8 +7,8 @@ from __future__ import annotations ...@@ -7,8 +7,8 @@ from __future__ import annotations
"""Launch Isaac Sim Simulator first.""" """Launch Isaac Sim Simulator first."""
import os import os
import traceback
from omni.isaac.orbit.app import AppLauncher from omni.isaac.orbit.app import AppLauncher
...@@ -22,10 +22,13 @@ simulation_app = app_launcher.app ...@@ -22,10 +22,13 @@ simulation_app = app_launcher.app
import shutil import shutil
import carb
from omni.isaac.orbit.terrains.config.rough import ROUGH_TERRAINS_CFG from omni.isaac.orbit.terrains.config.rough import ROUGH_TERRAINS_CFG
from omni.isaac.orbit.terrains.terrain_generator import TerrainGenerator from omni.isaac.orbit.terrains.terrain_generator import TerrainGenerator
if __name__ == "__main__":
def main():
# Create directory to dump results # Create directory to dump results
test_dir = os.path.dirname(os.path.abspath(__file__)) test_dir = os.path.dirname(os.path.abspath(__file__))
output_dir = os.path.join(test_dir, "output", "generator") output_dir = os.path.join(test_dir, "output", "generator")
...@@ -39,7 +42,17 @@ if __name__ == "__main__": ...@@ -39,7 +42,17 @@ if __name__ == "__main__":
ROUGH_TERRAINS_CFG.cache_dir = output_dir ROUGH_TERRAINS_CFG.cache_dir = output_dir
ROUGH_TERRAINS_CFG.curriculum = False ROUGH_TERRAINS_CFG.curriculum = False
# generate terrains # generate terrains
terrain_generator = TerrainGenerator(cfg=ROUGH_TERRAINS_CFG) terrain_generator = TerrainGenerator(cfg=ROUGH_TERRAINS_CFG) # noqa: F841
# close the simulation app if __name__ == "__main__":
try:
# Run the main function
main()
except Exception as err:
carb.log_error(err)
carb.log_error(traceback.format_exc())
raise
finally:
# close sim app
simulation_app.close() simulation_app.close()
...@@ -33,11 +33,10 @@ from __future__ import annotations ...@@ -33,11 +33,10 @@ from __future__ import annotations
import argparse import argparse
# omni-isaac-orbit # omni-isaac-orbit
from omni.isaac.kit import SimulationApp from omni.isaac.orbit.app import AppLauncher
# add argparse arguments # add argparse arguments
parser = argparse.ArgumentParser(description="This script shows how to use the terrain importer.") parser = argparse.ArgumentParser(description="This script shows how to use the terrain importer.")
parser.add_argument("--headless", action="store_true", default=False, help="Force display off at all times.")
parser.add_argument("--geom_sphere", action="store_true", default=False, help="Whether to use sphere mesh or shape.") parser.add_argument("--geom_sphere", action="store_true", default=False, help="Whether to use sphere mesh or shape.")
parser.add_argument( parser.add_argument(
"--terrain_type", "--terrain_type",
...@@ -53,12 +52,14 @@ parser.add_argument( ...@@ -53,12 +52,14 @@ parser.add_argument(
choices=["height", "random", "none"], choices=["height", "random", "none"],
help="The color scheme to use for the generated terrain.", help="The color scheme to use for the generated terrain.",
) )
# append AppLauncher cli args
AppLauncher.add_app_launcher_args(parser)
# parse the arguments
args_cli = parser.parse_args() args_cli = parser.parse_args()
# launch omniverse app # launch omniverse app
config = {"headless": args_cli.headless} app_launcher = AppLauncher(args_cli)
simulation_app = SimulationApp(config) simulation_app = app_launcher.app
"""Rest everything follows.""" """Rest everything follows."""
...@@ -185,7 +186,7 @@ def main(): ...@@ -185,7 +186,7 @@ def main():
break break
# If simulation is paused, then skip. # If simulation is paused, then skip.
if not sim.is_playing(): if not sim.is_playing():
sim.step(render=not args_cli.headless) sim.step()
continue continue
# Reset the scene # Reset the scene
if step_count % 500 == 0: if step_count % 500 == 0:
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
from __future__ import annotations from __future__ import annotations
import torch import torch
import traceback
import unittest import unittest
"""Launch Isaac Sim Simulator first. """Launch Isaac Sim Simulator first.
...@@ -16,7 +17,9 @@ This is only needed because of warp dependency. ...@@ -16,7 +17,9 @@ This is only needed because of warp dependency.
from omni.isaac.orbit.app import AppLauncher from omni.isaac.orbit.app import AppLauncher
# launch omniverse app in headless mode # launch omniverse app in headless mode
app_launcher = AppLauncher(headless=True) simulation_app = AppLauncher(headless=True).app
import carb
import omni.isaac.orbit.utils.math as math_utils import omni.isaac.orbit.utils.math as math_utils
...@@ -49,4 +52,12 @@ class TestMathUtilities(unittest.TestCase): ...@@ -49,4 +52,12 @@ class TestMathUtilities(unittest.TestCase):
if __name__ == "__main__": if __name__ == "__main__":
try:
unittest.main() unittest.main()
except Exception as err:
carb.log_error(err)
carb.log_error(traceback.format_exc())
raise
finally:
# close sim app
simulation_app.close()
...@@ -48,21 +48,22 @@ import contextlib ...@@ -48,21 +48,22 @@ import contextlib
import os import os
# omni-isaac-orbit # omni-isaac-orbit
from omni.isaac.kit import SimulationApp from omni.isaac.orbit.app import AppLauncher
# add argparse arguments # add argparse arguments
parser = argparse.ArgumentParser("Utility to empirically check if asset in instanced properly.") parser = argparse.ArgumentParser("Utility to empirically check if asset in instanced properly.")
parser.add_argument("input", type=str, help="The path to the USD file.") parser.add_argument("input", type=str, help="The path to the USD file.")
parser.add_argument("--headless", action="store_true", default=False, help="Force display off at all times.")
parser.add_argument("-n", "--num_clones", type=int, default=128, help="Number of clones to spawn.") parser.add_argument("-n", "--num_clones", type=int, default=128, help="Number of clones to spawn.")
parser.add_argument("-s", "--spacing", type=float, default=1.5, help="Spacing between instances in a grid.") parser.add_argument("-s", "--spacing", type=float, default=1.5, help="Spacing between instances in a grid.")
parser.add_argument("-p", "--physics", action="store_true", default=False, help="Clone assets using physics cloner.") parser.add_argument("-p", "--physics", action="store_true", default=False, help="Clone assets using physics cloner.")
# append AppLauncher cli args
AppLauncher.add_app_launcher_args(parser)
# parse the arguments
args_cli = parser.parse_args() args_cli = parser.parse_args()
# launch omniverse app # launch omniverse app
config = {"headless": args_cli.headless} app_launcher = AppLauncher(args_cli)
simulation_app = SimulationApp(config) simulation_app = app_launcher.app
"""Rest everything follows.""" """Rest everything follows."""
...@@ -123,7 +124,7 @@ def main(): ...@@ -123,7 +124,7 @@ def main():
# Simulate scene (if not headless) # Simulate scene (if not headless)
if not args_cli.headless: if not args_cli.headless:
with contextlib.suppress(KeyboardInterrupt): with contextlib.suppress(KeyboardInterrupt):
while True: while sim.is_playing():
# perform step # perform step
sim.step() sim.step()
......
...@@ -29,7 +29,6 @@ positional arguments: ...@@ -29,7 +29,6 @@ positional arguments:
optional arguments: optional arguments:
-h, --help Show this help message and exit -h, --help Show this help message and exit
--headless Force display off at all times. (default: False)
--make-instanceable, Make the asset instanceable for efficient cloning. (default: False) --make-instanceable, Make the asset instanceable for efficient cloning. (default: False)
--collision-approximation The method used for approximating collision mesh. Defaults to convexDecomposition. --collision-approximation The method used for approximating collision mesh. Defaults to convexDecomposition.
Set to \"none\" to not add a collision mesh to the converted mesh. (default: convexDecomposition) Set to \"none\" to not add a collision mesh to the converted mesh. (default: convexDecomposition)
...@@ -49,7 +48,6 @@ from omni.isaac.orbit.app import AppLauncher ...@@ -49,7 +48,6 @@ from omni.isaac.orbit.app import AppLauncher
parser = argparse.ArgumentParser(description="Utility to convert a mesh file into USD format.") parser = argparse.ArgumentParser(description="Utility to convert a mesh file into USD format.")
parser.add_argument("input", type=str, help="The path to the input mesh file.") parser.add_argument("input", type=str, help="The path to the input mesh file.")
parser.add_argument("output", type=str, help="The path to store the USD file.") parser.add_argument("output", type=str, help="The path to store the USD file.")
parser.add_argument("--headless", action="store_true", default=False, help="Force display off at all times.")
parser.add_argument( parser.add_argument(
"--make-instanceable", "--make-instanceable",
action="store_true", action="store_true",
...@@ -72,16 +70,21 @@ parser.add_argument( ...@@ -72,16 +70,21 @@ parser.add_argument(
default=None, default=None,
help="The mass (in kg) to assign to the converted asset. If not provided, then no mass is added.", help="The mass (in kg) to assign to the converted asset. If not provided, then no mass is added.",
) )
# append AppLauncher cli args
AppLauncher.add_app_launcher_args(parser)
# parse the arguments
args_cli = parser.parse_args() args_cli = parser.parse_args()
# launch omniverse app # launch omniverse app
simulation_app = AppLauncher(headless=args_cli.headless).app app_launcher = AppLauncher(args_cli)
simulation_app = app_launcher.app
"""Rest everything follows.""" """Rest everything follows."""
import os import os
import traceback
import carb
import omni.isaac.core.utils.stage as stage_utils import omni.isaac.core.utils.stage as stage_utils
import omni.kit.app import omni.kit.app
...@@ -149,28 +152,35 @@ def main(): ...@@ -149,28 +152,35 @@ def main():
print("-" * 80) print("-" * 80)
print("-" * 80) print("-" * 80)
# Determine if there is a GUI to update:
# acquire settings interface
carb_settings_iface = carb.settings.get_settings()
# read flag for whether a local GUI is enabled
local_gui = carb_settings_iface.get("/app/window/enabled")
# read flag for whether livestreaming GUI is enabled
livestream_gui = carb_settings_iface.get("/app/livestream/enabled")
# Simulate scene (if not headless) # Simulate scene (if not headless)
if not args_cli.headless: if local_gui or livestream_gui:
# Open the stage with USD # Open the stage with USD
stage_utils.open_stage(mesh_converter.usd_path) stage_utils.open_stage(mesh_converter.usd_path)
# Reinitialize the simulation # Reinitialize the simulation
app = omni.kit.app.get_app_interface() app = omni.kit.app.get_app_interface()
# Run simulation # Run simulation
with contextlib.suppress(KeyboardInterrupt): with contextlib.suppress(KeyboardInterrupt):
while True: while app.is_running():
# perform step # perform step
app.update() app.update()
if __name__ == "__main__": if __name__ == "__main__":
try: try:
# run the main execution
main() main()
except Exception as e: except Exception as err:
import traceback carb.log_error(err)
import carb
carb.log_error(traceback.format_exc()) carb.log_error(traceback.format_exc())
carb.log_error(e) raise
finally: finally:
# close sim app
simulation_app.close() simulation_app.close()
...@@ -21,7 +21,6 @@ positional arguments: ...@@ -21,7 +21,6 @@ positional arguments:
optional arguments: optional arguments:
-h, --help Show this help message and exit -h, --help Show this help message and exit
--headless Force display off at all times. (default: False)
--merge-joints Consolidate links that are connected by fixed joints. (default: False) --merge-joints Consolidate links that are connected by fixed joints. (default: False)
--fix-base Fix the base to where it is imported. (default: False) --fix-base Fix the base to where it is imported. (default: False)
--make-instanceable Make the asset instanceable for efficient cloning. (default: False) --make-instanceable Make the asset instanceable for efficient cloning. (default: False)
...@@ -37,13 +36,12 @@ import argparse ...@@ -37,13 +36,12 @@ import argparse
import contextlib import contextlib
# omni-isaac-orbit # omni-isaac-orbit
from omni.isaac.kit import SimulationApp from omni.isaac.orbit.app import AppLauncher
# add argparse arguments # add argparse arguments
parser = argparse.ArgumentParser(description="Utility to convert a URDF into USD format.") parser = argparse.ArgumentParser(description="Utility to convert a URDF into USD format.")
parser.add_argument("input", type=str, help="The path to the input URDF file.") parser.add_argument("input", type=str, help="The path to the input URDF file.")
parser.add_argument("output", type=str, help="The path to store the USD file.") parser.add_argument("output", type=str, help="The path to store the USD file.")
parser.add_argument("--headless", action="store_true", default=False, help="Force display off at all times.")
parser.add_argument( parser.add_argument(
"--merge-joints", "--merge-joints",
action="store_true", action="store_true",
...@@ -57,12 +55,14 @@ parser.add_argument( ...@@ -57,12 +55,14 @@ parser.add_argument(
default=False, default=False,
help="Make the asset instanceable for efficient cloning.", help="Make the asset instanceable for efficient cloning.",
) )
# append AppLauncher cli args
AppLauncher.add_app_launcher_args(parser)
# parse the arguments
args_cli = parser.parse_args() args_cli = parser.parse_args()
# launch omniverse app # launch omniverse app
config = {"headless": args_cli.headless} app_launcher = AppLauncher(args_cli)
simulation_app = SimulationApp(config) simulation_app = app_launcher.app
"""Rest everything follows.""" """Rest everything follows."""
...@@ -118,15 +118,23 @@ def main(): ...@@ -118,15 +118,23 @@ def main():
print("-" * 80) print("-" * 80)
print("-" * 80) print("-" * 80)
# Determine if there is a GUI to update:
# acquire settings interface
carb_settings_iface = carb.settings.get_settings()
# read flag for whether a local GUI is enabled
local_gui = carb_settings_iface.get("/app/window/enabled")
# read flag for whether livestreaming GUI is enabled
livestream_gui = carb_settings_iface.get("/app/livestream/enabled")
# Simulate scene (if not headless) # Simulate scene (if not headless)
if not args_cli.headless: if local_gui or livestream_gui:
# Open the stage with USD # Open the stage with USD
stage_utils.open_stage(urdf_converter.usd_path) stage_utils.open_stage(urdf_converter.usd_path)
# Reinitialize the simulation # Reinitialize the simulation
app = omni.kit.app.get_app_interface() app = omni.kit.app.get_app_interface()
# Run simulation # Run simulation
with contextlib.suppress(KeyboardInterrupt): with contextlib.suppress(KeyboardInterrupt):
while True: while app.is_running():
# perform step # perform step
app.update() app.update()
......
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