FastSim 0.1.0a36 目前是 Alpha 版本。本仓库是全新的 vNext 实现:不读取旧版 FastSim 配置,也不提供旧运行时的兼容导入。

为什么需要 FastSim?

Isaac Lab、MuJoCo 和 PyBullet 是仿真引擎或仿真框架。UniRoboSim 负责统一它们的 场景、实体、传感器、调试与控制能力。FastSim 解决的是另一层问题:把资产、运行 策略、Scenario 和已安装插件组织成一次可检查、可复现的仿真应用。

层级 职责
仿真后端 原生物理、渲染、设备与后端特有能力
UniRoboSim 后端发现与可移植仿真器契约
FastSim Core 配置、Registry 解析、执行计划、Lock、生命周期、范围化服务与控制仲裁
FastSim 插件 Rule-based、模型、遥操作、Agent、录制、回放、调试、TUI、Web 或服务化逻辑

如果应用只需要一层轻量、可移植的仿真器 API,可以直接使用 UniRoboSim。如果一次 运行需要由配置描述、启动前可检查、锁定到确定资源、无需修改运行时即可扩展,并且 需要接入多类控制源,则适合使用 FastSim。

FastSim 不拥有任务语义。pickplace、抓取位姿、Action 列表、规划器、模型 推理和遥操作设备都属于插件。Core 只提供这些插件共同使用的生命周期、数据、规划 读取和控制边界。

架构

FastSim 平台架构

CLI 属于 FastSim Core,不是插件。TUI、浏览器控制台、交互调试器、HTTP Server 等 功能接口采用插件形式,因此未安装、未启用时不会引入对应代码和运行开销。

安装

版本矩阵

FastSim 本身支持 Python 3.11 和 3.12。实际环境应选择后端 Provider 所要求的 Python 版本。

当前兼容版本 Python 说明
fastsim 0.1.0a36 3.11、3.12 固定依赖 unirobosim==0.10.5;运动学为可选功能
unirobosim 0.10.5 3.11、3.12 可移植核心,不内置任何仿真器
unirobosim-isaaclab 0.10.16 3.12 需要兼容的 Isaac Lab 3.0 / Isaac Sim 6.0 环境
unirobosim-mujoco 0.9.4 3.12 Provider 当前固定 MuJoCo 3.11.0
unirobosim-pybullet 0.9.4 3.11 Provider 当前固定 PyBullet 3.2.7
fastsim-kinematics-solver-spi 0.1.0 3.11、3.12 可选 Provider 契约
fastsim-kinematics-solver-portable 0.1.0 3.11、3.12 可选的确定性 URDF Provider

FastSim 0.1.0a36 保留了 0.1.0a12 引入的按需启用、逐通道独立时间戳与序号的观测流, 用于相机录制;纯数值 Record 捕获改为每个仿真 Tick 一个原子快照,因此通道数量不会放大队列项数。 原有快照查询与订阅 API 保持不变,直接应用读取状态时则会从同一个已 提交 Tick 原子取得 WorldState 与 Observation。实时分发和有序录制使用两套序号: channel_sequence 对所有到期的实时观测项排序,可选的 capture_sequence 只对实际 录制项排序。Record 0.2.3 对应 FastSim 0.1.0a8;当前 Record 0.3.11 与托管 Record 0.3.12 与 Replay 0.2.17 使用 FastSim >=0.1.0a36,<0.2 版本线,不同发布列的包不得混装。 启用有序录制时, 一次 Run 只会选择一条 观测录制通道。data_consumer 仅仅读取观测并不会自动成为 Recorder;安装包 Manifest 必须显式声明 semantics.plugin.recording_sources,并且 Core 最多接受一个启用的捕获 所有者。其他数据消费者继续使用普通实时订阅,不会产生全局排序或录制历史开销;选择 observations 作为录制源时,必须存在非空的已编译观测 Demand。

主录制文件发布现在默认使用结构完整性:不再计算 Payload SHA-256,同时继续保留 FSR 校验、固定文件身份、持久化、原子发布和失败清理。如果部署环境需要发现校验后的同尺寸 内容修改,可以显式启用严格 SHA-256。详见 Run 输出完整性

