Wiki
管理器与资源管理源码
本节把前面已经运行过的行为串成调用链。阅读目标是知道每层负责什么,以及故障发生在哪里。
1.示例 1:从机器人描述追到硬件实例
在固定版本源码中按顺序定位:
ControllerManager 接收 robot_description
→ ResourceManager::load_urdf
→ parse_control_resources_from_urdf
→ 按 system / actuator / sensor 分类
→ load_and_initialize_system 等函数
→ pluginlib 根据 XML 查找并创建派生对象
→ 调用 on_init
→ 导入状态、命令接口并验证描述一致性
1.1.关键数据怎样传递
URDF 字符串变成 HardwareInfo;HardwareInfo 保存组件、关节与参数;插件 on_init 获得这个对象;接口导出后,ResourceManager 以完整名字管理句柄。
查看时同时打开 MiniSystem 的 on_init 与导出函数。这样可以把框架调用与自己的代码对应起来。
2.示例 2:从 spawner 追到控制器插件
spawner 请求管理器服务
→ load_controller 根据 type 创建控制器实例
→ 初始化控制器节点和参数
→ configure_controller 调用 on_configure
→ switch_controller 协调停用与激活
→ 根据 InterfaceConfiguration 借出接口
→ on_activate
→ update 循环开始调度这个 active 控制器
spawner 是服务客户端,不是实时控制循环。它退出后,控制器仍由管理器持有并继续运行。
3.示例 3:把错误放回对应层
| 错误位置 | 典型原因 | 查找重点 |
|---|---|---|
| URDF 解析 | 标签、参数、关节声明不一致 | component_parser |
| 硬件加载 | 插件 XML、库、类名或依赖缺失 | pluginlib 与资源管理器日志 |
| 配置失败 | 参数错误、设备无法打开 | on_configure |
| 激活失败 | 接口不可用或已占用 | claim 与 switch 路径 |
| 周期报错 | 非法命令、反馈超时、算法失败 | read/update/write 返回值 |
4.示例 4:实际搜索源码
cd ~/ros2_control_humble_reference/ros2_control
rg -n 'load_urdf|claim_command_interface|load_and_initialize_system' hardware_interface/src
rg -n 'ControllerManager::(load_controller|switch_controller|read|update|write)' controller_manager/src
rg -n 'createSharedInstance|createUnmanagedInstance' controller_manager hardware_interface
rg 仅帮助定位,阅读时要打开函数上下文,不能只凭搜索命中行推断状态机行为。若系统没有 rg,可执行 sudo apt-get install ripgrep,或用编辑器搜索。
5.控制器切换为何需要协调
管理服务可能由 Executor 线程处理,而控制器列表和接口正在控制线程中使用。管理器需要安排切换时机,避免一边 update 一边随意删除对象。具体同步方式应以固定提交实现为准。
6.本节总结
ControllerManager 管理控制器与调度,ResourceManager 管理硬件与接口,pluginlib 创建可加载对象。它们一起让“配置里写一个名字”最终变成“某个 C++ 方法被周期调用”。
源码:ros2_control/controller_manager/controller_manager/spawner.py、ros2_control/controller_manager/src/controller_manager.cpp、ros2_control/hardware_interface/src/resource_manager.cpp。
返回 Humble 总览 · 上一篇:从零编写控制器 · 下一篇:实时循环与异步通信