SLAM+语音机器人DIY系列:(六)SLAM建图与自主避障导航——2.google-cartographer机器人SLAM建图

摘要                                            

通过前面的基础学习,本章进入最为激动的机器人自主导航的学习。在前面的学习铺垫后,终于迎来了最大乐趣的时刻,就是赋予我们的miiboo机器人能自由行走的生命。本章将围绕机器人SLAM建图、导航避障、巡航、监控等内容展开。本章内容:

1.在机器人上使用传感器

2.google-cartographer机器人SLAM建图

3.ros-navigation机器人自主避障导航

4.多目标点导航及任务调度

5.机器人巡航与现场监控



2.google-cartographer机器人SLAM建图

主流的激光SLAM算法有hectorgmappingkartocartographer

hector是一种结合了鲁棒性较好的扫描匹方法2D_SLAM方法和使用惯性传感系统的导航技术。传感器的要求较高,高更新频率小测量噪声的激光扫描仪,不需要里程计。使空中无人机与地面小车在不平坦区域运行存在运用的可能性。作者利用现代激光雷达的高更新率和低距离测量噪声,通过扫描匹配实时地对机器人运动进行估计。所以当只有低更新率的激光传感器时,即便测距估计很精确,对该系统都会出现一定的问题。

gmapping是一种基于粒子滤波的激光SLAM算法,它已经集成在ROS中,是移动机器人中使用最多的SLAM算法。基于粒子滤波的算法用许多加权粒子表示路径的后验概率,每个粒子都给出一个重要性因子。但是,它们通常需要大量的粒子才能获得比较好的的结果,从而增加该算法的的计算复杂性。此外,与PF重采样过程相关的粒子退化耗尽问题也降低了算法的准确性。

karto是基于图优化的SLAM算法,用高度优化和非迭代cholesky矩阵进行稀疏系统解耦作为解。图优化方法利用图的均值表示地图,每个节点表示机器人轨迹的一个位置点和传感器测量数据集,箭头的指向的连接表示连续机器人位置点的运动,每个新节点加入,地图就会依据空间中的节点箭头的约束进行计算更新。路标landmark越多,内存需求越大,然而图优化方式相比其他方法在大环境下制图优势更大。

cartographergoogle开发的实时室内SLAM项目,cartographer采用基于google自家开发的ceres非线性优化的方法,cartographer的量点在于代码规范与工程化,非常适合于商业应用和再开发。并且cartographer基于submap子图构建全局地图的思想,能有效的避免建图过程中环境中移动物体的干扰。并且cartographer支持多传感器数据(odometryIMULaserScan等)建图,支持2D_SLAM3D_SLAM建图。所以,我果断采用cartographer来建图,我的树莓派3主板跑cartographer实时建图是十分的流畅,这一点很欣慰^_^

2.1.google-cartographer建图算法原理分析

cartographer采用的是主流的SLAM框架,也就是特征提取、闭环检测、后端优化的三段式。由一定数量的LaserScan组成一个submap子图,一系列的submap子图构成了全局地图。用LaserScan构建submap的短时间过程累计误差不大,但是用submap构建全局地图的长时间过程就会存在很大的累计误差,所以需要利用闭环检测来修正这些submap的位置,闭环检测的基本单元是submap,闭环检测采用scan_match策略。cartographer的重点内容就是融合多传感器数据(odometryIMULaserScan等)的submap子图创建以及用于闭环检测的scan_match策略的实现。

18cartographer算法系统框图

2.2.cartographer_ros安装         

我们直接参考google-cartographer官方教程安装就行,官方教程分为cartographercartographer_ros,其实cartographer就是核心算法层、cartographer_ros是核心算法层的ros调用层。官方教程如下:

https://google-cartographer.readthedocs.io/en/latest/index.html#

https://google-cartographer-ros.readthedocs.io/en/latest/index.html#

直接按照第二个链接cartographer_ros的安装教程,就可将cartographer_roscartographer、以及各种依赖都安装了。不过特别说明一点,为了解决从官网下载ceres-solver速度慢的问题,我将ceres-solver的下载地址换到了github源;我需要将官方教程中生成的src/.rosinstall替换成了自己的内容,如图19。其余安装过程和官方教程一模一样。

