配置系统概述

相关源文件

以下文件用作生成此 wiki 页面的上下文:

robot_config 包提供了一个统一的配置系统,作为机器人硬件、外设、控制模式和 ML 策略 I/O 契约的**单一事实来源**。它通过将 ros2_control 参数、相机驱动、遥操作设置和推理契约整合到单个 YAML 文件中,消除了配置重复。

相关页面: 有关特定契约字段(观测、动作、QoS)的详细信息,请参阅 契约定义。有关外设驱动配置,请参阅 外设配置。有关启动文件生成,请参阅 启动系统。有关验证脚本,请参阅 配置验证


目的与范围

配置系统解决以下问题:

  • 配置漂移:此前,关节定义、相机参数和 ML 契约分散在多个文件中

  • 冗余:相同的相机分辨率或关节名称在 URDF、ros2_control 配置和 ML 契约中被重复定义

  • 模式切换:不同的控制范式(遥操作、模型推理、MoveIt 规划)需要单独的启动文件

  • 训练-部署对齐:记录数据与推理观测之间的不匹配导致失败

robot_config 包通过以下方式解决这些问题:

  1. 集中配置:一个 YAML 文件(so101_single_arm.yaml)定义所有硬件和软件参数

  2. 合成下游配置:ros2_control、相机驱动和契约从 YAML 自动生成

  3. 强制一致性:共享引用(如契约中的 peripheral: top)确保相机元数据正确传播

  4. 支持多模式控制:单一配置支持遥操作、模型推理和 MoveIt 模式


系统架构

        graph TB
    subgraph "Single Source of Truth"
        YAML["robot_config YAML<br/>so101_single_arm.yaml"]
    end

    subgraph "Configuration Loading"
        LOADER["load_robot_config()<br/>loader.py:147"]
        DATACLASS["RobotConfig<br/>config.py:105"]
        VALIDATOR["validate_control_mode_config()<br/>contract_builder.py:9"]
    end

    subgraph "Contract Synthesis"
        TOCONTRACT["RobotConfig.to_contract()<br/>config.py:133"]
        CONTRACT["Contract<br/>contract_utils.py:83"]
        SPECVIEW["SpecView<br/>contract_utils.py:112"]
    end

    subgraph "Launch Builders"
        ROBOT_LAUNCH["robot.launch.py<br/>launch/robot.launch.py:123"]
        CONTROL_BUILDER["generate_ros2_control_nodes()<br/>launch_builders/control.py"]
        PERCEPTION_BUILDER["generate_camera_nodes()<br/>launch_builders/perception.py"]
        EXEC_BUILDER["generate_execution_nodes()<br/>launch_builders/execution.py"]
        TELEOP_BUILDER["generate_teleop_nodes()<br/>launch_builders/teleop.py"]
        RECORDING_BUILDER["generate_recording_nodes()<br/>launch_builders/recording.py"]
    end

    subgraph "Runtime System"
        ROS2CTRL["ros2_control_node"]
        CAMERAS["usb_cam / realsense_node"]
        INFERENCE["lerobot_policy_node"]
        DISPATCHER["action_dispatcher_node"]
        RECORDER["episode_recorder"]
        TELEOP["robot_teleop"]
    end

    YAML --> LOADER
    LOADER --> DATACLASS
    DATACLASS --> VALIDATOR
    VALIDATOR --> TOCONTRACT
    TOCONTRACT --> CONTRACT
    CONTRACT --> SPECVIEW

    DATACLASS --> ROBOT_LAUNCH
    ROBOT_LAUNCH --> CONTROL_BUILDER
    ROBOT_LAUNCH --> PERCEPTION_BUILDER
    ROBOT_LAUNCH --> EXEC_BUILDER
    ROBOT_LAUNCH --> TELEOP_BUILDER
    ROBOT_LAUNCH --> RECORDING_BUILDER

    CONTROL_BUILDER --> ROS2CTRL
    PERCEPTION_BUILDER --> CAMERAS
    EXEC_BUILDER --> INFERENCE
    EXEC_BUILDER --> DISPATCHER
    TELEOP_BUILDER --> TELEOP
    RECORDING_BUILDER --> RECORDER

    CONTRACT -.->|"observations/actions"| INFERENCE
    CONTRACT -.->|"topics to record"| RECORDER
    CONTRACT -.->|"action topics"| DISPATCHER
    

源文件: src/robot_config/robot_config/loader.py:147-207, src/robot_config/robot_config/config.py:105-132, src/robot_config/launch/robot.launch.py:123-137


配置文件结构

顶层部分

