配置系统

FastSim 支持 YAMLJSON.sim 三种配置格式,由 ConfigManager 在启动时完成解析、合并与校验。整个配置系统被划分为五个相互独立又相互引用的配置块,分别描述环境、仿真器、场景、任务与扩展能力。

配置块一览

配置块顶层键职责
全局配置general项目扫描开关、资产根路径映射
仿真配置simulation仿真后端选择、时间步长、物理参数
场景配置scene实体声明:机器人、物体、传感器、光源
任务配置task动作序列与目标条件编排
扩展功能配置extension录制、回放、Benchmark、HTTP Server

配置格式

FastSim 支持三种配置文件格式,三者在语义上完全等价,ConfigManager 会根据文件扩展名自动选择解析器:

格式扩展名特点
YAML.yaml / .yml通用格式,社区广泛使用
JSON.json适合程序生成
.sim.simFastSim 专属 DSL,语法更简洁,支持变量、模板、文件引用等高级特性

YAML 格式示例

yaml
general:
  scan_project: true
  root_paths:
    assets: /path/to/assets

simulation:
  stereotype: isaaclab
  dt: 0.0166667
  initialize_steps: 30

scene:
  name: my_scene
  base_config:
    stereotype: ground_plane
  robot_cfg_dict:
    arm:
      stereotype: modular_robot
      asset_path: assets://robots/franka.usd

.sim 格式示例(等价配置)

text
general
    scan_project = true
    root_paths
        assets = /path/to/assets

simulation isaaclab
    dt = 0.0166667
    initialize_steps = 30

scene my_scene
    base ground_plane ground
    robot modular_robot arm
        asset_path = assets://robots/franka.usd

.sim 配置格式详解

.sim 是 FastSim 专属的配置 DSL(Domain Specific Language),设计目标是让机器人仿真配置更加简洁、可读。它最终会被解析为与 YAML 完全相同的 Python dict 结构。

基本语法规则

  • 缩进:使用 4 个空格作为一级缩进(类似 Python)
  • 注释:使用 # 行内注释
  • 赋值key = value(等号两边可以有空格)
  • 嵌套块:无等号的行表示子块头部,下级内容缩进 4 格
  • 值类型:自动推断 — true/false(布尔)、null/none(空值)、数字、[...](列表)、{...}(JSON 对象)、"quoted string"(字符串)、裸字符串

顶层 Section

.sim 文件由 5 个顶层 section 组成,与 YAML 的 5 个配置块一一对应:

text
general
    ...

simulation <stereotype>
    ...

scene <name>
    ...

task <name>
    ...

extension
    ...

simulationscene 的 section 头可以直接跟 stereotype 或 name,省去了在块内单独写一行。

实体声明语法

scenetask 内部,使用特殊的实体声明语法来定义实体,比 YAML 的嵌套字典更直观:

场景实体(scene 内部):

text
scene my_scene
    base <stereotype> <name>          # 地基
    robot <stereotype> <name>         # 机器人
    object <stereotype> <name>        # 物体
    sensor <stereotype> <name>        # 传感器
    light <stereotype> <name>         # 光源

任务实体(task 内部):

text
task my_task
    action <stereotype> <name>        # 动作
    goal <stereotype> <name>          # 目标

扩展内的观测者(extension 内部):

text
extension
    data_collect
        observer <stereotype> <name>  # 观测者

这些声明会自动被解析到对应的 dict 结构中。例如 robot modular_robot Franka 等价于 YAML 中:

yaml
robot_cfg_dict:
  Franka:
    stereotype: modular_robot

变量(let 声明)

使用 let 定义变量,通过 $name 引用,支持全局可见和算术表达式:

text
let base_path = /home/user/assets
let dt = 0.0166667
let steps = $(30 * 2)

simulation isaaclab
    dt = $dt
    initialize_steps = $steps

scene my_scene
    robot modular_robot arm
        asset_path = $base_path/robots/franka.usd
  • $name — 简单变量替换
  • $(expr) — 算术表达式求值(仅支持 + - * / 和括号)

文件引用(file 指令)

使用 file "path" 加载外部 JSON/YAML 文件作为值:

text
let grasp_pose = file "poses/grasp.json"

task pick_and_place
    action pick pick_cube
        robot_name = arm
        arm_name = main_arm
        pose
            source = inline
            frame = target
            data = $grasp_pose

file 指令也可以直接用在赋值中:

text
    data = file "poses/grasp.json"

支持 .json.yaml/.yml 格式,路径相对于当前 .sim 文件所在目录。

模板(template)

使用 template 定义可复用的配置片段,通过 use 应用:

text
template default_camera
    width = 1280
    height = 720
    camera_model = pinhole
    data_types = [rgb, depth]
    convention = opengl

scene my_scene
    sensor camera hand_cam
        use default_camera
        focal_length = 2.8
        attach_to
            target_name = arm
            is_articulation_part = true
            articulation_part_name = panda_link8

    sensor camera side_cam
        use default_camera
        focal_length = 4.0
        position = [1.0, 0.0, 0.8]