当前从源码仓库安装,不假定这些包已经发布到 PyPI。以下是 PyBullet 开发环境的 安装方式:

bash
git clone https://github.com/GitHofee/UniRoboSim.git
git clone https://github.com/GitHofee/UniRoboSim-pybullet.git
git clone https://github.com/FastSim-Benchmark/FastSim.git

python3.11 -m venv fastsim-dev
source fastsim-dev/bin/activate
python -m pip install --upgrade pip
python -m pip install -e ./UniRoboSim
python -m pip install -e ./UniRoboSim-pybullet
python -m pip install -e './FastSim[dev]'

MuJoCo 环境使用 Python 3.12,并改为安装 UniRoboSim-mujoco。Isaac Lab 环境应使用承载兼容 Isaac Lab 的同一个 Python 执行 pip,然后把 UniRoboSim-isaaclab 和 FastSim 安装到该环境中。不要仅为 FastSim 重复安装一套 Isaac。

确认当前实际调用的是哪个 FastSim:

bash
fastsim --version
fastsim doctor --json

doctor 当前报告包和 Python 信息。其 backend_integration 字段仍保守地显示 unverified,不能把它当成原生后端健康检查。

快速开始

仓库内提供了最小生命周期配置 examples/quickstart/run.yaml。它从本地 Registry 解析一个小型红色方块,无需下载机器人或安装插件即可检查配置、资源完整性和后端启动。

yaml
schema: fastsim/2
name: quickstart
backend: pybullet

runtime:
  launch_profile: headless
  physics_hz: 60
  control_hz: 30
  seed: 7

scenario:
  scene:
    objects:
      cube:
        use: object://fastsim/quickstart-cube
        pose:
          xyz_m: [0.0, 0.0, 0.5]
          quat_xyzw: [0.0, 0.0, 0.0, 1.0]

不启动仿真器即可完成校验和检查:

bash
fastsim config validate examples/quickstart/run.yaml --json
fastsim config expand examples/quickstart/run.yaml
fastsim config explain examples/quickstart/run.yaml runtime.physics_hz

生成并验证内容寻址 Lock:

bash
fastsim config lock examples/quickstart/run.yaml --output quickstart.lock --json
fastsim config verify-lock quickstart.lock --json

安装 PyBullet Provider 后,让应用运行两秒钟:

bash
fastsim run examples/quickstart/run.yaml --duration 2 --json

顶层字段刻意保持精简:

字段 含义
schema 全新配置契约,当前为 fastsim/2
name 稳定且对人可读的 Run 名称
backend 本次编译选择的 UniRoboSim Provider ID
runtime 物理、控制、传感器频率与随机种子策略
scenario 必选 scene 与插件拥有的可选 behavior/evaluation 数据
control 默认控制对象和控制源插件实例之间的优先级
plugins 本次 Run 选择的已安装插件实例
overrides 带来源记录的显式配置覆盖

Demo 教程库

demo/fundamentals 是循序渐进的 API 课程。每个编号案例都可以独立运行,并包含 Python 程序、Run 配置、英文 README 和中文 README。教程从不启动仿真器的配置检查开始,再逐步介绍生命周期、控制、 传感器、场景与规划查询、可复现运行和高级物理 Track。首次开发 FastSim 应从 01_config_validation_and_compilation 开始。

demo/components 是面向仿真平台使用者的组件编写 课程。它沿真实 Project 和 Registry 解析链路,提供 environment、object、articulation、 robot、sensor、light、deformable、fluid、Scenario、版本选择、后端 variant、默认值和 资源完整性的可复制案例。

demo/official_plugins 用于由正式发布的官方插件 组成、以配置为主的应用管线。只有插件包和原生验收门禁均已公开后才会加入可运行 案例,不会把占位内容描述成已经可用的产品。

直接开发仿真应用

需要自行编写完整仿真应用的开发者,可以直接使用异步 FastSimApplication,不必先实现 Plugin:

python
import asyncio
import fastsim


