🤖 roboto_origin_03 Wiki
首页 / 部署 / 配置文件系统详解

机器人的行为表现不仅取决于控制算法与模型权重,更深受配置参数系统的约束。本文档从第一性原理出发,系统梳理本项目全量配置文件的层级结构、参数语义、加载机制与自定义方法,帮助你在不修改源码的前提下安全地调整机器人行为、接入新策略或适配差异化硬件。

Sources: inference.launch.py, robot_interface.cpp, inference_node.hpp

配置文件体系总览

项目的配置系统采用分层解耦设计:推理参数由 ROS2 Parameter 机制托管,硬件参数由 yaml-cpp 直接解析,脚本参数由 PyYAML 独立加载。三类配置在运行时通过 InferenceNodeRobotInterface 两个核心类完成交汇,形成完整的控制闭环。

graph TD
    subgraph "ROS2 Parameter 层"
        A[inference.launch.py] -->|加载| B[inference*.yaml]
        B -->|declare_parameter<br/>get_parameter| C[InferenceNode]
    end
    
    subgraph "硬件抽象层"
        D[robot.yaml] -->|YAML::LoadFile| E[RobotInterface]
    end
    
    subgraph "Python 脚本层"
        F[scripts/config/*.yaml] -->|yaml.safe_load| G[set_zero.py<br/>motion_player.py]
    end
    
    C -->|apply_action| E
    G -->|robot_py.RobotInterface| E

三种配置的定位截然不同:inference*.yaml 决定策略如何思考(观测构造、模型选型、控制频率);robot.yaml 决定硬件如何响应(总线映射、关节限幅、阻抗参数);scripts/config/*.yaml 则服务于离线工具链(零点标定、动作回放)。理解这一边界是避免参数误配的前提。

Sources: CMakeLists.txt, inference_node.cpp, set_zero.py

推理节点配置:inference*.yaml

推理配置是整套系统中语义最密集的文件,所有以 inference 为前缀的 YAML 文件共享同一套参数模式,仅在数值或数组长度上体现策略差异。文件根节点必须为 inference_node.ros__parameters,这是 ROS2 declare_parameter API 所要求的命名空间。

参数全景

推理参数可分为六大语义组:

参数组 代表参数 作用域
策略加载 model_names, motion_names 多策略切换与动作序列绑定
观测构造 obs_layouts, extra_obs_layouts, frame_stacks, obs_stack_orders 神经网络输入张量的形状与内容
控制时序 dt, decimation, act_alpha 控制频率与动作平滑
归一化与裁剪 obs_scales_*, clip_observations, action_scale, clip_actions 数值安全与量纲统一
运动学映射 usd2urdf, joint_default_angle, joint_limits 关节顺序转换与物理约束
安全阈值 gravity_z_upper, clip_cmd 跌倒检测与速度指令限幅

Sources: ros_interface.cpp

观测布局语法

obs_layoutsextra_obs_layouts 是推理配置的核心,其语法为逗号分隔的 name:size 对。InferenceNode::parse_obs_layout 在初始化时严格校验该字符串,任何名称拼写错误或维度不匹配都会触发 std::runtime_error 异常。

当前系统支持的观测源及其语义如下:

观测源名称 维度 数据来源 适用场景
ang_vel 3 IMU 角速度 所有策略
gravity_b 3 IMU 姿态解算后的重力向量 所有策略
cmd_vel 3 手柄或 /cmd_vel 指令 所有策略
dof_pos 23 电机反馈关节位置(经 usd2urdf 映射) 所有策略
dof_vel 23 电机反馈关节速度 所有策略
last_action 23 上一时刻策略输出 所有策略
motion_pos 23 动作序列文件当前帧位置 动作模仿策略
motion_vel 23 动作序列文件当前帧速度 动作模仿策略
interrupt 1 手柄中断信号 中断策略
perception 187 /robot_0/elevation_data 地形高度图 地形感知策略

obs_layouts 中的字段将被 frame_stack 堆叠后作为 ONNX 模型的主输入;extra_obs_layouts 中的字段则不经堆叠,直接拼接在主输入之后。例如 inference_attn_enc.yaml 使用 frame_stacks: [5] 对基础观测堆叠 5 帧,再将 187 维地形感知数据作为 extra_obs_layouts 追加,最终输入尺寸为 (5 × 78) + 187

Sources: obs_manager.cpp, inference_attn_enc.yaml

观测堆叠顺序

obs_stack_orders 控制多帧观测在内存中的排布方式,仅当 frame_stack > 1 时生效:

Sources: inference_node.cpp

多策略配置约束

model_names 包含多个策略(如 inference_beyondmimic.yaml 中的 4 个模型)时,以下数组必须严格等长,否则 load_config 会抛出异常并终止节点:

motion_namesextra_obs_layouts 允许为空;若不为空,则长度也必须与 model_names 一致。空字符串的 motion_name 表示该策略不绑定动作序列。这一校验逻辑通过 require_policy_countrequire_empty_or_policy_count 两个 lambda 实现。

Sources: ros_interface.cpp

机器人硬件配置:robot.yaml

robot.yamlRobotInterface 构造函数以硬编码路径 ROOT_DIR + "config/robot.yaml" 加载,不经过 ROS2 Parameter 系统。这意味着运行时无法通过 ros2 param set 动态修改硬件参数;任何调整都必须重启节点才能生效。配置分为 imumotorsrobot 三个顶级节点。

IMU 配置

参数 类型 说明
imu_id int IMU 逻辑编号,用于多 IMU 区分
imu_interface_type string 通信方式,当前支持 "serial"
imu_interface string 设备路径,如 /dev/ttyUSB0
imu_type string IMU 型号,如 "HIPNUC"
baudrate int 串口波特率,默认 921600

Sources: robot.yaml, robot_interface.cpp

电机配置

电机配置的核心是总线拓扑描述motor_interface 列出所有 CAN 通道(如 ["can0", "can1", "can2", "can3"]),motor_num 描述每条通道挂载的电机数量(如 [6, 7, 5, 5]),二者长度必须一致。motor_id 则是按通道顺序展开的扁平数组,总长度等于 motor_num 之和。

参数 类型 说明
motor_id int[] 电机物理 ID 列表,按总线顺序排列
motor_interface_type string "can""canfd"
motor_interface string[] CAN 通道名称数组
motor_num int[] 各通道电机数量数组
motor_type string[] 各通道电机驱动类型,如 "DM"
motor_model int[] 电机型号编码,扁平数组
master_id_offset int MIT 控制帧的主 ID 偏移量
motor_zero_offset double[] 各电机零点偏移(弧度)

motor_zero_offset 中仅第 13 号电机(2.093)在出厂配置中具有非零值,其余均为 0.0,这通常对应特殊机械结构的关节偏置。

Sources: robot.yaml, robot_interface.cpp

机器人运动学配置

robot 节点承载运动学与安全相关的关键参数:

参数 类型 说明
type string 机器人类型,如 "atom01",用于选择闭链解耦算法
kp / kd double[] 各关节 MIT 控制的刚度与阻尼系数
motor_sign int[] 电机方向符号(1-1),用于对齐 URDF 与电机正方向
close_chain_motor_id int[] 闭链关节对应的电机物理 ID
urdf2motor int[] URDF 关节索引到电机索引的映射
extrinsic_R double[9] IMU 到机体坐标系的旋转矩阵(行优先)

close_chain_motor_idurdf2motor 共同定义了踝关节闭链运动学的解耦关系。当 type 字段存在时,RobotInterface 会实例化对应的 Decouple 对象,在 apply_action 中对左右踝关节进行前向/逆向解耦计算。

Sources: robot.yaml, robot_interface.cpp, robot_interface.cpp

脚本配置:scripts/config/

scripts/config/ 目录下的配置文件服务于 Python 离线工具,与 ROS2 推理节点完全解耦。

motion_player.yaml

该文件是 robot.yaml精简子集,仅保留 motorsrobot 节点,不含 imumotion_player.py 通过 robot_py.RobotInterface(config_file) 直接传入该路径,实现不依赖 ROS2 的动作回放。值得注意的是,其 motor_zero_offset 全为 0.0,与 robot.yaml 中第 13 号电机的非零偏移不同——这是因为在动作回放场景下,关节偏置通常已内置在动作数据文件中。

Sources: motion_player.yaml, motion_player.py

set_zero.yaml

零点标定配置进一步精简,仅保留电机创建所需的必要字段,不含 robot 运动学参数。set_zero.py 独立通过 yaml.safe_load 解析,并使用 motors_py.MotorDriver.create_motor 逐个实例化电机。标定完成后,各电机的 motor_zero_offset 会被写入电机内部存储,而非修改此 YAML 文件。

Sources: set_zero.yaml, set_zero.py

配置加载机制与运行时行为

理解配置何时被加载、以何种优先级被解析,是排查启动故障的关键。

推理节点加载链

sequenceDiagram
    participant User
    participant Launch as inference.launch.py
    participant Node as InferenceNode
    participant Robot as RobotInterface
    
    User->>Launch: ros2 launch inference inference.launch.py
    Launch->>Node: 加载 inference.yaml<br/>注入 ros__parameters
    Node->>Node: load_config()<br/>declare + get parameter
    Node->>Robot: 构造 RobotInterface<br/>路径: ROOT_DIR/config/robot.yaml
    Robot->>Robot: YAML::LoadFile<br/>解析 imu/motors/robot
    Node->>Node: setup_model()<br/>校验 ONNX 输入尺寸

InferenceNode 构造函数中,load_config()RobotInterface 的初始化顺序是固定的:先解析推理参数,再加载硬件配置。这意味着如果 robot.yaml 路径错误或格式非法,节点会在 load_config 成功之后、模型加载之前崩溃。

Sources: inference_node.hpp

参数校验与失败模式

load_config() 执行了多层防御性校验:

  1. 策略数量一致性obs_layoutsframe_stacksobs_stack_orders 必须与 model_names 等长。
  2. 观测源合法性parse_obs_layout 拒绝任何未在 obs_source_definitions 中注册的名称。
  3. ONNX 输入尺寸匹配setup_modelobs_num × frame_stack + extra_obs_num 与 ONNX 模型张量形状逐元素比对,任何不匹配都会抛出 std::runtime_error
  4. 关节限幅:运行时 get_dof_pos_obs 持续检测各关节是否超出 joint_limits,越界即调用 rclcpp::shutdown()
  5. 跌倒检测get_gravity_b_obs 监测重力向量 Z 分量,若大于 gravity_z_upper(默认 -0.5),判定机器人跌倒并安全停机。

Sources: ros_interface.cpp, inference_node.cpp, obs_manager.cpp

多策略配置文件对比

项目中预置了 6 套推理配置,分别对应不同的能力场景。下表从策略数量、观测结构、特殊能力三个维度进行对比:

配置文件 策略数 帧堆叠 特殊观测源 典型用途
inference.yaml 1 10 基础 locomotion 策略
inference_amp.yaml 1 1 AMP(Adversarial Motion Prior)风格策略
inference_attn_enc.yaml 1 5 perception:187 地形感知导航
inference_interrupt.yaml 1 10 interrupt:1 支持手柄中断信号的安全策略
inference_getup.yaml 2 10 / 1 motion_pos, motion_vel 基础策略 + 起身动作序列
inference_beyondmimic.yaml 4 10 / 1×3 motion_pos, motion_vel 基础策略 + 挥手/舞蹈/击打动作

inference_getupinference_beyondmimic 均包含多个策略,运行时通过手柄 LB 键切换 active_policy_idx_。含 motion_loader 的策略(motion_path 非空)被记录到 motion_policy_indices_,可通过 RB 键在动作序列间循环。

Sources: inference_beyondmimic.yaml, inference_getup.yaml, ros_interface.cpp

配置自定义指南

切换推理配置文件

默认的 inference.launch.py 硬编码了 inference.yaml

configs = [
    os.path.join(
        get_package_share_directory("inference"),
        "config",
        "inference.yaml",
    ),
]

若要切换至其他配置(如地形感知),修改该路径为 inference_attn_enc.yaml 后重新编译即可。更优雅的做法是在 launch 文件中通过 LaunchConfiguration 暴露命令行参数,但当前版本尚未实现。

Sources: inference.launch.py

接入新策略模型的最小步骤

假设你已训练得到一个 ONNX 模型 policy_custom.onnx 并放入 src/inference/models/

  1. 复制基线配置:以 inference.yaml 为模板,新建 inference_custom.yaml
  2. 更新模型名:将 model_names 改为 ["policy_custom.onnx"]
  3. 校验观测维度:确认 obs_layouts 中各字段维度之和与模型训练时的观测维度一致。
  4. 调整帧堆叠:若模型需要时序信息,设置 frame_stacksobs_stack_orders;若为单帧策略,设为 1
  5. 注册并编译:确保 CMakeLists.txt 中的 install(DIRECTORY config ...) 会将新文件安装到 share/ 目录,执行 colcon build --symlink-install

Sources: CMakeLists.txt

硬件参数调整的注意事项

修改 robot.yaml 中的 kp / kd 是调试机器人柔顺性的常见操作,但需遵循以下原则:

Sources: robot_interface.cpp, robot.yaml

延伸阅读与下一步

配置系统的深层机制与周边系统紧密耦合。若需进一步理解以下内容,建议按顺序阅读: