Error message here!

Hide Error message here!

忘记密码?

Error message here!

请输入正确邮箱

Hide Error message here!

密码丢失?请输入您的电子邮件地址。您将收到一个重设密码链接。

Error message here!

返回登录

Close

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

小虎哥哥爱学习 2019-02-21 23:04:00 阅读数:336 评论数:0 点赞数:0 收藏数:0

摘要                                            

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

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

2.google-cartographer机器人SLAM建图

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

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

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

2.google-cartographer机器人SLAM建图

主流的激光SLAM算法有hector、gmapping、karto、cartographer。

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

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

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

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

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

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

(图18)cartographer算法系统框图

2.2.cartographer_ros安装         

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

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

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

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

(1)安装编译工具

我来编译cartographer_ros,我们需要用到wsool和rosdep。为了加快编译,我们使用ninja工具进行编译。sudo apt-get updatesudo apt-get install -y python-wstool python-rosdep ninja-build

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

mkdircatkinwscarto cd catkinwscarto wstool init src wstool merge-t src https://raw.githubusercontent.com/googlecartographer/cartographerros/master/cartographerros.rosinstall wstool update-t src

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

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

(3)安装依赖项

安装cartographer_ros的依赖项proto3、deb包等。如果执行sudo rosdep init报错,可以直接忽略。src/cartographer/scripts/installproto3.sh sudorosdep init rosdep update rosdepinstall --from-paths src --ignore-src --rosdistro=${ROSDISTRO} -y

(4)编译和安装

上面的配置和依赖都完成后,就可以开始编译和安装cartographer_ros整个项目工程了。catkinmakeisolated --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中的优化问题。

(图20)cartographer_ros整体代码结构

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

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

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

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

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

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

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

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

参数imugravitytime_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模型启动项、cartographernode启动项、cartographeroccupancygridnode启动项。

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

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

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

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

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

启动cartographer_ros建图:

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

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

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

 打开终端,通过下面的命令直接启动就行了。source ~/catkinws/devel/setup.bash roslaunch miiboobringup miibooallsensor.launch

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

source ~/catkinwscarto/installisolated/setup.bash roslaunch cartographerros miiboo_mapbuild.launch

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

(图24)cartographer运行时正常的tf树

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

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

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

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

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

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

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

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

保存cartographer_ros建图结果:

当我们在房间里面扫描一圈,地图建立的差不多了,就可以将建图结果保存下来了,cartographer_ros提供了将建图结果保存为/*.pbstream专门的方法,其实就是一条命令。source ~/catkinwscarto/installisolated/setup.bash rosservice call/writestate /home/ubuntu/map/carto_map.pbstream

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

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

地图格式转换:

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

(图28)pbstream转GridMap启动文件

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

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

roslaunch cartographerros miiboopbstream2rosmap.launch pbstreamfilename:=/home/ubuntu/map/cartomap.pbstream mapfilestem:=/home/ubuntu/map/cartomap

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

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

后记                                                      

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

 

版权声明
本文为[小虎哥哥爱学习]所创,转载请带上原文链接,感谢
https://www.cnblogs.com/hiram-zhang/p/10415865.html

编程之旅,人生之路,不止于编程,还有诗和远方。
阅代码原理,看框架知识,学企业实践;
赏诗词,读日记,踏人生之路,观世界之行;

支付宝红包,每日可领