本文目的

本文主要记录调试运行demo中cartographer_paper_deutsches_museum.bag中代码的流程,不具体分析每个函数的功能而是理清调用关系.

首先cartographer ros入口

1.node_main.cc

在node_main中, 主要定义了一个Node node 和 map_builder, 这两个则主要就是为了链接cartographer_ros和cartographer. auto map_builder = cartographer::common::make_unique<:mapping::mapbuilder>(node_options.map_builder_options); Node node(node_options, std::move(map_builder), &tf_buffer); if (!FLAGS_load_state_filename.empty()) { node.LoadState(FLAGS_load_state_filename, FLAGS_load_frozen_state); } if (FLAGS_start_trajectory_with_default_topics) { node.StartTrajectoryWithDefaultTopics(trajectory_options); } ::ros::spin(); // ros一直循环,直到ctrl+c或者ROS主线程退出才会执行后面的语句 node.FinishAllTrajectories(); node.RunFinalOptimization(); if (!FLAGS_save_state_filename.empty()) { node.SerializeState(FLAGS_save_state_filename); // 序列化 }

下面就主要从这node中进行分析如何一步步的从cartographer_ros到cartographer.

实际运行roslaunch cartographer_ros demo_backpack_2d.launch bag_filename:=/home/lee/Downloads/cartographer_paper_deutsches_museum.bag之后除了获取一些配置文件信息之后最先输出的就是添加一条轨迹ID=0这一步是怎么来的呢,下面进行分析:

2. node.h && node.cc

主要功能就是wires up ROS topic to SLAM , 处理激光,里程计, IMU等传感器数据, 开始建图,结束建图,以及最后优化.

1, node.h

定义了几个关键变量基本都是map或者set类型, 表示一个轨迹一个相对应的变量 MapBuilderBridge map_builder_bridge_ GUARDED_BY(mutex_); std::map extrapolators_; std::unordered_map sensor_samplers_; std::unordered_map> subscribers_; std::unordered_set<:string> subscribed_topics_; std::unordered_map is_active_trajectory_ GUARDED_BY(mutex_);

1, StartTrajectoryWithDefaultTopics 建立轨迹 void Node::StartTrajectoryWithDefaultTopics(const TrajectoryOptions& options) { carto::common::MutexLocker lock(&mutex_); CHECK(ValidateTrajectoryOptions(options)); AddTrajectory(options, DefaultSensorTopics()); }

这里面有一个AddTrajectory函数主要功能:

trajectory_builder_interface.h

1, ComputeExpectedSensorIds:返回订阅的传感器集合, RANGE IMU ODOMETRY LANDMARK等 std::set<:mapping::trajectorybuilderinterface::sensorid>

2, map_builder_bridge_.AddTrajectory

map_builder_bridge

map_builder_bridge顾名思义就是cartographer_ros和cartographer中map_builder的一个桥梁,由它引入到cartographer的map_builder.c中, 第一幅图中打印的消息就是由LOG(INFO) << "Added trajectory with ID '" << trajectory_id << "'.";得到

3, AddExtrapolator

4,AddSensorSamplers

5,LaunchSubscribers

4. map_builder.cc int MapBuilder::AddTrajectoryBuilder(const std::set& expected_sensor_ids, const proto::TrajectoryBuilderOptions& trajectory_options, LocalSlamResultCallback local_slam_result_callback)

