2021@SDUSC
ROS-3DSLAM(3):信息流
2021年10月17日星期一——2021年10月20日星期三
一、背景简介:
对于信息流的分析理解能够有助于我们对于整个项目的下一步研究学习。虽然对于局部代码的阅读可能看不出来这样做的好处,但是毫无疑问这样的分析有助于我们下一步的对于整个系统的代码的解读工作。
考虑到雷达包的阅读工作量的问题,本周我负责的任务即为处理这个信息流的工作,这样也方便和组内的同学们统一阅读进度。
二、学习历程:
因为是对于全局代码的分析,考虑到我的时间和精力的问题,直接阅读代码显得不太可行,所以我决定这次阅读的主要参考放在网络上其他人的解读上,这样做的好处是节省了精力,但是坏处就是可能会带来其他人的错误,为此,我需要多加参考比对资料来降低错误发生的概率。但是,又受限于资料有限的问题,能够用来参考的文章实在是屈指可数,所以只能是先尝试着一边看大佬的分析,一边结合代码来完成相应的工作了。先把信息流提取出来,如果后边的学习中发现问题再尝试着改正。
在学习的过程中,我发现了一种名为“tf树”的数据结构,可以用来展示节点间的坐标变换的消息,相应的,这样也把话题信息的传递过程展示了出来,使得我们能够查看信息流。但遗憾的是,这必须在ros运行时展示,受限于手头有限的工具,我目前还没有办法采取这一工作,以后有条件时我会补充上来。
而后,我又发现了一个更为强大的功能包:rqt,它可以直接给ros系统生成node graph(节点图),方便我们对于信息流的直接分析,虽然我依旧没有可以用的ros系统运行的情况,但是网上却有图可以帮助我解决这个问题。这样的话就很方便了,我可以直接从这张图入手,来结合代码进行分析。
三、信息流分析
A、ros信息流预备知识
在分析信息流之前,有必要先回顾一下ros的基本概念:
- 节点
- 节点管理器
- 话题
- 消息
- 服务
- rqt功能包:Node Graph
后边遇到的稍微重要一些的名词术语我也放在这里了:
- imu
- odometry
- 闭环信息
- Marker和MarkerArray
- pose
B、Node Graph阅读
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-meWV32Qg-1634812390191)(https://xuwuzhou.top/images/LVI_SAM%E5%9B%BE%E7%89%872.png)]
(出处见文末)
这是通过rqt得到的节点图,下面我们开始结合代码对其进行分析。
C、重要节点:
通过上图不难看出这几个重要节点:
- /lvi_sam_imuPreintegration(IMU预积分节点)
- /lvi_sam_mapOptmization(图优化节点)
- /lvi_sam_featureExtraction(特征提取节点)
- /lvi_sam_imageProjection(生成深度图)
- /lvi_sam_visual_feature(生成视觉特征节点)
- /lvi_sam_visual_loop(闭环检测节点)
- /lvi_sam_visual_odometry(视觉里程计节点)
- /lvi_sam_rviz(传递给rviz节点?)
其中,前四个节点是雷达相关的节点,后面三个是视觉相关的节点,最后一个是rviz相关节点。
我们可以一一分析前七个包,而rviz相关节点的输入可以在其中体现。
我们下面依次来介绍。
我们的分析步骤很简单,先去源代码里找到相关的代码,根据代码分析其输入输出即可。
D、第一部分:雷达相关
1./lvi_sam_imuPreintegration(IMU预积分节点)
//声明
ros::Subscriber subImu;
ros::Subscriber subOdometry;
ros::Publisher pubImuOdometry;
ros::Publisher pubImuPath;
//下文的使用
subImu = nh.subscribe<sensor_msgs::Imu> (imuTopic, 2000, &IMUPreintegration::imuHandler, this, ros::TransportHints().tcpNoDelay());
subOdometry = nh.subscribe<nav_msgs::Odometry>(PROJECT_NAME + "/lidar/mapping/odometry", 5, &IMUPreintegration::odometryHandler, this, ros::TransportHints().tcpNoDelay());
pubImuOdometry = nh.advertise<nav_msgs::Odometry> ("odometry/imu", 2000);
pubImuPath = nh.advertise<nav_msgs::Path> (PROJECT_NAME + "/lidar/imu/path", 1);
输入:imu信息 odometry信息 输入是对于原始数据的处理
输出:odometry信息 轨迹信息; path信息 为了给rviz显示
2./lvi_sam_mapOptmization(图优化节点)
//输出
ros::Publisher pubLaserCloudSurround;
ros::Publisher pubOdomAftMappedROS;
ros::Publisher pubKeyPoses;
ros::Publisher pubPath;
ros::Publisher pubHistoryKeyFrames;
ros::Publisher pubIcpKeyFrames;
ros::Publisher pubRecentKeyFrames;
ros::Publisher pubRecentKeyFrame;
ros::Publisher pubCloudRegisteredRaw;
ros::Publisher pubLoopConstraintEdge;
//输出一
pubKeyPoses = nh.advertise<sensor_msgs::PointCloud2>(PROJECT_NAME + "/lidar/mapping/trajectory", 1);
pubLaserCloudSurround= nh.advertise<sensor_msgs::PointCloud2>(PROJECT_NAME + "/lidar/mapping/map_global", 1);
pubOdomAftMappedROS= nh.advertise<nav_msgs::Odometry>(PROJECT_NAME +"/lidar/mapping/odometry", 1);
pubPath= nh.advertise<nav_msgs::Path>(PROJECT_NAME + "/lidar/mapping/path", 1)