(02)Cartographer源码无死角解析-(22) 传感器数据分发→总体分析
admin
2024-01-28 08:05:59
0

讲解关于slam一系列文章汇总链接:史上最全slam从零开始,针对于本栏目讲解(02)Cartographer源码无死角解析-链接如下:
(02)Cartographer源码无死角解析- (00)目录_最新无死角讲解:https://blog.csdn.net/weixin_43013761/article/details/127350885
 
文末正下方中心提供了本人联系方式,点击本人照片即可显示WX→官方认证{\color{blue}{文末正下方中心}提供了本人 \color{red} 联系方式,\color{blue}点击本人照片即可显示WX→官方认证}文末正下方中心提供了本人联系方式,点击本人照片即可显示WX→官方认证
 

一、前言

首先对前面的知识做一个回顾,从 node_main.cc 文件中开始;

//根据配置文件,命令行参数与话题重映射,订阅默认话题开始一条轨迹
node.StartTrajectoryWithDefaultTopics(trajectory_options);AddTrajectory(options);//添加一条新轨迹// 调用map_builder_bridge的AddTrajectory, 添加一个轨迹const int trajectory_id =map_builder_bridge_.AddTrajectory(expected_sensor_ids, options);// 订阅话题与注册回调函数LaunchSubscribers(options, trajectory_id);

其上的 map_builder_bridge_.AddTrajectory 与 LaunchSubscribers() 是十分重要的两个函数:

(1):\color{blue}(1):(1): map_builder_bridge_.AddTrajectory 函数主要的核心就是构建CollatedTrajectoryBuilder对象存储于 node::map_builder_bridge_::map_builder_::trajectory_builders_变量之中,然后返回一个 trajectory_id,再根据 trajectory_id 构建一个 SensorBridge对象,创建该对象时代码如下:

  // Step: 2 为这个新轨迹 添加一个SensorBridgesensor_bridges_[trajectory_id] = absl::make_unique(trajectory_options.num_subdivisions_per_laser_scan,trajectory_options.tracking_frame,node_options_.lookup_transform_timeout_sec, tf_buffer_,map_builder_->GetTrajectoryBuilder(trajectory_id)); // CollatedTrajectoryBuilder

注意\color{red}注意注意 其上的 GetTrajectoryBuilder(trajectory_id) 就是获取 trajectory_builders_ 中的 CollatedTrajectoryBuilder 对象。然后作为参数传送给 SensorBridge 的构造函数。

(2):\color{blue}(2):(2): LaunchSubscribers() 会根据 trajectory_id 与其对应的配置 TrajectoryOptions& options,进行话题的订阅,同时出注册回调函数。

 
这里就不在贴代码了,Node::LaunchSubscribers() 主要订阅,注册了如下回调函数:

//位于 src/cartographer_ros/cartographer_ros/cartographer_ros/node.cc 文件之中
void Node::LaunchSubscribers(const TrajectoryOptions& options,const int trajectory_id)&Node::HandleLaserScanMessage//注册的单线雷达回调函数SensorBridge::HandleLaserScanMessage()//根据采样频率评估是否调用该函数&Node::HandleMultiEchoLaserScanMessage//注册的多回声雷达回调函数SensorBridge::HandleMultiEchoLaserScanMessage()//根据采样频率评估是否调用该函数&Node::HandlePointCloud2Message//注册的多线点云雷达回调函数SensorBridge::HandlePointCloud2Message()//根据采样频率评估是否调用该函数&Node::HandleImuMessage//注册的IMU回调函数SensorBridge::HandleImuMessage()//根据采样频率评估是否调用该函数......

还有一些回调函数,就不一一在这里列举了,所有的回调函数,根据查询的tf,对数据完成进行坐标系变换(变换到tracking_frame)之后,最终都会调用类似如下的一段代码:

或: trajectory_builder_->AddSensorData(sensor_id,carto::sensor::OdometryData{odometry_data->time, odometry_data->pose});
或: trajectory_builder_->AddSensorData(sensor_id,carto::sensor::FixedFramePoseData{time, absl::optional()});
或: trajectory_builder_->AddSensorData(sensor_id, carto::sensor::FixedFramePoseData{time, absl::optional(Rigid3d::Translation(ecef_to_local_frame_.value() *LatLongAltToEcef(msg->latitude, msg->longitude, msg->altitude)))});
或: trajectory_builder_->AddSensorData(sensor_id, landmark_data);......

上面只列举了一部分,从上面可以看出,trajectory_builder_->AddSensorData() 函数接收了各种各样的数据类型,那么其定然存在很多重载函数。其上的 trajectory_builder_ 就是 CollatedTrajectoryBuilder 的实例对象指针,每个 trajectory_id 都有一个与之对应的 CollatedTrajectoryBuilder 实例对象指针。
 

二、构造时的传参

根据上面的介绍,可以知道 trajectory_builder_ 就是类CollatedTrajectoryBuilder的实例指针,是在 src/cartographer/cartographer/mapping/map_builder.cc 文件的 MapBuilder::AddTrajectoryBuilder() 函数中实例化,通过上一篇博客了解到,其2D轨迹与3D轨迹的构建过程如下:

	// CollatedTrajectoryBuilder初始化trajectory_builders_.push_back(absl::make_unique(trajectory_options, sensor_collator_.get(), trajectory_id,expected_sensor_ids,// 将3D前端与3D位姿图打包在一起, 传入CollatedTrajectoryBuilderCreateGlobalTrajectoryBuilder3D(std::move(local_trajectory_builder), trajectory_id,static_cast(pose_graph_.get()),local_slam_result_callback, pose_graph_odometry_motion_filter)));// CollatedTrajectoryBuilder初始化trajectory_builders_.push_back(absl::make_unique(trajectory_options, sensor_collator_.get(), trajectory_id,expected_sensor_ids,// 将2D前端与2D位姿图打包在一起, 传入CollatedTrajectoryBuilderCreateGlobalTrajectoryBuilder2D(std::move(local_trajectory_builder), trajectory_id,static_cast(pose_graph_.get()),local_slam_result_callback, pose_graph_odometry_motion_filter)));

 

三、C++多态

CollatedTrajectoryBuilder 是在 src/cartographer/cartographer/mapping/internal/collated_trajectory_builder.cc 文件中定义。这里涉及到一个多态的知识点,创建的实例类型为 CollatedTrajectoryBuilder*,但是在构建 SensorBridge 时, SensorBridge 构造函数需要的类型为 carto::mapping::TrajectoryBuilderInterface*,从 collated_trajectory_builder.h 文件中,可以看到:

class CollatedTrajectoryBuilder : public TrajectoryBuilderInterface 

故 CollatedTrajectoryBuilder 是 TrajectoryBuilderInterface 的派生类。TrajectoryBuilderInterface 在 src/cartographer/cartographer/mapping/trajectory_builder_interface.h 文件中被声明。从类名,以及代码可以很明显的看出,其是一个接口类,定义了很多的纯虚函数。一个接口类可以派生出很多类型的子类,构建 SensorBridge 构造函数需要的参数为基类 TrajectoryBuilderInterface,这样有个好处,也就是由 TrajectoryBuilderInterface 派生出来子类,都可以用于 SensorBridge 的构造函数。

CollatedTrajectoryBuilder 的主要作用就是使用 sensor::CollatorInterface 整理传感器数据, 然后将其传递到2D和3D通用的 mapping::TrajectoryBuilderInterface。

另外再介绍一下 c++11中的std::function 与 using 的模板部分具体化

  c++11: std::function 通用多态函数封装器std::function 的实例能存储、复制及调用任何可调用 (Callable) 目标: 如函数、 lambda表达式、 bind表达式或其他函数对象, 还有指向成员函数指针和指向数据成员指针.它也是对 C++ 中现有的可调用实体的一种类型安全的包裹(相对来说, 函数指针的调用不是类型安全的)