use 会将模板中的所有字段复制到当前块,之后定义的字段可以覆盖模板中的值。

配置继承(from)

.sim 文件也支持配置继承,使用 from "path" 语法(等价于 YAML 中的 FROM):

text
from "./base_config.yaml"

scene
    robot_cfg_dict
        arm
            position = [0.5, 0.0, 0.0]   # 覆盖基础配置中的位置

被继承的文件可以是 .yaml.json.sim 格式。

编辑器支持

FastSim 提供 .sim 格式的语法高亮插件:

编辑器安装方式
VS Codecode --install-extension editors/vscode-sim/joysim-sim-0.1.0.vsix
Vim / Neovimset runtimepath+=/path/to/fastsim/editors/vim
JetBrainsSettings → Editor → TextMate Bundles → 添加 editors/vscode-sim

完整 .sim 示例

text
from "../../demo_root_paths.yaml"

general
    enable_profiling = true

simulation isaaclab
    launch_config
        device = cuda
        enable_cameras = true
        headless = false

scene pick_and_place
    base usd workspace
        source = local
        asset_path = asset://scenes/workspace.usd

    robot modular_robot Franka
        asset_path = asset://Franka/franka_robotiq.usd
        position = [0.0, 0.0, 0.0]
        source = local
        actuator_cfg_dict
            franka_arm
                stereotype = arm
                joint_names_expr = [panda_joint1, panda_joint2, panda_joint3, panda_joint4, panda_joint5, panda_joint6, panda_joint7]
                stiffness = 50000.0
                damping = 800.0
            gripper
                stereotype = gripper
                joint_names_expr = [robotiq_85_left_knuckle_joint]
        arm_modules
            main_arm
                arm_actuator_name = franka_arm
                ee_link_name = gripper_center
                ee_type = gripper
                ee_actuator_name = gripper

    object rigid red_cube
        source = local
        asset_path = asset://objects/cube_red.usd
        position = [0.4, 0.0, 0.5]

    sensor camera wrist_cam
        width = 640
        height = 480
        data_types = [rgb, depth]
        convention = ros
        attach_to
            target_name = Franka
            is_articulation_part = true
            articulation_part_name = panda_link8

task pick_and_place
    action pick pick_cube
        robot_name = Franka
        arm_name = main_arm
        target
            name = red_cube
        pose
            source = inline
            frame = target
            data = {"position": [0, 0, 0.1], "rotation": [1, 0, 0, 0]}

    goal on_top cube_on_tray
        object_A_name = red_cube
        object_B_name = tray

extension
    task_executor
        enable = true
        stop_sim_on_task_end = true

    data_collect
        enable = true
        observer robot_observer Franka
            observe_joint_positions = true
            observe_ee_pose = true
        observer sensor_observer wrist_cam
            observe_rgb = true
            observe_depth = true

配置继承(FROM 关键字)

FastSim 配置系统支持通过 FROM 关键字实现配置继承——在基础配置之上进行增量覆盖,避免重复编写大量相同配置。

yaml
# override_config.yaml
FROM: ./base_config.yaml    # 继承 base_config.yaml 中的所有字段

scene:
  name: my_override_scene   # 覆盖 scene.name
  object_cfg_dict:
    cube:
      position: [0.5, 0.0, 0.1]  # 覆盖 cube 的位置

继承规则:

  • FROM 的值为基础配置文件的路径(支持相对路径和 root_key:// 协议)
  • 子配置中定义的字段会深度合并覆盖基础配置的对应字段
  • 列表类型的字段是替换而非追加
  • 支持多级继承(A FROM B FROM C),并有循环继承检测

这在需要为同一场景创建多个变体(不同物体位置、不同任务参数)时非常有用,只需在基础配置上用几行覆盖即可。

配置加载与校验

ConfigManagerFastSim.__init__() 中被调用,依次完成:

  1. 读取:从文件路径加载配置(根据扩展名自动选择 YAML / JSON / .sim 解析器)
  2. 继承解析:若存在 FROM 字段(YAML/JSON)或 from "path" 语句(.sim),递归加载基础配置并深度合并
  3. 校验:每个配置块对应各自的 *Config 数据类,字段类型与约束在此阶段报错
  4. 项目扫描:若 general.scan_project: trueProjectLoader 扫描用户代码,收集可用的 stereotype 注册表

校验与查看命令:

bash
fastsim validate_configuration --config <config_file>
fastsim show_config --config <config_file>
fastsim diff_config <config_a> <config_b>   # 对比两个配置的差异
fastsim show-registry   # 查看已注册的所有 stereotype
fastsim inspect_scene --config <config_file>      # 查看场景实体
fastsim inspect_task --config <config_file>       # 查看任务详情
fastsim inspect_extension --config <config_file>  # 查看扩展详情