# 7. 插件 Plugin Plugin 按 **类名** 从动态库或进程内注册表实例化派生类型。对标 ROS `pluginlib`。 | 本文 §7 | 相关文档 | |---------|----------| | 可插拔算法 | [§0 指南](00_guide.md) · [§9 启动 Launch](09_launch.md) · [§10 组件 Component](10_component.md) | 与 [Component](10_component.md) 的区别:Component 由 DAG 加载;Plugin 由业务 `CreateInstance` 加载算法实现。 --- ## 7.1 加载流程
插件 描述文件 / 进程内注册 → CreateInstance mainboard--plugin= 或自动 LoadInstalledPlugins()
外部插件 XML 描述文件 + class_loader 动态库
描述 plugin.xml
解析 PluginDescription ParseFromDescriptionFile
加载 LoadPlugin PluginManager
动态库 .so class_loader 加载
进程内注册 主程序已静态链接,无需拆 .so
注册 RegisterInProcessClass 已链接 · 无需 .so
两路径汇合 · 按类名实例化
实例化 CreateInstance CreateInstance<Base> (class_name)
mainboard --plugin= LoadInstalledPlugins() AUTOLINK_PLUGIN_*
路径适用
外部插件XML 描述 + 动态库,规划器等可热插拔算法
进程内注册主程序已静态链接实现,无需拆 .so
--- ## 7.2 plugin.xml XML 由 `PluginDescription::ParseFromDescriptionFile` 解析(`plugin_description.cpp`): ```xml ``` | 元素 | 含义 | |------|------| | `library@path` | 动态库路径(相对 `AUTOLINK_PLUGIN_LIB_PATH`) | | `class@type` | 派生类名(`CreateInstance` 参数) | | `class@base_class` | 基类 RTTI 名 | 环境变量见 [§1.6](01_architecture.md#16-环境与路径变量)(`AUTOLINK_PLUGIN_*`)。 --- ## 7.3 CreateInstance `PluginManager` 单例:加载描述文件或进程内注册后,按类名实例化派生类型。 ```cpp #include "autolink/plugin_manager/plugin_manager.hpp" auto* pm = autolink::plugin_manager::PluginManager::Instance(); // 加载描述文件 pm->LoadPlugin("/path/to/planner_plugins.xml"); // 进程内注册(无需 XML) pm->RegisterInProcessClass("NavfnPlanner"); // 按类名创建 auto planner = pm->CreateInstance("NavfnPlanner"); // 列举某基类的所有派生类名 auto names = pm->GetDerivedClassNameByBaseClass(); ``` `RegisterInProcessClass` 适用于主程序已静态链接实现、不想拆 `.so` 的场景。 --- ## 7.4 Autonomy 集成 `autonomy/planning/planner_server.cpp` 在启动时注册内置规划器并加载外部描述文件: ```cpp void LoadExternalPlugins(const proto::PlannerOptions& options) { auto* pm = PluginPm::Instance(); pm->RegisterInProcessClass("NavfnPlanner"); pm->RegisterInProcessClass("DijkstraPlanner"); pm->RegisterInProcessClass("ThetaStarPlanner"); for (const auto& path : options.planner_plugin_libraries()) { if (!pm->LoadPlugin(path)) { AWARN << "Failed to load plugin description: " << path; } } pm->LoadInstalledPlugins(); } common::GlobalPlanner::SharedPtr CreatePlannerInstance(const std::string& type, ...) { const std::string resolved = ResolvePlannerClass(type); if (resolved == "NavfnPlanner") { return std::make_shared(...); } // 外部插件 auto instance = PluginPm::Instance()->CreateInstance(resolved); return common::GlobalPlanner::SharedPtr(std::move(instance)); } ``` 配置中通过 `planner_plugin_libraries` 传入 XML 路径列表。 --- ## 7.5 Component 对比 | | Component | Plugin | |---|-----------|--------| | 注册 | `AUTOLINK_REGISTER_COMPONENT` | XML `` 或 `RegisterInProcessClass` | | 加载触发 | DAG `class_name` | `LoadPlugin` / `CreateInstance` | | 生命周期 | `Init` / `Proc` / `Shutdown` | 由业务持有 `shared_ptr` | | 典型用途 | 通信驱动模块 | 算法策略替换 | Component 的 `.so` 同样经 `class_loader` 加载;单元测试见 `autolink/autolink/class_loader/class_loader_test.cpp`(`libplugin1.so` / `libplugin2.so`)。 --- ## 7.6 mainboard --plugin ```bash mainboard -d foo.dag --plugin=/path/to/plugins.xml ``` `.launch` XML: ```xml planning ... path/to/planner_plugins.xml ``` `autolink_launch` 解析 `` 列表并传给 `mainboard`(`autolink/tools/autolink_launch/main.cpp`)。 --- **导航**:[← §6 参数 Parameter](06_parameter.md) · [§0 指南](00_guide.md) · [§8 日志 Log →](08_log.md)