1)安装编译工具

我来编译cartographer_ros,我们需要用到wsoolrosdep。为了加快编译,我们使用ninja工具进行编译。

sudo apt-get update
sudo apt-get install -y python-wstool python-rosdep ninja-build

2)创建存放cartographer_ros的专门工作空间

mkdir catkin_ws_carto
cd catkin_ws_carto
wstool init src

wstool merge -t src https://raw.githubusercontent.com/googlecartographer/cartographer_ros/master/cartographer_ros.rosinstall

wstool update -t src

特别说明,在执行wstool update -t src之前,需要将src/.rosinstall文件修改成以下内容,解决ceres-solver下载不了的问题,如图19

(图19)我修改后的src/.rosinstall文件内容

(3安装依赖项

安装cartographer_ros的依赖项proto3deb包等。如果执行sudo rosdep init报错,可以直接忽略。

src/cartographer/scripts/install_proto3.sh
sudo rosdep init
rosdep update

rosdep install --from-paths src --ignore-src --rosdistro=${ROS_DISTRO} -y

4)编译和安装

上面的配置和依赖都完成后,就可以开始编译和安装cartographer_ros整个项目工程了。

catkin_make_isolated --install --use-ninja

特别提醒,以后对cartographer_ros中的配置文件或源码有改动时,都需要执行这个编译命令使修改生效。

2.3.cartographer_ros使用        

cartographer_ros整体代码结构分析:

最顶层的是cartographer_ros,作为rosj接口调用层,通过调用cartographer核心算法,订阅多传感器数据(/scan/imu/odom等),并发布地图、机器人位置信息(/map/tf等);其次是cartographer,作为SLAM算法的核心实现,特征提取、子图构建、闭环检测、全局优化都在这里实现,其中优化过程需要调用ceres-solver非线性优化库;最后是ceres-solver,是非线性优化库,用于求解SLAM中的优化问题。

20cartographer_ros整体代码结构

miiboo机器人上用cartographer_ros多传感器建图进行配置:

经过前面对cartographer_ros进行安装后,我们肯定迫不及待想在实际的miiboo机器人上使用cartographer_ros进行SLAM建图了。为了最大限度的提高SLAM建图的性能,我们的miiboo机器人提供了激光雷达、IMU、轮式里程计(/scan/imu/odom)这三种传感器的数据,所以我们需要先将cartographer_ros配置成对应的工作模式。

cartographer算法是一个非常通用和适应不同平台的开放框架算法,所以支持多种配置与工作模式。我们就来看看cartographer_ros如何进行配置。配置文件由*.lua书写被放在路径cartographer_ros/configuration_files/,我们需要建立一个我们自己的配置文件,取名就叫miiboo_mapbuild.lua吧,具体内容如图21。由于我们的miiboo机器人采用激光雷达、IMU、轮式里程计三种传感器融合建图,所以以下参数一定要设置正确:

参数tracking_frame设置为imu_link,因为我们使用/imu的数据;

参数published_frame设置为odom,因为我们使用/odom的数据;

参数provide_odom_frame设置为false,因为我们使用外部/odom,所以这里不需要内部提供;

参数use_odometry设置为true,因为我们使用外部/odom的数据;

参数use_imu_data设置为true,因为我们使用/imu的数据;

参数imu_gravity_time_constant设置为10,这个是IMU的重力加速度常数。

其余参数根据需要自行调整,由于cartographer是发展很迅速的算法,所以很多代码和文档一直在更新,所以参考官方文档来解读这些参数的含义是最好的选择,官方文档连接地址我贴在下面了。

https://google-cartographer-ros.readthedocs.io/en/latest/index.html

 

(图21)我们miiboo机器人的建图配置文件miiboo_mapbuild.lua

然后需要配置*.launch文件,我们给miiboo机器人建立启动文件取名叫miiboo_mapbuild.launch,存放路径在cartographer_ros/launch/里面,具体内容如图22

不难发现launch文件中包含三个node启动项,即urdf模型启动项、cartographer_node启动项、cartographer_occupancy_grid_node启动项。

第一个启动项是启动urdf模型,这个接口是提供给那些只使用cartographer单独建图的应用场景,由于我们miiboo机器人建立完地图后还需要继续进行自动导航任务,所以我们使用miiboo底盘提供的urdf模型,而不使用这里的urdf模型,所以这个启动项被注释掉了,这样建图和导航就更容易管理。

