mcpField
I
isaac-sim-troubleshooting

isaac-sim-troubleshooting

github.com/isaac-sim开发4.4k52 次安装5 天前更新
代码仓库

关于 isaac-sim-troubleshooting

面向 Isaac Sim 6 和 Kit 110 开发者的故障排查技能,帮助诊断卡顿、加载停滞、渲染异常及性能或内存问题。内容按子系统整理症状,并提供检查步骤和处理方法。

主要功能

  1. 01启动与关闭卡顿诊断
  2. 02场景加载与着色器排查
  3. 03Physics 和 Replicator 卡顿指南
  4. 04Hydra、Nucleus 与 GPU 问题检查
  5. 05独立库诊断

适用场景

  1. 01调查 Isaac Sim 启动停滞
  2. 02诊断大型 USD 场景加载缓慢
  3. 03排查物理或渲染卡顿
  4. 04检查 GPU 内存和 Nucleus 延迟

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/isaac-sim/isaacsim --skill isaac-sim-troubleshooting

安装后在 Claude Code 中输入/isaac-sim-troubleshooting确认已加载。

详细介绍

Isaac Sim 故障排查

目的

诊断 Isaac Sim 启动挂起、场景加载停滞、MDL/着色器编译冻结、物理步进阻塞、Replicator/Hydra 问题、Nucleus 延迟以及 GPU OOM 崩溃。

先决条件

  • 库故障需要配置好的构建环境或已安装的软件包环境。
  • Kit/GPU 先决条件仅适用于正在诊断的 Kit 工作负载。

限制

  • 症状列表仅供启发式参考;不同子系统的问题可能存在重叠。
  • 某些修复需要本地 Kit 构建或仅供 NVIDIA 内部使用的软件包。

故障排查

错误/症状原因解决方案
找不到扩展或导入项$ISAAC_SIM_DIR 错误或构建已过时将环境变量指向 _build/linux-x86_64/release,或重新构建
帧画面为黑色或空白缺少灯光或未使用 RTX 渲染模式添加穹顶灯/主光源;确认 RTX/PathTracing 设置
加载场景或首次渲染时挂起MDL 编译或场景过大按照 isaac-sim-troubleshooting 中的隔离步骤操作
关闭时挂起/SimulationApp.close()shutdown_and_release_framework() 期间,carb.tasking 线程池发生死锁使用 SIGALRM 看门狗(参见第 1a 节)——当 GIL 被发生死锁的 C 扩展占用时,threading.Event 无法触发

针对 Isaac Sim 6.0(Kit 110)在大型 USD 场景(1 万至 15 万个以上 prim,工厂/仓库孪生场景)中的挂起、冻结和性能下降进行诊断与解决。

上游调试文档:docs/isaacsim/utilities/debugging/(性能分析、Python 调试教程)。将此技能与 profile-isaac-sim 配合使用,进行基于 Tracy 的诊断。

独立库诊断

在不使用 Kit 的情况下,通过普通进程复现问题。检查已安装的发行包、 wheel/本机依赖闭包、加载器路径和重定位。使用 isaacsim.common.logging.Logger 进行库诊断,使用 carb.log_* 诊断 Kit, 仅在有意输出到标准输出时使用 print()。

快速诊断流程图

Isaac Sim hangs/freezes
    |
    +-- During startup (before stage load)?
    |       -> Section 1: Startup Hangs
    |
    +-- During shutdown / SimulationApp.close()?
    |       -> Section 1a: Shutdown Hangs (Kit Framework Deadlock)
    |
    +-- During stage open / USD loading?
    |       -> Section 2: Stage Loading Hangs
    |
    +-- During shader/material compilation?
    |       -> Section 3: MDL/Shader Compilation
    |
    +-- During physics stepping / `SimulationManager` setup or timeline play?
    |       -> Section 4: Physics Hangs
    |
    +-- During Replicator / sensor capture?
    |       -> Section 5: Replicator Hangs
    |
    +-- During rendering (viewport frozen)?
    |       -> Section 6: Hydra/Rendering Hangs
    |
    +-- Nucleus/remote asset fetch?
    |       -> Section 7: Nucleus Network Hangs
    |
    +-- OOM crash or memory spike?
    |       -> Section 8: Memory Issues
    |
    +-- Slow but not frozen?
            -> Section 9: Performance Optimization

第 1 节:启动挂起

常见原因和修复方法

1. 扩展冲突(循环导入)

./isaac-sim.sh --/app/extensions/exclude='["problematic.extension"]'

2. 渲染器初始化冻结

./isaac-sim.sh --vulkan         # Force Vulkan
./isaac-sim.sh --reset-user     # Reset user settings

3. 高核心数 CPU 上的线程过度订阅

./isaac-sim.sh \
    --/plugins/carb.tasking.plugin/threadCount=16 \
    --/plugins/omni.tbb.globalcontrol/maxThreadCount=16
simulation_app = SimulationApp({"headless": False, "limit_cpu_threads": 16})

4. Nucleus 登录弹窗挂起 — 强制终止 Isaac Sim 并重启。继续操作前请完成登录。

第 1a 节:关闭挂起(Kit 框架死锁)

症状

SimulationApp.close() 始终无法返回。进程无限期挂起(或直到 CI 在 1500 秒时将其终止)。堆栈跟踪显示,shutdown_and_release_framework() 或 unload_all_plugins() 期间,线程在 carb.tasking 线程池拆除过程中阻塞于 futex_wait。

根本原因