AddTrajectoryBuilder这个函数中包含3D和2D的部分,本文主要看2D的情况所以只提取2D中的代码段: { std::unique_ptr local_trajectory_builder; if (trajectory_options.has_trajectory_builder_2d_options()) { local_trajectory_builder = common::make_unique(trajectory_options.trajectory_builder_2d_options(),SelectRangeSensorIds(expected_sensor_ids)); } DCHECK(dynamic_cast(pose_graph_.get())); trajectory_builders_.push_back(common::make_unique( sensor_collator_.get(), trajectory_id, expected_sensor_ids, CreateGlobalTrajectoryBuilder2D( std::move(local_trajectory_builder), trajectory_id, static_cast(pose_graph_.get()), local_slam_result_callback))); if (trajectory_options.has_overlapping_submaps_trimmer_2d()) { const auto& trimmer_options = trajectory_options.overlapping_submaps_trimmer_2d(); pose_graph_->AddTrimmer(common::make_unique( trimmer_options.fresh_submaps_count(), trimmer_options.min_covered_area() / common::Pow2(trajectory_options.trajectory_builder_2d_options() .submaps_options() .grid_options_2d() .resolution()), trimmer_options.min_added_submaps_count())); } }

map_builder的主要功能就是综合TrajectoryBuilders (for local submaps) 和 a PoseGraph (for loop closure).从上面代码中可以看到几个变量和函数

1,local_trajectory_builder: LocalTrajectoryBuilder2D

2,trajectory_builders_ : std::vector<:unique_ptr>>

3,CollatedTrajectoryBuilder

4,CreateGlobalTrajectoryBuilder2D

5,pose_graph_: PoseGraph2D

接下来就需要对这几个进行分析了即进入到第二个部分cartographer.

cartographer模块

上面我们已经知道map_builder的功能就是同时处理前端和后端, 主要利用其中trajectory_builders_,一条轨迹就是一次建图的过程, 比如推着小车走一遍建立地图就是一轨迹, 如果需要再走一遍就可以再开启一条轨迹,ID++ trajectory_builders_.push_back(common::make_unique(sensor_collator_.get(), trajectory_id,expected_sensor_ids, CreateGlobalTrajectoryBuilder2D( std::move(local_trajectory_builder), trajectory_id, static_cast(pose_graph_.get()), local_slam_result_callback)));

我们来扒皮抽筋

其中有一个CreateGlobalTrajectoryBuilder2D()函数, 一个CollatedTrajectoryBuilder类,我们可以逐一跟进

第一CreateGlobalTrajectoryBuilder2D()是为了返回一个GlobalTrajectoryBuilder std::unique_ptr CreateGlobalTrajectoryBuilder2D( std::unique_ptr local_trajectory_builder, const int trajectory_id, mapping::PoseGraph2D* const pose_graph, const TrajectoryBuilderInterface::LocalSlamResultCallback& local_slam_result_callback) { return common::make_unique< GlobalTrajectoryBuilder>( std::move(local_trajectory_builder), trajectory_id, pose_graph, local_slam_result_callback); }

GlobalTrajectoryBuilder和CollatedTrajectoryBuilder都继承于TrajectoryBuilderInterface,其中在collated_trajectory_builder.h CollatedTrajectoryBuilder( sensor::CollatorInterface* sensor_collator, int trajectory_id, const std::set& expected_sensor_ids, std::unique_ptr wrapped_trajectory_builder);

wrapped_trajectory_builder就通过为用子类指针赋值基类,使得最终调用为GlobalTrajectoryBuilder的方法,我们需要进入到这个类中进行分析

1. collated_trajectory_builder