第二个启动项是启动cartographer_node建图节点,这个是SLAM建图主节点,我们建立的配置miiboo_mapbuild.lua将在这里被载入,同时这里可以对建图输入数据scanimuodomtopic名称做重映射。

第三个启动项是启动cartographer_occupancy_grid_node地图格式转换节点,由于cartographer_node建图节点提供的地图是submapList格式的,需要转换成GridMap格式才能在ROS中显示和使用。这里面有两个可配参数,resolution用来设置GridMap地图的分辨率,publish_period_sec用来设置GridMap地图发布的频率。

(图22)我们miiboo机器人的建图启动文件miiboo_mapbuild.launch

配置参数修改好后,不要忘了再编译一次整个catkin_ws_carto工作空间,切换到catkin_ws_carto目录,执行下面的编译命令。

catkin_make_isolated --install --use-ninja

启动cartographer_ros建图:

要在miiboo机器人上,启动cartographer_ros建图,分为这几个步骤:启动机器人上的各个传感器、启动cartographer_ros、在PC端启动键盘控制机器人运动并启动rviz观察地图(或者在Android手机端用miiboo机器人APP控制机器人运动和观察地图)。

首先,启动机器人上的各个传感器,为了操作方便,我已经将要启动的传感器都写入miiboo_bringup/launch/miiboo_all_sensor.launch这个启动文件了,文件内容如图23。这个启动文件包含机器人urdf启动项、miiboo底盘启动项、激光雷达启动项、IMU启动项、摄像头启动项、广播IP启动项。

(图23)各个传感器启动文件miiboo_all_sensor.launch

 打开终端,通过下面的命令直接启动就行了。

source ~/catkin_ws/devel/setup.bash 
roslaunch miiboo_bringup miiboo_all_sensor.launch 

然后,启动cartographer_ros,由于前面已经做好了相应的配置,所以直接使用命令启动就行了。

source ~/catkin_ws_carto/install_isolated/setup.bash
roslaunch cartographer_ros miiboo_mapbuild.launch

这里给个小提示,为了查看cartographer_ros建图算法有没有正常开始工作,我们可以用rosrun rqt_tf_tree rqt_tf_tree查看整个tf树的结构,正常的tf树如图24map->odom之间的关系由cartographer建图节点提供,odom->base_footprint之间的关系由miiboo底盘的轮式里程计提供,base_footprint->imu_linkbase_linkbase_laser_link之间的关系由miiboo机器人的urdf模型提供。从tf树不难看出整个建图过程中机器人定位的实现原理,cartographer建图节点通过维护map->odom之间的关系最终实现全局定位,miiboo底盘的轮式里程计通过维护odom->base_footprint之间的关系来实现局部定位,传感器之间的安装关系由urdf模型提供,这个静态关系主要用于多传感器数据融合。

