Scene 场景

Scene(场景)是仿真世界的声明式描述——你在 YAML 配置中写明"有哪些实体、它们是什么类型、资产从哪里来",SceneManager 负责在运行时将这份描述转化为可交互的仿真实体,并在每一帧维持它们的状态同步。

实体类型一览

FastSim 的场景由五类实体组成,每类实体通过 stereotype 字段指定具体行为:

类别配置键Stereotype说明
Basebase_configground_plane / usd / empty场景地基与环境,每个场景只有一个
Objectobject_cfg_dictrigid / articulated场景中的物体,刚体或关节体
Robotrobot_cfg_dictgeneral_robot / single_gripper_arm_robot机器人,支持规划器挂载
Sensorsensor_cfg_dictcamera传感器,当前重点支持相机
Lightlight_cfg_dictgeneral_light光源,控制场景照明

base_config 外,其余四类均为字典形式(robot_cfg_dict 等),key 是实体的唯一名称,在运行时通过该名称访问实体。

场景配置结构

一个典型的 scene 配置块:

yaml
scene:
  name: my_scene

  base_config:
    stereotype: ground_plane
    ground_plane_size: 10.0

  robot_cfg_dict:
    arm:
      stereotype: general_robot
      asset_path: assets://robots/ur5.usd
      ee_link_name: tool0
      use_planner: true

  object_cfg_dict:
    cube:
      stereotype: rigid
      mass: 0.5
      asset_path: assets://objects/cube.usd

  sensor_cfg_dict:
    wrist_cam:
      stereotype: camera
      width: 640
      height: 480
      data_types: [rgb, depth]
      attach_to: arm

  light_cfg_dict:
    main_light:
      stereotype: general_light
      light_type: distant
      intensity: 3000

源码配置类:fastsim/configs/scene_cfg.pySceneConfig)。

生命周期:从配置到实体

调用 FastSim.setup_all_before_loop() 时,场景构建按以下顺序执行:

text
SceneManager.setup_scene_from_config(scene_cfg)
  │
  ├─ set_base(base_config)
  │    └─ 根据 stereotype 实例化 Base 对象
  │
  ├─ add_all_spawnables(scene_cfg)
  │    └─ 遍历 object/robot/sensor/light 字典,实例化各 Spawnable
  │
  └─ spawn_all(include_base=True)
       └─ 将所有实体写入仿真器的 USD Stage(真正"出现"在仿真中)

[UniSim.reset()]
  └─ 物理复位 + 执行若干初始化步骤,使实体进入稳定初始状态

spawn 完成后,每个实体可通过名称访问:

python
robot = SceneManager.get_robot("arm")
cube  = SceneManager.get_object("cube")
cam   = SceneManager.get_sensor("wrist_cam")

仿真循环中的更新节奏

这是 Scene 最关键、也最容易被忽视的机制。每一帧 FastSim.step() 内部,场景的读写被严格划分为三个阶段:

text
① SceneManager.pre_physics_update()
   └─ write_to_sim_if_dirty()
      将上一帧设置的目标值(关节角度、速度、位置等)写入仿真器

② UniSim.step()
   └─ 物理引擎推进一帧,计算碰撞、动力学、接触力

③ SceneManager.post_physics_update()
   └─ update()
      从仿真器读取最新状态,刷新各实体的状态缓存

实践含义:

  • 设置控制目标(如 robot.set_joint_targets())会标记为"脏",在下一帧的 ① 阶段才真正写入物理引擎,而不是立即生效。
  • 读取实体状态(如 robot.get_ee_pose())读的是 ③ 阶段刷新后的缓存,在 step 之前读到的是上一帧的结果。
  • 如果你在控制线程中需要"设置目标 → 等待执行 → 读取结果",应使用同步 Command(sync=True),而不是直接调用实体方法。

实体类型详解

Base:地基与环境

每个场景有且仅有一个 Base,定义物理地面或环境容器。

Stereotype关键配置字段说明
ground_planeground_plane_size无限延伸的平面地基,最常用
usdasset_path, source从 USD 文件加载复杂环境(房间、工厂等)
empty无地基,适合空中或自定义物理场景

源码:fastsim/unisim/bases/


Object:场景物体

场景中可被操作的物体,支持物理属性配置。

Stereotype说明典型配置字段
rigid刚体,有质量和碰撞体积massdensityenable_gravityasset_path
articulated关节体(Articulation)asset_path、关节初始状态

rigid 也支持使用 primitive 几何体(box、sphere、cylinder)直接生成,无需 USD 文件:

yaml
object_cfg_dict:
  box:
    stereotype: rigid
    use_primitive: true
    primitive_type: box
    size: [0.05, 0.05, 0.05]
    mass: 0.2

源码:fastsim/unisim/objects/


Robot:机器人

机器人是场景中最复杂的实体,除基础运动学外还支持规划器挂载。

通用配置字段(所有 robot stereotype 共享):

字段说明
asset_path机器人 USD 资产路径
ee_link_name末端执行器的 link 名称,用于 get_ee_pose / solve_ik
ik_joint_names参与差分 IK 的关节子集,不设则使用全部关节
use_planner是否挂载运动规划器(Curobo 等)
planner_cfg规划器详细配置

single_gripper_arm_robot 额外字段:

字段说明
arm_actuator_name机械臂 actuator group 名称
gripper_actuator_name夹爪 actuator group 名称

源码:fastsim/unisim/robots/


Sensor:传感器

当前内置重点为相机(camera)。

字段说明
data_types采集的数据类型,如 [rgb, depth, semantic_segmentation]
width / height图像分辨率
clip_range深度裁剪范围 [near, far](米)
attach_to绑定到某个实体(如机器人的某个 link)
look_at相机朝向目标点或目标实体
convention坐标系约定:world / opengl / ros

源码:fastsim/unisim/sensors/models/camera.py


Light:光源

general_light 提供统一的光源配置接口,支持多种光源类型。

字段说明
light_typedistant(平行光)/ sphere(点光源)/ disk(面光源)
intensity光照强度
color颜色 [r, g, b],范围 0–1
temperature色温(K),与 color 互斥
visible光源 mesh 是否在渲染中可见

源码:fastsim/unisim/lights/models/general_light.py

资产路径解析

实体配置中的 asset_path 支持多种路径格式,由 Asset.resolve_url_path() 统一解析(源码:fastsim/utils/asset.py):

格式示例说明
绝对路径/data/robots/ur5.usd直接使用文件系统路径
相对路径./assets/cube.usd相对于配置文件所在目录
root_key 协议assets://robots/ur5.usd映射到 general.root_paths.assets 所指向的目录
HTTP(S)https://example.com/ur5.usd远端资产,自动下载并缓存到本地

root_key:// 协议是最推荐的用法——它将路径与具体机器环境解耦,只需在 general.root_paths 中配置一次根目录,其余配置文件直接使用逻辑路径:

yaml
general:
  root_paths:
    assets: /home/user/robot_assets
    # assets://robots/ur5.usd → /home/user/robot_assets/robots/ur5.usd