7. 插件 Plugin

Plugin 按 类名 从动态库或进程内注册表实例化派生类型。对标 ROS pluginlib

本文 §7

相关文档

可插拔算法

§0 指南 · §9 启动 Launch · §10 组件 Component

Component 的区别: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):

<library path="lib/libmy_planner.so">
  <class type="MyPlanner" base_class="autonomy::planning::common::GlobalPlanner"/>
  <class type="AnotherPlanner" base_class="autonomy::planning::common::GlobalPlanner"/>
</library>

元素

含义

library@path

动态库路径(相对 AUTOLINK_PLUGIN_LIB_PATH

class@type

派生类名(CreateInstance 参数)

class@base_class

基类 RTTI 名

环境变量见 §1.6AUTOLINK_PLUGIN_*)。


7.3 CreateInstance

PluginManager 单例:加载描述文件或进程内注册后,按类名实例化派生类型。

#include "autolink/plugin_manager/plugin_manager.hpp"

auto* pm = autolink::plugin_manager::PluginManager::Instance();

// 加载描述文件
pm->LoadPlugin("/path/to/planner_plugins.xml");

// 进程内注册(无需 XML)
pm->RegisterInProcessClass<common::GlobalPlanner>("NavfnPlanner");

// 按类名创建
auto planner = pm->CreateInstance<common::GlobalPlanner>("NavfnPlanner");

// 列举某基类的所有派生类名
auto names = pm->GetDerivedClassNameByBaseClass<common::GlobalPlanner>();

RegisterInProcessClass 适用于主程序已静态链接实现、不想拆 .so 的场景。


7.4 Autonomy 集成

autonomy/planning/planner_server.cpp 在启动时注册内置规划器并加载外部描述文件:

void LoadExternalPlugins(const proto::PlannerOptions& options) {
    auto* pm = PluginPm::Instance();
    pm->RegisterInProcessClass<common::GlobalPlanner>("NavfnPlanner");
    pm->RegisterInProcessClass<common::GlobalPlanner>("DijkstraPlanner");
    pm->RegisterInProcessClass<common::GlobalPlanner>("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<planner::navfn::NavfnPlanner>(...);
    }
    // 外部插件
    auto instance = PluginPm::Instance()->CreateInstance<common::GlobalPlanner>(resolved);
    return common::GlobalPlanner::SharedPtr(std::move(instance));
}

配置中通过 planner_plugin_libraries 传入 XML 路径列表。


7.5 Component 对比

Component

Plugin

注册

AUTOLINK_REGISTER_COMPONENT

XML <class>RegisterInProcessClass

加载触发

DAG class_name

LoadPlugin / CreateInstance

生命周期

Init / Proc / Shutdown

由业务持有 shared_ptr

典型用途

通信驱动模块

算法策略替换

Component 的 .so 同样经 class_loader 加载;单元测试见 autolink/autolink/class_loader/class_loader_test.cpplibplugin1.so / libplugin2.so)。


7.6 mainboard –plugin

mainboard -d foo.dag --plugin=/path/to/plugins.xml

.launch XML:

<autolink>
    <module>
        <name>planning</name>
        <dag_conf>...</dag_conf>
        <plugin>path/to/planner_plugins.xml</plugin>
    </module>
</autolink>

autolink_launch 解析 <plugin> 列表并传给 mainboardautolink/tools/autolink_launch/main.cpp)。


导航← §6 参数 Parameter · §0 指南 · §8 日志 Log →