async def main() -> None:
    async with fastsim.app("run.yaml") as simulation:
        await simulation.start()
        targets = await simulation.control.targets()
        print([(item.entity_id, item.resource_group) for item in targets])

        operation = await simulation.control.submit_joints(
            actor="droid",
            group="arm",
            path=[
                [0.0, -0.4, 0.0, -2.0, 0.0, 1.6, 0.8],
                [0.2, -0.2, 0.1, -1.8, 0.1, 1.4, 0.6],
            ],
            dt=1.0 / 60.0,
            timeout=10.0,
        )
        print(await operation.status())
        result = await operation.result()
        await operation.release()
        print(result.status)

        moved = await simulation.scene.set_pose(
            "objects.red_cube",
            xyz_m=(0.55, -0.15, 0.72),
        )
        print(moved.status)


asyncio.run(main())

这一门面提供异步生命周期、一致的 World/Observation 状态、可选启用的 Scene/Frame/规划几何 查询、刚体位姿与拖动命令、紧凑 RGB 与粒子流体查询、控制目标发现、Joint Path、通用多资源物理 Track, 以及明确的 operation status/result/cancel/release。它不暴露仿真器原生句柄,也不 引入 pick、place、规划等任务语义。

可选的只求解 simulation.kinematics 客户端可把末端位姿转换为有序关节解,但不会执行 这些关节值。它只读取已编译机器人组件中经过校验的 URDF,在当前 Generation 原子取得 关节状态,并在 Application Loop 外运行已安装 Provider。详见中英文 Application 运动学求解指南

Planning 发布开销较高,而且必须拿到完整碰撞场景。只有确实需要 Scene、Frame 或 规划几何 API 时,才使用 fastsim.app("run.yaml", planning_reads=True)。普通控制和 传感器运行默认不启用 Planning;此时若误调用 Planning API,会明确失败,而不会返回 缺少部分碰撞体的数据。

可选的 fastsim-plugin-server 包把同一套门面开放为 fastsim-http/1

bash
pip install fastsim-plugin-server
fastsim-server run.yaml --host 127.0.0.1 --port 8000

控制接口返回 202 Accepted 与 operation ID,因此 HTTP 调用同样是异步的。非本机 监听必须同时启用 HTTPS 与 Bearer Token 鉴权。精确传输 Schema 可在服务启动后通过 /api/v1/docs 查看。

如需常驻远程控制面,可以空载启动 Server,并授权一个可信 Project 目录。独立 Web Client 随后可以上传一份独立配置,或选择该命名目录下的配置,再要求 Server 启动:

bash
fastsim-server \
  --launch-root runs=/srv/fastsim-runs \
  --browser-origin http://127.0.0.1:8080

配置模型

文件格式与项目发现

Run 和 Project 文档均支持 YAML、JSON、TOML。FastSim 从 Run 文件所在位置逐级 向上查找唯一一个 .fastsim/project.yaml.json.toml。Project 负责声明 Registry 索引、可信资源根目录、缓存策略、离线模式,以及可选的插件部署权限上限。

快速开始使用的 Project 指向随示例一起提供的组件索引:

yaml
schema: fastsim-project/1
installed_packages: false
registries:
  - name: quickstart
    path: components/index.yaml

更大的 Project 可以发现已安装组件 Catalog,并按确定顺序叠加其他索引:

yaml
schema: fastsim-project/1
installed_packages: true
registries:
  - name: project-assets
    path: assets/index.yaml

robot://frankaobject://kitchen/cupscenario://house/heat-foodplugin://example/controlleruse 值由 Project 的 Registry 解析。不写版本时 选择 Registry 的 stable 版本;也可以用 @ 指定精确版本,例如 robot://franka@1.4.0。编译会记录精确 Manifest 和资源摘要,Lock 则把它们固定 下来供之后运行。

FastSim 刻意不提供递归 include$ref 或配置继承语言。可复用内容应成为 Registry 中的版本化组件,而 Run 只描述选择了什么和明确覆盖了什么。

Scenario

每个独立 Run 必须有一个 Scenario,其中 scene 必选。behaviorevaluation 是可选的、不透明 Mapping:FastSim 会原样保留,只把它们授予 Manifest 明确请求 相应部分的插件。

