🤖 roboto_origin_03 Wiki
首页 / 推理子模块 / Launch 文件与启动配置

在 ROS 2 项目中,Launch 文件是连接代码与运行时的桥梁。它将可执行节点、参数文件、话题重映射等资源组织在一个可复现的启动脚本中。对于本推理包而言,理解 inference.launch.py 及其引用的 YAML 配置文件,是让你的机器人从"编译成功"走向"实际动起来"的第一道门槛。本篇将带你逐层拆解启动链路:从 Python Launch 的语法骨架,到 YAML 参数如何被节点解析并转化为实时控制行为,再到不同预设配置(行走、起身、舞蹈等)的切换方式。

Sources: inference.launch.py, package.xml

Launch 文件结构解析

本项目使用 ROS 2 标准的 Python Launch System。启动脚本位于 launch/inference.launch.py,其核心逻辑非常简洁:构造一个 LaunchDescription,其中包含一个 Node 动作,指向推理可执行文件并注入参数文件。

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

    return LaunchDescription(
        [
            Node(
                package="inference",
                executable="inference_node",
                name="inference_node",
                parameters=configs,
                output="screen",
            ),
        ]
    )

文件中的关键元素如下表所示:

字段 含义
package "inference" 目标功能包的名称,Launch 系统会据此在 ament 索引中查找资源
executable "inference_node" 要启动的可执行文件名
name "inference_node" 节点在 ROS 2 图中的逻辑名称,会覆盖 rclcpp 内部的默认名
parameters [...inference.yaml] 加载到节点的 ROS 2 参数文件列表,支持传入多个 YAML
output "screen" 将标准输出打印到终端

初学者需要特别注意parameters 字段接收的是一个列表,这意味着你可以同时传入多个 YAML 文件,后面的值会覆盖前面的同名参数。当前默认仅加载 config/inference.yaml。若你在修改配置后发现行为没有变化,请检查是否对 install 空间下的 YAML 做了更新(ROS 2 运行时读取的是安装后的副本,而非源码目录)。

Sources: inference.launch.py, CMakeLists.txt

配置文件体系总览

本项目的配置分为两条独立线索:推理参数(由 launch 文件传入节点)与 机器人硬件参数(由源码硬编码路径加载)。下表展示了 config/ 目录中各 YAML 的用途对比:

配置文件 模型数量 是否含 Motion 特殊观测源 典型使用场景
inference.yaml 1 标准行走
inference_amp.yaml 1 AMP 风格行走,速度范围更大
inference_getup.yaml 2 是(起身) motion_pos, motion_vel 跌倒后自动起身
inference_beyondmimic.yaml 4 是(wave/dance/punch) motion_pos, motion_vel 手柄切换多动作表演
inference_interrupt.yaml 1 interrupt 支持外部中断动作覆盖
inference_attn_enc.yaml 1 perception 带地形感知的注意力策略
robot.yaml IMU、电机、关节零点与限位

推理参数的 YAML 文件共享同一套语法格式:根节点必须为 inference_node:,其下嵌套 ros__parameters:,再之下才是具体参数键值。robot.yaml 则采用扁平结构,由 RobotInterface 直接解析,无需经过 ROS 2 参数系统。

Sources: inference.yaml, robot.yaml

启动流程与文件依赖

当你在工作空间中执行 ros2 launch inference inference.launch.py 时,系统会按照以下顺序完成初始化:

flowchart TD
    A[ros2 launch inference inference.launch.py] --> B[Python Launch 解析 LaunchDescription]
    B --> C[定位 install/share/inference/config/inference.yaml]
    C --> D[启动 inference_node 进程]
    D --> E[InferenceNode 构造函数]
    E --> F[load_config: 读取 ROS 2 参数]
    E --> G[RobotInterface 加载 config/robot.yaml]
    F --> H[setup_model: 加载 ONNX 模型并校验输入维度]
    G --> I[初始化 CAN/Serial 硬件]
    H --> J[启动 inference 线程]
    I --> K[启动 control 线程]
    J --> L[等待手柄/服务触发运行]
    K --> L

上述流程中有两个关键校验点会在启动阶段直接抛出异常并终止程序:一是 YAML 中 model_names 的长度必须与 obs_layoutsframe_stacksobs_stack_orders 严格一致;二是 ONNX 模型的输入维度必须与 obs_layout 推导出的总维度(含 frame_stack 倍增)完全匹配。因此,修改 YAML 后务必重新构建并安装,否则节点将在启动时崩溃。

Sources: inference_node.hpp, ros_interface.cpp, inference_node.cpp

核心参数分类详解

YAML 中的参数可按作用域分为 全局参数(所有策略共享)与 策略级参数(每个策略独立)。初学者最容易混淆的是策略级数组的长度必须与 model_names 的长度对齐。

策略级参数(数组,长度 = model_names 数量)

参数名 类型 说明
model_names string[] ONNX 模型文件名,位于 models/ 目录
motion_names string[] 动作参考文件名,位于 motions/ 目录;为空字符串表示无动作参考
obs_layouts string[] 主观测布局描述,语法为 name:size, name:size, ...
extra_obs_layouts string[] 额外观测布局(如感知特征),可选
frame_stacks int[] 时序帧堆叠数量;1 表示不堆叠,10 表示保留最近 10 帧
obs_stack_orders string[] 堆叠维度顺序,frame_majorobs_major

