From fdd592ab8b84fb3c6bb4875685c883a00fc0779a Mon Sep 17 00:00:00 2001 From: Rafael Wiltz Date: Tue, 29 Jul 2025 16:52:11 -0400 Subject: [PATCH] Add configurable xr anchor prim --- .../isaaclab/devices/openxr/openxr_device.py | 19 ++++++++++++++++++- .../isaaclab/devices/openxr/xr_cfg.py | 10 ++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/source/isaaclab/isaaclab/devices/openxr/openxr_device.py b/source/isaaclab/isaaclab/devices/openxr/openxr_device.py index 4e5e0824980..48d1f9a7f45 100644 --- a/source/isaaclab/isaaclab/devices/openxr/openxr_device.py +++ b/source/isaaclab/isaaclab/devices/openxr/openxr_device.py @@ -107,7 +107,20 @@ def __init__( self._previous_joint_poses_right = {name: default_pose.copy() for name in HAND_JOINT_NAMES} self._previous_headpose = default_pose.copy() - xr_anchor = SingleXFormPrim("/XRAnchor", position=self._xr_cfg.anchor_pos, orientation=self._xr_cfg.anchor_rot) + # Create XR anchor based on configuration + if self._xr_cfg.anchor_prim_path is not None: + # Create XR anchor as child of specified prim for dynamic positioning + xr_anchor_path = f"{self._xr_cfg.anchor_prim_path}/XRAnchor" + # Use relative positioning when attached to a prim + xr_anchor = SingleXFormPrim( + xr_anchor_path, position=self._xr_cfg.anchor_pos, orientation=self._xr_cfg.anchor_rot + ) + else: + # Use static positioning at root level (original behavior) + xr_anchor = SingleXFormPrim( + "/XRAnchor", position=self._xr_cfg.anchor_pos, orientation=self._xr_cfg.anchor_rot + ) + carb.settings.get_settings().set_float("/persistent/xr/profile/ar/render/nearPlane", self._xr_cfg.near_plane) carb.settings.get_settings().set_string("/persistent/xr/profile/ar/anchorMode", "custom anchor") carb.settings.get_settings().set_string("/xrstage/profile/ar/customAnchor", xr_anchor.prim_path) @@ -136,6 +149,10 @@ def __str__(self) -> str: msg = f"OpenXR Hand Tracking Device: {self.__class__.__name__}\n" msg += f"\tAnchor Position: {self._xr_cfg.anchor_pos}\n" msg += f"\tAnchor Rotation: {self._xr_cfg.anchor_rot}\n" + if self._xr_cfg.anchor_prim_path is not None: + msg += f"\tAnchor Prim Path: {self._xr_cfg.anchor_prim_path} (Dynamic Anchoring)\n" + else: + msg += f"\tAnchor Mode: Static (Root Level)\n" # Add retargeter information if self._retargeters: diff --git a/source/isaaclab/isaaclab/devices/openxr/xr_cfg.py b/source/isaaclab/isaaclab/devices/openxr/xr_cfg.py index 41e13078eb5..041e8856fcb 100644 --- a/source/isaaclab/isaaclab/devices/openxr/xr_cfg.py +++ b/source/isaaclab/isaaclab/devices/openxr/xr_cfg.py @@ -30,6 +30,16 @@ class XrCfg: This quantity is only effective if :attr:`xr_anchor_pos` is set. """ + anchor_prim_path: str | None = None + """Specifies the prim path to attach the XR anchor to for dynamic positioning. + + When set, the XR anchor will be attached to the specified prim (e.g., robot root prim), + allowing the XR camera to move with the prim. This is particularly useful for locomotion + robot teleoperation where the robot moves and the XR camera should follow it. + + If None, the anchor will use the static :attr:`anchor_pos` and :attr:`anchor_rot` values. + """ + near_plane: float = 0.15 """Specifies the near plane distance for the XR device.