在 trajectory_builder_interface.h 中可以看到如下一段代码:

  // A callback which is called after local SLAM processes an accumulated// 'sensor::RangeData'. If the data was inserted into a submap, reports the// assigned 'NodeId', otherwise 'nullptr' if the data was filtered out.using LocalSlamResultCallback =std::function)>;

其上表示用 LocalSlamResultCallback 表示一个回调函数,该回调函数无返回值,需要传入五个参数。

 
 
 

相关内容

热门资讯

珠宝商投储能,白酒厂配储柜……... 周大福开始做储能了,没错,就是你知道的那个周大福。 2026年4月,周大福创建宣布在芬兰投建储能项...
手握10亿订单却“缺血”?偏科... 文 | 创业最前线 5月28日,苏州天瞳威视电子科技股份有限公司(以下简称“天瞳威视”)向港交所主...
原创 重... 太空探索技术公司SpaceX于2026年6月12日正式登陆纳斯达克完成上市挂牌作业。此举旨在从资本整...
原创 喝... 01 先看一个反直觉的数字。 白酒行业的总产量,从2016年的1358万千升降到了去年的354万千升...
广信科技:高级管理人员变动公告 证券日报网讯 6月18日,广信科技发布公告称,公司于2026年6月16日召开第六届董事会第十次会议,...
原创 金... 老铁们,这两天最扎心的画面大概是:前阵子排队抢金镯子的阿姨们,一回头发现金店挂牌价又降了,算下来一克...
世界杯-维尼修斯传射库尼亚2球... 北京时间6月20日8点30分,2026年世界杯C组次轮,巴西队对阵海地队。上半场第24分钟库尼亚为巴...
原创 巨... 巨化股份 (600160)1998年上市持股28年累计收益率超47倍 1795字 制冷剂价格飙涨至...
见证历史!“AI双雄”碾压茅台... 6月18日,A股市值排名格局迎来重大变化。工业富联(601138.SH)与中际旭创(300308.S...
IPO雷达 | 核心客户也是直... 近日,深交所正式受理上海季丰电子股份有限公司(下称 “季丰电子”)的创业板 IPO 申请。这家深耕半...
6分美国提前出线却未锁小组第一... 北京时间6月20日3:00,世界杯小组赛D组第2轮,美国2-0澳大利亚,喜提6分领跑D组,提前出线,...
有先兆偏头痛的中老年人更易脑卒... 李先生六十多岁,年轻时就有偏头痛,发作时会先看到闪光或视野缺损,随后头痛难忍。最近听邻居说“偏头痛会...
寻找A股低价潜力股,这些方向值... 最近在和朋友聊天时,他突然问我:“如果现在想在A股找一些值得长期关注的标的,有没有哪些是被市场低估、...
原创 6... 下班路上进超市,顺手拿起一箱常温奶,价签写着49.9元。很多人都干过同一个动作:手机一划,打开平台一...
原创 端... 长沙晚报掌上长沙6月19日讯(全媒体记者 曹开阳)6月18日,A股迎来端午节前最后一个交易日,市场整...
美联储:美国上周银行存款19.... 美联储:美国上周银行存款19.354万亿美元,之前一周19.295万亿美元。
阿里收购朴朴,即时零售变局 放下一周的交易疲惫,静下心梳理行业动态与交易逻辑,本篇为大家准备了5条要闻。一、周末要闻导读 1.阿...
原创 6... 连莫斯科核心城区的加油站都开始限量卖油了,打了一千五百多天的战争,代价终于扎扎实实落到俄罗斯普通人的...
场景险龙头白鸽在线启动港股招股... 日前,白鸽在线(厦门)数字科技股份有限公司(简称“白鸽在线”,股票代码“2672”)发布公告,公司自...
贝兰他珠单抗显著延长骨髓瘤无病... 想象一个场景:一位接受过多次治疗的多发性骨髓瘤患者,在复诊时听到医生说“有望无病至少十二个月”。这句...