yaml
scenario:
  scene:
    environment:
      use: scene://example/apartment
      static: true
    robots:
      mobile_manipulator:
        use: robot://example/mobile-manipulator
        pose:
          xyz_m: [0.0, 0.0, 0.0]
          quat_xyzw: [0.0, 0.0, 0.0, 1.0]
        scale: [1.0, 1.0, 1.0]
    objects:
      cup:
        use: object://example/cup
        pose:
          xyz_m: [0.7, -0.2, 0.85]
          quat_xyzw: [0.0, 0.0, 0.0, 1.0]
  behavior:
    program: heat-and-deliver
  evaluation:
    profile: household-success

environment.static 默认是 true:Environment 保持为可碰撞的静态支撑世界,未显式 声明的内部 actor 不参与动态求解。当 Environment 资产内部 authored 机构本身需要交互时, 设置为 false。显式声明的 robot、object 和 articulation 不受该开关影响。

配置 Schema 为环境、刚体、普通铰接体、机器人、柔性体、流体、传感器和灯光都保留 了分组。当前 UniRoboSim Runtime Lowering 可以运行启用的 Environment、Object、 Articulation、Robot、程序化表面柔性体、Fluid 和受支持的 Sensor。启用灯光或不受支持的 柔性体形式时会在 Runtime Composition 阶段 Fail Closed;仅有 Provider 支持还不够。

场景布局必须是物理数据。不能用 inside: refrigerator 这样的语义关系代替位姿; 食物和冰箱都需要确定的变换。任务插件可以自行解释 behavior 中的语义标注,但 Core 不会把这种语义变成场景状态。

Run 也可以不展开 Scenario,而是选择一个 Registry 组件:

yaml
scenario:
  use: scenario://example/heat-food

fastsim config materialize 可以把引用的 Scenario 展开回可移植、可直接运行的配置。

运行频率与后端选择

yaml
backend: isaaclab
runtime:
  launch_profile: headless
  physics_hz: 60
  control_hz: 30
  sensor_hz: {}
  rate_policy: exact
  seed: 7

启动档位支持 visibleheadlessheadless-physics

启动档位 原生窗口 相机传感器渲染
visible 开启 开启
headless 关闭 按需可用
headless-physics 关闭 关闭

默认值是 headless,因此既有 Run 配置仍保持无窗口、可按需使用相机的行为。其他默认值 是物理 60 Hz、控制 30 Hz、exact 频率策略和随机种子 0。使用 exact 时,物理频率必须是每个控制或传感器频率的整数倍;accumulate 允许非整数比例。

配置编译器可以接受有名称的 sensor_hz 条目,但当前 UniRoboSim Runtime Lowering 要求该 Mapping 为空。所有可缩放的物理实体均可配置正数 XYZ scale:刚体与静态场景 可非等比缩放,独立铰接体仅允许等比缩放;Isaac Lab 复合 USD 若包含内嵌动态实体可等比 缩放,非等比缩放仅在 author 后为静态、且碰撞表达支持时放行。不支持的资产与 scale 组合会在启动仿真前明确失败,不会静默忽略配置。

用户在 Run 中选择后端。未锁定时,也可在检查或启动时临时覆盖而不修改文件:

bash
fastsim config validate examples/quickstart/run.yaml --backend mujoco --json
fastsim run examples/quickstart/run.yaml --backend mujoco --launch-profile visible --duration 2 --json

--backend--launch-profile 都是编译覆盖项。两者都不能和 --lock 一起使用, 因为修改任意一项都会改变执行计划,必须重新生成 Lock。

后端切换本身并不等于资产格式转换。只有所有组件都提供兼容 Variant 或资源,且 Provider 声明所需能力时,同一份 Run 才能移植。不同引擎的原生渲染、接触、柔性体、 流体、传感器输出和控制器行为可能不同;FastSim 不会因为只修改了 Provider ID 就 宣称数值结果完全一致。

在当前物理运行切片中,PyBullet 或 MuJoCo 实体必须解析到唯一一个 model/vnd.urdf+xml 类型的 simulation 资源;Isaac Lab 实体必须解析到唯一一个 model/vnd.usd 类型的 simulation 资源。MuJoCo 原生 Provider 可以暴露更多格式, 但 FastSim 当前锁定的 Profile 仍只接收 URDF。资产转换是显式预处理步骤,不是修改 backend 后自动发生的副作用。

