插件开发
插件开发
Apollo9.0 中,感知的插件有两部分:lidar_detection_filter 的 object_filter_bank 中;pointcloud_map_based_roi 的 roi_filter 中。
插件机制是一个比组件更加轻量化的动态加载机制,其目的是让开发者可以更加聚焦到功能逻辑上,更加方便地进行功能扩展。插件开发独立性较强,能被组件灵活的使用,根据需要加载插件。
插件开发,以lidar_detection_filter为例。其中object_filter_bank中可以执行多种filter,所有的filter都放到std::vector<std::shared_ptr<BaseObjectFilter>>中。
新建文件夹
在如下目录中新建文件夹,过滤器名称为new_filter,用于放代码和相关配置。
├── lidar_detection_filter├── conf├── dag├── data├── object_filter_bank│ ├── object_filter_bank.cc│ ├── object_filter_bank.h│ ├── roi_boundary_filter│ ├── new_filter // 新定义filter├── interface├── proto├── lidar_detection_filter_component.cc├── lidar_detection_filter_component.h├── cyberfile.xml├── README.md└── BUILD
功能定义
过滤器功能实现。
首先,继承BaseObjectFilter类,实现Init(初始化配置项),Filter(功能代码),Name(获取类名称)。
然后,在new_filter.h最后定义:CYBER_PLUGIN_MANAGER_REGISTER_PLUGIN(apollo::perception::lidar::NewFilter, BaseObjectFilter)。以此说明此功能是插件形式开发。
class NewFilter : public BaseObjectFilter {public:/*** @brief Construct a new NewFilter object**/NewFilter() = default;virtual ~NewFilter() = default;/*** @brief Init of NewFilter** @param options object filer options* @return true* @return false*/bool Init(const ObjectFilterInitOptions& options =ObjectFilterInitOptions()) override;/*** @brief filter objects using new filter algorithm** @param options object filter options* @param frame lidar frame to filter* @return true* @return false*/bool Filter(const ObjectFilterOptions& options, LidarFrame* frame) override;/*** @brief Name of NewFilter object** @return std::string name*/std::string Name() const override { return "NewFilter"; }private:... ...};CYBER_PLUGIN_MANAGER_REGISTER_PLUGIN(apollo::perception::lidar::NewFilter, BaseObjectFilter)
插件的具体功能定义在Filter函数中。此函数接受的是点云当前帧的frame,frame中数据主要有以下几种:
- 点云,以及其索引;
- 非地面点云索引,roi内点云索引;
- 检测障碍物(包括模型检测、背景聚类);
- lidar坐标系到世界坐标系的pose;
- 主车一定范围内的高精地图信息。
lidar_detection_filter是基于检测障碍物做的过滤,过滤功能由开发者根据实际情况自定义。
配置文件
在object_filter_bank/proto中定义new_filter的配置项,在data/new_filter.pb.txt中增加new_filter的配置。
├── lidar_detection_filter├── conf├── dag├── data│ ├── new_filter.pb.txt // 过滤库,在其中增加new_filter配置├── object_filter_bank│ ├── object_filter_bank.cc│ ├── object_filter_bank.h│ ├── roi_boundary_filter│ ├── proto // new_filter 配置定义│ ├── new_filter├── interface├── proto├── lidar_detection_filter_component.cc├── lidar_detection_filter_component.h├── cyberfile.xml├── README.md└── BUILD
插件管理
首先,BUILD中的编译如下,插件需要用apollo_plugin的方式来编译。
load("//tools:apollo_package.bzl", "apollo_package", "apollo_plugin")load("//tools:cpplint.bzl", "cpplint")package(default_visibility = ["//visibility:public"])apollo_plugin(name = "libnew_filter.so",srcs = ["new_filter.cc"],hdrs = ["new_filter.h"],description = ":plugins.xml",deps = [],)
然后,新建new_filter/plugins.xml,并在其中定义:
<library path="modules/perception/lidar_detection_filter/object_filter_bank/new_filter/libnew_filter.so"><class type="apollo::perception::lidar::NewFilter" base_class="apollo::perception::lidar::BaseObjectFilter"></class></library>
插件使用
插件定义好之后,就可以使用插件。使用方法是:在配置文件 modules/perception/lidar_detection_filter/data/filter_bank.pb.txt 中增加此插件的配置。
plugins {name: "ROIBoundaryFilter"config_path: "perception/lidar_detection_filter/data"config_file: "roi_boundary_filter.pb.txt"}plugins {name: "BackgroundFilter"config_path: "perception/lidar_detection_filter/data"config_file: "background_filter.pb.txt"}plugins {name: "NewFilter" # 在这里增加new_filter的配置config_path: "perception/lidar_detection_filter/data"config_file: "new_filter.pb.txt"}
配置好new_filter插件之后,启动 lidar_detection_filter 组件,运行感知,加载各个插件配置内容。当有数据进来时就new_filter就会执行Filter函数,完成过滤功能。