shutdown_and_release_framework() 会先调用 app->shutdown(),再调用 framework->unloadAllPlugins()。这些 C 扩展调用在内部因本机线程 join 而发生死锁时,会一直占用 GIL。Python 端的 threading.Event.wait() 看门狗无法触发,因为它需要 GIL 来检查超时并调用 os.kill()——因此会一直得不到调度。

修复方法:SIGALRM 看门狗

无论 GIL 状态如何,内核都会发送 SIGALRM。在阻塞的 C 调用之前设置闹钟;如果发生死锁,闹钟处理程序会无条件向进程发送 SIGKILL。

模式(通用化——适用于任何可能发生死锁的本机拆除操作):

  1. 保存之前的 SIGALRM 处理程序。
  2. 安装一个调用 os.kill(os.getpid(), signal.SIGKILL) 的处理程序。
  3. signal.alarm(timeout_seconds)——完整关闭设置为 120 秒,卸载插件设置为 30 秒。
  4. 调用阻塞的本机函数。
  5. 在 finally 中:取消闹钟(signal.alarm(0))并恢复之前的处理程序。
何时怀疑此问题
  • 所有测试断言均通过后,CI 作业仍然挂起(关闭阶段)。
  • strace 显示主线程卡在 Kit 插件系统中的 futex_wait。
  • 基于 Python 的超时机制(threading、asyncio)未能触发,且没有任何提示。
关键见解

每当 Python 看门狗必须监控一个可能无限期持有 GIL 的 C 扩展调用时,threading.Event/threading.Timer 都会因资源不足而无法运行。在 CPython 中,signal.alarm()(Linux)或 os.alarm() 是唯一可靠且不依赖 GIL 的超时机制。

参考
  • 文件:source/extensions/isaacsim.simulation_app/isaacsim/simulation_app/simulation_app.py

第 2 节:舞台加载卡住

诊断

检查图层数量:

for layer in stage.GetUsedLayers():
    print(f"  {layer.GetDisplayName()} ({layer.GetFileFormat().formatId})")

如果图层数量 > 1,000,这是主要瓶颈。

常见原因

1. 图层数量过多(>1,000 个图层)

策略冷加载耗时图层数
每个资产单独存储4 分钟11,488
库打包53 秒8

修复方法:将资产打包到库图层中(将每个资产单独存储的文件合并到少量库 .usd/.usdc 图层中;分层资产模式请参阅 usd-composition-architecture)。

2. 引用缺失或损坏 — 导致 USD 尝试所有解析器,包括网络回退。修复方法:审核引用:

from pxr import Sdf
for layer in stage.GetUsedLayers():
    for ref in layer.GetExternalReferences():
        if not os.path.exists(ref):
            print(f"MISSING: {ref}")

第 3 节:着色器/MDL 编译

  • 首次启动始终会编译 MDL 着色器,可能需要 5-15 分钟,属于正常现象
  • 后续启动会使用着色器缓存
  • 缓存位置:~/.nvidia-omniverse/data/Kit/Isaac-Sim/shader_cache/
  • 强制重新构建:删除缓存文件夹

第 4 节:物理卡住

物理设置/首次播放时卡住(SimulationManager.setup_simulation、timeline.play() 或旧版 world.reset() 流程——若要迁移并停止使用 omni.isaac.core.World,请参阅扩展重命名):通常由以下原因导致:

  • 物理开始运行时,尚未定义 PhysicsScene。
  • 首个步进中接触对过多。
  • 启用了 GPU 动力学,且刚体过多(>100K)。

修复方法:

# Ensure PhysicsScene exists before reset
if not stage.GetPrimAtPath("/World/PhysicsScene"):
    ps = UsdPhysics.Scene.Define(stage, "/World/PhysicsScene")
    
# Reduce initial contact storm
px_scene.CreateEnableStabilizationAttr().Set(True)

第 5 节:Replicator 卡住

  • rep.orchestrator.run() 卡住:调用前确保时间轴正在播放(omni.timeline.get_timeline_interface().play() 或 isaacsim.core.experimental.utils.app.play(commit=True))。
  • step_async() 始终无法完成:确保在异步上下文中正确使用 await rep.orchestrator.step_async()。
  • 帧捕获卡住:捕获前调用一次 app_utils.update_app()(或 simulation_app.update()),让渲染器获取新帧。

第 6 节:渲染(Hydra)卡住

  • 视口黑屏且冻结:检查 GPU 内存(nvidia-smi)
  • RTX 渲染器内存溢出:降低纹理流送预算:
    carb.settings.get_settings().set("/rtx/resourcemanager/textureMipCountBudget", 256)
    

第 7 节:Nucleus 网络卡住

  • 设置超时:carb.settings.set("/omni/client/timeout_seconds", 10.0)
  • 尽可能使用本地资产:将所需 USD 复制到本地磁盘
  • 禁用 Nucleus:仅进行本地工作时,使用 --/omni/client/enabled=false 启动

第 8 节:内存问题

  • Prims > 150K:启用实例化(UsdGeom.PointInstancer)
  • 纹理:使用纹理图集,降低分辨率
  • 监控:watch -n1 'nvidia-smi --query-gpu=memory.used,memory.free --format=csv'

第 9 节:性能优化

  • 图层数量:打包到库图层中(参见第 2 节)
  • 网格实例化:对重复资产使用 PointInstancer
  • 载荷加载:将大型子场景标记为未加载的载荷
  • 物理:降低非关键对象的碰撞网格复杂度

评论

支持 Markdown