铰接组件可以在对应后端 Variant 的 Defaults 中声明 articulation_drive。这是由组件 维护的物理标定,而不是让每个 Run 重复填写的调参项:MuJoCo 使用逐关节位置刚度与 阻尼,PyBullet 使用位置增益和可选速度增益。FastSim 会核对实际 Backend、组件声明 的稳定关节名及参数类型,将配置完整保留在 Lock 中,并且只把这个有类型的字段投影给 Adapter;省略时保持 Adapter 之前的行为。只有通过上述精确校验后,后端原生驱动标定 才会从可移植 Replay 兼容性摘要中排除。

插件:默认简单,需要时再精细配置

一个插件实例有五个配置块:

yaml
plugins:
  controller:
    use: plugin://example/controller
    bindings:
      robot: mobile_manipulator
    access: all
    session:
      freshness:
        max_observation_age_sim_s: 0.25
      lease:
        timeout_s: 5.0
      heartbeat:
        timeout_s: 2.0
    config:
      model_endpoint: http://model.example.test/v1/action
配置块 归属和用途 能否省略
use 已安装插件在 Registry 中的身份 不能
bindings 把插件内部角色名映射到 Scenario 实体 可以;兼容实体会被确定性推导
access 收窄服务、观测和控制组范围 可以;省略与 all 都表示 Manifest/Run/部署上限的精确交集
session Core 强制执行的新鲜度、Lease 与心跳超时 可以;使用 Manifest 默认值
config 由插件 Manifest 校验的插件私有配置 插件 Schema/默认值允许时可以

插件 Manifest 是完整声明,包含角色、运行入口、Scenario 输入、服务依赖、绑定策略、 控制能力、Session 默认值与私有配置 Schema。因此普通用户通常只需写 useconfig。部署负责人可在 Project 中增加 plugin_access_limits Allowlist;这是编译期 能力上限,不是操作系统沙箱。

四种插件角色是 control_producerdata_consumerextensioninterface。 Rule-based、模型、遥操作和 Agent 控制器都是普通 control_producer 插件。录制与 回放属于数据消费者,调试和外部接口按职责选择 Extension 或 Interface 角色。这些角色 名称不会给 Core 自动增加功能——仍需安装并选中相应插件包。

控制优先级填写的是插件“实例名”,不是插件包身份:

yaml
control:
  default_robot: mobile_manipulator
  precedence: [teleop, model]

优先级只解决重叠控制资源的 Authority,不会执行任务,也不会决定下一个 Action。 Scenario 只有一个启用机器人时会推导 default_robot,多机器人时也可以显式配置; 但插件 Actor 仍由 bindings 选择,不会被该默认值暗中重定向。

控制与规划数据流

无论控制命令来自哪里,都使用同一条路径:

text
插件 capture/query -> 插件计算 -> ControlChunk
    -> Control service -> ControlChunkExecutor -> UniRoboSim -> 仿真器
  • Rule-based 插件读取自己的 behavior 程序,捕获一致的机器人状态和世界几何,在自身 线程或进程中运行 IK/规划器,再提交关节轨迹。
  • 模型插件读取观测,在本地或远端推理,再提交下一段关节或由 EE 结果转换的 Chunk。
  • 遥操作插件采样设备或网络信号,提交短小且可替换的 Chunk。
  • Agent 插件使用完全相同的范围化查询与控制服务,不拥有隐式仿真器权限。

面向插件初学者的统一门面是 fastsim.plugins.easy.PluginClient。它不是第二套仿真器 EasyAPI,而是把公开的范围化服务组合为一致规划快照和关节路径提交:

python
import asyncio

from fastsim.plugins.easy import PluginClient


