本人讲解关于slam一系列文章汇总链接:史上最全slam从零开始,针对于本栏目讲解(02)Cartographer源码无死角解析-接如下:
(02)Cartographer源码无死角解析- (00)目录_最新无死角讲解:https://blog.csdn.net/weixin_43013761/article/details/127350885
文末正下方中心提供了本人
联系方式,
点击本人照片即可显示
W
X
→
官方认证
{\color{blue}{文末正下方中心}提供了本人 \color{red} 联系方式,\color{blue}点击本人照片即可显示WX→官方认证}
文末正下方中心提供了本人联系方式,点击本人照片即可显示WX→官方认证
一、前言
下面我们就正式开始讲解代码了,那么不用多说,首先我们是从 main 函数开始分析,那么问题来了,如何找到 main 函数呢?根据src/cartographer_ros/cartographer_ros/launch/lx_rs16_2d_outdoor.launch 文件,可以看到其有 node,名字name分别为:cartographer_node,cartographer_occupancy_grid_node 他们分别做什么的,先不去理会,就假设现在我们不知道。src/cartographer_ros/cartographer_ros/cartographer_ros/CMakeLists.txt 文件中搜索 cartographer_node、cartographer_occupancy_grid_node 可以看到看到如下内容:
# 生成建图节点
google_binary(cartographer_node
SRCS
node_main.cc
)
google_binary(cartographer_occupancy_grid_node
SRCS
occupancy_grid_node_main.cc
)
其上的 google_binary 是 google 自己封装好的cmake(cmake是一门编程语言,可以定义函数)函数,其会把 node_main.cc 生成二进制可执行文件 cartographer_node,occupancy_grid_node_main.cc 生成二进制可执行文件 cartographer_occupancy_grid_node。对于 .launch 文件中的节点 rviz 与 playbag 后续过程中进行讲解。
node_main.cc 文件位于 src/cartographer_ros/cartographer_ros/cartographer_ros/ 文件夹下,那么下面我们就开始分析吧。
二、gflags与glog
1、gflags
首先在 node_main.cc 文件中,可以看到如下几个宏:
DEFINE_bool 、 DEFINE_string、
其都是来自于 gflags 中,其是谷歌命令行解析工具。主要用于解析用命令行执行可执行文件时传入的参数。与getops()不同的是,在gflags中flag可以分散的定义在各个文件之中,而不用定义在一起,这就意味着在我们可以在一个单独的文件中只定义这个文件所需要用到的一些flag,链接了该文件应用都可以使用该文件中的flag,这样就能非常方便的实现代码的复用,如果不同的文件定义了相同的flag,则会产生错误,所以需要明确规范gflags的使用规范。
/**
* note: gflags是一套命令行参数解析工具
* DEFINE_bool在gflags.h中定义
* gflags主要支持的参数类型包括bool, int32, int64, uint64, double, string等
* 定义参数通过DEFINE_type宏实现, 该宏的三个参数含义分别为命令行参数名, 参数默认值, 以及参数的帮助信息
* 当参数被定义后, 通过FLAGS_name就可访问到对应的参数
*/
如下源码中的示例:
DEFINE_bool(collect_metrics, false,
"Activates the collection of runtime metrics. If activated, the "
"metrics can be accessed via a ROS service.");
DEFINE_bool 表示闯入的参数为 bool类型, collect_metrics 表示命令行需要传入的参数,false 代表默认值,后的剩下的字符串是备注, 在 .launch 中的的代码有如下:
type="cartographer_node" args="
-configuration_directory $(find cartographer_ros)/configuration_files
-configuration_basename lx_rs16_2d_outdoor.lua"
<remap from="points2" to="rslidar_points" />
<remap from="scan" to="front_scan" />
<remap from="odom" to="odom_scout" />
<remap from="imu" to="imu" />
表示再在执行 cartographer_node 程序的时候,其传入的两个参数,分别为 -configuration_directory,-configuration_basename,其与 node_main.cc 文文件中的 configuration_directory,configuration_basename 是一一对应的。另外,runlaunch 指令还会把 remap(重映射)操作也当作参数传入到 main 函数的 **argv 中。如下:
传送进来的参数会经过
// note: 初始化glog库
google::InitGoogleLogging(argv[0]);
// 使用gflags进行参数的初始化. 其中第三个参数为remove_flag
// 如果为true, gflags会移除parse过的参数, 否则gflags就会保留这些参数, 但可能会对参数顺序进行调整.
google::ParseCommandLineFlags(&argc, &argv, true);
两个函数的处理,处理之后变换成如下:
先来看看 DEFINE_xxx 的宏定义变量:
(
1
)
\color{blue}(1)
(1) collect_metrics→默认为false,激活运行时度量的集合.如果激活, 可以通过ROS服务访问度量。.launch文件中没有配置,所以其使用的是默认值。
(
2
)
\color{blue}(2)
(2) configuration_directory→在.launch中被被配置为 $(find cartographer_ros)/configuration_files。
(
3
)
\color{blue}(3)
(3) configuration_basename→在.launch中被被配置为 lx_rs16_2d_outdoor.lua
(
4
)
\color{blue}(4)
(4) load_frozen_state→默认为true,.launch中未配置,使用默认值。将保存的状态加载为冻结(非优化)轨迹。
(
5
)
\color{blue}(5)
(5) start_trajectory_with_default_topics→使用默认主题(话题)开始第一个轨迹
(
6
)
\color{blue}(6)
(6) save_state_filename→保存轨迹文件的路径
如果想引用这些参数,在参数的前面加入FLAGS_即可,比如引用上面的 cartographer_node,书写成 FLAGS_configuration_directory 即可。其变量本人打印如下:
FLAGS_configuration_directory→"/my_work/ROS/work/cartographer_detailed_comments_ws/install_isolated/share/cartographer_ros/configuration_files"
FLAGS_configuration_basename="lx_rs16_2d_outdoor.lua"
2、glog