roboto_inference 是一个基于 ROS 2 的实时强化学习策略推理包,专门用于将训练好的神经网络策略(ONNX 格式)部署到真实机器人上。它的核心使命是把仿真环境中训练得到的智能体行为,以低延迟、高确定性的方式迁移到物理世界——从读取 IMU 和关节传感器数据,到组装观测向量、执行神经网络前向推理,再到通过 CAN 总线驱动电机,形成完整的感知-决策-执行闭环。对于刚接触机器人部署的开发者来说,可以把本项目理解为连接"AI 模型"与"真实硬件"之间的桥梁。
Sources: package.xml
项目定位与核心能力
本仓库并非一个通用的机器人框架,而是围绕策略推理运行时这一核心目标构建的专用系统。它同时支持单一策略持续运行和多策略动态切换两种模式,能够适应从基础行走到舞蹈、起身、交互动作等多样化场景。系统通过 YAML 文件描述观测值布局、模型路径和硬件参数,开发者无需重新编译即可调整推理行为。此外,项目提供了 Python 绑定模块,允许在 Python 脚本中直接操作底层硬件接口,方便快速验证和调试。
Sources: CMakeLists.txt, pybind_module.cpp
系统架构总览
整个系统由三个层次组成:ROS 2 交互层负责接收手柄指令与外部感知话题;推理与观测层负责组装观测值、管理帧堆叠并执行 ONNX 推理;硬件抽象层则通过 CAN/CANFD 与电机通信,并采集 IMU 姿态数据。两个实时线程——inference(低频策略推理)和 control(高频动作下发)——以固定周期协同工作,确保控制指令的时序确定性。
flowchart TB
subgraph ROS2["ROS 2 交互层"]
JOY[/joy 手柄话题/]
CMD[/cmd_vel 指令话题/]
PERC[/感知话题/]
ACTION[/action 动作话题/]
JS[/joint_states 关节状态/]
SRV[("服务接口")]
end
subgraph INF["推理与观测层 (InferenceNode)"]
OBS["观测值组装与归一化"]
STACK["帧堆叠 (Frame Stack)"]
ONNX["ONNX Runtime 推理"]
POLICY["多策略运行时"]
end
subgraph HW["硬件抽象层 (RobotInterface)"]
IMU["IMU 驱动"]
MOTOR["电机驱动 (CAN/CANFD)"]
DECOUPLE["闭环解耦与运动学映射"]
end
JOY -->|速度指令| OBS
CMD -->|速度指令| OBS
PERC -->|地形/外部观测| OBS
OBS --> STACK
STACK --> ONNX
POLICY -->|切换模型| ONNX
ONNX -->|输出动作| HW
HW -->|关节反馈| OBS
IMU -->|角速度/重力向量| OBS
ACTION -->|发布| HW
JS -->|发布| HW
SRV -.->|初始化/急停/复位| INF
SRV -.->|电机上电/下电| HW
Sources: inference_node.hpp, robot_interface.hpp
项目目录结构
为了让初学者快速定位关键代码,以下是本仓库的核心目录说明。src/ 存放 C++ 源码,config/ 和 models/ 分别存放参数配置与神经网络模型,thirdparty/ 则内置了跨架构依赖(x64 与 aarch64),简化了部署流程。
roboto_inference/
├── config/ # YAML 参数配置
│ ├── inference.yaml # 默认单策略配置
│ ├── inference_getup.yaml# 多策略配置示例(行走 + 起身)
│ └── robot.yaml # 电机与 IMU 硬件参数
├── include/
│ └── robot_interface.hpp # 硬件抽象层公共接口
├── launch/
│ └── inference.launch.py # ROS 2 启动文件
├── models/ # ONNX 策略模型
│ ├── policy.onnx
│ ├── policy_getup.onnx
│ └── ...
├── motions/ # NPZ 动作参考数据(用于模仿学习)
├── src/ # 核心源码
│ ├── inference_node.cpp # 节点主逻辑与双线程循环
│ ├── inference_node.hpp # 节点类定义与策略运行时结构
│ ├── obs_manager.cpp # 观测值解析与源管理
│ ├── robot_interface.cpp # 硬件接口实现
│ ├── ros_interface.cpp # ROS 参数加载与回调
│ └── utils/ # 工具模块
│ ├── motion_loader.hpp
│ ├── close_chain_mapping.hpp
│ └── thread_pool.hpp
└── thirdparty/ # 第三方库(ONNX Runtime, yaml-cpp, cnpy)
Sources: get_dir_structure 综合结构
核心特性一览
| 特性 | 说明 | 对应学习章节 |
|---|---|---|
| 多策略运行时 | 支持同时加载多个 ONNX 模型,运行时通过手柄热切换 | 多策略运行时与热切换机制 |
| 实时双线程 | inference 线程负责推理,control 线程以更高频率平滑下发动作,均绑定 SCHED_FIFO |
实时双线程设计与调度策略 |
| 动态观测布局 | 通过字符串描述(如 ang_vel:3, dof_pos:23)自由组合观测源,无需改代码 |
观测布局配置与动态解析 |
| 帧堆叠支持 | 支持 frame_major 与 obs_major 两种堆叠顺序,兼容主流 RL 训练框架 |
观测值组装、归一化与帧堆叠 |
| 硬件抽象 | RobotInterface 封装电机与 IMU,支持闭环解耦和关节映射 |
RobotInterface 设计与实现 |
| Python 绑定 | 提供 robot_py 模块,可用 Python 脚本初始化电机、读取状态 |
Python 绑定与脚本化控制 |
| 安全机制 | 观测裁剪、动作裁剪、关节限位、重力方向检测与中断动作覆盖 | 安全监控、限位与故障处理 |
Sources: inference_node.hpp, inference_node.cpp, obs_manager.cpp
本 wiki 的阅读路线
如果你是第一次接触本项目,建议按照以下顺序学习,从"让机器人动起来"逐步深入到"理解每一行代码":
- Quick Start — 编译、安装依赖并运行第一个推理节点。
- 硬件准备与电机初始化 — 理解 CAN 总线接线、电机 ID 配置与上电流程。
- 手柄与指令控制入门 — 学习手柄映射、速度指令发布和安全操作习惯。
- Launch 文件与启动配置 — 掌握如何切换 YAML 配置以启用不同策略组合。
完成上述入门章节后,你可以根据兴趣深入以下方向:
- 想理解系统如何实时运转 → 阅读 系统架构总览、实时双线程设计与调度策略
- 想修改观测值或适配自己的模型 → 阅读 观测布局配置与动态解析、新增观测源与模型适配指南
- 想接入新的传感器或修改硬件逻辑 → 阅读 RobotInterface 设计与实现、电机驱动与 CAN/CANFD 通信