robot:
  name: so101_single_arm             # 机器人标识符
  type: so101                         # 机器人硬件类型
  robot_type: so_101                  # LeRobot 数据集元数据

  models: {}                          # 策略检查点库
  joints: {}                          # 统一关节定义 (DRY)
  control_modes: {}                   # teleop | model_inference | moveit_planning
  ros2_control: {}                    # 硬件插件配置
  peripherals: []                     # 相机和传感器
  contract: {}                        # 观测和动作 (ML I/O)
  teleoperation: {}                   # 主臂 / 手柄配置
  recording: {}                       # Bag 录制设置

各部分在子页面 5.1-5.5 中有详细说明。

源文件: src/robot_config/config/robots/so101_single_arm.yaml:5-329


配置加载流程

        sequenceDiagram
    participant L as robot.launch.py
    participant Loader as load_robot_config()
    participant YAML as so101_single_arm.yaml
    participant RC as RobotConfig
    participant Val as validate_control_mode_config()
    participant Contract as to_contract()

    L->>Loader: load_robot_config(config_path)
    Loader->>YAML: read YAML file
    YAML-->>Loader: robot_data dict
    Loader->>RC: construct RobotConfig dataclass
    Note over Loader,RC: Resolves $(find pkg), $(env VAR)
    RC-->>Loader: RobotConfig instance
    Loader->>Val: validate_control_mode_config(robot_config, mode)
    Note over Val: Check model refs, observations, controllers
    Val-->>Loader: validation OK or raise ContractSynthesisError
    Loader->>Contract: robot_config.to_contract()
    Note over Contract: Synthesize Contract from observations/actions
    Contract-->>Loader: Contract instance
    Loader-->>L: RobotConfig + Contract
    

关键函数:

函数

文件

用途

load_robot_config()

loader.py:147-207

解析 YAML,解析路径, 构造 RobotConfig

validate_control_mode_config()

contract_builder.py:9-103

在启动前验证模式引用

RobotConfig.to_contract()

config.py:133-228

Contract

源文件: src/robot_config/robot_config/loader.py:147-207, src/robot_config/robot_config/contract_builder.py:9-103, src/robot_config/robot_config/config.py:133-228


配置类

核心数据类

        classDiagram
    class RobotConfig {
        +str name
        +str type
        +str robot_type
        +Ros2ControlConfig ros2_control
        +List~CameraConfig~ peripherals
        +ContractExtensionConfig contract
        +get_camera(name) CameraConfig
        +to_contract() Contract
    }

    class Ros2ControlConfig {
        +str hardware_plugin
        +Dict params
        +str urdf_path
    }

    class CameraConfig {
        +str name
        +str driver
        +int width, height, fps
        +str frame_id
        +Dict transform
    }

    class ContractExtensionConfig {
        +str base_contract
        +List~ContractObservation~ observations
        +List~ContractAction~ actions
        +float rate_hz
        +float max_duration_s
    }

    class Contract {
        +str name
        +float rate_hz
        +List~ObservationSpec~ observations
        +List~ActionSpec~ actions
    }

    class SpecView {
        +str key
        +str topic
        +str ros_type
        +bool is_action
        +List~str~ names
        +Tuple image_resize
    }

    RobotConfig --> Ros2ControlConfig
    RobotConfig --> CameraConfig
    RobotConfig --> ContractExtensionConfig
    RobotConfig --> Contract : to_contract()
    Contract --> SpecView : iter_specs()
    

源文件: src/robot_config/robot_config/config.py:8-232, src/robot_config/robot_config/contract_utils.py:26-211


控制模式架构

配置系统支持三种控制模式,每种模式具有不同的控制器类型和推理设置:

控制模式

控制器

推理

用途

teleop

position_controllers

禁用

人工遥操作(主臂、手柄)

model_inference

position_controllers

启用

端到端策略(ACT、Diffusion)

moveit_planning

trajectory_controllers

可选

基于规划的策略(VoxPoser、VLM)

模式选择流程

        graph LR
    YAML["default_control_mode<br/>in YAML"]
    OVERRIDE["--control_mode<br/>launch arg"]
    VALIDATE["validate_control_mode_config()"]
    CONTROLLERS["generate_ros2_control_nodes()"]
    INFERENCE["generate_execution_nodes()"]

    YAML --> VALIDATE
    OVERRIDE -.->|overrides| VALIDATE
    VALIDATE --> CONTROLLERS
    VALIDATE --> INFERENCE

    CONTROLLERS --> POS["position_controllers<br/>(teleop, model_inference)"]
    CONTROLLERS --> TRAJ["trajectory_controllers<br/>(moveit_planning)"]

    INFERENCE --> ENABLED["with_inference=True<br/>spawn policy + dispatcher"]
    INFERENCE --> DISABLED["with_inference=False<br/>skip inference nodes"]
    

配置示例:

control_modes:
  model_inference:
    description: "High-frequency end-to-end control mode (ACT/pi0)"
    controllers:
      - joint_state_broadcaster
      - arm_position_controller
      - gripper_position_controller
    inference:
      enabled: true
      execution_mode: "distributed"  # or "monolithic"
      model: so101_act
    executor:
      type: topic
      control_frequency: 50.0

源文件: src/robot_config/config/robots/so101_single_arm.yaml:46-103, src/robot_config/robot_config/contract_builder.py:9-103


启动系统集成

启动构建器模式

robot.launch.py 文件通过专门的构建器编排节点生成:

        graph TB
    MAIN["robot.launch.py<br/>launch_setup()"]

    subgraph "Builder Modules"
        CTRL["control.py<br/>generate_ros2_control_nodes()"]
        PERCEP["perception.py<br/>generate_camera_nodes()"]
        EXEC["execution.py<br/>generate_execution_nodes()"]
        TELEOP["teleop.py<br/>generate_teleop_nodes()"]
        REC["recording.py<br/>generate_recording_nodes()"]
    end

    subgraph "Generated Nodes"
        ROS2CTRL_NODE["ros2_control_node"]
        SPAWNER["controller_spawner"]
        CAM1["usb_cam_node (top)"]
        CAM2["usb_cam_node (wrist)"]
        POL["lerobot_policy_node"]
        DISP["action_dispatcher_node"]
        TEL["robot_teleop_node"]
        EPIREC["episode_recorder"]
    end

    MAIN --> CTRL
    MAIN --> PERCEP
    MAIN --> EXEC
    MAIN --> TELEOP
    MAIN --> REC

    CTRL --> ROS2CTRL_NODE
    CTRL --> SPAWNER
    PERCEP --> CAM1
    PERCEP --> CAM2
    EXEC --> POL
    EXEC --> DISP
    TELEOP --> TEL
    REC --> EPIREC
    

构建器职责:

构建器

文件

生成内容

control.py

launch_builders/control.py

ros2_control_node, controller spawners

perception.py

launch_builders/perception.py

usb_cam / realsense nodes, static_transform_publisher

execution.py

launch_builders/execution.py:1-259

lerobot_policy_node, action_dispatcher_node

teleop.py

launch_builders/teleop.py

robot_teleop_node(主臂 / 手柄)

recording.py

launch_builders/recording.py:1-226

episode_recorder(分集)或 ros2 bag record(连续)

源文件: src/robot_config/launch/robot.launch.py:123-318, src/robot_config/robot_config/launch_builders/execution.py:1-259


契约合成

契约系统定义 ML 策略的观测(输入)和动作(输出)。robot_config YAML 是合成契约的**单一事实来源**。

合成流程

        graph TB
    YAML["robot_config YAML<br/>observations + actions"]
    PERIPH["peripherals section<br/>(camera metadata)"]

    TOCONTRACT["RobotConfig.to_contract()"]

    OBSSPEC["ObservationSpec<br/>topic, type, image_resize"]
    ACTSPEC["ActionSpec<br/>publish_topic, type, names"]

    CONTRACT["Contract<br/>(contract_utils.py)"]

    INFERENCE["lerobot_policy_node<br/>(subscribes to obs topics)"]
    RECORDER["episode_recorder<br/>(records obs + act topics)"]
    BAG2LR["bag_to_lerobot<br/>(converts to LeRobot format)"]

    YAML --> TOCONTRACT
    PERIPH --> TOCONTRACT
    TOCONTRACT --> OBSSPEC
    TOCONTRACT --> ACTSPEC
    OBSSPEC --> CONTRACT
    ACTSPEC --> CONTRACT

    CONTRACT --> INFERENCE
    CONTRACT --> RECORDER
    CONTRACT --> BAG2LR
    

外设引用示例:

peripherals:
  - type: camera
    name: top
    width: 640
    height: 480
    fps: 30

contract:
  observations:
    - key: observation.images.top
      topic: /camera/top/image_raw
      peripheral: top  # Auto-fills width/height/fps from peripheral
      image:
        resize: [480, 640]

当调用 to_contract() 时,peripheral: top 引用会自动将 width: 640height: 480fps: 30 注入到 ObservationSpec 中。

源文件: src/robot_config/robot_config/config.py:133-228, src/robot_config/config/robots/so101_single_arm.yaml:130-247


路径解析

配置加载器解析 ROS 风格的路径替换:

语法

示例

解析方式

$(find pkg)

$(find robot_config)/config/contracts/act.yaml

搜索 install/share 目录

$(env VAR)

$(env HOME)/.calibrate/so101.json

读取环境变量

实现: robot_config/utils.py:resolve_ros_path()

源文件: src/robot_config/robot_config/loader.py:66-90, src/robot_config/robot_config/utils.py


验证系统