async def run_rulebased_step(context, planner):
    async with PluginClient(context) as client:
        source = await client.capture(
            actor="robot",
            group="arm",
            ee="tool0",
            geometry=True,
            timeout=5.0,
        )

        # 规划器属于插件。CPU/GPU 计算不能阻塞 FastSim 应用事件循环。
        joint_path = await asyncio.to_thread(planner.solve, source.view)

        result = await client.control.joints(
            joint_path,
            source=source,
            dt=1.0 / 30.0,
            timeout=30.0,
        )
        if not result.ok:
            raise RuntimeError(f"control failed: {result.status}: {result.message}")

Capture 包含所选控制目标、有序 Joint ID、位置、速度、单位、限位、可选末端变换、 scene/frame 快照,以及可选几何 Catalog。Mesh/SDF 等资源在有界 Lease 内按需解析, 不会被复制到每一帧 Observation。控制进入队列前,FastSim 会根据当前 World Generation 与声明的预期运动重新校验该 Capture。

高级 Rule-based 规划器可以提交已投影的物理 Track,无需自行构造 ControlChunk

python
async def submit_projected_trajectory(client, source, planner_trajectory):
    base_capability = source.projection_capabilities.resolve_projection(base_resource)
    embedded_base = base_capability.embedded_base_joints[0]

    projection = VirtualJointProjection(
        ProjectionBinding(
            virtual_base=virtual_axes,
            arm_joint_names=arm_joint_names,
            arm_joint_units=arm_joint_units,
            base_resource=base_resource,
            arm_resource=arm_resource,
            embedded_base_joints=embedded_base,
        ),
        capabilities=source.projection_capabilities,
    )
    tracks = projection.project(planner_trajectory)
    return await client.control.physical_tracks(
        (tracks.base_track, tracks.arm_track),
        source=source,
        timeout=30.0,
    )

该能力来自 Capture 内不可变且已授权的 Target Catalog。只有组件 Manifest 声明了精确的 x/y/yaw 物理 Joint、(m, m, rad) 单位、Controller 与支持的运动学模型时,内嵌底盘 能力才会出现。physical_tracks() 会在消费 Capture 前拒绝调用方自行伪造的能力声明, 以及后端未声明的 base-pose Command Space。 完整 Manifest 与准入约束见 Embedded base-joint capabilities

PluginControlClient.joints() 会等到当前 Chunk 进入终态才返回。Rule-based 控制源只需 等待本段结果后再提交下一段,就能形成顺序执行。底层 ChunkExecutionPolicy 默认要求 全部帧已应用、终点保持,并允许抢占。伺服控制源可通过底层控制服务提交新的重叠 Chunk;Executor 会把被替代的旧 Chunk 标记为 PREEMPTED,并在 Control Tick 边界启动 新 Chunk。需要更精细行为的插件可以使用 fastsim.control 中公开的底层契约。

physical_tracks() 是顺序 Rule-based 路径:并发调用按 FIFO 顺序进入执行,同一物理资源 上的后续调用不能抢占前一调用。更简单的 joints()/joints_many() 仍保留伺服抢占语义。

规划或模型计算耗时不会隐式阻塞物理。插件需自行决定计算期间的策略:通过操作员 工作流暂停 Run、保持上一有效目标,或按 Idle Policy 让世界继续。录制插件应根据控制 和生命周期事件跳过或标注空闲区间,而不是假定每个物理 Tick 都是有效训练数据。

公开 Python API

应用生命周期

稳定的同步应用门面由 fastsimfastsim.api 导出:

python
import fastsim

with fastsim.open("examples/quickstart/run.yaml", launch_profile="visible") as run:
    running = run.start(timeout=30.0)
    paused = run.pause(timeout=30.0)
    stepped = run.single_step(timeout=30.0)
    resumed = run.resume(timeout=30.0)
    status = run.snapshot()
    plugins = run.plugin_status()
    run.stop(timeout=30.0)

FastSimRun 还提供 preparereset 和幂等 close。一个 Run 拥有一个应用事件循环 线程与一个 UniRoboSim Runtime。插件不能调用这个同步门面;它们通过 PluginRuntimeContext 接收异步范围化服务。

异步路径 API 接受相同的编译覆盖参数:

python
import fastsim

app = fastsim.app(
    "examples/quickstart/run.yaml",
    launch_profile="headless-physics",
)

