vlambda博客
学习文章列表

开发者说丨 Apollo 源码分析:Perception 如何启动?


Perception系统是以多种sensor的数据,以及高精度地图的信息作为输入,经过一系列的计算及处理,对自动驾驶车的周围的环境精确感知。能够为下游模块提供丰富的信息,包括障碍物的位置、形状、类别及速度信息,也包括对一些特殊场景的语义理解(包括施工区域,交通信号灯及交通路牌等)。


下面是由社区开发者—Frank909提供的文章,Perception如何启动进行详细讲解,这篇文章将给刚接触自动驾驶的开发者们带来一些帮助。


    ENJOY THE FOLLOWING  


从 Apollo 的官方文档,我们很容易得知 Perception 是核心的组件之一,但像所有的 C++ 程序一样,每个应用都有一个 Main 函数入口,那么引出本文要探索的 2 个问题:


  • Perception 的入口在哪里?
  • Perception 如何启动?


开发者说丨 Apollo 源码分析:Perception 如何启动?


在讲 Perception 组件具体内容前,非常有必要讲 CyberRT


开发者说丨 Apollo 源码分析:Perception 如何启动?


CyberRT 就是 Apollo 中的一套基础框架,是面向组件(component)的。组件呈现高度的模块化。


每个组件包含特定的算法,用于处理数据输入,并输出算法处理的结果。


玩过 ROS 的同学应该对此类东西不陌生,CyberRT 和 ROS 类似,实际上 Apollo 最初也是用的 ROS1,后来因为时延问题得不到满足,所以自行开发了一个类似的,但性能更好。


回到组件问题,Perception 也是组件,之前的文章有介绍,它接收传感器的数据,然后输出障碍物的 3D 信息。


在 CyberRT 中,有如何定义、实现、启动组件的机制说明。


开发者说丨 Apollo 源码分析:Perception 如何启动?


通常 4 个步骤进行组件开发:


  • 设置组件文件结构
  • 实现组件类
  • 设置配置文件
  • 启动组件


开发者说丨 Apollo 源码分析:Perception 如何启动?


按照 Apollo 官方文档提示,一个 component 相关的文档有这几个:


Header file: common_component_example.hSource file: common_component_example.ccBuild file: BUILDDAG dependency file: common.dagLaunch file: common.launch
按照上图提示,我们可以去源码中搜索相关的文件。


Apollo 6.0 官方文档有这么一句:


开发者说丨 Apollo 源码分析:Perception 如何启动?


这是说 Perception 模块现在可以只有一个组件:Dectection。


为什么这么说呢?


Apollo 是多数据融合的,它融合 Camera、Lidar、Radar 目标,而这 3 个都是一个 component。

开发者说丨 Apollo 源码分析:Perception 如何启动?

我们可以先从总入口出发,再一个个分析。

所以,我们得先寻找 Detection 相关的组件。

很容易找到,路径:


  
    
    
  
apollo/modules/perception/onboard/component


这个目录下,定义和实现了很多感知相关的组件,本文只关注于Detection


它的两个相关文件是:


  • detection_component.h
  • detection_component.cc


    detection_component.h


  
    
    
  
