Unverified Commit 570dec32 authored by Mayank Mittal's avatar Mayank Mittal Committed by GitHub

Adds semantic tags into spawner configuration (#186)

# 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
parent 39f95498
[package] [package]
# Note: Semantic Versioning is used: https://semver.org/ # Note: Semantic Versioning is used: https://semver.org/
version = "0.9.10" version = "0.9.11"
# Description # Description
title = "ORBIT framework for Robot Learning" title = "ORBIT framework for Robot Learning"
......
Changelog 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) 0.9.10 (2023-10-16)
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
......
...@@ -55,10 +55,10 @@ def spawn_light( ...@@ -55,10 +55,10 @@ def spawn_light(
cfg = cfg.to_dict() cfg = cfg.to_dict()
# delete spawner func specific parameters # delete spawner func specific parameters
del cfg["prim_type"] del cfg["prim_type"]
# delete meta parameters from base class # delete custom attributes in the config that are not USD parameters
del cfg["func"] non_usd_cfg_param_names = ["func", "copy_from_source", "visible", "semantic_tags"]
del cfg["visible"] for param_name in non_usd_cfg_param_names:
del cfg["copy_from_source"] del cfg[param_name]
# set into USD API # set into USD API
for attr_name, value in cfg.items(): for attr_name, value in cfg.items():
# special operation for texture properties # special operation for texture properties
......
...@@ -97,6 +97,8 @@ def spawn_camera( ...@@ -97,6 +97,8 @@ def spawn_camera(
attribute_types = CUSTOM_PINHOLE_CAMERA_ATTRIBUTES attribute_types = CUSTOM_PINHOLE_CAMERA_ATTRIBUTES
else: else:
attribute_types = CUSTOM_FISHEYE_CAMERA_ATTRIBUTES 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 # get camera prim
prim = prim_utils.get_prim_at_path(prim_path) prim = prim_utils.get_prim_at_path(prim_path)
...@@ -110,7 +112,7 @@ def spawn_camera( ...@@ -110,7 +112,7 @@ def spawn_camera(
# set attribute values # set attribute values
for param_name, param_value in cfg.__dict__.items(): for param_name, param_value in cfg.__dict__.items():
# check if value is valid # 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 continue
# obtain prim property name # obtain prim property name
if param_name in attribute_types: if param_name in attribute_types:
......
...@@ -38,6 +38,22 @@ class SpawnerCfg: ...@@ -38,6 +38,22 @@ class SpawnerCfg:
visible: bool = True visible: bool = True
"""Whether the spawned asset should be visible. Defaults to 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 copy_from_source: bool = True
"""Whether to copy the asset from the source prim or inherit it. Defaults to True. """Whether to copy the asset from the source prim or inherit it. Defaults to True.
......
...@@ -15,7 +15,7 @@ import omni.isaac.core.utils.stage as stage_utils ...@@ -15,7 +15,7 @@ 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 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 from omni.isaac.orbit.utils.string import to_camel_case
...@@ -220,6 +220,21 @@ def clone(func: Callable) -> Callable: ...@@ -220,6 +220,21 @@ def clone(func: Callable) -> Callable:
# set the prim visibility # set the prim visibility
if hasattr(cfg, "visible"): if hasattr(cfg, "visible"):
prim_utils.set_prim_visibility(prim, 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 # activate rigid body contact sensors
if hasattr(cfg, "activate_contact_sensors") and cfg.activate_contact_sensors: if hasattr(cfg, "activate_contact_sensors") and cfg.activate_contact_sensors:
schemas.activate_contact_sensors(prim_paths[0], cfg.activate_contact_sensors) schemas.activate_contact_sensors(prim_paths[0], cfg.activate_contact_sensors)
......
...@@ -101,10 +101,13 @@ class TestSpawningSensors(unittest.TestCase): ...@@ -101,10 +101,13 @@ class TestSpawningSensors(unittest.TestCase):
cfg: The configuration object. cfg: The configuration object.
custom_attr: The custom attributes for sensor. 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) prim = prim_utils.get_prim_at_path(prim_path)
for attr_name, attr_value in cfg.__dict__.items(): for attr_name, attr_value in cfg.__dict__.items():
# skip names we know are not present # 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 continue
# obtain prim property name # obtain prim property name
if attr_name in custom_attr: if attr_name in custom_attr:
......
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