obs_layouts 中支持的观测源名称如下表所示。每个名称后跟的 size 必须与模型训练时的观测维度严格对应:

观测源名称 维度含义 出现场景
ang_vel 机体角速度(3D) 所有策略
gravity_b 机体坐标系下的重力方向(3D) 所有策略
cmd_vel 线速度/角速度指令(3D) 所有策略
dof_pos 关节位置(23) 所有策略
dof_vel 关节速度(23) 所有策略
last_action 上一时刻动作输出(23) 所有策略
motion_pos 参考动作关节位置(23) 含 motion 的策略
motion_vel 参考动作关节速度(23) 含 motion 的策略
interrupt 中断标志位(1) 中断模式策略
perception 外部感知数据(如地形,187) 注意力编码器策略

Sources: ros_interface.cpp, obs_manager.cpp

全局运行参数

参数名 典型值 功能说明
dt 0.004 控制线程周期(秒),对应 250 Hz
decimation 5 推理相对于控制的降采样倍数;推理频率 = 1 / (dt × decimation),即 50 Hz
act_alpha 1.0 动作平滑系数;1.0 为完全响应新动作,越小越平滑
intra_threads 1 ONNX Runtime 内部算子线程数;设为 1 可减少实时抖动
joint_num 23 机器人关节总数,必须与硬件和模型一致
action_scale 0.25 模型原始输出到目标关节偏移的缩放系数
clip_actions 100.0 动作输出的绝对值上限
clip_observations 100.0 观测值在送入 ONNX 前的绝对值上限
gravity_z_upper -0.5 摔倒检测阈值;当机体重力向量 z 分量大于此值时节点自动关闭

dtdecimation 共同决定了系统的实时节奏:控制线程dt 为周期向电机发送指令,推理线程dt × decimation 为周期执行 ONNX 推理并更新目标动作。初学者在更换策略模型时,必须确保这两个值与训练时的控制频率一致,否则会出现时序失配。

Sources: inference_node.cpp, inference_node.cpp

机器人映射与安全参数

参数名 类型 说明
usd2urdf int[] USD 训练环境中的关节索引到 URDF/实际电机索引的置换映射
joint_default_angle double[] 各关节的默认站姿角度(弧度),共 23 个
joint_limits double[] 各关节的 [min, max] 限位对,共 46 个值;超出即触发保护停机
clip_cmd double[] 手柄/指令速度限制 [x_min, x_max, y_min, y_max, yaw_min, yaw_max]
obs_scales_* float 各观测项的归一化缩放系数,通常保持 1.0

usd2urdf 是一个极易出错但至关重要的映射。训练环境(如 Isaac Gym/Sim)中的关节顺序通常与真实机器人电机的物理编号不同。该数组的每个元素 usd2urdf[i] 表示:将模型输出的第 i 个动作值,作用到实际机器人的第 usd2urdf[i] 号关节上。修改此数组前,建议对照训练代码中的关节定义表逐项核对。

Sources: inference.yaml, ros_interface.cpp

如何切换预设配置

项目内置了多种行为模式,切换方式仅需修改 launch 文件中的 configs 列表。例如,如果你想启动"起身模式",将 inference.launch.py 中的配置路径替换即可:

configs = [
    os.path.join(
        get_package_share_directory("inference"),
        "config",
        "inference_getup.yaml",  # 将 inference.yaml 替换为所需的配置文件
    ),
]

下表展示了不同场景推荐的配置文件:

你想让机器人做什么 推荐配置文件 需要额外资源
基础站立与行走 inference.yaml policy.onnx
高速/风格化行走 inference_amp.yaml policy_amp.onnx
跌倒后自动起身 inference_getup.yaml policy.onnx + policy_getup.onnx + getup.npz
表演 wave / dance / punch inference_beyondmimic.yaml 对应 4 个 ONNX + 3 个 NPZ
支持外部中断动作 inference_interrupt.yaml policy_interrupt.onnx
带地形感知的行走 inference_attn_enc.yaml policy_attn_enc.onnx + 外部 elevation 话题

修改后,执行 colcon build --packages-select inference 重新安装配置文件,再运行 launch 命令。

Sources: inference.launch.py, CMakeLists.txt

启动前检查清单

在按下回车键运行 ros2 launch 之前,建议对照以下清单进行确认:

  1. 可执行文件名一致:确认 CMakeLists.txtadd_executable 生成的目标名,与 launch 文件中 executable 字段匹配。若构建系统生成的名称与 launch 中不一致,启动会报 executable not found
  2. 模型文件存在models/ 目录中包含 YAML 中 model_names 列出的全部 .onnx 文件。
  3. 动作文件存在:若使用 motion_names,确认 motions/ 目录中有对应的 .npz 文件。
  4. 数组长度对齐obs_layoutsframe_stacksobs_stack_orders 的长度必须等于 model_names 的长度。motion_namesextra_obs_layouts 可以为空,若不为空则长度也必须对齐。
  5. 关节维度一致joint_numusd2urdfjoint_default_anglejoint_limits 的长度/维度必须与真实机器人匹配。
  6. 硬件接口就绪:确认 robot.yaml 中的 can0 ~ can3 或串口设备已正常初始化。

Sources: ros_interface.cpp

下一步

完成启动配置的学习后,你已经能够让机器人进入初始化状态。为了深入理解启动之后系统内部发生了什么,建议按照以下顺序继续阅读: