(02)Cartographer源码无死角解析-(09) gflags与glog简介、及其main函数讲解

news2024/11/16 21:48:34

本人讲解关于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

 
 
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1434.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件工程结构化设计

目录 结构化分析与结构化设计的关系&#xff1a; 体系结构设计概念&#xff1a; 图形工具&#xff1a; 层次图&#xff1a;调用关系​编辑 HIPO图&#xff1a;层次图IPO图 软件结构图&#xff1a; 软件设计原则&#xff1a; 模块化&#xff1a; 模块划分注意事项&#xf…

巴什博弈——范围拿物品问题

巴什博弈 巴什博弈&#xff08;Bash game&#xff09; 是一个双人博弈&#xff1a;有一堆总数为n的物品&#xff0c;2名玩家轮流从中拿取物品。每次至少拿1件&#xff0c;至多拿m件&#xff0c;不能不拿&#xff0c;最终将物品拿完者获胜。 巴什博弈除了两人轮流按一定数量拿物…

【黄啊码】MySQL入门—14、细说数据库的MVCC机制

大家好&#xff0c;我是黄啊码。上一篇文章中&#xff0c;我们讲到了锁的划分&#xff0c;以及乐观锁和悲观锁的思想。今天我们就来看下 MVCC&#xff0c;它就是采用乐观锁思想的一种方式。那么它到底有什么用呢&#xff1f; 我们知道事务有 4 个隔离级别&#xff0c;以及可能…

共谋韬略、共巢未来,电巢与韬略“战略合作签约仪式”圆满举办!

前言 2022年10月27日下午&#xff0c;电巢科技与韬略科技齐聚深圳南山&#xff0c;共同举办了隆重的战略合作签约仪式&#xff0c;双方就整合核心资源、共同打造高质量数字化内容等战略方针达成了一致&#xff0c;携手开启合作新篇章。 电巢科技和韬略科技基于相契合的发展战略…

Numpy基础教程

1 Numpy 对象2 Numpy创建numpy.array 构造器来创建numpy.emptynumpy.zerosnumpy.onesnumpy.arangeNumpy索引3 Numpy常用操作numpy.reshapenumpy.reshape(arr,newshape,order C)numpy.transposenumpy.expand_dimsnumpy.squeezeNumpy功能十分强大的python扩展库&#xff0c;数学…

基于Java+Springboot+Vue+elememt美食论坛平台设计实现

博主介绍&#xff1a;✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取联系&#x1f345;精彩专栏推荐订阅&#x1f447;&#x1f…

07-树(Tree)结构分析

文章目录树(Tree)结构分析什么是树&#xff1f;树中的相关名词如何理解&#xff1f;什么是二叉树&#xff1f;什么是二叉搜索树&#xff1f;什么是AVL树&#xff1f;什么是2-3树&#xff1f;什么是红黑树&#xff1f;总结&#xff08;Summary&#xff09;树(Tree)结构分析 什么…

【飞桨PaddleSpeech语音技术课程】— 语音识别-流式服务

FastAPI websocket 流式语音识别服务 0. 背景 流式语音识别(Streaming ASR)或者在线语音识别(Online ASR) 是随着输入语音的数据不断增加&#xff0c;实时给出语音识别的文本结果。与之相对的是非实时或者离线语音识别&#xff0c;是传入完整的音频数据&#xff0c;一次给出整…

ppocrlabel简单教学

前言 给我们小白成员的快速上手ppocrlabel的指南 1. ppocr环境配置 建议是先创建一个虚拟环境 【直接参考】&#xff1a;https://blog.csdn.net/weixin_42708301/article/details/119864744 2. ppocrlabel环境安装 【参考文档】PaddleOCR-release-2.6\PPOCRLabel\README_c…

将STM32 内部Flash虚拟成优盘,进行IAP升级

书接上回&#xff0c;上篇文章已经成功的将 STM32 内部FLASH虚拟成优盘进行文件存储了。 【将 STM32 内部Flash虚拟成优盘】https://blog.csdn.net/qq_44810226/article/details/127508789 然后我们开始固件升级流程&#xff1a; 从上图可以看出&#xff0c;固件存储的位置是不…

Python-代码封装思想

