Unverified Commit 588bd36a authored by Mayank Mittal's avatar Mayank Mittal Committed by GitHub

Migrates framework to support Isaac Sim 2023.1 (#172)

# Description

From Isaac Sim 2023.X onwards (Kit 105.X onwards), there are various
noticeable changes that include renaming certain extensions and
upgrading to the latest USD.

This MR ensures that Orbit remains compatible with the coming release of
Isaac Sim while still supporting 2022.2.1.

## Type of change

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

## Checklist

- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./orbit.sh --format`
- [x] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file

---------
Signed-off-by: 's avatarMayank Mittal <12863862+Mayankm96@users.noreply.github.com>
Co-authored-by: 's avatarNikita Rudin <nrudin@nvidia.com>
Co-authored-by: 's avatarAutonomousHansen <hhansen@theaiinstitute.com>
Co-authored-by: 's avatarjsmith-bdai <142246516+jsmith-bdai@users.noreply.github.com>
parent c719c596
......@@ -14,7 +14,7 @@ per-file-ignores=*/__init__.py:F401
ignore=E402,E501,W503,E203,D401,R504,R505,SIM102,SIM117
max-line-length = 120
max-complexity = 30
exclude=_*,.vscode,.git,docs/**,**/test/**
exclude=_*,.vscode,.git,docs/**
# docstrings
docstring-convention=google
# annotations
......
......@@ -32,11 +32,12 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
apt -y autoremove && apt clean autoclean && \
rm -rf /var/lib/apt/lists/*
# FIXME: Only necessary for streaming until this fix is properly
# rolled out by NVIDIA after Isaac Sim2023.1 release
# FIXME: Only necessary for streaming until this fix is properly rolled out by NVIDIA after Isaac Sim2023.1 release
# Ref: https://forums.developer.nvidia.com/t/running-a-standalone-example-with-gui-in-docker-container/248147/3
RUN sed -i 's/\("omni.isaac.quadruped"\s=\s{}\)/"omni.isaac.quadruped" = {order = 10}/g' \
${ISAACSIM_PATH}/apps/omni.isaac.sim.python.kit
RUN if [[ "${ISAACSIM_VERSION}" == "2022.2"* ]]; then \
sed -i 's/\("omni.isaac.quadruped"\s=\s{}\)/"omni.isaac.quadruped" = {order = 10}/g' \
${ISAACSIM_PATH}/apps/omni.isaac.sim.python.kit \
fi
# Copy the orbit directory
COPY ../ ${ORBIT_PATH}
......
......@@ -71,18 +71,22 @@ case $mode in
echo "[INFO] Copying artifacts from the 'orbit' container..."
echo -e "\t - /workspace/orbit/logs -> ${SCRIPT_DIR}/artifacts/logs"
echo -e "\t - /workspace/orbit/docs/_build -> ${SCRIPT_DIR}/artifacts/docs/_build"
echo -e "\t - /workspace/orbit/data_storage -> ${SCRIPT_DIR}/artifacts/data_storage"
# enter the script directory
pushd ${SCRIPT_DIR} > /dev/null 2>&1
# We have to remove before copying because repeated copying without deletion
# causes strange errors such as nested _build directories
# warn the user
echo -e "[WARN] Removing the existing artifacts...\n"
rm -rf ./artifacts/logs ./artifacts/docs/_build
rm -rf ./artifacts/logs ./artifacts/docs/_build ./artifacts/data_storage
# create the directories
mkdir -p ./artifacts/docs
# copy the artifacts
docker cp orbit:/workspace/orbit/logs ./artifacts/logs
docker cp orbit:/workspace/orbit/docs/_build ./artifacts/docs/_build
docker cp orbit:/workspace/orbit/data_storage ./artifacts/data_storage
echo -e "\n[INFO] Finished copying the artifacts from the container."
popd > /dev/null 2>&1
;;
......
......@@ -22,19 +22,19 @@ services:
# These volumes follow from this page
# https://docs.omniverse.nvidia.com/app_isaacsim/app_isaacsim/install_faq.html#save-isaac-sim-configs-on-local-disk
- type: volume
source: isaac-cache
target: ${DOCKER_ISAACSIM_PATH}/kit/cache/Kit
source: isaac-cache-kit
target: ${DOCKER_ISAACSIM_PATH}/kit/cache
- type: volume
source: isaac-cache
source: isaac-cache-ov
target: ${DOCKER_USER_HOME}/.cache/ov
- type: volume
source: isaac-cache
source: isaac-cache-pip
target: ${DOCKER_USER_HOME}/.cache/pip
- type: volume
source: isaac-cache
source: isaac-cache-gl
target: ${DOCKER_USER_HOME}/.cache/nvidia/GLCache
- type: volume
source: isaac-cache
source: isaac-cache-compute
target: ${DOCKER_USER_HOME}/.nv/ComputeCache
- type: volume
source: isaac-logs
......@@ -67,10 +67,13 @@ services:
# to the host machine
- type: volume
source: orbit-docs
target: /workspace/orbit/docs/_build/
target: /workspace/orbit/docs/_build
- type: volume
source: orbit-logs
target: /workspace/orbit/logs
- type: volume
source: orbit-data
target: /workspace/orbit/data_storage
network_mode: host
deploy:
resources:
......@@ -86,10 +89,15 @@ services:
volumes:
# isaac-sim
isaac-cache:
isaac-cache-kit:
isaac-cache-ov:
isaac-cache-pip:
isaac-cache-gl:
isaac-cache-compute:
isaac-logs:
isaac-data:
isaac-docs:
# orbit
orbit-docs:
orbit-logs:
orbit-data:
......@@ -114,6 +114,7 @@ autodoc_mock_imports = [
"omni.isaac.kit",
"omni.isaac.cloner",
"omni.isaac.urdf",
"omni.isaac.version",
"gym",
"skrl",
"stable_baselines3",
......
......@@ -75,6 +75,7 @@ If you use ``orbit`` in your work, please cite the `paper <https://arxiv.org/abs
:caption: References
source/refs/faq
source/refs/migration
source/refs/contributing
source/refs/troubleshooting
source/refs/issues
......
Migration Guide (Isaac Sim)
===========================
Moving from Isaac Sim 2022.2.1 to 2023.1.0 brings in a number of changes to the
APIs and the way the application is built. This document outlines the changes
and how to migrate your code to the new APIs. Many of these changes attribute to
the underlying Omniverse Kit upgrade from 104.2 to 105.1. The new upgrade brings
the following notable changes:
* Update to USD 22.11
* Upgrading the Python from 3.7 to 3.10
.. warning::
This document is a work in progress and will be updated as we move closer
to the release of Isaac Sim 2023.1.0.
Renaming of PhysX Flatcache to PhysX Fabric
-------------------------------------------
The PhysX Flatcache has been renamed to PhysX Fabric. The new name is more
descriptive of the functionality and is consistent with the naming convention
used by Omniverse called `Fabric`_. Consequently, the Python module name has
also been changed from :mod:`omni.physxflatcache` to :mod:`omni.physxfabric`.
Following this, on the Isaac Sim side, various renaming have occurred:
* The parameter passed to :class:`SimulationContext` constructor via the keyword :obj:`sim_params`
now expects the key ``use_fabric`` instead of ``use_flatcache``.
* The Python attribute :attr:`SimulationContext.get_physics_context().use_flatcache` is now
:attr:`SimulationContext.get_physics_context().use_fabric`.
* The Python function :meth:`SimulationContext.get_physics_context().enable_flatcache` is now
:meth:`SimulationContext.get_physics_context().enable_fabric`.
Renaming of the URDF and MJCF Importers
---------------------------------------
Starting from Isaac Sim 2023.1, the URDF and MJCF importers have been renamed to be more consistent
with the other asset importers in Omniverse. The importers are now available on NVIDIA-Omniverse GitHub
as open source projects.
Due to the extension name change, the Python module names have also been changed:
* URDF Importer: :mod:`omni.importer.urdf` (previously :mod:`omni.isaac.urdf`)
* MJCF Importer: :mod:`omni.importer.mjcf` (previously :mod:`omni.isaac.mjcf`)
Deprecation of :class:`UsdLux.Light` API
----------------------------------------
As highlighted in the release notes of `USD 22.11`_, the ``UsdLux.Light`` API has
been deprecated in favor of the new ``UsdLuxLightAPI`` API. In the new API the attributes
are prefixed with ``inputs:``. For example, the ``intensity`` attribute is now available as
``inputs:intensity``.
The following example shows how to create a `SphereLight` using the old API and
the new API.
.. dropdown:: :fa:`eye,mr-1` Code for Isaac Sim 2022.2.1 and below
.. code-block:: python
import omni.isaac.core.utils.prims as prim_utils
prim_utils.create_prim(
"/World/Light/GreySphere",
"SphereLight",
translation=(4.5, 3.5, 10.0),
attributes={"radius": 2.5, "intensity": 600.0, "color": (0.75, 0.75, 0.75)},
)
.. dropdown:: :fa:`eye,mr-1` Code for Isaac Sim 2023.1.0 and above
.. code-block:: python
import omni.isaac.core.utils.prims as prim_utils
prim_utils.create_prim(
"/World/Light/WhiteSphere",
"SphereLight",
translation=(-4.5, 3.5, 10.0),
attributes={
"inputs:radius": 2.5,
"inputs:intensity": 600.0,
"inputs:color": (1.0, 1.0, 1.0)
},
)
.. _Fabric: https://docs.omniverse.nvidia.com/kit/docs/usdrt/latest/docs/usd_fabric_usdrt.html
.. _`USD 22.11`: https://github.com/PixarAnimationStudios/OpenUSD/blob/release/CHANGELOG.md
......@@ -77,7 +77,7 @@ needed to run Orbit inside a Docker container. These are summarized below:
* ``Dockerfile``: Defines orbit image by overlaying Orbit dependencies onto the Isaac Sim Docker image.
* ``docker-compose.yaml``: Creates mounts to allow direct editing of Orbit code from the host machine that runs
the container along with X11 forwarding. It also creates several named volumes such as ``isaac-cache`` to store frequently
the container along with X11 forwarding. It also creates several named volumes such as ``isaac-cache-kit`` to store frequently
re-used resources compiled by Isaac Sim, such as shaders, and to retain logs, data, and documents.
* ``.env``: Stores environment variables required for the build process and the container itself.
* ``container.sh``: A script that wraps the ``docker-compose`` command to build the image and run the container.
......@@ -104,7 +104,7 @@ The script ``container.sh`` wraps around three basic ``docker-compose`` commands
1. ``start``: This builds the image and brings up the container in detached mode (i.e. in the background).
2. ``enter``: This begins a new bash process in an existing orbit container, and which can be exited
without bringing down the container.
3. ``copy``: This copies the ``logs`` and ``docs/_build`` artifacts, from the ``orbit-logs`` and ``orbit-docs``
3. ``copy``: This copies the ``logs``, ``data_storage`` and ``docs/_build`` artifacts, from the ``orbit-logs``, ``orbit-data`` and ``orbit-docs``
volumes respectively, to the ``docker/artifacts`` directory. These artifacts persist between docker
container instances.
4. ``stop``: This brings down the container and removes it.
......@@ -125,8 +125,8 @@ To copy files from the container to the host machine, you can use the following
# Copy the file /workspace/orbit/logs to the current directory
docker cp orbit:/workspace/orbit/logs .
The script ``container.sh`` provides a wrapper around this command to copy the ``logs`` and ``docs/_build``
directories to the ``docker/artifacts`` directory. This is useful for copying the logs and documentation:
The script ``container.sh`` provides a wrapper around this command to copy the ``logs`` , ``data_storage`` and ``docs/_build``
directories to the ``docker/artifacts`` directory. This is useful for copying the logs, data and documentation:
.. code:: bash
......@@ -163,12 +163,17 @@ Understanding the mounted volumes
The ``docker-compose.yaml`` file creates several named volumes that are mounted to the container.
These are summarized below:
* ``isaac-cache``: This volume is used to store frequently re-used resources compiled by Omniverse, such as shaders.
* ``isaac-logs``: This volume is used to store logs generated by Omniverse.
* ``isaac-data``: This volume is used to store data generated by Omniverse.
* ``isaac-docs``: This volume is used to store documents generated by Omniverse.
* ``orbit-docs``: This volume is used to store documentation of Orbit when built inside the container.
* ``orbit-logs``: This volume is used to store logs generated by Orbit workflows when ran inside the container.
* ``isaac-cache-kit``: This volume is used to store cached Kit resources (`/isaac-sim/kit/cache` in container)
* ``isaac-cache-ov``: This volume is used to store cached OV resources (`/root/.cache/ov` in container)
* ``isaac-cache-pip``: This volume is used to store cached pip resources (`/root/.cache/pip`` in container)
* ``isaac-cache-gl``: This volume is used to store cached GLCache resources (`/root/.cache/nvidia/GLCache` in container)
* ``isaac-cache-compute``: This volume is used to store cached compute resources (`/root/.nv/ComputeCache` in container)
* ``isaac-logs``: This volume is used to store logs generated by Omniverse. (`/root/.nvidia-omniverse/logs` in container)
* ``isaac-data``: This volume is used to store data generated by Omniverse. (`/root/.local/share/ov/data` in container)
* ``isaac-docs``: This volume is used to store documents generated by Omniverse. (`/root/Documents` in container)
* ``orbit-docs``: This volume is used to store documentation of Orbit when built inside the container. (`/workspace/orbit/docs/_build` in container)
* ``orbit-logs``: This volume is used to store logs generated by Orbit workflows when ran inside the container. (`/workspace/orbit/logs` in container)
* ``orbit-data``: This volume is used to store whatever data users may want to preserve between container runs. (`/workspace/orbit/data_storage` in container)
To view the contents of these volumes, you can use the following command:
......@@ -176,8 +181,8 @@ To view the contents of these volumes, you can use the following command:
# list all volumes
docker volume ls
# inspect a specific volume, e.g. isaac-cache
docker volume inspect isaac-cache
# inspect a specific volume, e.g. isaac-cache-kit
docker volume inspect isaac-cache-kit
Invalid mount config for type "bind"
......
......@@ -227,7 +227,25 @@ class AppLauncher:
# note: moved here since it requires to have the viewport extension to be enabled first.
enable_extension("omni.replicator.isaac")
# enable urdf importer
enable_extension("omni.isaac.urdf")
# read isaac sim version (this includes build tag, release tag etc.)
# note: we do it once here because it reads the VERSION file from disk and is not expected to change.
from omni.isaac.version import get_version
isaacsim_version = get_version()
if int(isaacsim_version[2]) == 2022:
enable_extension("omni.isaac.urdf")
else:
enable_extension("omni.importer.urdf")
# set the nucleus directory manually to the 2023.1.0 version
# TODO: Remove this once the 2023.1.0 version is released
carb_settings_iface.set_string(
"/persistent/isaac/asset_root/default",
"http://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/2023.1.0",
)
carb_settings_iface.set_string(
"/persistent/isaac/asset_root/nvidia",
"http://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/2023.1.0",
)
# update the global flags
# TODO: Remove all these global flags. We don't need it anymore.
......
......@@ -15,6 +15,7 @@ import omni.isaac.core.utils.prims as prim_utils
import omni.kit
from omni.isaac.core.materials import PhysicsMaterial
from omni.isaac.core.prims import GeometryPrim
from omni.isaac.version import get_version
from pxr import Gf, PhysxSchema, UsdPhysics, UsdShade
......@@ -96,43 +97,18 @@ def create_ground_plane(
value=Gf.Vec3f(*color),
prev=None,
)
# Change the settings of the sphere light
# Add light source
# By default, the one from Isaac Sim is too dim for large number of environments.
# Warning: This is specific to the default grid plane asset.
light_intensity = kwargs.get("light_intensity", 1e7)
light_radius = kwargs.get("light_radius", 100.0)
# -- light intensity
if light_intensity is not None:
omni.kit.commands.execute(
"ChangeProperty",
prop_path=f"{prim_path}/SphereLight.intensity",
value=light_intensity,
prev=None,
)
# -- light radius
if light_radius is not None:
# set radius of the light
omni.kit.commands.execute(
"ChangeProperty",
prop_path=f"{prim_path}/SphereLight.radius",
value=light_radius,
prev=None,
)
# as a rule of thumb, we set the sphere center 1.5 times
omni.kit.commands.execute(
"ChangeProperty",
prop_path=f"{prim_path}/SphereLight.xformOp:translate",
value=(0.0, 0.0, 1.5 * light_radius),
prev=None,
)
# -- ambient light
ambient_light = kwargs.get("ambient_light", True)
if ambient_light:
prim_utils.create_prim(
f"{prim_path}/AmbientLight",
"DistantLight",
attributes={"intensity": 600.0},
)
# check isaacsim version to determine the attribute name
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()}
# create light prim
prim_utils.create_prim(f"{prim_path}/AmbientLight", "DistantLight", attributes=attributes)
def move_nested_prims(source_ns: str, target_ns: str):
......
......@@ -7,9 +7,9 @@ from __future__ import annotations
from dataclasses import MISSING
from omni.isaac.orbit.controllers import DifferentialIKControllerCfg
from omni.isaac.orbit.managers.action_manager import ActionTerm, ActionTermCfg
from omni.isaac.orbit.utils import configclass
from omni.isaac.orbit.controllers import DifferentialIKControllerCfg
from . import binary_joint_actions, joint_actions, non_holonomic_actions, task_space_actions
......
......@@ -161,11 +161,17 @@ class RewardManager(ManagerBase):
raise TypeError(
f"Configuration for the term '{term_name}' is not of type RewardTermCfg. Received '{type(term_cfg)}'."
)
# check for valid weight type
if not isinstance(term_cfg.weight, (float, int)):
raise TypeError(
f"Weight for the term '{term_name}' is not of type float or int. Received '{type(term_cfg.weight)}'."
)
# resolve common parameters
self._resolve_common_term_cfg(term_name, term_cfg, min_argc=1)
# remove zero scales and multiply non-zero ones by dt
# note: we multiply weights by dt to make them agnostic to control decimation
if term_cfg.weight == 0:
term_cfg.weight = float(term_cfg.weight)
if term_cfg.weight == 0.0:
continue
# add function to list
self._term_names.append(term_name)
......
......@@ -22,7 +22,6 @@ import numpy as np
import torch
from dataclasses import MISSING
import omni.isaac.core.utils.prims as prim_utils
import omni.isaac.core.utils.stage as stage_utils
import omni.kit.commands
import omni.physx.scripts.utils as physx_utils
......@@ -145,8 +144,8 @@ class VisualizationMarkers:
# get next free path for the prim
prim_path = stage_utils.get_next_free_path(cfg.prim_path)
# create a new prim
prim = prim_utils.define_prim(prim_path, "PointInstancer")
self._instancer_manager = UsdGeom.PointInstancer(prim)
stage = stage_utils.get_current_stage()
self._instancer_manager = UsdGeom.PointInstancer.Define(stage, prim_path)
# store inputs
self.prim_path = prim_path
self.cfg = cfg
......@@ -157,10 +156,10 @@ class VisualizationMarkers:
# create a child prim for the marker
self._add_markers_prototypes(self.cfg.markers)
# Note: We need to do this the first time to initialize the instancer.
# Otherwise, the instancer will not be visible.
self._instancer_manager.GetProtoIndicesAttr().Set([0])
self._instancer_manager.GetPositionsAttr().Set([Gf.Vec3f()])
self._count = 1
# Otherwise, the instancer will not be "created" and the function `GetInstanceIndices()` will fail.
self._instancer_manager.GetProtoIndicesAttr().Set(list(range(self.num_prototypes)))
self._instancer_manager.GetPositionsAttr().Set([Gf.Vec3f(0.0)] * self.num_prototypes)
self._count = self.num_prototypes
def __str__(self) -> str:
"""Return: A string representation of the class."""
......@@ -361,3 +360,9 @@ class VisualizationMarkers:
)
# add child reference to point instancer
self._instancer_manager.GetPrototypesRel().AddTarget(marker_prim_path)
# check that we loaded all the prototypes
prototypes = self._instancer_manager.GetPrototypesRel().GetTargets()
if len(prototypes) != len(markers_cfg):
raise RuntimeError(
f"Failed to load all the prototypes. Expected: {len(markers_cfg)}. Received: {len(prototypes)}."
)
......@@ -120,6 +120,7 @@ class Camera(SensorBase):
for _, annotators in self._rep_registry.items():
for annotator, render_product_path in zip(annotators, self._render_product_paths):
annotator.detach([render_product_path])
annotator = None
def __str__(self) -> str:
"""Returns: A string containing information about the instance."""
......@@ -226,9 +227,10 @@ class Camera(SensorBase):
# get attribute from the class
param_attr = getattr(sensor_prim, f"Get{param_name}Attr")
# set value
# note: We have to do it this way because the camera might be on a different layer (default cameras are on session layer),
# and this is the simplest way to set the property on the right layer.
omni.usd.utils.set_prop_val(param_attr(), param_value)
# note: We have to do it this way because the camera might be on a different
# layer (default cameras are on session layer), and this is the simplest
# way to set the property on the right layer.
omni.usd.set_prop_val(param_attr(), param_value)
"""
Operations - Set pose.
......@@ -423,7 +425,10 @@ class Camera(SensorBase):
sensor_prim = UsdGeom.Camera(cam_prim)
self._sensor_prims.append(sensor_prim)
# Get render product
# From Isaac Sim 2023.1 onwards, render product is a HydraTexture so we need to extract the path
render_prod_path = rep.create.render_product(cam_prim_path, resolution=(self.cfg.width, self.cfg.height))
if not isinstance(render_prod_path, str):
render_prod_path = render_prod_path.path
self._render_product_paths.append(render_prod_path)
# Iterate over each data type and create annotator
# TODO: This will move out of the loop once Replicator supports multiple render products within a single
......
......@@ -12,13 +12,22 @@ import random
from datetime import datetime
import omni.kit.commands
from omni.isaac.urdf import _urdf as omni_urdf
from omni.isaac.version import get_version
from omni.isaac.orbit.utils.assets import check_file_path
from omni.isaac.orbit.utils.io import dump_yaml
from .urdf_loader_cfg import UrdfLoaderCfg
# check if the urdf importer extension is available
# note: the urdf importer's name changed in 2023.1 onwards
isaacsim_version = get_version()
if int(isaacsim_version[2]) == 2022:
from omni.isaac.urdf import _urdf as omni_urdf
else:
from omni.importer.urdf import _urdf as omni_urdf
_DRIVE_TYPE = {
"none": 0,
"position": 1,
......
......@@ -7,7 +7,6 @@ from __future__ import annotations
import carb
import omni.isaac.core.utils.stage as stage_utils
import omni.physx.scripts.utils as physx_utils
from pxr import PhysxSchema, Usd, UsdPhysics
from ..utils import apply_nested, safe_set_attribute_on_usd_schema
......@@ -43,11 +42,6 @@ def define_articulation_root_properties(
# check if prim path is valid
if not prim.IsValid():
raise ValueError(f"Prim path '{prim_path}' is not valid.")
# check if we can apply the articulation root schema
if physx_utils.familyHasConflictingAPI(prim, UsdPhysics.ArticulationRootAPI):
raise TypeError(
f"Cannot apply ArticulationRootAPI on prim '{prim_path}'. The prim already has conflicting API schemas."
)
# check if prim has articulation applied on it
if not UsdPhysics.ArticulationRootAPI(prim):
UsdPhysics.ArticulationRootAPI.Apply(prim)
......@@ -138,11 +132,6 @@ def define_rigid_body_properties(
# check if prim path is valid
if not prim.IsValid():
raise ValueError(f"Prim path '{prim_path}' is not valid.")
# check if we can apply the articulation root schema
if physx_utils.familyHasConflictingAPI(prim, UsdPhysics.RigidBodyAPI):
raise TypeError(
f"Cannot apply RigidBodyAPI on prim '{prim_path}'. The prim already has conflicting API schemas."
)
# check if prim has articulation applied on it
if not UsdPhysics.RigidBodyAPI(prim):
UsdPhysics.RigidBodyAPI.Apply(prim)
......@@ -226,7 +215,6 @@ def define_collision_properties(
Raises:
ValueError: When the prim path is not valid.
TypeError: When the prim already has conflicting API schemas.
"""
# obtain stage
if stage is None:
......@@ -236,11 +224,6 @@ def define_collision_properties(
# check if prim path is valid
if not prim.IsValid():
raise ValueError(f"Prim path '{prim_path}' is not valid.")
# check if we can apply the articulation root schema
if physx_utils.familyHasConflictingAPI(prim, UsdPhysics.CollisionAPI):
raise TypeError(
f"Cannot apply CollisionAPI on prim '{prim_path}'. The prim already has conflicting API schemas."
)
# check if prim has articulation applied on it
if not UsdPhysics.CollisionAPI(prim):
UsdPhysics.CollisionAPI.Apply(prim)
......
......@@ -456,11 +456,11 @@ class SimulationContext(_SimulationContext):
physx_scene_api.CreateMaxIterationCountAttr(self.cfg.physx.max_position_iteration_count)
else:
# position iteration count
physx_scene_api.CreateMinPositionIterationCountsAttr(self.cfg.physx.min_position_iteration_count)
physx_scene_api.CreateMaxPositionIterationCountsAttr(self.cfg.physx.max_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)
# velocity iteration count
physx_scene_api.CreateMinVelocityIterationCountsAttr(self.cfg.physx.min_velocity_iteration_count)
physx_scene_api.CreateMaxVelocityIterationCountsAttr(self.cfg.physx.max_velocity_iteration_count)
physx_scene_api.CreateMinVelocityIterationCountAttr(self.cfg.physx.min_velocity_iteration_count)
physx_scene_api.CreateMaxVelocityIterationCountAttr(self.cfg.physx.max_velocity_iteration_count)
# create the default physics material
# this material is used when no material is specified for a primitive
......
......@@ -53,8 +53,12 @@ def spawn_light(
isaac_sim_version = int(get_version()[2])
# convert to dict
cfg = cfg.to_dict()
del cfg["func"]
# delete spawner func specific parameters
del cfg["prim_type"]
# delete meta parameters from base class
del cfg["func"]
del cfg["visible"]
del cfg["copy_from_source"]
# set into USD API
for attr_name, value in cfg.items():
# special operation for texture properties
......
......@@ -110,7 +110,7 @@ def spawn_camera(
# set attribute values
for param_name, param_value in cfg.__dict__.items():
# check if value is valid
if param_value is None or param_name in ["func", "copy_from_source", "lock_camera"]:
if param_value is None or param_name in ["func", "copy_from_source", "lock_camera", "visible"]:
continue
# obtain prim property name
if param_name in attribute_types:
......
......@@ -3,12 +3,14 @@
#
# SPDX-License-Identifier: BSD-3-Clause
"""Wrapper around the Python 3.7 onwards `dataclasses` module."""
from __future__ import annotations
"""Wrapper around the Python 3.7 onwards `dataclasses` module."""
import sys
from copy import deepcopy
from dataclasses import MISSING, Field, dataclass, field, replace
from typing import Any, Callable, ClassVar, Dict, Type
from typing import Any, Callable, ClassVar
from .dict import class_to_dict, update_class_from_dict
......@@ -97,7 +99,7 @@ These are redefined here to add new docstrings.
"""
def _class_to_dict(obj: object) -> Dict[str, Any]:
def _class_to_dict(obj: object) -> dict[str, Any]:
"""Convert an object into dictionary recursively.
Returns:
......@@ -106,7 +108,7 @@ def _class_to_dict(obj: object) -> Dict[str, Any]:
return class_to_dict(obj)
def _update_class_from_dict(obj, data: Dict[str, Any]) -> None:
def _update_class_from_dict(obj, data: dict[str, Any]) -> None:
"""Reads a dictionary and sets object variables recursively.
This function performs in-place update of the class member attributes.
......@@ -216,7 +218,11 @@ def _add_annotation_types(cls):
elif key != value.__name__:
# note: we don't want to add type annotations for nested configclass. Thus, we check if
# the name of the type matches the name of the variable.
hints[key] = Type[value]
if sys.version_info < (3, 10):
hints[key] = type[value]
else:
# since Python 3.10, type hints are stored as strings
hints[key] = f"type[{value.__name__}]"
# Note: Do not change this line. `cls.__dict__.get("__annotations__", {})` is different from
# `cls.__annotations__` because of inheritance.
......
......@@ -462,19 +462,9 @@ class TestCameraSensor(unittest.TestCase):
# Ground-plane
kit_utils.create_ground_plane("/World/defaultGroundPlane")
# Lights-1
prim_utils.create_prim(
"/World/Light/GreySphere",
"SphereLight",
translation=(4.5, 3.5, 10.0),
attributes={"radius": 1.0, "intensity": 300.0, "color": (0.75, 0.75, 0.75)},
)
prim_utils.create_prim("/World/Light/GreySphere", "SphereLight", translation=(4.5, 3.5, 10.0))
# Lights-2
prim_utils.create_prim(
"/World/Light/WhiteSphere",
"SphereLight",
translation=(-4.5, 3.5, 10.0),
attributes={"radius": 1.0, "intensity": 300.0, "color": (1.0, 1.0, 1.0)},
)
prim_utils.create_prim("/World/Light/WhiteSphere", "SphereLight", translation=(-4.5, 3.5, 10.0))
# Random objects
for i in range(8):
# sample random position
......
......@@ -269,19 +269,9 @@ class TestHeightScannerSensor(unittest.TestCase):
# Ground-plane
kit_utils.create_ground_plane("/World/defaultGroundPlane")
# Lights-1
prim_utils.create_prim(
"/World/Light/GreySphere",
"SphereLight",
translation=(4.5, 3.5, 10.0),
attributes={"radius": 1.0, "intensity": 30000.0, "color": (0.75, 0.75, 0.75)},
)
prim_utils.create_prim("/World/Light/GreySphere", "SphereLight", translation=(4.5, 3.5, 10.0))
# Lights-2
prim_utils.create_prim(
"/World/Light/WhiteSphere",
"SphereLight",
translation=(-4.5, 3.5, 10.0),
attributes={"radius": 1.0, "intensity": 30000.0, "color": (1.0, 1.0, 1.0)},
)
prim_utils.create_prim("/World/Light/WhiteSphere", "SphereLight", translation=(-4.5, 3.5, 10.0))
# Cubes
num_cubes = 4
for i in range(num_cubes):
......
......@@ -79,19 +79,9 @@ class TestKitUtilities(unittest.TestCase):
# Ground-plane
kit_utils.create_ground_plane("/World/defaultGroundPlane")
# Lights-1
prim_utils.create_prim(
"/World/Light/GreySphere",
"SphereLight",
translation=(4.5, 3.5, 10.0),
attributes={"radius": 1.0, "intensity": 300.0, "color": (0.75, 0.75, 0.75)},
)
prim_utils.create_prim("/World/Light/GreySphere", "SphereLight", translation=(4.5, 3.5, 10.0))
# Lights-2
prim_utils.create_prim(
"/World/Light/WhiteSphere",
"SphereLight",
translation=(-4.5, 3.5, 10.0),
attributes={"radius": 1.0, "intensity": 300.0, "color": (1.0, 1.0, 1.0)},
)
prim_utils.create_prim("/World/Light/WhiteSphere", "SphereLight", translation=(-4.5, 3.5, 10.0))
if __name__ == "__main__":
......
......@@ -14,8 +14,6 @@ simulation_app = AppLauncher(headless=True).app
"""Rest everything follows."""
import gc
import sys
import torch
import traceback
import unittest
......@@ -29,13 +27,13 @@ import omni.isaac.orbit.sim as sim_utils
from omni.isaac.orbit.assets import Articulation
from omni.isaac.orbit.assets.config import FRANKA_PANDA_ARM_WITH_PANDA_HAND_CFG, UR10_CFG
from omni.isaac.orbit.controllers import DifferentialIKController, DifferentialIKControllerCfg
from omni.isaac.orbit.utils.math import compute_pose_error, sample_uniform, subtract_frame_transforms
from omni.isaac.orbit.utils.math import compute_pose_error, subtract_frame_transforms
class TestDifferentialIKController(unittest.TestCase):
"""Test fixture for checking that differential IK controller tracks commands properly."""
def setUp(self) -> None:
def setUp(self):
"""Create a blank new stage for each test."""
# Wait for spawning
stage_utils.create_new_stage()
......@@ -52,7 +50,7 @@ class TestDifferentialIKController(unittest.TestCase):
# Create interface to clone the scene
cloner = GridCloner(spacing=2.0)
cloner.define_base_env("/World/envs")
self.env_prim_paths = cloner.generate_paths(f"/World/envs/env", self.num_envs)
self.env_prim_paths = cloner.generate_paths("/World/envs/env", self.num_envs)
# create source prim
prim_utils.define_prim(self.env_prim_paths[0], "Xform")
# clone the env xform
......@@ -70,7 +68,7 @@ class TestDifferentialIKController(unittest.TestCase):
]
self.ee_pose_b_des_set = torch.tensor(ee_goals_set, device=self.sim.device)
def tearDown(self) -> None:
def tearDown(self):
"""Stops simulator after each test."""
# stop simulation
self.sim.stop()
......@@ -202,8 +200,6 @@ class TestDifferentialIKController(unittest.TestCase):
# update buffers
robot.update(sim_dt)
return None
if __name__ == "__main__":
try:
......
......@@ -89,19 +89,9 @@ def main():
# Ground
world.scene.add_default_ground_plane()
# Lights-1
prim_utils.create_prim(
"/World/Light/GreySphere",
"SphereLight",
translation=(4.5, 3.5, 10.0),
attributes={"radius": 2.5, "intensity": 600.0, "color": (0.75, 0.75, 0.75)},
)
prim_utils.create_prim("/World/Light/GreySphere", "SphereLight", translation=(4.5, 3.5, 10.0))
# Lights-2
prim_utils.create_prim(
"/World/Light/WhiteSphere",
"SphereLight",
translation=(-4.5, 3.5, 10.0),
attributes={"radius": 2.5, "intensity": 600.0, "color": (1.0, 1.0, 1.0)},
)
prim_utils.create_prim("/World/Light/WhiteSphere", "SphereLight", translation=(-4.5, 3.5, 10.0))
# Xform to hold objects
if args_cli.scenario == "cube":
prim_utils.create_prim("/World/Objects", "Xform")
......
......@@ -97,19 +97,9 @@ def main():
# Ground-plane
world.scene.add_default_ground_plane(prim_path="/World/defaultGroundPlane", z_position=0.0)
# Lights-1
prim_utils.create_prim(
"/World/Light/GreySphere",
"SphereLight",
translation=(4.5, 3.5, 10.0),
attributes={"radius": 2.5, "intensity": 600.0, "color": (0.75, 0.75, 0.75)},
)
prim_utils.create_prim("/World/Light/GreySphere", "SphereLight", translation=(4.5, 3.5, 10.0))
# Lights-2
prim_utils.create_prim(
"/World/Light/WhiteSphere",
"SphereLight",
translation=(-4.5, 3.5, 10.0),
attributes={"radius": 2.5, "intensity": 600.0, "color": (1.0, 1.0, 1.0)},
)
prim_utils.create_prim("/World/Light/WhiteSphere", "SphereLight", translation=(-4.5, 3.5, 10.0))
# -- Robot
# resolve asset
if args_cli.asset == "orbit":
......
......@@ -54,7 +54,8 @@ def main():
sim_params = {
"use_gpu": True,
"use_gpu_pipeline": True,
"use_flatcache": True,
"use_flatcache": True, # deprecated from Isaac Sim 2023.1 onwards
"use_fabric": True, # used from Isaac Sim 2023.1 onwards
"enable_scene_query_support": True,
}
sim = SimulationContext(
......@@ -73,13 +74,6 @@ def main():
prim_utils.define_prim("/World/envs/env_0")
# Define the scene
# -- Light
prim_utils.create_prim(
"/World/sphereLight",
"SphereLight",
translation=(0.0, 0.0, 500.0),
attributes={"radius": 100.0, "intensity": 50000.0, "color": (0.75, 0.75, 0.75)},
)
# -- Ball
DynamicSphere(prim_path="/World/envs/env_0/ball", translation=np.array([0.0, 0.0, 5.0]), mass=0.5, radius=0.25)
......
......@@ -5,6 +5,16 @@
from __future__ import annotations
"""Launch Isaac Sim Simulator first."""
from omni.isaac.kit import SimulationApp
# launch omniverse app
config = {"headless": True}
simulation_app = SimulationApp(config)
"""Rest everything follows."""
import torch
import unittest
from collections import namedtuple
......
......@@ -5,6 +5,16 @@
from __future__ import annotations
"""Launch Isaac Sim Simulator first."""
from omni.isaac.kit import SimulationApp
# launch omniverse app
config = {"headless": True}
simulation_app = SimulationApp(config)
"""Rest everything follows."""
import unittest
from collections import namedtuple
......@@ -121,7 +131,7 @@ class TestRewardManager(unittest.TestCase):
# compute expected reward
expected_reward = cfg["term_1"].weight * self.env.dt
# compute reward using manager
rewards = self.rew_man.compute()
rewards = self.rew_man.compute(dt=self.env.dt)
# check the reward for environment index 0
self.assertEqual(float(rewards[0]), expected_reward)
self.assertEqual(tuple(rewards.shape), (self.env.num_envs,))
......
......@@ -44,7 +44,7 @@ from omni.isaac.core.simulation_context import SimulationContext
from omni.isaac.core.utils.carb import set_carb_setting
from omni.isaac.core.utils.viewports import set_camera_view
import omni.isaac.orbit.compat.utils.kit as kit_utils
import omni.isaac.orbit.sim as sim_utils
from omni.isaac.orbit.assets import Articulation
from omni.isaac.orbit.assets.config.anymal import ANYMAL_C_CFG
from omni.isaac.orbit.sensors.contact_sensor import ContactSensor, ContactSensorCfg
......@@ -57,21 +57,12 @@ Helpers
def design_scene():
"""Add prims to the scene."""
# Ground-plane
kit_utils.create_ground_plane("/World/defaultGroundPlane")
# Lights-1
prim_utils.create_prim(
"/World/Light/GreySphere",
"SphereLight",
translation=(4.5, 3.5, 10.0),
attributes={"radius": 2.5, "intensity": 600.0, "color": (0.75, 0.75, 0.75)},
)
# Lights-2
prim_utils.create_prim(
"/World/Light/WhiteSphere",
"SphereLight",
translation=(-4.5, 3.5, 10.0),
attributes={"radius": 2.5, "intensity": 600.0, "color": (1.0, 1.0, 1.0)},
)
cfg = sim_utils.GroundPlaneCfg()
cfg.func("/World/defaultGroundPlane", cfg)
# Lights
cfg = sim_utils.SphereLightCfg()
cfg.func("/World/Light/GreySphere", cfg, translation=(4.5, 3.5, 10.0))
cfg.func("/World/Light/WhiteSphere", cfg, translation=(-4.5, 3.5, 10.0))
"""
......@@ -87,10 +78,6 @@ def main():
# Set main camera
set_camera_view([2.5, 2.5, 2.5], [0.0, 0.0, 0.0])
# Enable flatcache which avoids passing data over to USD structure
# this speeds up the read-write operation of GPU buffers
if sim.get_physics_context().use_gpu_pipeline:
sim.get_physics_context().enable_flatcache(True)
# Enable hydra scene-graph instancing
# this is needed to visualize the scene when flatcache is enabled
set_carb_setting(sim._settings, "/persistent/omnihydra/useSceneGraphInstancing", True)
......@@ -113,7 +100,7 @@ def main():
robot = Articulation(cfg=robot_cfg)
# Contact sensor
contact_sensor_cfg = ContactSensorCfg(
prim_path="/World/envs/env_.*/Robot/.*_SHANK", debug_vis=False if args_cli.headless else True
prim_path="/World/envs/env_.*/Robot/.*_SHANK", debug_vis=not args_cli.headless
)
contact_sensor = ContactSensor(cfg=contact_sensor_cfg)
# filter collisions within each environment instance
......
......@@ -69,12 +69,7 @@ def design_scene(sim: SimulationContext, num_envs: int = 2048):
prim_utils.define_prim("/World/envs/env_0")
# Define the scene
# -- Light
prim_utils.create_prim(
"/World/sphereLight",
"SphereLight",
translation=(0.0, 0.0, 500.0),
attributes={"radius": 100.0, "intensity": 50000.0, "color": (0.75, 0.75, 0.75)},
)
prim_utils.create_prim("/World/light", "DistantLight")
# -- Balls
# -- Ball physics
DynamicSphere(
......@@ -101,7 +96,8 @@ def main():
sim_params = {
"use_gpu": True,
"use_gpu_pipeline": True,
"use_flatcache": True,
"use_flatcache": True, # deprecated from Isaac Sim 2023.1 onwards
"use_fabric": True, # used from Isaac Sim 2023.1 onwards
"enable_scene_query_support": True,
}
sim = SimulationContext(
......@@ -123,7 +119,7 @@ def main():
max_init_terrain_level=None,
num_envs=1,
)
terrain_importer = TerrainImporter(terrain_importer_cfg)
_ = TerrainImporter(terrain_importer_cfg)
# Create a ray-caster sensor
ray_caster_cfg = RayCasterCfg(
......@@ -131,7 +127,7 @@ def main():
mesh_prim_paths=["/World/ground"],
pattern_cfg=patterns.GridPatternCfg(resolution=0.1, size=(1.6, 1.0)),
attach_yaw_only=True,
debug_vis=False if args_cli.headless else True,
debug_vis=not args_cli.headless,
)
ray_caster = RayCaster(cfg=ray_caster_cfg)
# Create a view over all the balls
......
......@@ -34,9 +34,8 @@ from omni.isaac.core.prims import GeometryPrim, RigidPrim
from omni.isaac.core.simulation_context import SimulationContext
from pxr import Gf, Usd, UsdGeom
from omni.isaac.orbit.compat.utils.kit import create_ground_plane
import omni.isaac.orbit.sim as sim_utils
from omni.isaac.orbit.sensors.camera import Camera, CameraCfg
from omni.isaac.orbit.sim import PinholeCameraCfg
from omni.isaac.orbit.utils import convert_dict_to_backend
from omni.isaac.orbit.utils.math import convert_quat
from omni.isaac.orbit.utils.timer import Timer
......@@ -59,7 +58,7 @@ class TestCamera(unittest.TestCase):
prim_path="/World/Camera",
update_period=0,
data_types=["distance_to_image_plane"],
spawn=PinholeCameraCfg(
spawn=sim_utils.PinholeCameraCfg(
focal_length=24.0, focus_distance=400.0, horizontal_aperture=20.955, clipping_range=(0.1, 1.0e5)
),
colorize=False,
......@@ -347,21 +346,12 @@ class TestCamera(unittest.TestCase):
def _populate_scene():
"""Add prims to the scene."""
# Ground-plane
create_ground_plane("/World/defaultGroundPlane")
# Lights-1
prim_utils.create_prim(
"/World/Light/GreySphere",
"SphereLight",
translation=(4.5, 3.5, 10.0),
attributes={"radius": 1.0, "intensity": 300.0, "color": (0.75, 0.75, 0.75)},
)
# Lights-2
prim_utils.create_prim(
"/World/Light/WhiteSphere",
"SphereLight",
translation=(-4.5, 3.5, 10.0),
attributes={"radius": 1.0, "intensity": 300.0, "color": (1.0, 1.0, 1.0)},
)
cfg = sim_utils.GroundPlaneCfg()
cfg.func("/World/defaultGroundPlane", cfg)
# Lights
cfg = sim_utils.SphereLightCfg()
cfg.func("/World/Light/GreySphere", cfg, translation=(4.5, 3.5, 10.0))
cfg.func("/World/Light/WhiteSphere", cfg, translation=(-4.5, 3.5, 10.0))
# Random objects
random.seed(0)
for i in range(8):
......
......@@ -19,7 +19,6 @@ import unittest
import carb
import omni.isaac.core.utils.prims as prim_utils
import omni.isaac.core.utils.stage as stage_utils
from omni.isaac.core.simulation_context import SimulationContext
from pxr import UsdPhysics
......
......@@ -43,7 +43,7 @@ class TestSimulationContext(unittest.TestCase):
self.assertIs(sim1, sim3)
# try to delete the singleton
sim2.__del__()
sim2.clear_instance()
self.assertTrue(sim1.instance() is None)
# create new instance
sim4 = SimulationContext()
......
......@@ -20,6 +20,7 @@ import omni.isaac.core.utils.prims as prim_utils
import omni.isaac.core.utils.stage as stage_utils
from omni.isaac.core.simulation_context import SimulationContext
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
from omni.isaac.orbit.utils.assets import ISAAC_ORBIT_NUCLEUS_DIR
......@@ -34,6 +35,8 @@ class TestSpawningFromFiles(unittest.TestCase):
self.dt = 0.1
# Load kit helper
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
stage_utils.update_stage()
......@@ -60,7 +63,10 @@ class TestSpawningFromFiles(unittest.TestCase):
def test_spawn_urdf(self):
"""Test loading prim from URDF file."""
# retrieve path to urdf importer extension
extension_path = get_extension_path_from_name("omni.isaac.urdf")
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")
# Spawn franka from URDF
cfg = sim_utils.UrdfFileCfg(
urdf_path=f"{extension_path}/data/urdf/robots/franka_description/robots/panda_arm_hand.urdf", fix_base=True
......
......@@ -150,9 +150,7 @@ class TestSpawningLights(unittest.TestCase):
else:
# convert attribute name in prim to cfg name
prim_prop_name = to_camel_case(attr_name, to="cC")
if self.isaac_sim_version <= 2022:
prim_prop_name = prim_prop_name
else:
if self.isaac_sim_version > 2022:
prim_prop_name = f"inputs:{prim_prop_name}"
# configured value
configured_value = prim.GetAttribute(prim_prop_name).Get()
......
......@@ -104,12 +104,12 @@ class TestSpawningSensors(unittest.TestCase):
prim = prim_utils.get_prim_at_path(prim_path)
for attr_name, attr_value in cfg.__dict__.items():
# skip names we know are not present
if attr_name in ["func", "copy_from_source", "lock_camera"] or attr_value is None:
if attr_name in ["func", "copy_from_source", "lock_camera", "visible"] or attr_value is None:
continue
# obtain prim property name
if attr_name in custom_attr:
prim_prop_name = custom_attr[attr_name][0]
# check custom attributes
prim_prop_name = custom_attr[attr_name][0]
else:
# convert attribute name in prim to cfg name
prim_prop_name = to_camel_case(attr_name, to="cC")
......
......@@ -27,6 +27,7 @@ import omni.isaac.core.utils.prims as prim_utils
from omni.isaac.core.articulations import ArticulationView
from omni.isaac.core.simulation_context import SimulationContext
from omni.isaac.core.utils.extensions import get_extension_path_from_name
from omni.isaac.version import get_version
from omni.isaac.orbit.sim.loaders import UrdfLoader, UrdfLoaderCfg
......@@ -37,7 +38,10 @@ class TestUrdfLoader(unittest.TestCase):
def setUp(self):
"""Create a blank new stage for each test."""
# retrieve path to urdf importer extension
extension_path = get_extension_path_from_name("omni.isaac.urdf")
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")
# default configuration
self.config = UrdfLoaderCfg(
urdf_path=f"{extension_path}/data/urdf/robots/franka_description/robots/panda_arm_hand.urdf", fix_base=True
......@@ -46,6 +50,8 @@ class TestUrdfLoader(unittest.TestCase):
self.dt = 0.01
# Load kit helper
self.sim = SimulationContext(physics_dt=self.dt, rendering_dt=self.dt, backend="numpy")
# Isaac Sim version
self.isaacsim_version_year = int(get_version()[2])
def tearDown(self) -> None:
"""Stops simulator after each test."""
......
......@@ -14,15 +14,15 @@ Example usage:
# generate terrain
# -- use physics sphere mesh
./orbit.sh -p source/extensions/omni.isaac.orbit/test/terrains/test_terrain_importer.py --terrain_type generated
./orbit.sh -p source/extensions/omni.isaac.orbit/test/terrains/check_terrain_importer.py --terrain_type generator
# -- usd usd sphere geom
./orbit.sh -p source/extensions/omni.isaac.orbit/test/terrains/test_terrain_importer.py --terrain_type generated --geom_sphere
./orbit.sh -p source/extensions/omni.isaac.orbit/test/terrains/check_terrain_importer.py --terrain_type generator --geom_sphere
# usd terrain
./orbit.sh -p source/extensions/omni.isaac.orbit/test/terrains/test_terrain_importer.py --terrain_type usd
./orbit.sh -p source/extensions/omni.isaac.orbit/test/terrains/check_terrain_importer.py --terrain_type usd
# plane terrain
./orbit.sh -p source/extensions/omni.isaac.orbit/test/terrains/test_terrain_importer.py --terrain_type plane
./orbit.sh -p source/extensions/omni.isaac.orbit/test/terrains/check_terrain_importer.py --terrain_type plane
"""
from __future__ import annotations
......@@ -41,9 +41,9 @@ parser.add_argument("--geom_sphere", action="store_true", default=False, help="W
parser.add_argument(
"--terrain_type",
type=str,
choices=["generated", "usd", "plane"],
choices=["generator", "usd", "plane"],
default="generator",
help="Type of terrain to import. Can be 'generated' or 'usd' or 'plane'.",
help="Type of terrain to import. Can be 'generator' or 'usd' or 'plane'.",
)
parser.add_argument(
"--color_scheme",
......@@ -75,6 +75,7 @@ from omni.isaac.core.prims import GeometryPrim, RigidPrim, RigidPrimView
from omni.isaac.core.simulation_context import SimulationContext
from omni.isaac.core.utils.viewports import set_camera_view
import omni.isaac.orbit.sim as sim_utils
import omni.isaac.orbit.terrains as terrain_gen
from omni.isaac.orbit.terrains.config.rough import ROUGH_TERRAINS_CFG
from omni.isaac.orbit.terrains.terrain_importer import TerrainImporter
......@@ -89,6 +90,7 @@ def main():
"use_gpu": True,
"use_gpu_pipeline": True,
"use_flatcache": True,
"use_fabric": True,
"enable_scene_query_support": True,
}
sim = SimulationContext(
......@@ -120,16 +122,12 @@ def main():
# Define the scene
# -- Light
prim_utils.create_prim(
"/World/sphereLight",
"SphereLight",
translation=(0.0, 0.0, 500.0),
attributes={"radius": 100.0, "intensity": 50000.0, "color": (0.75, 0.75, 0.75)},
)
cfg = sim_utils.DistantLightCfg(intensity=1000.0)
cfg.func("/World/Light", cfg)
# -- Ball
if args_cli.geom_sphere:
# -- Ball physics
sphere = DynamicSphere(
_ = DynamicSphere(
prim_path="/World/envs/env_0/ball", translation=np.array([0.0, 0.0, 5.0]), mass=0.5, radius=0.25
)
else:
......
......@@ -7,10 +7,11 @@ from __future__ import annotations
import copy
import os
import sys
import unittest
from dataclasses import MISSING, asdict, field
from functools import wraps
from typing import Callable, ClassVar, List, Type
from typing import Callable, ClassVar
from omni.isaac.orbit.utils.configclass import configclass
from omni.isaac.orbit.utils.dict import class_to_dict, update_class_from_dict
......@@ -615,11 +616,16 @@ class TestConfigClass(unittest.TestCase):
cfg = DummyClassCfg()
# since python 3.10, annotations are stored as strings
if sys.version_info >= (3, 10):
annotations = {k: eval(v) for k, v in cfg.__annotations__.items()}
else:
annotations = cfg.__annotations__
# check types
self.assertEqual(cfg.__annotations__["class_name_1"], type)
self.assertEqual(cfg.__annotations__["class_name_2"], Type[DummyClass])
self.assertEqual(cfg.__annotations__["class_name_3"], Type[DummyClass])
self.assertEqual(cfg.__annotations__["class_name_4"], ClassVar[Type[DummyClass]])
self.assertEqual(annotations["class_name_1"], type)
self.assertEqual(annotations["class_name_2"], type[DummyClass])
self.assertEqual(annotations["class_name_3"], type[DummyClass])
self.assertEqual(annotations["class_name_4"], ClassVar[type[DummyClass]])
# check values
self.assertEqual(cfg.class_name_1, DummyClass)
self.assertEqual(cfg.class_name_2, DummyClass)
......
......@@ -31,7 +31,7 @@ class TestDictUtilities(unittest.TestCase):
"b": 2,
"c": {"d": 3, "e": 4, "f": {"g": 5, "h": 6}},
"i": 7,
"j": lambda x: x**2,
"j": lambda x: x**2, # noqa: E731
"k": dict_utils.class_to_dict,
}
# print the dictionary
......@@ -61,7 +61,7 @@ class TestDictUtilities(unittest.TestCase):
"""Test string <-> callable conversion for lambda expression."""
# create lambda function
func = lambda x: x**2
func = lambda x: x**2 # noqa: E731
# convert function to string
test_string = dict_utils.callable_to_string(func)
# convert string to function
......
......@@ -51,7 +51,8 @@ sim:
enable_scene_query_support: False
use_gpu_pipeline: True
use_flatcache: True
use_flatcache: True # deprecated from Isaac Sim 2023.1 onwards
use_fabric: True # used from Isaac Sim 2023.1 onwards
device: "cuda:0"
physx:
......
......@@ -38,7 +38,8 @@ sim:
enable_scene_query_support: False
use_gpu_pipeline: True
use_flatcache: True
use_flatcache: True # deprecated from Isaac Sim 2023.1 onwards
use_fabric: True # used from Isaac Sim 2023.1 onwards
device: "cuda:0"
physx:
......
......@@ -51,7 +51,8 @@ sim:
enable_scene_query_support: False
use_gpu_pipeline: True
use_flatcache: True
use_flatcache: True # deprecated from Isaac Sim 2023.1 onwards
use_fabric: True # used from Isaac Sim 2023.1 onwards
device: "cuda:0"
physx:
......
......@@ -105,6 +105,7 @@ def parse_env_cfg(task_name: str, use_gpu: bool = True, num_envs: int = None, **
args_cfg["sim"]["physx"]["use_gpu"] = True
args_cfg["sim"]["device"] = "cpu"
args_cfg["sim"]["use_flatcache"] = False
args_cfg["sim"]["use_fabric"] = False
# number of environments
if num_envs is not None:
......
......@@ -113,6 +113,8 @@ class RslRlVecEnvWrapper(gym.Wrapper):
def step(self, actions: torch.Tensor) -> VecEnvStepReturn: # noqa: D102
# record step information
obs_dict, rew, dones, extras = self.env.step(actions)
# render the environment to allow for visualization
self.env.render()
# return step information
obs = obs_dict["policy"]
extras["observations"] = obs_dict
......
......@@ -24,7 +24,6 @@ import gym
import gym.envs
import torch
import unittest
from typing import Dict, Union
import omni.usd
......
......@@ -80,19 +80,9 @@ def main():
# Ground-plane
kit_utils.create_ground_plane("/World/defaultGroundPlane", z_position=-1.05)
# Lights-1
prim_utils.create_prim(
"/World/Light/GreySphere",
"SphereLight",
translation=(4.5, 3.5, 10.0),
attributes={"radius": 2.5, "intensity": 600.0, "color": (0.75, 0.75, 0.75)},
)
prim_utils.create_prim("/World/Light/GreySphere", "SphereLight", translation=(4.5, 3.5, 10.0))
# Lights-2
prim_utils.create_prim(
"/World/Light/WhiteSphere",
"SphereLight",
translation=(-4.5, 3.5, 10.0),
attributes={"radius": 2.5, "intensity": 600.0, "color": (1.0, 1.0, 1.0)},
)
prim_utils.create_prim("/World/Light/WhiteSphere", "SphereLight", translation=(-4.5, 3.5, 10.0))
# -- Table
table_usd_path = f"{ISAAC_NUCLEUS_DIR}/Props/Mounts/SeattleLabTable/table_instanceable.usd"
prim_utils.create_prim("/World/envs/env_0/Table", usd_path=table_usd_path)
......
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