(图24cartographer运行时正常的tf

最后,在PC端启动键盘控制机器人运动并启动rviz观察地图(或者在Android手机端用miiboo机器人APP控制机器人运动和观察地图)。如果用PC端控制和观察,启动命令如下。

PC端打开一个新终端,运行rviz启动命令。

rosrun rviz rviz

rviz窗口中添加订阅/map,就可以看到建图效果了,如图25

(图25)在PC端用rviz观察地图

PC端再打开一个新终端,运行键盘控制启动命令。

rosrun teleop_twist_keyboard teleop_twist_keyboard.py

在该终端下,用键盘就可以控制机器人前进、后退、左转、右转了。

如果是在Android手机端用miiboo机器人APP控制机器人运动和观察地图,直接就能使用,如图26

(图26)在Android手机端用miiboo机器人APP控制机器人运动和观察地图

保存cartographer_ros建图结果:

当我们在房间里面扫描一圈,地图建立的差不多了,就可以将建图结果保存下来了,cartographer_ros提供了将建图结果保存为*.pbstream专门的方法,其实就是一条命令。

source ~/catkin_ws_carto/install_isolated/setup.bash
rosservice call /write_state  /home/ubuntu/map/carto_map.pbstream

其实就是调用cartographer_ros提供的叫/write_state这个名字的服务,服务传入参数/home/ubuntu/map/carto_map.pbstream为地图的保存路径。保存成功后,会返回相应的状态信息,如图27

(图27)调用/write_state服务保存建图结果

地图格式转换:

由于用cartographer_ros提供的/write_state方法保存的地图是*.pbstream的格式,而要在后续的自主导航中使用这个地图,我们需要将其转换为ROS中通用的GridMap格式。其实很简单,cartographer_ros已经跟我们提供了cartographer_pbstream_to_ros_map这个节点用于转换的实现。所以,我们只需要写一个启动文件启动这个节点就行了,我给这个启动文件取名miiboo_pbstream2rosmap.launch,存放路径是cartographer_ros/launch/,启动文件的内容如图28。在使用这个启动文件进行启动时,需要从外部传入两个参数,参数pbstream_filename为待转换的*.pbstream文件路径,参数map_filestem为转换后存放结果的文件路径。

(图28pbstreamGridMap启动文件

配置参数修改好后,不要忘了再编译一次整个catkin_ws_carto工作空间,切换到catkin_ws_carto目录,执行下面的编译命令。

catkin_make_isolated --install --use-ninja

最后,就可以打开终端,使用启动这个启动文件,对地图格式进行转换了,命令如下。

roslaunch cartographer_ros miiboo_pbstream2rosmap.launch pbstream_filename:=/home/ubuntu/map/carto_map.pbstream map_filestem:=/home/ubuntu/map/carto_map

保存结束后,节点会自动退出,这时我们可以得到转换后的地图,转换后的GridMap地图由*.pgm*.yaml两部分构成,这时标准的ROS格式地图,可以被ROS导航框架中的map_server节点直接调用,转换后的地图结果如图29

(图29)地图格式转换后的结果

后记                                                      

------SLAM+语音机器人DIY系列【目录】快速导览------

第1章:Linux基础

1.Linux简介

2.安装Linux发行版ubuntu系统

3.Linux命令行基础操作

第2章:ROS入门

1.ROS是什么

2.ROS系统整体架构

3.在ubuntu16.04中安装ROS kinetic

4.如何编写ROS的第一个程序hello_world

5.编写简单的消息发布器和订阅器

6.编写简单的service和client

7.理解tf的原理

8.理解roslaunch在大型项目中的作用

9.熟练使用rviz

10.在实际机器人上运行ROS高级功能预览

第3章:感知与大脑

1.ydlidar-x4激光雷达

2.带自校准九轴数据融合IMU惯性传感器

3.轮式里程计与运动控制

4.音响麦克风与摄像头

5.机器人大脑嵌入式主板性能对比

6.做一个能走路和对话的机器人

第4章:差分底盘设计

1.stm32主控硬件设计

2.stm32主控软件设计

3.底盘通信协议

4.底盘ROS驱动开发

5.底盘PID控制参数整定

6.底盘里程计标

第5章:树莓派3开发环境搭建

1.安装系统ubuntu_mate_16.04

2.安装ros-kinetic

3.装机后一些实用软件安装和系统设置

4.PC端与robot端ROS网络通信

5.Android手机端与robot端ROS网络通信

6.树莓派USB与tty串口号绑定

7.开机自启动ROS节点

第6章:SLAM建图与自主避障导航

1.在机器人上使用传感器

2.google-cartographer机器人SLAM建图

3.ros-navigation机器人自主避障导航

4.多目标点导航及任务调度

5.机器人巡航与现场监控

第7章:语音交互与自然语言处理

1.语音交互相关技术

2.机器人语音交互实现

3.自然语言处理云计算引擎

第8章:高阶拓展

1.miiboo机器人安卓手机APP开发

2.centos7下部署Django(nginx+uwsgi+django+python3)

----------------文章将持续更新,敬请关注-----------------

 

如果大家对博文的相关类容感兴趣,或有什么技术疑问,欢迎加入下面的《SLAM+语音机器人DIY》QQ技术交流群,一起讨论学习^_^

关于我们:

视频教程:

 

https://www.bilibili.com/video/av61448040

 

posted @ 2019-02-21 23:04 小虎哥哥爱学习 阅读(...) 评论(...) 编辑 收藏