设置 CloudXR 远程操作#

NVIDIA CloudXR 可以实现在任何网络上向扩展现实(XR)设备流畅、高保真地进行沉浸式流媒体传输。

Isaac Lab 开发人员可以使用 CloudXR 与 Isaac Lab 一起构建需要沉浸式 XR 渲染以提高空间准确性和/或需要手部追踪以进行灵巧机器人远程操作的远程操作工作流程。

在这些工作流程中,Isaac Lab 渲染并提交机器人仿真的立体视图给 CloudXR,然后 CloudXR 对渲染视图进行编码并通过低延迟、GPU 加速的管道实时将渲染视图传送到兼容的 XR 设备上。来自 XR 设备的手部追踪等控制输入通过 CloudXR 从 XR 设备返回到 Isaac Lab,可以用来控制机器人。

本指南解释了如何在 Isaac Lab 中使用 CloudXR 和 Apple Vision Pro 进行沉浸式流媒体和远程操作。

备注

有关支持的手部跟踪外围设备的更多信息,请参阅 Manus + Vive 手部跟踪

概述#

使用 CloudXR 与 Isaac Lab 包括以下组件:

  • Isaac Lab 用于仿真机器人环境并应用从远程操作员接收的控制数据。

  • NVIDIA CloudXR Runtime 在 Isaac Lab 工作站上以 Docker 容器运行,并将虚拟仿真从 Isaac Lab 流式传输到兼容的 XR 设备。

  • Isaac XR 远程操控示例客户端 是一个用于 Apple Vision Pro 的示例应用程序,可以使用 CloudXR 沉浸式流媒体和远程操作 Isaac Lab 仿真。

本指南将为您介绍如何:

以及 已知问题

系统要求#

在使用 CloudXR 与 Isaac Lab 之前,请查看以下系统要求:

  • Isaac Lab 工作站

    • Ubuntu 22.04 或 Ubuntu 24.04

    • 以 120Hz 物理模拟维持 45 FPS 的硬件要求:
      • CPU: 16 核 AMD Ryzen Threadripper Pro 5955WX 或更高

      • Memory: 64GB RAM

      • GPU: 1x RTX PRO 6000 GPU(或等效型号,例如 1x RTX 5090)或更高

    • 有关驱动程序要求的详细信息,请参阅 Technical Requirements 指南。

    • Docker 26.0.0+, Docker Compose 2.25.0+ 和 NVIDIA Container Toolkit 。有关如何安装,请参阅 Isaac Lab Docker 指南

  • Apple Vision Pro

    • visionOS 26

    • Apple M3 Pro 芯片,配备 11 核 CPU,至少 5 个性能核心和 6 个效率核心

    • 16GB 统一内存

    • 256 GB 固态硬盘

  • 基于 Apple Silicon 的 Mac(用于使用 Xcode 为 Apple Vision Pro 构建 Isaac XR 远程操控示例客户端应用程序)

    • macOS Sequoia 15.6 或更高版本

    • Xcode 26.0

  • Wifi 6 能力路由器

    • 强大的无线连接对于高质量的流媒体体验至关重要。请参阅 Omniverse Spatial Streaming 的要求以获取更多详细信息。

    • 我们建议使用专用路由器,因为并发使用会降低质量

    • Apple Vision Pro 和 Isaac Lab 工作站必须能够相互实现 IP 可达性(注意: 很多机构网络将会阻止设备互相访问,导致 Apple Vision Pro 找不到 Isaac Lab 工作站于网络中)

备注

如果您使用的是 DGX Spark,请查看 DGX Spark 限制 了解兼容性信息。

使用 CloudXR 运行 Isaac Lab#

CloudXR Runtime 在您的 Isaac Lab 工作站上的 Docker 容器中运行,并负责将 Isaac Lab 仿真流式传输到兼容的 XR 设备。

确保已在您的 Isaac Lab 工作站上安装 DockerDocker ComposeNVIDIA Container Toolkit ,如 Isaac Lab Docker 指南 中所描述。

还要确保您的防火墙允许通过运行的 CloudXR 使用的端口进行连接:

sudo ufw allow 47998:48000,48005,48008,48012/udp
sudo ufw allow 48010/tcp

有两种选项可运行 CloudXR Runtime Docker 容器:

选项1(推荐): 使用 Docker Compose 同时运行 Isaac Lab 和 CloudXR Runtime容器

