场景数据提供器#

SceneDataProvider 连接物理仿真后端与使用场景数据的可视化器/渲染器。无论启用哪个物理后端,它都提供统一的 Warp 原生读取路径,获取刚体变换和可视几何,使渲染器与可视化器无需依赖具体物理后端。

概述#

Isaac Lab 支持多个物理后端(PhysX 和 Newton)及可视化器(Omniverse Kit、Newton、Rerun、Viser)。每种组合都需要将场景数据从物理引擎传递到渲染器或可视化器。 SceneDataProvider 负责这一数据流:物理管理器提供 SceneDataBackend ,包装原生张量视图;提供器在其上处理格式转换和重新映射。

from isaaclab.sim import SimulationContext

# The SimulationContext owns the active provider; consumers fetch it instead of
# constructing one directly.
provider = SimulationContext.instance().get_scene_data_provider()

架构#

惰性读取约定#

使用 TimestampedBuffer 将缓存数据与最近一次成功更新的时间戳配对。存储由数据所有者分配,容器本身不分配或转换数据。同一步内的写入通过 reset_timestamps 使受影响的资产缓存失效,并推进 SDP 的发布时间戳。请求数据后,各使用者比较自己的时间戳,因为解析原生指针本身也可能发现变化。只跟踪上传操作的使用者只需时间戳,无需再保存一份 SDP 数据引用。

SDP 读取器采用与资产数据相同的时间戳检查机制,缓存缓冲区和映射数据,不使用绑定工厂或存储的更新回调。匹配的原生数组绕过转换。调用方管理的目标仅通过弱引用保存,因此调用方释放目标后,其缓存映射也会失效。

待执行工作由其执行者管理。Newton 的 forward() 和 PhysX/OVPhysX 的 update_kinematics() 在内部检查 kinematics_dirty ,成功后清除;读取器直接调用操作,无需检查该标志。重排后的关节体视图仍会刷新自身的派生数组。传感器和 Newton 共享 BVH 同样使用脏标志,设备掩码选择需要处理的环境。应保留即时接触读取,以检测接触消失。

采样周期和有限差分使用仿真时间 [s];Fabric 几何更新周期使用渲染帧数。两者都不是发布计数器。CUDA 图回放时不会执行 Python 条件检查,因此捕获的工作必须保留在图中,或使用设备端失效机制。Newton 保留选择性重置掩码,并在外部回放写入后采用保守读取。

数据流#