cartographer运行没有map_Cartographer激光SLAM2D源码分析相关推荐

  1. yaf php源码,PHP-Yaf执行流程-源码分析

    介绍 Yaf框架是通过PHP扩展实现的一种PHP MVC开发框架,因为Yaf框架是PHP扩展实现的,所以性能非常高,而且通过阅读源码可以深入的了解框架内部实现细节和一些优秀的扩展开发技巧,但是学习Ya ...

  2. java activerecord.db_JFinal 源码分析 [DB+ActiveRecord]

    我记得以前有人跟我说,"面试的时候要看spring的源码,要看ioc.aop的源码"那为什么要看这些开源框架的源码呢,其实很多人都是"应急式"的去读,就像读一篇 ...

  3. Django----FBV 与 CBV 介绍、CBV源码分析

    文章目录 一.CBV和FBV 二.CBV 源码分析 一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应. 响应可以是一张网页的HTML内容,一个重定 ...

  4. Spark源码分析之七:Task运行(一)

    在Task调度相关的两篇文章<Spark源码分析之五:Task调度(一)>与<Spark源码分析之六:Task调度(二)>中,我们大致了解了Task调度相关的主要逻辑,并且在T ...

  5. Django源码分析2:本地运行runserver分析

    django源码分析 本文环境python3.5.2,django1.10.x系列1.根据上一篇文章分析了,django-admin startproject与startapp的分析流程后,根据dja ...

  6. HDFS源码分析心跳汇报之BPServiceActor工作线程运行流程

    在<HDFS源码分析心跳汇报之数据结构初始化>一文中,我们了解到HDFS心跳相关的BlockPoolManager.BPOfferService.BPServiceActor三者之间的关系 ...

  7. Spark RPC框架源码分析(二)RPC运行时序

    前情提要: Spark RPC框架源码分析(一)简述 一. Spark RPC概述 上一篇我们已经说明了Spark RPC框架的一个简单例子,Spark RPC相关的两个编程模型,Actor模型和Re ...

  8. laravel $request 多维数组取值_Laravel 运行原理分析与源码分析,底层看这篇足矣

    精选文章内容 一.运行原理概述 laravel的入口文件 index.php 1.引入自动加载 autoload.php 2.创建应用实例,并同时完成了: 基本绑定($this.容器类Containe ...

  9. 【源码分析】storm拓扑运行全流程源码分析

    [源码分析]storm拓扑运行全流程源码分析 @(STORM)[storm] 源码分析storm拓扑运行全流程源码分析 一拓扑提交流程 一stormpy 1storm jar 2def jar 3ex ...

最新文章

  1. 没有任何基础学编程从哪开始_没有任何的绘画基础,该怎么学绘画?
  2. 关于C语言的问卷调查
  3. 一个通过引用返回局部变量的列子
  4. 成功解决成功解决return _iterencode(o, 0) ValueError: Circular reference detected
  5. 我的notepad++
  6. python脚本监控mysql数据库_Python脚本监控mysql数据库,Python脚本监控mongo数据库
  7. Linux视频 pad,Wine 1.9.10 发布下载, 改善视频输出
  8. C语言 数组内存溢出 - C语言零基础入门教程
  9. 如何基于Docker快速搭建Elasticsearch集群?
  10. 由SELECT ... FROM ... FOR UPDATE想到的
  11. android的JNI标准 android的NDK
  12. gridview的表头固定
  13. 龙腾P2P流媒体点播系统商业计划书
  14. 如何在谷歌浏览器官网下载谷歌浏览器32位、64位或其他版本最新的离线安装包?
  15. 腾讯云白piao指南
  16. 远程计算机显卡,微软远程桌面连接(RDP)优化方案-显卡加速-提升帧率-挂载U盘...
  17. 香蜜沉沉烬如霜里的共付鸿蒙,香蜜沉沉烬如霜的伤感句子35条
  18. UE发生GPU崩溃D3D丢失,真的跟硬件有关系。
  19. 融资融券是对A股明显利好
  20. 展锐智能机平台sc9820e调试pwm背光所遇问题小结

热门文章

  1. C 标准库—— string.h
  2. python自动化办公能做什么-用Python自动办公,做职场高手(完结)
  3. 如何自学python知乎-如何快速学习python?
  4. 零基础学python图文版-零基础学Minecraft编程(图文版) 中文pdf完整版[41MB]
  5. python代码-我整理的Python代码规则
  6. python有趣的代码-有趣的一行 Python 代码
  7. linux ssh客户端乱码,Win10专业版下Open ssh客户端乱码咋办?
  8. python decorator. decorator_decorator在Python中的作用
  9. SpringSecurity系列(四) Spring Security 实现权限树形菜单
  10. 计算机网络实验5以太网链路帧实验,计算机网络实验-使用Wireshark分析以太网帧与ARP协议.docx...