在您的 Isaac Lab 工作站上:

  1. 从 Isaac Lab 仓库的根目录开始,使用 Isaac Lab 的 container.py 脚本启动 Isaac Lab 和 CloudXR Runtime容器

    ./docker/container.py start \
        --files docker-compose.cloudxr-runtime.patch.yaml \
        --env-file .env.cloudxr-runtime
    

    如果提示,选择激活 X11 转发,这对于查看 Isaac Sim UI 是必要的。

    备注

    container.py 脚本是 Docker Compose 的一个薄包装器。额外的 --files--env-file 参数会增强基础 Docker Compose 配置,以额外运行 CloudXR Runtime

    有关 container.py 和使用 Docker Compose 运行 Isaac Lab 的更多详细信息,请参阅 Docker 指南

  2. 使用以下命令进入 Isaac Lab 基础容器:

    ./docker/container.py enter base
    

    从 Isaac Lab 基础容器内部,您可以运行使用 XR 的 Isaac Lab 脚本。

  3. 使用示例遥操作任务运行:

    ./isaaclab.sh -p scripts/environments/teleoperation/teleop_se3_agent.py \
        --task Isaac-PickPlace-GR1T2-Abs-v0 \
        --teleop_device handtracking \
        --enable_pinocchio
    
  4. 在下一步骤中,您将希望保留容器运行。 但是一旦完成,您可以停止容器:

    ./docker/container.py stop \
        --files docker-compose.cloudxr-runtime.patch.yaml \
        --env-file .env.cloudxr-runtime
    

    小技巧

    如果重启时遇到问题,您可以运行以下命令清理孤立容器:

    docker system prune -f
    
选项2: 使用 Docker 作为本地进程运行 Isaac Lab 和 CloudXR Runtime 容器

Isaac Lab 可以作为连接到 CloudXR Runtime Docker 容器的本地进程运行。但是,此方法需要手动指定用于 Isaac Lab 实例和 CloudXR Runtime 之间通信的共享目录。

在您的 Isaac Lab 工作站上:

  1. 从Isaac Lab存储库的根目录中为临时缓存文件创建一个本地文件夹:

    mkdir -p $(pwd)/openxr
    
  2. 启动CloudXR Runtime,将上面创建的目录挂载到容器中的 /openxr 目录中:

    docker run -it --rm --name cloudxr-runtime \
        --user $(id -u):$(id -g) \
        --gpus=all \
        -e "ACCEPT_EULA=Y" \
        --mount type=bind,src=$(pwd)/openxr,dst=/openxr \
        -p 48010:48010 \
        -p 47998:47998/udp \
        -p 47999:47999/udp \
        -p 48000:48000/udp \
        -p 48005:48005/udp \
        -p 48008:48008/udp \
        -p 48012:48012/udp \
        nvcr.io/nvidia/cloudxr-runtime:5.0.1
    

    备注

    如果你选择一个特定的GPU而不是 all ,你需要确保Isaac Lab也在该GPU上运行。

    小技巧

    如果运行 cloudxr-runtime 容器时遇到问题,您可以运行以下命令清理孤立容器:

    docker stop cloudxr-runtime
    docker rm cloudxr-runtime
    
  3. 在打算运行Isaac Lab的新终端中,导出以下环境变量,这些环境变量引用了上面创建的目录:

    export XDG_RUNTIME_DIR=$(pwd)/openxr/run
    export XR_RUNTIME_JSON=$(pwd)/openxr/share/openxr/1/openxr_cloudxr.json
    

    现在您可以运行使用XR的Isaac Lab脚本。

  4. 使用示例遥操作任务运行:

    ./isaaclab.sh -p scripts/environments/teleoperation/teleop_se3_agent.py \
        --task Isaac-PickPlace-GR1T2-Abs-v0 \
        --teleop_device handtracking \
        --enable_pinocchio
    

随着Isaac Lab和CloudXR Runtime的运行:

  1. 在 Isaac Sim UI 中: 找到名为 AR 的面板并选择以下选项:

    • 选择的输出插件: OpenXR

    • OpenXR 运行时: System OpenXR Runtime

    Isaac Sim UI: AR 面板

    备注

    Isaac Sim 允许您从多个 OpenXR 运行时选项中进行选择:

    • System OpenXR Runtime: 使用在 Isaac Lab 外部安装的运行时,例如本教程中通过 Docker 设置的 CloudXR Runtime。

    • CloudXR Runtime (5.0): 使用内置的 CloudXR Runtime。

    • Custom: 允许您指定并运行您选择的任何自定义 OpenXR Runtime。

  2. 单击 Start AR

视口应显示正在渲染的两只眼睛,并且您应该看到状态 “AR profile is active” 。

