Cartographer建图与应用---第二弹
前言
这个过程中又重装了一边系统...不过问题不大,重装的速度比之前快多了,可能是熟练度上来了哈哈哈哈。我在想有没有必要写一个重装系统的帖子?
但是其实问题就是carto的protoc是3.4.1,而编译考核资料的protoc是3.0.0,也就是Ubuntu自带的protoc版本。我也有查找过同时兼容两个protoc版本的方法,这一个我觉得是很有可能成功的:https://blog.csdn.net/qq_41847318/article/details/105677603,我也觉得很有道理:不就是将protoc下载到不同的位置,然后编译的时候根据需要什么protoc版本就刷新环境变量链接到那个protoc版本就好了!
但是很遗憾,我没有成功。虽然是这样,但是我觉得这个方法还是很值得借鉴的,最后我是重装了系统然后先编译考核材料,再下载carto的。后面又试了一下,果然编译考核材料还是会因为protoc版本出问题,不过还好有其他的解决方法。
任务分析
考核要求的任务是利用carto算法让小车在仿真环境中建图。对应本系列的第一弹,其实很容易,相较于测试其实就需要对launch文件和lua文件的参数配置一个更深入的了解才行。
这里放上建好的美图一张~
任务需求
在使用给定的qingzhou机器人进行建图导航的过程中,我才体会到对一个机器人的整体结构的掌握和所发布的话题有多么重要,这里对应的就是两个命令:
rosrun rqt_tf_tree rqt_tf_tree
:作用是生成**机器人的TF树,也就是机器人的机械结构frame,在TF树中我们可以看到机器人的基座标是什么、imu的link...比如这下面就是qingzhou的tf树
rosrun rostopic list
:作用是列出现在所有发布的话题,这一点非常重要,因为前面说过使用carto建图就是利用话题进行通信交互的结果,在launch文件中就需要用到这里的话题,所以也需要事先清楚
参数配置
明确了上面那些操作之后,接下来就是进行参数的配置了
launch文件
其实launch文件参数的配置和第一篇文章讲的差不多,就是有一个点我是自己发现的:
点击查看代码
<remap from="scan" to="/scan" />
<remap from="imu" to="/qingzhou/imu" />
<remap from="odom" to="/qingzhou/ackermann_steering_controller/odom" />
这一段代码我们在前面说过是将carto订阅的话题进行重定位的,但是初始给出的只有scan和odom两项,我以为就只有这两个可以进行remap的操作。但是后面发现有一个问题:我在lua文件中开启了imu参数的配置后,carto会报出警告说明要订阅的是话题/imu,但是已经发布的话题中没有这个,还会把已经发布的话题列出来(原文差不多就是这个意思),所以其实它把问题已经说的很清楚了。
那么需要我们解决的就是如何将imu的话题和carto建立连接,很简单,就是运行机器人和gazebo之后用rostopic list
列出话题,然后从中寻找imu的话题即可,最后将imu的话题remap到上面去。
launch全部代码如下:
点击查看代码
<!--
Copyright 2016 The Cartographer Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<launch>
<param name="/use_sim_time" value="true" />
<node name="cartographer_node" pkg="cartographer_ros"
type="cartographer_node" args="
-configuration_directory $(find cartographer_ros)/configuration_files
-configuration_basename qingzhou_mapping.lua"
output="screen">
<remap from="scan" to="/scan" />
<remap from="imu" to="/qingzhou/imu" />
<remap from="odom" to="/qingzhou/ackermann_steering_controller/odom" />
</node>
<node name="cartographer_occupancy_grid_node" pkg="cartographer_ros"
type="cartographer_occupancy_grid_node" args="-resolution 0.05" />
</launch>
lua文件
lua文件中参数配置的作用主要就是开启什么,参考frame是什么之类的。这里的参数配置我参考的是这篇帖子,讲的已经很详细了:https://zhuanlan.zhihu.com/p/354723907
只不过里面在对于odom的配置讲的有点绕,结合其他一些个人的发现,我这里重新解释一下:
imu的使用
imu是机器人的姿态传感器,一般来讲加上imu建图效果会更好。所以我们这里加上imu,首先需要将tracking_frame
改为imu对应的frame,这里我是imu_link
,从TF树中就可以看出来(如果不需要imu,就将它设置为base_link
即可)
除此之外,我们在下面找到TRAJECTORY_BUILDER_2D.use_imu_data = true
,这里说明的是需不需要使用imu的数据,我们改为true,这样子配合launch文件中的<remap from="imu" to="/qingzhou/imu" />
,我们的imu就配置u好了~
odom的使用
odom是机器人的里程计,正常情况下加上odom效果会好。关于odom的配置,在那篇文章中是这样说的:
首先是两个开关参数provide_odom_frame和use_odometry,use_odometry是控制是否使用里程计信息,provide_odom_frame是控制carto是否提供里程计tf。
provide_odom_frame开关参数:这里先理解carto建图时一定会有的map_frame也就是map的tf,建图时carto本质上能得到的一般是base_link与map之间的位置关系(因为激光雷达和imu的tf与base_link一般是固定的,map即它建得的地图固定坐标系),而描述位置关系在ROS一般就直接是两个坐标系的tf,但是我们知道tf树是不能多个导向同一个的,会冲突,所以如果本身有坐标系指向base_link(比如odom、base_footprint这些),那么map要描述与base_link的位置关系就只能连到再上一层了(比如map→odom→base_link就可以)。了解了这个基本机制之后,就可以来了解另外两个配置参数怎么一起使用了,另外的两个配置参数只与这个开关参数有关,前面说了carto建图知道的是map与base_link之间的关系,但是由于tf树的机制并不是任意情况都能够直接用tf连接base_link与map的,而carto内部不知道你外部tf树的复杂情况,因此提供了这两个参数要求你手动定义,首先说明published_frame参数,这个参数理解为指定你要把map连接到哪个坐标系(因为不一定能够直接连base_link),假如base_link上面本身你已经有odom的tf连接着,那么这个published_frame就可以指定为odom,如果只是这样普通的情况,直接就这样设置,然后设置provide_odom_frame为false即可,即不需要carto提供odom的tf,因为我们本身有了,这种情况下map就会直接连接published_frame,而假如我们没有odom的tf,而且我们希望carto能够给我们提供一个odom的tf(因为其实carto得到了这个信息),那么就将provide_odom_frame设置为true,同时odom_frame设置为你想要carto提供的odom的tf名字,这时,carto就会帮你生成map→odom_frame→publisher_frame这样的tf,对于这种我们没有odom的情况,一般published_frame也就指定为base_link或者base_footprint。
use_odometry开关参数:这个直接决定是否使用里程计信息(一般也就是我们是否有提供里程计信息),还是需要先理解一个前置知识,就是odom的tf与odom话题之间的关系,两者有关系,但并不等同,odom的tf一般也就是指odom与base_link的坐标系关系,它本身只有坐标系关系,即两个坐标系之间的平移矩阵、旋转矩阵;而odom话题就需要了解它的话题类型了,odom即里程计话题一般有专门的类型nav_msgs/Odometry,它内部不仅仅有tf包括的信息(它会指定child_frame的名字然后包括了旋转、平移的关系,具体去搜这个话题的定义),还会有速度信息、协方差矩阵也就是不确定性关系这些,因此如果odom的tf需要转换成odom的话题,需要手动定义协方差以及速度。了解了这些后,回到use_odometry的意义,它本身是决定是否使用里程计的信息,现在可以进一步说明是决定是否使用odom的话题,它一定是使用odom的话题,因此launch文件那个odom的remap就是和这个一起联动使用的。odom_frame和published_frame参数与use_odometry无关。
说实话挺绕的,我们先把标黑的部分理解了就行
odom_frame
的意思是 建图过程中的odom的frame的名称是什么。如果自己的机器人有odom的frame,就在TF树中找到odom的名字然后写上就行,如果没有odom的frame,那么就设置为自己想要的carto提供的odom的tf名字
published_frame
的意思是 建图过程中作为基座标的frame名字是什么,也就是要将map连接到哪个坐标系。如果自己的机器人在base_link上有自己的odom,就设置为自己的odom就好了;如果机器人没有odom,就设置为base_link即可,然后map直接连接到base_link
provide_odom_frame
的意思是 需不需要carto给你生成一个odom的frame,自己的机器人有就不需要,没有就需要
use_odometry
的意思是 要不要使用odom的数据参与到建图之中,如果需要就设置为true,不需要就false。这个参数和前面几个没什么关系
-
机器人有odom的情形:首先在launch文件中将odom的话题remap成自己的odom话题,然后对lua文件进行配置:
provide_odom_frame
设置为false,不需要carto生成;odom_frame
和published_frame
设置为自己的tf树中odom的名字; -
机器人没有odom的情形:
provide_odom_frame
设置为true,需要carto给我们生成;odom_frame
设置为需要carto给我们生成的odom在TF树中的名字;published_frame
设置为base_link
; -
不需要使用odom的情形:
provide_odom_frame
设置为false,不需要carto生成;published_frame
设置为base_link
;odom_frame
设置随便,反正不需要用到odom,最主要的就是use_odometry
设置为false
就比如我不需要用到odom,我是这样设置的:
点击查看代码
published_frame = "base_link",
odom_frame = "odom",
provide_odom_frame = false,
use_odometry = false,
使用carto生成的odom的机器人的TF树如下,就出现了一个odom
建图效果
前面的参数配置好之后,开始建图。这里也分为需不需要odom、imu的区别;多次测试之后,发现只需要imu,不需要odom的建图效果最好(仅针对本车)
无odom无imu
有imu无odom
有imu有odom
可以看出,仅使用imu的效果是最好的,可能这个车的odom有什么问题,但是也懒得去调整了。
脚本
应上一篇文章的要求,我把保存地图的命令写在一个脚本里面了
新建一个.sh文件,输入要执行的命令之后记得加上权限:chmod +x xxx.sh
,然后直接./xxx.sh
运行就可以了。
点击查看代码
rosservice call /finish_trajectory 0
rosservice call /write_state "{filename: '/home/cy/mymap.pbstream'}"
rosrun cartographer_ros cartographer_pbstream_to_ros_map -map_filestem=/home/cy/mymap.pbstream -pbstream_filename=/home/cy/mymap.pbstream -resolution=0.05
后记
感谢互联网大佬们!
https://zhuanlan.zhihu.com/p/354723907
https://blog.csdn.net/liuxin_hello/article/details/137502468