Apollo 5.0 源码学习笔记(四)| 感知模块 | 激光感知
本系列博客旨在记录自己在学习百度无人驾驶开源框架Apollo的心得和体会,欢迎大家阅读和点赞,并提出宝贵意见,大家相互学习,如需转载,请注明出处,谢谢!
文章目录
激光感知模块目录结构
文件夹结构:以下文件夹都是在perception/lidar/
下app
——lidar应用类,主处理类,即最终应用程序应该是实例化该文件夹下的类来完成common
——定义lidar感知模块需要用的通用数据结构,例如LidarFrame,通用处理方法等;lib
——激光雷达感知中算法实现库interface
——各种算法类的基类定义,作为算法通用类的接口lib/roi_filter
——包含hdmap_roi_filter和roi_service_filter两个文件夹,前者用来利用高精度地图的信息来对LidarFrame中给出的高精度地图查询信息对点云进行ROI限制。
perception/map/hdmap
——用在感知模块用来查询与高精度地图相关的信息。
DAG
文件描述了整个系统的拓扑关系,也定义了每个Component需要订阅的话题:modules/perception/production/dag/dag_streaming_perception.dag;
激光雷达感知模块的目标:https://github.com/ApolloAuto/apollo/issues/9588
传感器配置:
配置参数:proto
定义:modules/perception/proto/sensor_meta_schema.proto
具体实现:modules/perception/production/data/perception/common/sensor_meta.pt
传感器管理类:SensorManager
类:modules/perception/common/sensor_manager/sensor_manager.h
Lidar处理流程:
激光雷达感知模块处理过程包括点云分割-》目标分类-》目标跟踪,涉及到的处理类有SegmentationComponent
、RecognitionComponent
。
我们首先看一下激光感知处理过程中的消息变化和对应的话题:
drivers::PointCloud[/apollo/sensor/velodyne128、/apollo/sensor/lidar_front, lidar_rear_left, lidar_rear_right]->LidarFrameMessage[/perception/inner/SegmentationObjects]->SensorFrameMessage[/perception/inner/PrefusedObjects]->
PerceptionObstacles[/apollo/perception/obstacles]
Lidar相关类型定义:
LidarFrame[modules/perception/lidar/common/lidar_frame.h]
——一帧的激光雷达帧数据,包含该帧激光雷达原始点云cloud
、世界坐标系下点云world_cloud
、激光雷达位姿lidar2world_pose
、分割出的目标序列segmented_objects
、跟踪目标序列tracked_objects
,以及其他一些属性;
SegmentationComponent—— 点云分割类
modules/perception/onboard/component/segmentation_component.h
输入:drivers::PointCloud
类型点云,
输出:LidarFrameMessage
,话题名为:/perception/inner/SegmentationObjects
。
该类配置参数proto
定义:modules/perception/onboard/proto/lidar_component_config.proto
,
具体实现文件在:modules/perception/production/conf/perception/lidar/velodyne16_segmentation_conf.pb.txt
,每个激光雷达一个实现文件。
通过modules/perception/lidar/app/lidar_obstacle_segmentation.cc
中的LidarObstacleSegmentation
类完成实际激光雷达点云分割工作;
LidarObstacleSegmentation——点云分割类
目的:分割原始点云,得到分割目标序列,即完成对点云目标的分割,得到属于该分割目标的点云,并拟合轮廓,得到bbox等属性;
LidarObstacleSegmentation::Process函数
1、首先进行点云预处理——主要对输入点云进行范围滤波、范围限定等操作,填充lidar_frame->cloud
,同时进行坐标变换,得到world_cloud
;
2、然后调用MapManager::Update
,在绝对坐标系下即高精度地图坐标系下根据激光雷达的绝对位置找到周围感兴趣区域,填充lidar_frame->hdmap_struct
;
3、调用分割算法:实际调用的是CNNSegmentation::Segment
填充lidar_frame->segmented_objects
向量
4、调用ObjectBuilder::Build
函数计算segmented_objects
中目标的polygon、center、anchor_point
等属性;
5、调用ObjectFilterBank
:对分割后目标进行ROIBoundaryFilter
即调用之前找到的激光雷达周围高精度地图感兴趣区域,来限定部分激光雷达目标;
RecognitionComponent——目标识别与跟踪
modules/perception/onboard/component/recognition_component.h
输入:LidarFrameMessage
输出:SensorFrameMessage
,话题名:"/perception/inner/PrefusedObjects"
跟踪分割后的点云目标,估计目标运动信息,填充LidarFrame
的tracked_objects
数据域。
参数配置:
具体实现文件在:modules/perception/production/conf/perception/lidar/recognition_conf.pb.txt
,
主传感器是velodyne64
,Apollo5.5
改为velodyne128
了。
具体算法流程:
通过modules/perception/lidar/app/lidar_obstacle_tracking.cc
中的LidarObstacleTracking
类完成
算法类的配置参数定义在:modules/perception/production/data/perception/lidar/models/lidar_obstacle_pipeline/velodyne16/lidar_obstacle_tracking.conf
可以看出实际使用的multi_target_tracker
为MlfEngine,fusion_classifier
为FusedClassifier
。
调用多目标跟踪算法:实际调用的是MlfEngine
类的Track
函数;
调用FusedClassifier
算法:对目标序列进行分类,填充目标类型信息;