Isaac Lab视口渲染两只眼睛

Isaac Lab现在准备好从CloudXR客户端接收连接。 接下来的部分将指导您构建并连接CloudXR客户端。

在Isaac Lab中了解有关远程操作和仿真学习的更多信息

要了解有关Isaac Lab远程操作脚本以及如何在Isaac Lab中构建新的远程操作和仿真学习工作流的更多信息,请参阅 ​​Isaac Lab Mimic 中的遥操作与模仿学习​

使用Apple Vision Pro进行远程操作#

本节将带您了解如何为Apple Vision Pro构建和安装Isaac XR远程操作示例客户端,连接到Isaac Lab并远程操作虚拟机器人。

为Apple Vision Pro构建和安装Isaac XR远程操作示例客户端应用程序#

在您的Mac上:

  1. 克隆 Isaac XR 远程操作示例客户端 GitHub存储库:

    git clone git@github.com:isaac-sim/isaac-xr-teleop-sample-client-apple.git
    
  2. 切换到与您的 Isaac Lab 版本匹配的应用程序版本:

    Isaac Lab 版本

    客户端应用程序版本

    2.3

    v2.3.0

    2.2

    v2.2.0

    2.1

    v1.0.0

    git checkout <client_app_version>
    
  3. 按照存储库中的README构建并安装应用程序到您的Apple Vision Pro上。

使用Apple Vision Pro远程操作Isaac Lab机器人#

在您的Apple Vision Pro上安装了Isaac XR远程操作示例客户端后,您现在可以连接到Isaac Lab了。

小技巧

在佩戴头显之前 ,您可以先从 Mac 验证连接性:

# Test signaling port (replace <isaac-lab-ip> with your workstation IP)
nc -vz <isaac-lab-ip> 48010