fastsim.open_plan(plan)fastsim.application_plan(plan) 刻意不提供启动档位参数;在 该边界上,不可变 ExecutionPlan 是唯一权威。使用 Lock 时,应先在配置或编译覆盖中 确定档位再生成 Lock;路径 API 会拒绝对已锁定 Run 再传入 launch_profile

配置编译与执行计划

python
from fastsim.config import load_project

context = load_project("examples/quickstart/run.yaml")
compiled = context.compiler().compile_file("examples/quickstart/run.yaml")
plan = compiled.execution_plan
print(plan.backend, plan.digest)

fastsim.config 导出严格 Codec、Project/Registry/Compiler 契约与结构化诊断; fastsim.plan 导出不可变 ExecutionPlanScenarioPlan、Lock 校验、Diff/Explain 与 Freeze/Thaw 工具。

插件 SPI 与范围化运行时服务

fastsim.plugins 导出插件 Factory/Runtime 协议、不可变 Binding、生命周期状态、已安装 插件发现和 Conformance Runner。插件只能看到已在编译 Binding 中授予的服务。当前 公开服务键如下:

服务键 用途
run.info Run 身份与不可变运行元数据
scenario.read Manifest 声明需要的 Scenario 部分
scene.query 实体 Catalog 与一致场景状态
frame.query Frame Catalog、Transform 与 Delta
scene.geometry 规划几何 Catalog、Transform、Delta 与 Lease 资源
scene.command 当所选后端声明匹配的公开命令能力时,提供可撤销的场景位姿、拖拽、挂接与解除挂接命令
planning.capture 一致的 scene/frame/geometry/control-target 捕获与重新校验
observations 已授权 Observation 快照与订阅
fluid.emitters 实时粒子流体 Reservoir 与 Emitter 控制
fluid.audit data_consumer 录制插件提供后端接受后的紧凑发射 Batch
fluid.replay control_producer 回放插件提供仅启动期可用的不可变发射计划加载
control.targets 已授权 Actor、Resource Group、Axis、Command Space 与 Controller
control Session、Chunk 提交、取消与状态
artifact.read 对 Manifest 声明插件制品的有界读取
event.publish 有界插件事件

后端原生 Handle、Runtime Authority 对象及其他插件的私有配置不会直接暴露。

CLI 参考

不存在 fastsim config compile 命令。下面需要编译的命令会自行完成编译。

命令 用途
fastsim doctor [--json] 检查当前 FastSim 安装
fastsim config validate RUN 解析并校验 Run
fastsim config expand RUN 输出规范化有效配置
fastsim config materialize RUN --output PATH 写出 Scenario 已展开的可运行配置
fastsim config explain RUN PATH 解释某个有效字段的来源
fastsim config diff BEFORE AFTER 比较两份有效配置
fastsim config lock RUN [--output PATH] 写出内容寻址 Lock
fastsim config verify-lock LOCK 校验 Lock 结构及每个本地资源摘要
fastsim config convert INPUT --to yaml|json|toml [--output PATH] 转换可移植配置语法
fastsim plugins list RUN 不导入代码,列出编译后的插件元数据
fastsim plugins inspect RUN INSTANCE 不导入代码,检查一个插件实例
fastsim plugins diagnose RUN 只导入并校验该 Run 实际选择的 Factory
fastsim settings path|list|get|describe|set|unset|validate|export|import|reset 管理可选的工作站级偏好
fastsim outputs root|list|stats|inspect|verify|open|remove|clean 管理有界的 Run 输出文件
fastsim server status [--url URL] 检查独立 FastSim Server 的存活与就绪状态
fastsim run RUN 编译并运行一个应用

所有需要编译的命令都支持 --project PATH、可重复的 --registry PATH--offline--online--cache-root PATH--network-timeout SECONDS--backend ID--launch-profile {visible,headless,headless-physics}--json;但 verify-lock 没有编译覆盖参数,convert 仅转换语法。run 另外支持:

  • --lock PATH:校验并使用已经生成的 Lock;
  • --duration SECONDS:经过非负的 Wall-clock 时间后停止;
  • --timeout SECONDS:正数生命周期操作超时,默认 30 秒;
  • --output-root PATH:提供给输出型插件的可信本地根目录;
  • --gpus IDS:本次 Run 使用的逗号分隔 GPU ID。