继上文所将讲的pythonrequestsUnittest框架&#xff0c;本文将继续分享python代码的进一步封装思想&#xff0c;来提高代码的整体运行效率及整洁性&#xff0c;本文以接口测试框架为例进行讲解。 关于Unittest单元测试框架的具体使用方法链接链接&#xff08;点击跳转&#xf…

MMEngine理解

MMEngine理解1 简介1.1 架构1.2 模块介绍1.2.1 核心模块与相关组件1.2.1 公共基础模块2 上手示例2.1 构建模型2.2 构建数据集和数据加载器2.3 构建评测指标2.4 构建执行器并执行任务3. 基础模块3.1 注册器&#xff08;Registry&#xff09;3.1.1 什么是注册器3.1.2 使用流程3.1…

OSPF路由协议(二)

作者介绍&#xff1a; ⭐️作者&#xff1a;小刘在C站 ❄️每天分享课堂笔记&#xff0c;一起努力&#xff0c;共赴美好人生&#xff01; ☁️夕阳下&#xff0c;是最美的绽放。 目录 一.Router id 二.DR,BDR 三.DR BDR 选举过程 四.ospf 度量值 cost 代价 五.ospf 的数据…

部署vue项目到阿里云服务器

一般前端工程师只会使用npm run serve 在开发环境下验证&#xff0c;那么如何把npm run build 打出的包部署到服务器上进行上线呢&#xff1f;这篇文章就详细阐述这一流程。 1. 购买或试用阿里云服务器 作为新用户可以试用一个月阿里云服务器&#xff0c;阿里云官方网址如下&a…

【数据结构与算法分析】0基础带你学数据结构与算法分析07--二叉树

在学习上一章后&#xff0c;我们对树加以限制&#xff0c;如果树的度为 2&#xff0c;那么就称这颗树为 二叉树 (binary tree)。 二叉树的性质 在一棵二叉树上&#xff0c;有一些重要的性质&#xff1a; 第 i 层 (i∈N) 上最多有 2^(i−1) 个结点层次为 k(k∈N) 的树最多有 …

进程地址空间

目录 程序地址空间 感知虚拟地址空间的存在 进程地址空间 分页 & 虚拟地址空间 Linux2.6内核进程调度队列 程序地址空间 我们在学习C语言的时候了解过程序地址空间的分布&#xff1a; 需要注意的是&#xff1a;程序地址空间不是内存。我们在linux操作系统中通过代码来…

刷题笔记之二(字符串中找出连续最长的数字串+数组中出现次数超过一半的数字+另类加法+计算糖果+进制转换)

目录 1. 多层继承问题 2. 继承中子类的构造要引用super 3. 比较地址 4. 字符串中找出连续最长的数字串(编程题) 5. 数组中出现次数超过一半的数字&#xff08;编程题&#xff09; 6. 另类加法&#xff08;编程题&#xff09; 7. Interface 接口中定义方法 8. 实现或继…

C语言学习(二)之字符串和格式化输入/输出

文章目录一、字符串二、 输入2.1 scanf()作用2.2 两种用法三、输出3.1 printf()3.1.1 printf 四种用法3.1.2 常用输出控制符3.1.3 为什么需要输出控制符一、字符串 字符串是一个或多个字符的序列。如&#xff1a;“Hello World” 双引号不是字符串的一部分。仅告知编译器它括…

【学习笔记】《深入浅出Pandas》第16章:可视化

文章目录16.1 plot方法16.1.1 plot概述16.1.2 plot基础方法16.1.3 图形类型16.1.4 x轴和y轴16.1.5 图形标题16.1.6 字体大小16.1.7 线条样式16.1.8 背景辅助线16.1.9 图例16.1.10 图形大小16.1.11 色系16.1.12 绘图引擎16.1.14 图形叠加16.1.15 颜色的表示16.1.16 解决图形中的…

量子笔记:量子计算 toy python implementation from scratch

目录 0. 概要 1. 量子比特表示&#xff1a;用二维张量表示 2. 张量积的实现 2.1 用scipy.linalg.kron()实现张量积 2.2 用张量积计算双量子系统的基 3. 多量子系统基向量表示和生成 3.1 Helper function: bin_ext 3.2 多量子系统的基的生成 3.3 numpy.matrix numpy.m…