系统有三层:

  1. SceneDataBackend :各物理管理器实现的小型接口。它将后端变换数组直接作为 SceneDataFormat 中的一种 Warp 结构提供,同时给出每个变换的 prim 路径和总数。原生状态写入或缓冲区交换后,数据生产者递增 transforms_timestamp 。SDP 在读取时间戳前调用 get_transforms(output_format) ,因为解析指针本身可能检测到交换。默认实现返回已有的 transforms 属性。这是逻辑发布时间戳,不是经过的时间,在后端生命周期内不会重置,因此独立读取器不会相互掩盖变化。

    • SceneDataBackend.transforms :Warp 结构形式的原生数据( SceneDataFormat.Vec3_Quat 、 SceneDataFormat.Transform 、 SceneDataFormat.Matrix44 或 SceneDataFormat.Vec3_Matrix33 )。

    • SceneDataBackend.transforms_timestamp :原生变换的逻辑更新时间戳。

    • SceneDataBackend.transform_count :变换数量。

    • SceneDataBackend.transform_paths :USD prim 路径列表,每个变换对应一个路径。

    • SceneDataBackend.native_transform_formats :无需转换即可提供的格式。PhysX 提供打包位姿或 Fabric 矩阵,只刷新请求的表示形式。

    • SceneDataBackend.get_geometry_batches() :原生点数组或插值输入,配对后端构建时编译得到的精确可视 prim 路径和范围。请求的原生表示可用时直接返回,否则返回主要表示,由 SDP 转换。返回类型始终为批次列表,包括原生 Fabric 情况。

    • SceneDataBackend.geometry_timestamp :逻辑更新时间戳,同一步内的写入和原生指针交换都会推进它。与资产数据缓冲区一样,缓存输出记录其所包含数据的时间戳。这不是已过的仿真时间,也不是由某个读取器清除的共享脏标志。

    • SceneDataBackend.native_geometry_formats :无需转换即可获得的几何格式。

  2. SceneDataProvider :包装后端,提供格式转换和索引重新映射。

    • SceneDataProvider.get_transforms() :格式与顺序匹配时绑定原生数组,否则绑定 SDP 管理的缓冲区;对每个生产者时间戳和目标布局只转换一次。这些共享数组只读,即使它们替换了预分配的输出字段。传入 allow_passthrough=False ,则直接写入调用方管理的数组。

    • SceneDataProvider.create_mapping() :构建从后端 prim 路径到使用者期望顺序的重映射数组。当渲染器或可视化器希望按自己的刚体列表、而非物理视图顺序索引变换时使用。

    • SceneDataProvider.get_geometry_points() :按精确可视 prim 路径索引的只读世界空间点视图。原生点范围直接引用生产者数据;插值与目标重排融合为一次缓存转换。使用固定原生存储的使用者,将该数组或 FabricPoints 作为 output ,将可视路径偏移作为 offsets 传入。调用返回所提供的目标。目标缓存保留索引元数据,不保留使用者缓冲区,并随目标释放而失效。

    • SceneDataProvider.get_camera_transforms() :从 USD 舞台发现各相机、各环境的世界变换。

    • SceneDataProvider.num_envs :从 /World/envs/env_<id> prim 推断的环境数量。

  3. 后端实现:

    • PhysxSceneDataBackend (位于 isaaclab_physx.physics 内部)包装 PhysX 的 RigidBodyView ,以 SceneDataFormat.Transform 提供变换。存在可变形物体时,还通过 SceneDataFormat.Points 提供展平的仿真节点位置。

    • OvPhysxSceneDataBackend (位于 isaaclab_ov.physics 内部)对刚体变换和 OVPhysX 可变形节点张量采用与 PhysX 相同的约定。

    • NewtonSceneDataBackend (位于 isaaclab_newton.physics 内部)包装 Newton 模型的 body_q ,以 SceneDataFormat.Transform 提供。

PhysX 后端#

使用 PhysX 物理后端时,提供器直接从 PhysX 的 RigidBodyView 读取变换,这是一个经通配符展开、覆盖所有环境中全部刚体的张量视图。变换以 SceneDataFormat.Transform (Warp transformf 数组)返回,因此需要这种格式的使用者可零拷贝获取数据。

Newton 原生使用者(Newton 可视化器、Rerun、Viser、Newton Warp 渲染器)还需要 Newton Model/State 。它们声明的克隆上下文在初始化前,根据共享克隆计划构建该表示。刚体 body_q 绑定 SDP 请求的 Transform 数组,无需每帧再拷贝到第二个状态缓冲区。OVRTX 直接向 SDP 请求 TransposedMatrix44d ,在同一次转换中处理目标顺序和静态缩放,不再从 Newton 状态读取刚体变换。对于仿真网格与可视网格不同的可变形物体,生产者根据声明的原型只编译一次重心坐标索引和权重。SDP 将插值结果直接写入 Newton 表示最终的 particle_q 槽位,无需中间的仿真规模缓冲区,也无需使用者自行重映射。原生 PhysX 带填充的节点数组直接借用,无需重新打包。

OVRTX 通过 SDP 接收同样的精确可视路径数据。它不导入 Newton 管理器,也不请求 Newton 模型。网格、粒子云和线缆曲线使用统一的点绑定路径。