用户级设置默认不存在,并且永远不会进入 Run 或 Lock。完整设置项与优先级见 用户级设置;FSR 查找、校验、打开 Viewer 与有界清理见 输出管理 CLI

示例:

bash
fastsim config convert run.yaml --to json --output run.json
fastsim plugins list run.yaml --json
fastsim plugins inspect run.yaml controller --json
fastsim plugins diagnose run.yaml --json
fastsim settings list --effective --json
fastsim outputs list --status complete --json
fastsim server status --url http://127.0.0.1:8010 --json
fastsim run run.yaml --launch-profile headless-physics --duration 60 --timeout 30 --json
fastsim run run.yaml --lock run.lock --duration 60 --timeout 30 --json

开发插件

官方与共享插件包位于独立的 FastSim-Plugins 仓库,其中 包含打包约定、最小插件模板、Producer 工具和 Conformance 工具。一个插件是普通 Python Distribution,并包含:

  1. fastsim-component/2 Manifest 与 Registry Index;
  2. 注册在 fastsim.plugins Entry-point Group 中、名称与 module:attribute Value 和 Manifest 声明精确一致的 Factory;
  3. 实现 fastsim-plugin-runtime/1 SPI 的生命周期 Hook;
  4. 聚焦测试与 FastSim Conformance 测试。

建议先阅读仓库中的 添加一个插件 指南并复制最小模板,而不是手工重建打包元数据。

独立的 FastSim-RuleBased-TestRepo 包含面向三个水平层次的中文开发指南、通用插件开发 Agent Skill、真实可安装参考插件和 Rule-based 验收代码。它展示一致的几何/Joint 捕获、插件自有规划与 Joint Chunk 提交, 但不是生产版 Rule-based 任务实现。

开发与验证

bash
python -m pip install -e '.[dev]'
python -m pytest
python -m ruff check src tests
python -m ruff format --check src tests
python -m build

修改配置或文档时可优先运行:

bash
python -m pytest tests/unit/config tests/unit/test_cli.py tests/architecture/test_readme.py
fastsim config validate examples/quickstart/run.yaml --json

真实后端测试与纯 SDK 测试分离,需要对应 Provider、原生仿真器、必要时的 GPU/Display, 并要求显式启用。单元测试通过不表示每个后端能力都已经运行过。

发布检查

发布 Alpha 修订前:

  1. 在支持的 Python 版本运行完整源码测试。
  2. 构建 Wheel 和 Sdist,在干净环境安装 Wheel,并重新运行包与 CLI Smoke Test。
  3. 运行相关真实后端 Gate;除非明确是 Headless 性能 Gate,否则保留可见窗口。
  4. 校验 Lock/资源完整性及候选插件的 Conformance。
  5. 在证据中记录精确的 FastSim、UniRoboSim Core、Provider、仿真器、驱动、资产与 Seed 版本。

当前限制

  • 这是 Alpha 契约,不是稳定的 1.0 API。
  • 刻意不支持旧版 FastSim 配置与导入。
  • FastSim Core 不包含 Task/Action 语义、规划器、模型推理、遥操作设备驱动、录制/回放、 TUI、Web、Debug、HTTP 或 MCP 实现。它们都需要独立安装插件;应以对应插件自身的 发布状态为准,不能从 Core 的扩展能力推断功能已经完成。
  • 当前应用门面采用一进程一世界,不提供环境级 Vectorization。
  • 后端选择已统一,但资产支持、物理精度、渲染、传感器、流体、柔性体与性能仍属于 Provider 能力。
  • 当前 Runtime Lowering 可以接收 Environment、Rigid Object、Articulation、Robot、 程序化表面柔性体、Particle Fluid 和受支持的 Camera Sensor。FastSim Composition 尚未实现 体积柔性体、Light Lowering 和命名 Sensor Rate;具体缩放限制取决于实体类型、资产形式和 Provider 能力。
  • fastsim doctor 尚未检查原生后端健康状态。
  • License 元数据当前为 LicenseRef-Pending;源码公开可读不代表已经声明开源许可证。