Source code for isaaclab_experimental.managers.scene_entity_cfg

# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause

"""Experimental fork of :class:`isaaclab.managers.SceneEntityCfg`.

This adds Warp-only cached selections (e.g. a joint mask) while keeping compatibility
with the stable manager stack (which type-checks against the stable SceneEntityCfg).
"""

from __future__ import annotations

from typing import TYPE_CHECKING

import warp as wp

from isaaclab.assets import ArticulationCfg
from isaaclab.managers.scene_entity_cfg import SceneEntityCfg as _SceneEntityCfg

if TYPE_CHECKING:
    from isaaclab.scene import InteractiveScene


[docs] class SceneEntityCfg(_SceneEntityCfg): """Scene entity configuration with an optional Warp joint mask. Notes: - `joint_mask` is intended for Warp kernels only. """ joint_mask: wp.array | None = None """Integer indices of selected joints — used for subset-sized gathers where a boolean mask cannot provide the mapping from output index k to joint index.""" joint_ids_wp: wp.array | None = None """Integer indices of selected bodies — used for subset-sized body gathers.""" body_ids_wp: wp.array | None = None @classmethod def from_stable(cls, stable: _SceneEntityCfg) -> SceneEntityCfg: """Build a warp scene-entity cfg from a stable one. Copies every field declared on the stable cfg; the warp-specific fields stay ``None`` and are filled by :meth:`resolve` at scene build time. """ return cls(**{name: getattr(stable, name) for name in _SceneEntityCfg.__dataclass_fields__}) def resolve(self, scene: InteractiveScene): # run the stable resolution first (fills joint_ids/body_ids from names/regex) super().resolve(scene) entity = scene[self.name] # -- Warp joint mask / ids for articulations if isinstance(entity.cfg, ArticulationCfg): if self.joint_ids == slice(None): joint_ids_list = list(range(entity.num_joints)) mask_list = [True] * entity.num_joints else: joint_ids_list = list(self.joint_ids) mask_list = [False] * entity.num_joints for idx in joint_ids_list: mask_list[idx] = True self.joint_mask = wp.array(mask_list, dtype=wp.bool, device=scene.device) self.joint_ids_wp = wp.array(joint_ids_list, dtype=wp.int32, device=scene.device) # -- Warp body ids if self.body_ids is not None and self.body_ids != slice(None): self.body_ids_wp = wp.array(list(self.body_ids), dtype=wp.int32, device=scene.device) elif hasattr(entity, "num_bodies"): self.body_ids_wp = wp.array(list(range(entity.num_bodies)), dtype=wp.int32, device=scene.device)