PhysX 负责原生 Fabric 刷新,并通过 SDP 提供所得矩阵,无需获取打包位姿。 isaaclab_physx.renderers.fabric.FabricBackend 管理共享的原生舞台和层级句柄。该资源由舞台和设备唯一标识,而非 SDP 来源或属性类型。物理初始化后,Kit、Isaac RTX 和显式 Fabric 同步通过 sim.get_or_create_backend(FabricBackendCfg(stage=sim.stage, device=sim.device)) 获取同一资源。仿真注册表无需预先知道存在哪些后端。变换绑定是该资源上的状态,不是独立后端。使用者将仿真的 SDP 传给 update_transforms(provider) ;对于其他物理后端,它直接转换为 Fabric 局部矩阵,再传播 GPU 层级。核心 RenderContext 不管理 Fabric 绑定。由于物理提供绝对位姿(嵌套刚体也如此),它将刚体目标绑定为仅在 Fabric 中重置变换栈的根节点。可视后代仍继承所属刚体的变换,已编写的 USD 不变。原生源索引和世界缩放只绑定一次。Fabric 的选择复用 API 报告场景级结构变化;资源刷新数组视图,无需重复路径匹配或缩放获取。其他情况下,GPU 传播复用层级拓扑。没有变化的请求从不获取可写 Fabric 数组。渲染器不选择特定物理后端的同步路径。同一 Fabric 资源通过 update_geometries(provider, frame) 接收几何。PhysX 直接提供原生 FabricPoints ,无需转换或重写。其他后端的网格点直接插值到 GPU Fabric 存储中。当前 Kit Hydra 路径要求 Points 和 BasisCurves 使用 CPU Fabric 目标,SDP 负责设备传输,无需写入 USD 属性。只传输已到更新间隔的目标。世界空间点目标会重置变换栈,避免重复应用环境或刚体位姿。 FabricMatrix44 和 FabricPoints 仅包含数组存储,不包含绑定或原生引擎句柄。

Newton 后端#

使用 Newton 物理后端时,后端直接包装 Newton 模型的 body_q 。无需影子模型或逐帧同步:Newton 已管理权威模型和状态,提供器将该状态以 SceneDataFormat.Transform 暴露。

原生读取会统一处理待生效的状态写入,只执行一次。新的物理数据发布本身不要求执行正向运动学。Kit/RTX 在渲染前通过 SDP 请求当前 Fabric 变换,无需额外调用物理 forward() 。无界面视口采集按需请求这些变换,而非每个可视化器步都请求。

外部回放的 CUDA 图不会调用 Python 写入钩子。写入被捕获后,Newton 会在读取时保守地重新发布变换,避免未通知的回放使渲染数据过时。这类读取无法利用未变化数据的发布缓存。

几何数据发布#

Newton 可变形物体和 MPM 的位置是原生 particle_q 范围的直接视图。线缆数据借用原生刚体位姿和胶囊体参数,SDP 对每个更新时间戳只计算一次曲线端点。相机渲染器和查看器使用同一缓存结果。

ClonePlan 始终是通用的复制与分发描述。资产构造时编写原型几何,原生导入将这些原型与计划组合,并记录原生范围。使用者绑定到这些已完成的资源,不会再次遍历已完成的舞台进行发现。

# Default: read-only native or converted views, cached by producer timestamp.
points_by_path = provider.get_geometry_points()

# A consumer with fixed native storage receives the conversion directly.
provider.get_geometry_points(output=state.particle_q, offsets=visual_path_offsets)

# A Fabric consumer supplies native storage and its exact visual-path row indices.
provider.get_geometry_points(output=fabric_points, offsets=visual_path_rows)

内部的展平节点查询和由物理管理的几何同步方法已移除。渲染使用者改用 get_geometry_points ;物理管理器不再从 pre_render 运行几何写入器。

变换转换缓存使用 TimestampedBuffer ,与资产数据使用相同的数据/时间戳容器。仅在需要转换时分配存储,转换成功后才确认数据已更新。匹配的原生格式仍直接传递,不分配存储。即使物理状态未变,更换 Fabric 目标也会使缓存绑定失效。

与关节体和刚体物体数据一样,当前时间戳与缓存缓冲区时间戳用途不同:一个标识当前状态,另一个标识缓冲区中的状态。资产数据随时间推进 _sim_timestamp ,并在同一步内写入时使依赖缓冲区失效。SDP 则在这些写入时推进 geometry_timestamp ,使独立更新的使用者都能看到变化。输出缓存负责自身的新鲜度检查;下游上传或 BVH 可能需要自己的失效机制,但不应重复管理转换缓存的状态。

数据需求#

可视化器和渲染器声明自己需要的场景数据。在构造使用者时、共享克隆计划构建前,就会确定这些需求:

组件

需要 Newton 模型

需要 USD 舞台

Kit 可视化器

No

Yes

Newton 可视化工具

Yes

No

Rerun 可视化器

Yes

No

Viser 可视化器

Yes

No

Isaac RTX 渲染器

No

Yes

Newton Warp 渲染器

Yes

No

OVRTX 渲染器

No

Yes

另请参阅#

  • 渲染器 :使用场景数据的渲染器后端

  • 可视化 :使用场景数据的可视化器后端