namespace apollo { namespace perception { namespace onboard {
class DetectionComponent : public cyber::Component<drivers::PointCloud> { public: DetectionComponent() = default; virtual ~DetectionComponent() = default;
bool Init() override; bool Proc(const std::shared_ptr<drivers::PointCloud>& message) override;
private: static std::atomic<uint32_t> seq_num_; std::string sensor_name_; // bool enable_hdmap_ = true; float lidar_query_tf_offset_ = 20.0f; std::string lidar2novatel_tf2_child_frame_id_; std::string output_channel_name_; base::SensorInfo sensor_info_; TransformWrapper lidar2world_trans_; std::unique_ptr<lidar::LidarObstacleDetection> detector_; std::shared_ptr<apollo::cyber::Writer<LidarFrameMessage>> writer_; };
CYBER_REGISTER_COMPONENT(DetectionComponent);
} // namespace onboard } // namespace perception }
可以看到是以点云数据输入为主。

开发者说丨 Apollo 源码分析:Perception 如何启动?


detection_component.cc


  
    
    
  
bool DetectionComponent::Init() { LidarDetectionComponentConfig comp_config; if (!GetProtoConfig(&comp_config)) { return false; } ADEBUG << "Lidar Component Configs: " << comp_config.DebugString(); output_channel_name_ = comp_config.output_channel_name(); sensor_name_ = comp_config.sensor_name(); lidar2novatel_tf2_child_frame_id_ = comp_config.lidar2novatel_tf2_child_frame_id(); lidar_query_tf_offset_ = static_cast<float>(comp_config.lidar_query_tf_offset()); // enable_hdmap_ = comp_config.enable_hdmap(); writer_ = node_->CreateWriter<LidarFrameMessage>(output_channel_name_);
if (!InitAlgorithmPlugin()) { AERROR << "Failed to init detection component algorithm plugin."; return false; } return true; }
bool DetectionComponent::Proc( const std::shared_ptr<drivers::PointCloud>& message) { AINFO << std::setprecision(16) << "Enter detection component, message timestamp: " << message->measurement_time() << " current timestamp: " << Clock::NowInSeconds();
auto out_message = std::make_shared<LidarFrameMessage>();
bool status = InternalProc(message, out_message); if (status) { writer_->Write(out_message); AINFO << "Send lidar detect output message."; } return status; }


nit 和 Proc 是组件两个核心方法。



apollo/modules/perception/onboard/component/BUILD


BUILD 文件定义了 perception 中所有的 component 如 camera,radar,lidar 等的信息,本文只关注 Detection。


  
    
    
  
cc_library( name = "detection_component", srcs = ["detection_component.cc"], hdrs = ["detection_component.h"], deps = [ ":lidar_inner_component_messages", "//cyber/time:clock", "//modules/common/util:string_util", "//modules/perception/common/sensor_manager", "//modules/perception/lib/registerer", "//modules/perception/lidar/app:lidar_obstacle_detection", "//modules/perception/lidar/common", "//modules/perception/onboard/common_flags", "//modules/perception/onboard/proto:lidar_component_config_cc_proto", "//modules/perception/onboard/transform_wrapper", "@eigen", ], )

开发者说丨 Apollo 源码分析:Perception 如何启动?


一个 Component 的配置文件有 2 种:


  • DAG
  • Launch


DAG 定义了模块的依赖关系。


Launch 文件定义了模块的启动。


先看 Launch 文件。


apollo/modules/perception/production/launch/perception_all.launch


  
    
    
  
<cyber> <desc>cyber modules list config</desc> <version>1.0.0</version> <!-- sample module config, and the files should have relative path like ./bin/cyber_launch ./bin/mainboard ./conf/dag_streaming_0.conf --> <module> <name>perception</name> <dag_conf>/apollo/modules/perception/production/dag/dag_streaming_perception.dag</dag_conf> <!-- if not set, use default process --> <process_name>perception</process_name> <version>1.0.0</version> </module> <module> <name>perception_camera</name> <dag_conf>/apollo/modules/perception/production/dag/dag_streaming_perception_camera.dag</dag_conf> <!-- if not set, use default process --> <process_name>perception</process_name> <version>1.0.0</version> </module>
<module> <name>perception_traffic_light</name> <dag_conf>/apollo/modules/perception/production/dag/dag_streaming_perception_trafficlights.dag</dag_conf> <!-- if not set, use default process --> <process_name>perception_trafficlights</process_name> <version>1.0.0</version> </module> <module> <name>motion_service</name> <dag_conf>/apollo/modules/perception/production/dag/dag_motion_service.dag</dag_conf> <!-- if not set, use default process --> <process_name>motion_service</process_name> <version>1.0.0</version> </module> </cyber>


我们可以发现 Perception 模块中的 dag 路径:


 <dag_conf>/apollo/modules/perception/production/dag/dag_streaming_perception.dag</dag_conf>


它里面的内容长什么样子呢?


module_config {

module_library : "/apollo/bazel-bin/modules/perception/onboard/component/libperception_component_lidar.so"
components { class_name : "DetectionComponent" config { name: "Velodyne128Detection" config_file_path: "/apollo/modules/perception/production/conf/perception/lidar/velodyne128_detection_conf.pb.txt" flag_file_path: "/apollo/modules/perception/production/conf/perception/perception_common.flag" readers { channel: "/apollo/sensor/lidar128/compensator/PointCloud2" } } }
components { class_name : "RecognitionComponent" config { name: "RecognitionComponent" config_file_path: "/apollo/modules/perception/production/conf/perception/lidar/recognition_conf.pb.txt" readers { channel: "/perception/inner/DetectionObjects" } } }
components { class_name: "RadarDetectionComponent" config { name: "FrontRadarDetection" config_file_path: "/apollo/modules/perception/production/conf/perception/radar/front_radar_component_conf.pb.txt" readers { channel: "/apollo/sensor/radar/front" } } }
components { class_name: "RadarDetectionComponent" config { name: "RearRadarDetection" config_file_path: "/apollo/modules/perception/production/conf/perception/radar/rear_radar_component_conf.pb.txt" readers { channel: "/apollo/sensor/radar/rear" } } }
components { class_name: "FusionComponent" config { name: "SensorFusion" config_file_path: "/apollo/modules/perception/production/conf/perception/fusion/fusion_component_conf.pb.txt" readers { channel: "/perception/inner/PrefusedObjects" } } }}
module_config { module_library : "/apollo/bazel-bin/modules/v2x/fusion/apps/libv2x_fusion_component.so"
components { class_name : "V2XFusionComponent" config { name : "v2x_fusion" flag_file_path : "/apollo/modules/v2x/conf/v2x_fusion_tracker.conf" readers: [ { channel: "/perception/vehicle/obstacles" } ] } }}


我们发现了 DetectionComponent 的身影,看它的配置参数是 Velodyne 128 线激光雷达的配置文件,确实可以看到 Apollo 是以 Lidar 为主。


开发者说丨 Apollo 源码分析:Perception 如何启动?


定义了一个 component 相关的文档后,就可以启动了。


命令:


cyber_launch start apollo/modules/perception/production/launch/perception_all.launch


自此,我们就发现了在 Apollo 中启动 perception 一个组件的整个代码过程。


总结


因为 Perception 这个模块非常庞大,涉及到 Camera、Radar、Lidar 3 种类型的传感器,针对各个传感器的数据处理和模型处理会产生 10 多个任务,每个任务都被设计成了组件。


直接去阅读相关的代码会非常容易让自己迷失在代码森林中,所以,本文先讲解一下 CyberRT 这个基础框架 Component 的配置机制,熟悉基础套路后,以后再去学习相应组件时,查询代码就变得非常容易。


开发者说丨 Apollo 源码分析:Perception 如何启动?

*CSDN

https://blog.csdn.net/briblue/article/details/111598755

https://mp.weixin.qq.com/s/hlsBBc9p4kc3SuwGnGqnZw


以上是"Apollo 源码分析:Perception 如何启动?"的全部内容,更多话题讨论、技术交流可以扫描下方二维码添加『Apollo小哥哥』为好友,进开发者交流群。


开发者说丨 Apollo 源码分析:Perception 如何启动?


开发者说丨 Apollo 源码分析:Perception 如何启动?


* 以上内容为开发者原创,不代表百度官方言论,已获开发者授权。

开发者说丨 Apollo 源码分析:Perception 如何启动?





更多关于开发套件的参数信息

请点击下方文章链接查看




长按识别下方二维码

登记购买套件


开发者说丨 Apollo 源码分析:Perception 如何启动?


开发者说丨 Apollo 源码分析:Perception 如何启动?

开发者说丨 Apollo 源码分析:Perception 如何启动?

开发者说丨 Apollo 源码分析:Perception 如何启动?
开发者说丨 Apollo 源码分析:Perception 如何启动?