- 默认禁用的托管
interface插件:只观察有界的 Run、插件事件和场景历史,不持有仿真权限; - 基于操作者所拥有
FastSimApplication的InteractiveDebugSession:提供暂停、恢复、单步、 带确认门禁的重置/停止、条件暂停断点、实体检查和 RGB 截图请求。
这种拆分遵循 FastSim 的公开能力边界。托管插件拿不到实时 Runtime、后端句柄、生命周期控制命令或
simulation.query;它只能通过 run.lifecycle 请求协调终止。应用所有者才拥有暂停和相机读取所需的
公开方法。本包不穿透私有 composition 对象,也不包含抓取、放置等任务语义。
安装
支持 Python 3.11 和 3.12:
python -m pip install "fastsim>=0.1.0a15,<0.2" \
"fastsim-plugin-interactive-debug==0.1.3"
源码安装:
python -m pip install /path/to/fastsim-next
python -m pip install \
/path/to/fastsim-plugins/packages/fastsim-plugin-interactive-debug
该发行包发布两个托管插件入口:
fastsim.components / fastsim.interactive-debugfastsim.plugins / fastsim.interactive-debug
安全默认值:零激活
仅添加组件时保持安全、无活动:
plugins:
debug:
use: plugin://fastsim/interactive-debug
组件默认 enabled: false。托管实例仍参与正常插件生命周期记账,但不会查找服务、查询场景、创建订阅、
发布事件、注册回调或创建后台任务,也不会注册物理 tick 钩子,因此禁用后的稳态不会增加逐 tick 工作。
启用调试必须是明确的 Run 配置选择。
托管观察器
启用观察;若需要查看整个场景而非仅查看隐式绑定的机器人/关节体,请显式写空绑定:
plugins:
debug:
use: plugin://fastsim/interactive-debug
bindings: {}
config:
enabled: true
watches:
arm_joint_0:
path: /scene/entities/robot/articulation/state/positions/0
breakpoints:
joint_limit:
watch: arm_joint_0
operator: ge
expected: 1.2
action: notify
enabled: true
省略实例的 bindings 时,FastSim 会推导所有可用机器人/关节体别名;显式 {} 会让公开 scene-query
授权保持非实体限定,从而能检查普通物体。部署访问策略仍可缩小或拒绝这些可选服务。
托管 watch 文档的根路径如下:
/run
/scene/run_id
/scene/generation
/scene/tick
/scene/sim_time_s
/scene/entities/<entity-id>/descriptor
/scene/entities/<entity-id>/state
/scene/entities/<entity-id>/links/<link-id>
/scene/entities/<entity-id>/articulation/descriptor
/scene/entities/<entity-id>/articulation/state
/scene/attachments
路径采用 RFC 6901 JSON Pointer:/ 编码为 ~1,~ 编码为 ~0,tuple 下标使用十进制。
它们只是数据查找,不是 Python 表达式。支持 eq、ne、gt、ge、lt、le、
contains、changed 和 exists。
托管断点支持 action: notify。命中会写入有界历史,并发布命名空间内的 breakpoint.hit 事件。
若配置已启用的 action: pause,prepare() 会明确抛出 CAPABILITY_UNAVAILABLE,不会静默降级。
自动暂停请使用下文的应用会话。
托管对象提供:
plugin.status
plugin.event_history
plugin.state_history
plugin.inspect_entity("box")
plugin.inspect_object("box")
plugin.inspect_articulation("robot")
plugin.inspect_robot("robot")
plugin.request_run_stop(confirm=True)
最后一个调用通过公开 run.lifecycle 服务提交 RunCompletionRequest(outcome="cancelled"),这是插件侧
唯一可用的终止动作。pause()、resume()、single_step()、reset() 和
request_screenshot() 都会抛出稳定的 DebugCapabilityUnavailableError。
watch 会自动建立最小场景需求:/scene/entities/<id>/... 只读取对应实体;多个实体 watch
会合并成一次查询;/scene/tick 等时间戳 watch 直接使用 delta envelope,不重建 catalog。
使用 watch 不需要开启 streams.scene: true。该开关只用于明确要求每个保留的场景历史样本
都包含完整场景文档的情况,因此其成本会随场景规模增长。静态 catalog 会持续复用,只有
generation、catalog revision 或 catalog digest 变化时才重新读取。
应用所有者交互会话
当操作者拥有公开异步 FastSimApplication 时,使用 InteractiveDebugSession:
import asyncio
import fastsim
from fastsim_plugin_interactive_debug import InteractiveDebugSession
async def main() -> None:
simulation = fastsim.app("run.yaml", planning_reads=True)
async with simulation:
await simulation.prepare()
debug = InteractiveDebugSession(simulation)
debug.add_watch(
"arm_joint_0",
"/scene/entities/robot/articulation/state/positions/0",
)
debug.add_breakpoint(
"joint_limit",
watch="arm_joint_0",
operator="ge",
expected=1.2,
action="pause",
)
await debug.attach()
await debug.start_monitoring(interval_s=0.1)
await simulation.start()
status = debug.status
robot = await debug.inspect_robot("robot")
capture = await debug.request_screenshot("overview_camera")
await debug.pause()
await debug.step(5)
await debug.resume()
await debug.close()
asyncio.run(main())
FastSim 的应用 scene client 要求 planning_reads=True。会话仅调用 snapshot()、
scene.catalog/state、plugin_events()、公开生命周期方法和 camera_rgb()。
应用会话在没有 scene watch 时不会读取场景;实体 watch 使用选择性查询并缓存静态 catalog。
只有确实需要每个调试历史样本都包含完整场景时,才传入 full_scene_history=True。
reset() 与 stop() 必须传入 confirm=True:重置会替换仿真 generation,停止会拆除 Run。
close() 只停止调试监控,不会关闭或停止传入的应用。暂停断点采用边沿触发,并在公开快照边界求值。
单次 step(count) 最多 10,000 步,断点命中后会提前结束。
应用会话 watch 文档使用 /application 和 /scene 根路径。例如
/application/runtime/tick 读取 Runtime tick;上面的场景路径继续位于 /scene 下。
历史与状态
两个接口都返回不可变的 DebugStatus、DebugHistoryRecord、WatchResult 和
BreakpointHit。托管接口默认限制如下:
| 历史 | 默认容量 | 最大可配置值 |
|---|---|---|
| 生命周期/插件/场景事件 | 256 | 65,536 |
| 一致场景状态 | 128 | 16,384 |
| 断点命中 | 128 | 16,384 |
容量满时淘汰最旧记录,历史永不无界增长;订阅队列同样有界。状态包含可用能力、精确限制、消费者运行状态、 当前 generation/tick/time、watch 结果、断点历史和有界的最后错误。
检查与截图
检查结果完全由公开 SceneCatalogSnapshot 和 SceneStateSnapshot 组装:
- 物体使用通用实体描述、pose 和 twist;
- 关节体增加有序关节描述、位置、速度及 SI 单位;
- 机器人是
kind: robot的实体,复用同一套通用关节体契约。
结果中没有后端原生 Robot 句柄。
request_screenshot(entity_id) 调用应用公开的 camera_rgb(),返回不可变 RGB24 字节和元数据:
相机实体、宽高、Run/generation/tick/time、字节数、媒体类型和 SHA-256。它不会截取桌面或 viewport,
也不编码 PNG。若后端或实体不提供 RGB 相机,会原样传播 FastSim 的类型化查询失败。
精确限制
- 托管插件不能暂停、恢复、单步、重置或直接停止 Runtime。
- 托管插件不能请求按需相机截图;已配置 RGB observation 不能冒充暂停时的新截图。
- 应用断点是轮询/快照边界检查,不是物理 tick 内的原子断点;条件可能在两次轮询间跨越。
- 场景检查需要
scene.query;应用侧还必须启用planning_reads=True。 - 仅支持已配置场景相机的 RGB24;桌面、viewport、深度、分割、PNG 和视频不在本版本范围内。
- watch 不能执行代码、调用方法或修改状态。
- 本包不会生成控制轨迹、抓取/放置、attachment、planner 或 task 动作。
- 真实后端、GPU、相机设备和 GUI 验证取决于部署环境,单元测试不宣称这些检查已通过。
开发验证
在本包目录执行,并确保 a13 源码位于 PYTHONPATH 首位:
FASTSIM_SRC=/path/to/fastsim-next/src
PYTHONPATH="$FASTSIM_SRC:src" python -m pytest -q
python -m ruff check src tests
PYTHONPATH="$FASTSIM_SRC:src" python -m mypy src/fastsim_plugin_interactive_debug
python -m build --no-isolation
测试覆盖禁用零激活与 tick 循环 A/B 性能、严格配置、不可执行 watch、断点边沿、有界历史与队列、服务拒绝、
托管生命周期清理、协调终止、参考 FastSimApplication 生命周期纵切、应用安全门禁、普通物体/机器人/通用
关节体检查、场景相机 RGB 截图元数据、manifest/digest 一致性、entry-point 元数据以及 wheel/sdist 内容。