尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Newton 保留 OpenUSD 碰撞组过滤语义:inverted filters、merged groups 与多成员关系导入解析

Newton 保留 OpenUSD 碰撞组过滤语义:inverted filters、merged groups 与多成员关系导入解析 Newton 保留 OpenUSD 碰撞组过滤语义inverted filters、merged groups 与多成员关系导入解析【免费下载链接】newtonAn open-source, GPU-accelerated physics simulation engine built upon NVIDIA Warp, specifically targeting roboticists and simulation researchers.项目地址: https://gitcode.com/GitHub_Trending/newton9/newton导读本文围绕 Newton基于 NVIDIA Warp 的 GPU 加速物理仿真引擎的 USD 导入管线展开深入讲解其如何将 OpenUSDUsdPhysics中通过CollisionGroup、physics:filteredPairs表达的碰撞过滤规则完整地保留到ModelBuilder中。文章覆盖反向过滤inverted filters、合并组merged groups、多重成员关系multiple memberships与未分组碰撞体ungrouped colliders四类关键语义并结合 import_usd.py 源码与 test_import_usd_collision_groups.py 测试用例给出可直接复用的导入验证方法。读完本文你将理解 OpenUSD 碰撞过滤与 Newton 碰撞组 ID、过滤配对filter pairs两套机制之间的映射原理并能自行排查资产导入后的碰撞丢失问题。OpenUSD 碰撞过滤的两套表达机制在 USD 资产中碰撞过滤可以出现在两个层级Newton 的导入器对两者都做了处理UsdPhysics.CollisionGroup碰撞组把多个碰撞体归入一个命名组再通过组与组之间的filteredGroups关系声明哪些组之间禁止碰撞。这是一个默认允许、显式禁用allow-by-default的模型。physics:filteredPairs关系直接在两个图元collider、body 或 articulation prim之间声明这对对象不碰撞属于按实体精确过滤可标注在任一端点上且语义是对称的。Newton 自身则提供了一套基于整数碰撞组 ID的机制见 builder.py 中ShapeConfig.collision_group默认值为1即默认组设为0则禁用该形状的所有碰撞以及形状级过滤配对shape_collision_filter_pairs无序的(shape_a, shape_b)索引对见 builder.py。两套语义并不一一对应因此导入器必须做一次显式的降级lowering把 OpenUSD 组级过滤展开成 Newton 的逐形状过滤配对。changelog 记录changelog/4145.fixed.md正是这一修复在 USD 导入期间完整保留碰撞组过滤包括反向过滤、合并组、多重成员关系以及未分组碰撞体。Newton 碰撞组 ID 的判定逻辑要理解导入器为什么要显式展开先看 Newton 本地碰撞组的判定规则。ModelBuilder._test_group_pair(group_a, group_b)builder.py与 GPU 端broad_phase_common.test_group_pairkernel 保持完全一致任一组为0不碰撞0是禁用哨兵值组为正数仅当group_a group_b或对方为负数时碰撞同组或与任意组交互组为负数仅当group_a ! group_b时碰撞负组表示与其它所有非本组对象碰撞。可见该模型是等值匹配的整数语义无法直接表达 OpenUSD 中组 A 与组 B 禁止碰撞但 A 与 C 允许碰撞这种任意图结构。因此导入器必须把 OpenUSD 的禁用关系物化为显式的add_shape_collision_filter_pair配对而不是试图把组名翻译成整数 ID。源码注释也明确指出OpenUSD groups are allow-by-default filters and cannot be represented by Newtons equality-based collision group IDs, so their disabled pairs are lowered explicitly after all rigid shapes existimport_usd.py。与此同时导入器会把 builder 的默认collision_group来自builder.default_shape_cfg.collision_group保留到每个导入形状上使得调用方仍然可以用0或共享负组来整体关闭碰撞测试test_nonpositive_builder_collision_groups验证了默认组为0或-1时所有导入形状保留该默认值且任意两形状之间_test_group_pair均返回 False见 test_import_usd_collision_groups.py。导入期的核心流程从组到配对整个降级流程位于 import_usd.py 的导入主体中可以分为四个阶段阶段一收集每个碰撞体的组成员身份。解析每个刚体碰撞体时记录其完整成员签名tuple(sorted(str(group) ...))import_usd.py存入imported_rigid_collider_groups: dict[path, tuple[str, ...]]。之所以保留完整签名而非单个组是因为一个碰撞体可能同时属于多个组。阶段二计算 OpenUSD 的碰撞组判定表。通过UsdPhysics.CollisionGroup.ComputeCollisionGroupTable(stage)一次性算出任意两个组之间是否允许碰撞import_usd.py。ComputeCollisionGroupTable是 OpenUSD 提供的标准 API它会综合filteredGroups关系与invertFilteredGroups属性给出权威结论导入器直接复用避免自己重写组图遍历逻辑。阶段三按成员签名分桶后物化禁用配对。所有碰撞体按其完整成员签名分组colliders_by_groups这样表查询次数只与不同组组合的数量成正比而只物化 OpenUSD 真正禁用的配对import_usd.py。对每一对组签名调用_groups_collide(groups_a, groups_b)两侧都有组时要求所有组对在collision_group_table.IsCollisionEnabled(...)上全部为 True 才允许碰撞全真才真只有一侧有组另一侧是未分组碰撞体时退化为检查该侧组成员——若其中任一成员组或其合并组集合属于 inverted 组则不允许碰撞见下节。只要判定为不碰撞就把签名内所有碰撞体两两组合组内用itertools.combinations跨组用itertools.product以规范化顺序(min, max)调用builder.add_shape_collision_filter_pair加入过滤配对并先去重已存在的配对existing_filter_pairs。阶段四处理physics:filteredPairs关系。导入器会遍历所有 prim收集标注了physics:filteredPairs关系的图元_collect_filtered_pairs将源-目标路径排序后去重存入集合关系可能只在单端标注Newton 的过滤配对是对称的自配对无效被跳过见 import_usd.py。由于physics:filteredPairs可以标注在 body 甚至 articulation prim 上collider 循环不会访问 body prim导入器在 body 路径表path_body_map上再做一遍收集import_usd.py。随后通过_resolve_collision_shape_ids把路径解析为实际 shape 索引原生 collider 路径 → 单个 shapebody 路径 → 其下所有 shapecable 路径 → 其全部胶囊 shapecloth / volume 粒子形变体 → 明确返回不支持标准粒子碰撞过滤无法表达import_usd.py。解析失败目标不存在、未产生碰撞参与者等时会输出带具体原因的warnings.warn提示该filteredPairs未被导入import_usd.py。只有在所有刚体 shape 与 cable 胶囊都已创建后才会应用这些配对shape 索引此后保持稳定collapse_fixed_joints只重映射 body且与阶段三共用同一个去重集合避免重复追加。四类关键语义的逐一解析反向过滤Inverted FiltersOpenUSD 允许在组上设置invertFilteredGroups属性UsdPhysics.CollisionGroup.CreateInvertFilteredGroupsAttr()含义为与该组被过滤的组之外的其它组都禁止碰撞。导入器在遍历 stage 时把所有反向组收集进inverted_groups集合import_usd.py并在_groups_collide的单侧分支中生效只要未分组碰撞体那一侧涉及的任一组成员或其合并组属于反向组就判定为不碰撞。测试用例test_normal_and_inverted_filteringtest_import_usd_collision_groups.py构造了 GroupC 反向过滤 GroupB 的场景验证最终过滤配对包含A0-A1组内自过滤、A0-B、A1-B正常跨组过滤、A0-C、A1-C反向组与正常组的交互以及C-Ungrouped反向组对未分组碰撞体生效——反向过滤会把未被显式过滤的组也纳入禁用范围这正是反向语义的关键体现。合并组Merged GroupsOpenUSD 的mergeGroupName属性UsdPhysics.CollisionGroup.CreateMergeGroupNameAttr()可以把多个命名组合并为一个逻辑实体同名的合并组共享同一过滤行为。导入器构建了groups_by_merge_name: dict[merge_name, set[group_path]]与group_merge_names: dict[group_path, merge_name]import_usd.py在_groups_collide中若一个组的merge_name非空其有效组成员会展开为该合并名下所有组只要其中任一有效组属于反向组即不允许碰撞。测试用例test_merged_groups_and_multiple_membershipstest_import_usd_collision_groups.py中MergedGroupA 与 MergedGroupB 共享merge_groupshared且 MergedGroupA 过滤了 FilteredGroup于是合并语义下 MergedB 同样与 Filtered 不碰撞验证结果(MergedA, Filtered), (MergedB, Filtered)都出现在过滤配对中。多重成员关系Multiple Memberships一个碰撞体可以同时属于多个组导入器以完整成员签名全部组路径的排序元组作为分桶键天然支持多成员场景签名相同的碰撞体共享同一判定结果。测试中Multi同时加入 MultiGroupA 与 MultiGroupBMultiGroupA 过滤了 FilteredGroup因此Multi-Filtered被禁用而 MultiGroupB 中的Other不受影响。未分组碰撞体Ungrouped Colliders没有加入任何组的碰撞体属于默认允许状态但仍受反向过滤约束。_groups_collide的if groups_a and groups_b:分支在任一侧为空时走单侧逻辑对空侧之外的那组做反向组检查从而保证未分组碰撞体与反向组碰撞被正确禁用而普通组与未分组碰撞体之间保持允许test_unfiltered_and_ungrouped_colliders验证普通组 A、B 与未分组碰撞体之间无任何过滤配对见 test_import_usd_collision_groups.py。组过滤与配对过滤的合成语义当 OpenUSD 资产同时使用CollisionGroup过滤和physics:filteredPairs时两者的禁用效果是叠加的任一机制要求禁用某对 shape该对即被禁用。测试test_group_filters_compose_with_filtered_pairstest_import_usd_collision_groups.py同时构造了基于physics:filteredPairs的 PairA-PairB 与基于组的 GroupA-GroupB 过滤并断言两类配对都出现在builder.shape_collision_filter_pairs中。从实现看阶段三与阶段四共用existing_filter_pairs去重集合且在导入完成后ModelBuilder.finalize()会对组判定_test_group_pair与过滤配对做与运算来确定最终是否碰撞测试的_assert_filtered_pairs断言逻辑正是group_pair_enabled and pair not in filtered_pairs见 test_import_usd_collision_groups.py。与 MJCF 混用紧凑过滤配对的保留shape_collision_filter_pairs在 Newton 内部存在一种紧凑表示_BuilderShapeCollisionFilterPairs用于合并 builder 时保持对象身份稳定以命中模板缓存_materialized_filter_template见 builder.py。这保证了先导入 USD 再追加 MJCF的混合场景下USD 侧产生的过滤配对不会被破坏。测试test_mjcf_import_after_usdtest_import_usd_collision_groups.py演示了标准用法注册 MuJoCo 求解器自定义属性后先builder.add_usd(stage)再builder.add_mjcf(...)最终两个 shape 都正确进入 builder。如何验证与排查仓库提供了完整的回归测试可直接运行验证导入语义python -m unittest newton.tests.test_import_usd_collision_groups需要安装usd-core否则测试会被unittest.skipUnless(USD_AVAILABLE, Requires usd-core)跳过见 test_import_usd_collision_groups.py。测试中的_assert_filtered_pairs是一个值得借鉴的验证模板它把期望的禁用形状对与builder.shape_collision_filter_pairs的实际内容比对并同时用_test_group_pair校验组判定确保组与配对两个维度都符合预期。排查真实资产时可以按同样思路遍历builder.shape_collision_filter_pairs并留意导入期warnings.warn输出的physics:filteredPairs was not imported提示——那通常意味着某个过滤端点无法解析到实际 shape如粒子形变体或不存在的路径。小结Newton 对 OpenUSD 碰撞过滤的导入遵循组默认允许、禁用显式物化的原则用UsdPhysics.CollisionGroup.ComputeCollisionGroupTable获得权威组判定把完整成员签名分桶后降级为逐 shape 的shape_collision_filter_pairs并对反向过滤、合并组、多成员与未分组碰撞体四类边界语义做了完整覆盖physics:filteredPairs关系则通过路径解析到 shape 后按对称去重追加。这套实现使基于 OpenUSD 生态Isaac、USD 资产库等制作的碰撞配置能在 Newton 中得到一致复现相关行为均有 import_usd.py 源码与 test_import_usd_collision_groups.py 测试的双重背书。【免费下载链接】newtonAn open-source, GPU-accelerated physics simulation engine built upon NVIDIA Warp, specifically targeting roboticists and simulation researchers.项目地址: https://gitcode.com/GitHub_Trending/newton9/newton创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表