预期输出: Connection to <ip> port 48010 [tcp/*] succeeded!

如果连接失败,请检查运行时容器是否正在运行( docker ps )以及是否有过时的运行时容器阻塞端口。

在您的 Isaac Lab 工作站上:

  1. 确保Isaac Lab和CloudXR像 使用 CloudXR 运行 Isaac Lab 中描述的那样都在运行,包括使用支持远程操作的脚本启动Isaac Lab。 例如:

    ./isaaclab.sh -p scripts/environments/teleoperation/teleop_se3_agent.py \
        --task Isaac-PickPlace-GR1T2-Abs-v0 \
        --teleop_device handtracking \
        --enable_pinocchio
    

    备注

    请记住,上面的脚本应在Isaac Lab Docker容器内部运行(选项1,推荐),或使用环境变量配置为由运行中的CloudXR Runtime Docker容器共享的目录(选项2)。

  2. 定位名为 AR 的面板。

  3. 单击 Start AR ,并确保视口显示正在渲染的两只眼睛。

返回到您的Apple Vision Pro:

  1. 打开Isaac XR远程操作示例客户端。 您应该看到一个UI窗口:

    Isaac Sim UI: AR 面板
  2. 输入您的Isaac Lab工作站的IP地址。

    备注

    Apple Vision Pro和Isaac Lab机器必须可以相互访问IP。

    我们建议在此过程中使用专用的Wifi 6路由器,因为许多机构无线网络将阻止设备相互访问,使得Apple Vision Pro无法在网络上找到Isaac Lab工作站。

  3. 单击 连接

    第一次尝试连接时,您可能需要允许应用程序访问权限,比如手部跟踪和本地网络使用,然后再次连接。

  4. 经过一段时间后,您应该可以在Apple Vision Pro上看到Isaac Lab仿真,以及用于远程操作的控件。

    Isaac Sim UI: AR 面板
  5. 单击 播放 开始远程操作虚拟机器人。 现在,机器人的运动应该由您的手动作指导。

    您可以重复使用UI控件 播放停止重置 远程操作会话。

    小技巧

    对于需要双手操纵的远程操作任务,可以使用visionOS辅助功能来控制远程操作,而无需使用手势。 例如,为了启用对UI的语音控制:

    1. Settings > Accessibility > Voice Control 中,打开 Voice Control

    2. Settings > Accessibility > Voice Control > Commands > Basic Navigation 中,打开 <item name>

    3. 现在,您可以在应用程序连接时说 “播放” , “停止” 和 “重置” 来控制远程操作。

  6. 通过移动双手远程操作虚拟机器人。

    Isaac Lab使用CloudXR进行手工灵巧机器人的远程操作

    备注

    红点表示手部关节的跟踪位置。点的运动与机器人之间的延迟或偏移可能是由机器人关节和/或机器人控制器的限制引起的。

    备注

    当逆运动学求解器无法找到有效解时,XR 设备显示屏将出现错误消息。要从这种状态恢复,请单击 重置 按钮将机器人恢复到原始姿势,并继续远程操作。

    XR 设备中的 IK 错误消息显示
  7. 完成示例后,单击 断开连接 以断开与Isaac Lab的连接。

在Isaac Lab中了解有关远程操作和仿真学习的更多信息

请参阅 ​​Isaac Lab Mimic 中的遥操作与模仿学习​ 了解如何记录远程操作演示并使用Isaac Lab构建远程操作和仿真学习工作流。

Manus + Vive 手部跟踪#

当头戴式设备的光学手部跟踪被遮挡时,Manus 手套和 HTC Vive 追踪器可以提供手部跟踪。此设置需要具有 Manus SDK 许可证的 Manus 手套以及连接到手套的 Vive 追踪器。需要 Isaac Sim 5.1 或更高版本。

使用 Manus + Vive 追踪运行远程操作示例:

安装说明

Vive 追踪器集成通过 libsurvive 库提供。

要安装,请克隆存储库,构建 python 包,并安装所需的 udev 规则。在您的 Isaac Lab 虚拟环境中,运行以下命令:

git clone https://github.com/collabora/libsurvive.git
cd libsurvive
pip install scikit-build
python setup.py install

sudo cp ./useful_files/81-vive.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules && sudo udevadm trigger

Manus 集成通过 Isaac Sim 远程操作输入插件框架提供。请按照 isaac-teleop-device-plugins 中的构建和安装步骤安装插件。

在将要启动 Isaac Lab 的同一终端中,设置:

export ISAACSIM_HANDTRACKER_LIB=<path to isaac-teleop-device-plugins>/build-manus-default/lib/libIsaacSimManusHandTracking.so

安装插件后,运行远程操作示例:

./isaaclab.sh -p scripts/environments/teleoperation/teleop_se3_agent.py \
    --task Isaac-PickPlace-GR1T2-Abs-v0 \
    --teleop_device manusvive \
    --xr \
    --enable_pinocchio

推荐的工作流程是启动 Isaac Lab,单击 Start AR ,然后戴上 Manus 手套、Vive 追踪器和头显。准备好开始会话后,使用语音命令启动 Isaac XR 远程操作示例客户端并连接到 Isaac Lab。

Isaac Lab 在会话的初始帧期间使用来自 Apple Vision Pro 的腕部姿态数据自动校准 Vive 追踪器。如果校准失败,例如红点没有准确跟随操作员的手,请重新启动 Isaac Lab 并以手掌向上的姿势开始,以提高校准可靠性。

为获得最佳性能,将灯塔放置在手部上方,略微向下倾斜。确保灯塔保持稳定;建议使用支架以防止摇晃。

确保在远程操作任务时,手部始终保持稳定并对灯塔可见。请参阅: 安装基站设置基站的提示

备注

首次启动 Manus Vive 设备时,Vive 灯塔可能需要几秒钟进行校准。在此期间保持 Vive 追踪器稳定并对灯塔可见。如果灯塔移动或跟踪失败或不稳定,可以通过删除校准文件来强制校准: $XDG_RUNTIME_DIR/libsurvive/config.json 。如果未设置 XDG_RUNTIME_DIR,默认目录为 ~/.config/libsurvive

有关更多信息,请查阅 libsurvive 文档: libsurvive

为获得最佳性能,将灯塔放置在手部上方,略微向下倾斜。如果两只手都可见,一个灯塔就足够了。确保灯塔保持稳定;建议使用支架以防止摇晃。

备注

为避免资源争用和崩溃,请确保 Manus 和 Vive 设备连接到不同的 USB 控制器/总线。使用 lsusb -t 来识别不同的总线并连接设备。

Vive 追踪器会自动计算映射到从稳定的 OpenXR 手部跟踪腕部姿态获得的左右腕关节。此自动映射计算支持最多 2 个 Vive 追踪器;如果检测到超过 2 个 Vive 追踪器,则使用检测到的前两个追踪器进行校准,这可能不正确。

在Isaac Lab中为XR进行开发#

本节将指导您如何在 Isaac Lab 中开发 XR 环境,用于构建远程操作工作流程。

使用启用了 XR 扩展的 Isaac Lab#

为了启用 XR 所需的扩展,并在 UI 中看到 AR 面板,必须通过向使用 app.AppLauncher 的任何 Isaac Lab 脚本传递 --xr 标志来加载带有 XR 体验文件的 Isaac Lab。

例如: 您可以通过使用额外的 --xr 标志来调用任何 教程 中启用和使用 XR。

配置 XR 场景放置#

可以使用 XR 锚点在 XR 设备的本地坐标系内放置机器人仿真,并可通过环境配置中的 xr 字段(类型为 openxr.XrCfg )进行配置。

具体来说: 由 openxr.XrCfganchor_posanchor_rot 字段指定的姿势将出现在 XR 设备的本地坐标系原点上,这应该在地板上。

备注

在 Apple Vision Pro 上,本地坐标系可以通过按住数字表冠重置到用户下方的地板上的位置。

例如: 如果机器人应该出现在用户的位置,则 anchor_posanchor_rot 属性应设置为机器人正下方地板上的姿势。

备注

通过在位置的 anchor 处创建一个 primitive,并修改 xr/profile/ar/anchorMode/xrstage/profile/ar/customAnchor 设置, openxr.OpenXRDevice 中应用 XR 锚点配置。

如果正在运行的脚本不使用 openxr.OpenXRDevice ,则需要显式执行这一步骤。

优化 XR 性能#

配置物理和渲染时间步

为了提供高保真的沉浸式体验,建议确保仿真渲染时间步大致与 XR 设备显示时间步匹配。

还要确保此时间步可以实时进行仿真和渲染。

Apple Vision Pro 显示器运行在 90Hz,但许多 Isaac Lab 仿真在为 XR 渲染立体视图时无法实现90Hz性能;因此,为了在 Apple Vision Pro 上获得最佳体验,我们建议以90Hz的仿真 dt 和2的渲染间隔运行,这意味着仿真每两个仿真步骤渲染一次,或者如果性能允许,则以45Hz运行。

您仍然可以根据需要设置较低或较高的仿真 dt,但这可能导致在 XR 中渲染时仿真速度快或慢。

通过修改环境的 __post_init__ 函数中的 sim.SimulationCfg 来覆盖环境的时间步配置。例如:

@configclass
class XrTeleopEnvCfg(ManagerBasedRLEnvCfg):

    def __post_init__(self):
        self.sim.dt = 1.0 / 90
        self.sim.render_interval = 2

还要注意,默认情况下,CloudXR 试图根据 Isaac Lab 的渲染时间来动态调整其节奏。如果渲染时间变化很大,这可能导致在 XR 渲染时仿真看起来加速或减速。如果出现此问题,CloudXR 可以通过在启动 CloudXR Runtime Docker 容器时将环境变量 NV_PACER_FIXED_TIME_STEP_MS 设置为整数来配置使用固定时间步。

尝试在 CPU 上运行物理计算

目前建议尝试使用 --device cpu 标志在 Isaac Lab 远程操作脚本上运行。这将导致物理计算在 CPU 上进行,当仿真中只有一个环境时可能会降低延迟。

使用 XR 设备输入控制机器人#

Isaac Lab 提供了一个灵活的架构,用于使用 XR 跟踪数据来控制仿真机器人。本节解释了这种架构的组件以及它们如何相互配合。

OpenXR 设备#

isaaclab.devices.OpenXRDevice 是 Isaac Lab 中启用基于 XR 的远程操作的核心组件。该设备与 CloudXR 接口,从 XR 头显接收跟踪数据并将其转换为机器人控制命令。

在本质上,XR 远程操作需要将用户输入(如手部移动和姿势)映射(或 “重映射” )为机器人控制信号。Isaac Lab 通过其 OpenXRDevice 和 Retargeter 架构使其变得简单。OpenXRDevice 通过 Isaac Sim 的 OpenXR API 捕获手部跟踪数据,然后通过一个或多个 Retargeters 将其转换为机器人动作。

在使用 CloudXR 时,OpenXRDevice 还与 XR 设备的用户界面集成,允许用户直接从他们的 XR 环境触发仿真事件。

重映射架构#

Retargeters 是将原始跟踪数据转换为有意义的机器人控制信号的专业组件。它们实现了 isaaclab.devices.RetargeterBase 接口,并在初始化期间传递给 OpenXRDevice。

Isaac Lab 提供了三种主要的手部跟踪 retargeters:

Se3RelRetargeter (isaaclab.devices.openxr.retargeters.Se3RelRetargeter)
  • 从相对手部运动生成增量机器人命令

  • 适用于精确操纵任务

Se3AbsRetargeter (isaaclab.devices.openxr.retargeters.Se3AbsRetargeter)
  • 将手部位置直接映射到机器人末端执行器位置

  • 实现了1:1的空间控制

GripperRetargeter (isaaclab.devices.openxr.retargeters.GripperRetargeter)
  • 根据拇指-食指距离控制夹具状态

  • 与位置 retargeters 一起用于完整的机器人控制

GR1T2Retargeter (isaaclab.devices.openxr.retargeters.GR1T2Retargeter)
  • 将 OpenXR 手部跟踪数据重新定位到 GR1T2 手部末端执行器命令

  • 处理左手和右手,将手部姿势转换为 GR1T2 机器人手的关节角度

  • 支持跟踪手部关节的可视化

UnitreeG1Retargeter (isaaclab.devices.openxr.retargeters.UnitreeG1Retargeter)
  • 使用 Inspire 5 指手部末端执行器命令将 OpenXR 手部跟踪数据重定向到 Unitree G1

  • 处理左手和右手,将手部姿态转换为 G1 机器人手部的关节角度

  • 支持跟踪手部关节的可视化

可以组合 retargeters 以同时控制不同的机器人功能。

使用带有手部跟踪的 Retargeters#

以下是设置手部跟踪的示例:

from isaaclab.devices import OpenXRDevice, OpenXRDeviceCfg
from isaaclab.devices.openxr.retargeters import Se3AbsRetargeter, GripperRetargeter

# Create retargeters
position_retargeter = Se3AbsRetargeter(
    bound_hand=OpenXRDevice.TrackingTarget.HAND_RIGHT,
    zero_out_xy_rotation=True,
    use_wrist_position=False  # Use pinch position (thumb-index midpoint) instead of wrist
)
gripper_retargeter = GripperRetargeter(bound_hand=OpenXRDevice.TrackingTarget.HAND_RIGHT)

# Create OpenXR device with hand tracking and both retargeters
device = OpenXRDevice(
    OpenXRDeviceCfg(xr_cfg=env_cfg.xr),
    retargeters=[position_retargeter, gripper_retargeter],
)

# Main control loop
while True:
    # Get the latest commands from the XR device
    commands = device.advance()
    if commands is None:
        continue

    # Apply the commands to the environment
    obs, reward, terminated, truncated, info = env.step(commands)

    if terminated or truncated:
        break

这是用于人形机器人远程操作的数据流和算法图。使用 Apple Vision Pro,我们为每只手收集 26 个关键点。腕部关键点用于控制手部末端执行器,而其余的手部关键点用于手部重定向。

teleop_diagram

对于灵巧手重定向,我们目前使用 Dexpilot 优化器,它依赖于五个指尖和手掌进行重定向。用于重定向的链接必须准确地定义在指尖处——而不是手指中间——以确保准确的优化。请参考下面的图像进行手部资产选择,找到合适的手部资产,或根据需要在 IsaacLab 中添加指尖链接。

hand_asset

为 XR UI 事件添加回调#

The OpenXRDevice 可以处理由用户与 XR UI 元素(如按钮和菜单)互动触发的事件。当用户与这些元素交互时,设备会触发已注册的回调函数:

# Register callbacks for teleop control events
device.add_callback("RESET", reset_callback)
device.add_callback("START", start_callback)
device.add_callback("STOP", stop_callback)

当用户与 XR UI 交互时,这些回调将被触发以控制仿真或录制过程。您还可以使用客户端自定义键添加自定义消息,这些消息将触发这些回调,从而允许通过直接用户互动的编程方式控制仿真。自定义键可以是与回调注册匹配的任何字符串值。

远程操控环境配置#

基于 XR 的远程操作可以通过在您的环境配置中使用 teleop_devices 字段集成到 Isaac Lab 的环境配置系统中:

from dataclasses import field
from isaaclab.envs import ManagerBasedEnvCfg
from isaaclab.devices import DevicesCfg, OpenXRDeviceCfg
from isaaclab.devices.openxr import XrCfg
from isaaclab.devices.openxr.retargeters import Se3AbsRetargeterCfg, GripperRetargeterCfg

@configclass
class MyEnvironmentCfg(ManagerBasedEnvCfg):
    """Configuration for a teleoperation-enabled environment."""

    # Add XR configuration with custom anchor position
    xr: XrCfg = XrCfg(
        anchor_pos=[0.0, 0.0, 0.0],
        anchor_rot=[1.0, 0.0, 0.0, 0.0]
    )

    # Define teleoperation devices
    teleop_devices: DevicesCfg = field(default_factory=lambda: DevicesCfg(
        # Configuration for hand tracking with absolute position control
        handtracking=OpenXRDeviceCfg(
            xr_cfg=None,  # Will use environment's xr config
            retargeters=[
                Se3AbsRetargeterCfg(
                    bound_hand=0,  # HAND_LEFT enum value
                    zero_out_xy_rotation=True,
                    use_wrist_position=False,
                ),
                GripperRetargeterCfg(bound_hand=0),
            ]
        ),
        # Add other device configurations as needed
    ))

遥控设备工厂#

要从您的环境配置中创建远程操作设备,请使用 create_teleop_device 工厂函数:

from isaaclab.devices import create_teleop_device
from isaaclab.envs import ManagerBasedEnv

# Create environment from configuration
env_cfg = MyEnvironmentCfg()
env = ManagerBasedEnv(env_cfg)

# Define callbacks for teleop events
callbacks = {
    "RESET": lambda: print("Reset simulation"),
    "START": lambda: print("Start teleoperation"),
    "STOP": lambda: print("Stop teleoperation"),
}

# Create teleop device from configuration with callbacks
device_name = "handtracking"  # Must match a key in teleop_devices
device = create_teleop_device(
    device_name,
    env_cfg.teleop_devices,
    callbacks=callbacks
)

# Use device in control loop
while True:
    # Get the latest commands from the device
    commands = device.advance()
    if commands is None:
        continue

    # Apply commands to environment
    obs, reward, terminated, truncated, info = env.step(commands)

扩展 Retargeting 系统#

重定向系统被设计为可扩展的。您可以按照以下步骤创建自定义的重定向器:

  1. 为您的重新定位者创建一个配置数据类:

from dataclasses import dataclass
from isaaclab.devices.retargeter_base import RetargeterCfg

@dataclass
class MyCustomRetargeterCfg(RetargeterCfg):
    """Configuration for my custom retargeter."""
    scaling_factor: float = 1.0
    filter_strength: float = 0.5
    # Add any other configuration parameters your retargeter needs
  1. 通过扩展 RetargeterBase 类来实现您的 retargeter 类:

from isaaclab.devices.retargeter_base import RetargeterBase
from isaaclab.devices import OpenXRDevice
import torch
from typing import Any

class MyCustomRetargeter(RetargeterBase):
    """A custom retargeter that processes OpenXR tracking data."""

    def __init__(self, cfg: MyCustomRetargeterCfg):
        """Initialize retargeter with configuration.

        Args:
            cfg: Configuration object for retargeter settings.
        """
        super().__init__()
        self.scaling_factor = cfg.scaling_factor
        self.filter_strength = cfg.filter_strength
        # Initialize any other required attributes

    def retarget(self, data: dict) -> Any:
        """Transform raw tracking data into robot control commands.

        Args:
            data: Dictionary containing tracking data from OpenXRDevice.
                Keys are TrackingTarget enum values, values are joint pose dictionaries.

        Returns:
            Any: The transformed control commands for the robot.
        """
        # Access hand tracking data using TrackingTarget enum
        right_hand_data = data[OpenXRDevice.TrackingTarget.HAND_RIGHT]

        # Extract specific joint positions and orientations
        wrist_pose = right_hand_data.get("wrist")
        thumb_tip_pose = right_hand_data.get("thumb_tip")
        index_tip_pose = right_hand_data.get("index_tip")

        # Access head tracking data
        head_pose = data[OpenXRDevice.TrackingTarget.HEAD]

        # Process the tracking data and apply your custom logic
        # ...

        # Return control commands in appropriate format
        return torch.tensor([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0])  # Example output
  1. 通过将其添加到 RETARGETER_MAP 中,使用工厂注册您的重定向器。

# Import your retargeter at the top of your module
from my_package.retargeters import MyCustomRetargeter, MyCustomRetargeterCfg

# Add your retargeter to the factory
from isaaclab.devices.teleop_device_factory import RETARGETER_MAP

# Register your retargeter type with its constructor
RETARGETER_MAP[MyCustomRetargeterCfg] = MyCustomRetargeter
  1. 现在您可以在 teleop 设备配置中使用自定义的 retargeter:

from isaaclab.devices import OpenXRDeviceCfg, DevicesCfg
from isaaclab.devices.openxr import XrCfg
from my_package.retargeters import MyCustomRetargeterCfg

# Create XR configuration for proper scene placement
xr_config = XrCfg(anchor_pos=[0.0, 0.0, 0.0], anchor_rot=[1.0, 0.0, 0.0, 0.0])

# Define teleop devices with custom retargeter
teleop_devices = DevicesCfg(
    handtracking=OpenXRDeviceCfg(
        xr_cfg=xr_config,
        retargeters=[
            MyCustomRetargeterCfg(
                scaling_factor=1.5,
                filter_strength=0.7,
            ),
        ]
    ),
)

随着 OpenXR 能力的扩展超出手部跟踪以涵盖头部跟踪和其他功能,可以开发额外的 retargeters 将这些数据映射到各种机器人控制范式。

创建自定义遥控设备#

您可以按照以下步骤创建并注册自定义遥操作设备:

  1. 创建一个用于您的设备的配置数据类:

from dataclasses import dataclass
from isaaclab.devices import DeviceCfg

@dataclass
class MyCustomDeviceCfg(DeviceCfg):
    """Configuration for my custom device."""
    sensitivity: float = 1.0
    invert_controls: bool = False
    # Add any other configuration parameters your device needs
  1. 通过继承 DeviceBase 类来实现您的设备类:

from isaaclab.devices import DeviceBase
import torch

class MyCustomDevice(DeviceBase):
    """A custom teleoperation device."""

    def __init__(self, cfg: MyCustomDeviceCfg):
        """Initialize the device with configuration.

        Args:
            cfg: Configuration object for device settings.
        """
        super().__init__()
        self.sensitivity = cfg.sensitivity
        self.invert_controls = cfg.invert_controls
        # Initialize any other required attributes
        self._device_input = torch.zeros(7)  # Example: 6D pose + gripper

    def reset(self):
        """Reset the device state."""
        self._device_input.zero_()
        # Reset any other state variables

    def add_callback(self, key: str, func):
        """Add callback function for a button/event.

        Args:
            key: Button or event name.
            func: Callback function to be called when event occurs.
        """
        # Implement callback registration
        pass

    def advance(self) -> torch.Tensor:
        """Get the latest commands from the device.

        Returns:
            torch.Tensor: Control commands (e.g., delta pose + gripper).
        """
        # Update internal state based on device input
        # Return command tensor
        return self._device_input
  1. 将您的设备注册到远程操作设备工厂,方法是将其添加到 DEVICE_MAP :

# Import your device at the top of your module
from my_package.devices import MyCustomDevice, MyCustomDeviceCfg

# Add your device to the factory
from isaaclab.devices.teleop_device_factory import DEVICE_MAP

# Register your device type with its constructor
DEVICE_MAP[MyCustomDeviceCfg] = MyCustomDevice
  1. 现在您可以在环境配置中使用您的自定义设备:

from dataclasses import field
from isaaclab.envs import ManagerBasedEnvCfg
from isaaclab.devices import DevicesCfg
from my_package.devices import MyCustomDeviceCfg

@configclass
class MyEnvironmentCfg(ManagerBasedEnvCfg):
    """Environment configuration with custom teleop device."""

    teleop_devices: DevicesCfg = field(default_factory=lambda: DevicesCfg(
        my_custom_device=MyCustomDeviceCfg(
            sensitivity=1.5,
            invert_controls=True,
        ),
    ))

已知问题#

  • XR_ERROR_VALIDATION_FAILURE: xrWaitFrame(frameState->type == 0) when stopping AR Mode

    此错误消息可以安全地忽略。这是由 AR 模式的退出处理程序中的竞争条件引起的。

  • XR_ERROR_INSTANCE_LOST in xrPollEvent: Call to "xrt_session_poll_events" failed

    如果 CloudXR 运行时在 Isaac Lab 之前退出,可能会发生此错误。重新启动 CloudXR 运行时以恢复远程操作。

  • [omni.usd] TF_PYTHON_EXCEPTION when starting/stopping AR Mode

    此错误消息可以安全地忽略。这是由 AR 模式的进入/退出处理程序中的竞争条件引起的。

  • Invalid version string in _ParseVersionString

    这个错误消息可能是由使用较旧版本的 USD 创作的着色器资产引起的,通常可以忽略。

  • XR 设备成功连接,但未显示视频,即使 Isaac Lab 视口响应跟踪。

    当主机和容器之间的 GPU 索引不同时,会发生此错误,导致 CUDA 加载到错误的 GPU 上。要解决此问题,请在运行时容器中将 NV_GPU_INDEX 设置为 012 ,以确保 CUDA 选择的 GPU 与主机匹配。

Kubernetes 部署#

有关在 Kubernetes 集群上部署用于 Isaac Lab 的 XR Teleop 的信息,请参阅 在 Kubernetes 上部署 CloudXR 远程操作