Skip to content

Commit

Permalink
Adds semantic tags into spawner configuration (#186)
Browse files Browse the repository at this point in the history
# Description

This MR adds support for adding semantic tag labels to the spawner
config. It uses the format provided by replicator to label something as
a class type name and class data name. For example: ("fruit",
"avocado").

## Type of change

- 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`
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
  • Loading branch information
Mayankm96 authored Oct 17, 2023
1 parent 39f9549 commit 570dec3
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 8 deletions.
2 changes: 1 addition & 1 deletion source/extensions/omni.isaac.orbit/config/extension.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]

# Note: Semantic Versioning is used: https://semver.org/
version = "0.9.10"
version = "0.9.11"

# Description
title = "ORBIT framework for Robot Learning"
Expand Down
11 changes: 11 additions & 0 deletions source/extensions/omni.isaac.orbit/docs/CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
Changelog
---------

0.9.11 (2023-10-17)
~~~~~~~~~~~~~~~~~~~

Added
^^^^^

* Added the support for semantic tags into the :class:`omni.isaac.orbit.sim.spawner.SpawnerCfg` class. This allows
the user to specify the semantic tags for a prim when spawning it into the scene. It follows the same format as
Omniverse Replicator.


0.9.10 (2023-10-16)
~~~~~~~~~~~~~~~~~~~

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ def spawn_light(
cfg = cfg.to_dict()
# 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"]
# delete custom attributes in the config that are not USD parameters
non_usd_cfg_param_names = ["func", "copy_from_source", "visible", "semantic_tags"]
for param_name in non_usd_cfg_param_names:
del cfg[param_name]
# set into USD API
for attr_name, value in cfg.items():
# special operation for texture properties
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ def spawn_camera(
attribute_types = CUSTOM_PINHOLE_CAMERA_ATTRIBUTES
else:
attribute_types = CUSTOM_FISHEYE_CAMERA_ATTRIBUTES
# custom attributes in the config that are not USD Camera parameters
non_usd_cfg_param_names = ["func", "copy_from_source", "lock_camera", "visible", "semantic_tags"]

# get camera prim
prim = prim_utils.get_prim_at_path(prim_path)
Expand All @@ -110,7 +112,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", "visible"]:
if param_value is None or param_name in non_usd_cfg_param_names:
continue
# obtain prim property name
if param_name in attribute_types:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,22 @@ class SpawnerCfg:
visible: bool = True
"""Whether the spawned asset should be visible. Defaults to True."""

semantic_tags: list[tuple[str, str]] | None = None
"""List of semantic tags to add to the spawned asset. Defaults to None,
which means no semantic tags will be added.
The semantic tags follow the `Replicator Semantic` tagging system. Each tag is a tuple of the
form ``(type, data)``, where ``type`` is the type of the tag and ``data`` is the semantic label
associated with the tag. For example, to annotate a spawned asset in the class avocado, the semantic
tag would be ``[("class", "avocado")]``.
You can specify multiple semantic tags by passing in a list of tags. For example, to annotate a
spawned asset in the class avocado and the color green, the semantic tags would be
``[("class", "avocado"), ("color", "green")]``.
.. _Replicator Semantic: https://docs.omniverse.nvidia.com/extensions/latest/ext_replicator/semantics_schema_editor.html
"""

copy_from_source: bool = True
"""Whether to copy the asset from the source prim or inherit it. Defaults to True.
Expand Down
17 changes: 16 additions & 1 deletion source/extensions/omni.isaac.orbit/omni/isaac/orbit/sim/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import omni.kit.commands
from omni.isaac.cloner import Cloner
from omni.isaac.version import get_version
from pxr import PhysxSchema, Sdf, Usd, UsdPhysics, UsdShade
from pxr import PhysxSchema, Sdf, Semantics, Usd, UsdPhysics, UsdShade

from omni.isaac.orbit.utils.string import to_camel_case

Expand Down Expand Up @@ -220,6 +220,21 @@ def wrapper(prim_path: str, cfg: SpawnerCfg, *args, **kwargs):
# set the prim visibility
if hasattr(cfg, "visible"):
prim_utils.set_prim_visibility(prim, cfg.visible)
# set the semantic annotations
if hasattr(cfg, "semantic_tags") and cfg.semantic_tags is not None:
# note: taken from replicator scripts.utils.utils.py
for semantic_type, semantic_value in cfg.semantic_tags:
# deal with spaces by replacing them with underscores
semantic_type_sanitized = semantic_type.replace(" ", "_")
semantic_value_sanitized = semantic_value.replace(" ", "_")
# set the semantic API for the instance
instance_name = f"{semantic_type_sanitized}_{semantic_value_sanitized}"
sem = Semantics.SemanticsAPI.Apply(prim, instance_name)
# create semantic type and data attributes
sem.CreateSemanticTypeAttr()
sem.CreateSemanticDataAttr()
sem.GetSemanticTypeAttr().Set(semantic_type)
sem.GetSemanticDataAttr().Set(semantic_value)
# activate rigid body contact sensors
if hasattr(cfg, "activate_contact_sensors") and cfg.activate_contact_sensors:
schemas.activate_contact_sensors(prim_paths[0], cfg.activate_contact_sensors)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,13 @@ def _validate_properties_on_prim(self, prim_path: str, cfg: object, custom_attr:
cfg: The configuration object.
custom_attr: The custom attributes for sensor.
"""
# delete custom attributes in the config that are not USD parameters
non_usd_cfg_param_names = ["func", "copy_from_source", "lock_camera", "visible", "semantic_tags"]
# get prim
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", "visible"] or attr_value is None:
if attr_name in non_usd_cfg_param_names or attr_value is None:
continue
# obtain prim property name
if attr_name in custom_attr:
Expand Down

0 comments on commit 570dec3

Please sign in to comment.