validate_config.py 脚本强制执行配置文件之间的一致性:

        graph LR
    VALIDATOR["ConfigValidator<br/>validate_config.py:26"]
    YAML["robot_config YAML"]
    CONTROLLERS["so101_controllers.yaml"]
    URDF["so101.urdf.xacro"]

    VALIDATOR --> JOINTS["Check joints section"]
    VALIDATOR --> CTRL["Check controller refs"]
    VALIDATOR --> PERIPH["Check peripheral refs"]

    JOINTS --> YAML
    CTRL --> CONTROLLERS
    PERIPH --> YAML

    VALIDATOR --> OK["Exit 0: OK"]
    VALIDATOR --> FAIL["Exit 1: Errors"]
    

验证检查:

  1. 关节一致性:验证 joints.armjoints.gripper 与控制器定义匹配

  2. 控制器引用:确保 control_modes.<mode>.controllers 存在于 ros2_control.controllers

  3. 外设引用:验证 contract.observations[].peripheral 存在于 peripherals[]

  4. 模型引用:检查 inference.model 存在于 models 部分中

用法:

python3 scripts/validate_config.py \
    src/robot_config/config/robots/so101_single_arm.yaml

源文件: scripts/validate_config.py:1-310, src/robot_config/robot_config/contract_builder.py:9-103


关键设计模式

单一事实来源

所有下游配置都从 robot_config YAML 合成

这消除了跨文件手动同步关节名称、相机分辨率或主题名称的需要。

基于引用的元数据注入

契约通过名称引用外设,而不是复制元数据:

peripherals:
  - name: top
    width: 640
    height: 480

contract:
  observations:
    - key: observation.images.top
      peripheral: top  # Metadata auto-injected

此模式在 config.py:133-228 中实现。

模式驱动的节点生成

启动系统使用活动控制模式有条件地生成节点:

if active_control_mode == 'teleop':
    actions.extend(generate_teleop_nodes(robot_config))

if with_inference:  # Auto-detected from mode config
    actions.extend(generate_execution_nodes(robot_config, mode))

参见 robot.launch.py:243-275

源文件: src/robot_config/robot_config/config.py:133-228, src/robot_config/launch/robot.launch.py:243-275


集成点

与 ros2_control 集成

配置系统生成 ros2_control URDF 和控制器启动命令:

ros2_control:
  hardware_plugin: so101_hardware/SO101SystemHardware
  port: /dev/ttyACM0
  controllers:
    - joint_state_broadcaster
    - arm_position_controller

生成的节点: ros2_control_node,每个控制器的 controller_spawner

源文件: src/robot_config/robot_config/launch_builders/control.py

与推理服务集成

execution.py 构建器生成带有自动合成契约的 lerobot_policy_node

inference:
  enabled: true
  model: so101_act
  execution_mode: "distributed"

传递的参数:

  • checkpoint:从 models.so101_act.path 解析

  • robot_config_path:YAML 的绝对路径(用于契约合成)

  • execution_mode:”monolithic” 或 “distributed”

源文件: src/robot_config/robot_config/launch_builders/execution.py:61-127

与分集记录器集成

recording.py 构建器将 robot_config_path 传递给 episode_recorder

recording:
  bag_base_dir: "~/rosbag/episodes"
  storage: mcap

记录器使用 robot_config.to_contract() 确定要订阅的主题。

源文件: src/robot_config/robot_config/launch_builders/recording.py:102-168, src/dataset_tools/dataset_tools/episode_recorder.py:194-206


文件组织

src/robot_config/
├── config/
│   ├── robots/                    # 机器人特定的 YAML 文件
│   │   ├── so101_single_arm.yaml
│   │   └── so101_dual_arm.yaml
│   └── contracts/                 # 基础契约模板(已弃用)
├── launch/
│   └── robot.launch.py            # 主编排器
├── robot_config/
│   ├── config.py                  # 数据类定义
│   ├── loader.py                  # YAML 加载和解析
│   ├── contract_utils.py          # 契约合成和运行时
│   ├── contract_builder.py        # 启动前验证
│   ├── utils.py                   # 路径解析辅助函数
│   └── launch_builders/           # 模块化节点生成器
│       ├── control.py
│       ├── perception.py
│       ├── execution.py
│       ├── teleop.py
│       ├── recording.py
│       └── simulation.py
└── README.md

源文件: src/robot_config/


常见使用模式

使用默认模式启动

ros2 launch robot_config robot.launch.py robot_config:=so101_single_arm

使用 YAML 中的 default_control_mode

覆盖控制模式

ros2 launch robot_config robot.launch.py \
    robot_config:=so101_single_arm \
    control_mode:=teleop \
    record:=true

覆盖为遥操作模式并启用录制。

自定义配置路径

ros2 launch robot_config robot.launch.py \
    config_path:=/path/to/custom.yaml

源文件: src/robot_config/launch/robot.launch.py:21-61


下一步

有关配置系统特定方面的详细信息:

源文件: src/robot_config/README.en.md:1-582, src/robot_config/launch/robot.launch.py:1-387