1.SLAM与ROS的关系
1.1.关于SLAM
在了解SLAM之前,需要先对机器人有一个整体的认识。机器人是一个复杂的装置,涉及到执行机构、感知、决策等主要环节。机器人上的配备的常用执行机构有轮式运动底盘、机械手臂、音响和显示屏;机器人上的感知设备通常有激光雷达、声呐、摄像头、IMU、轮式里程计编码盘、麦克风、触摸感应;机器人的决策是机器人智能的体现,机器人通常借助感知装置持续跟外部环境进行交互,从而来获取机器人的状态和环境的状态,我们可以简单的把机器人获取自身状态的行为叫做自我认知,把机器人获取环境状态的行为叫做环境认知。机器人的自我认知和环境认知往往是相辅相成互相作用的,所以这里就不做区分了。由于目前的机器人智能还比较低级,所以这里讲到的机器人认知也是低级别的,例如人脸识别、语音识别、机器人定位、环境障碍物探测。有了认知,机器人就可以帮人类完成很多工作了,例如搬运货物、照看小孩、陪伴闲聊、帮忙管理家里的智能设备、查询天气交通新闻资讯等等。我们可以把机器人帮助人类完成的这些个工作叫做机器人的技能,机器人拥有的这些个技能我们可以简单的理解为机器人低级别的思想。机器人的躯壳+机器人的认知+机器人的思想,基本上就是机器人该有的模样了。
图1.1.1 一个典型机器人的模样
这样一看,机器人是一个超级复杂的东西,但是机器人上现在关键性的技术就那么几个。其实,学界和工业界热门的研究和开发也是围绕这几个关键技术展开的。关键技术1:机器人移动底盘,绝大部分机器人需要依靠移动底盘来行走,当然除了水下机器人和腿型机器人这些特殊形态外,电机的效率功率、电机控制电路、编码器检测、底盘运动模型等组成部分,机器人底盘是AGV智能车、家庭服务机器人、农业工业自动化移动平台必不可少的关键组件。关键技术2:机械手臂,机器人抓取物品、组装零件、写字画画都需要用到机械手臂,高性能的舵机、精密的机械关节、智能关节控制算法等几个组成部分,机械手臂在工业自动化领域已经得到广泛应用,比如汽车自动装配、手机零配件装配,不过应用在服务机器人和AGV智能车上的轻便微型机械手臂目前还不成熟或者说还不普及。关键技术3:SLAM导航,这里终于讲到了大名鼎鼎的SLAM技术了,学术上的SLAM是指同时定位和建图技术,但是平时大家说的SLAM通常是广义的机器人定位+环境建图+自主导航+动态避障,我们这里也讨论的是广义的SLAM,简单点说SLAM技术帮助机器人认识环境并在环境中自由行走到目的地。关键技术4:语音识别,语音交互是大部分机器人的标配,人类通过语音交互向机器人下达任务指令,语音交互包括语音识别、语音合成、自然语言处理等部分组成,目前基于语音交互做出来的小机器人也是遍地开花。关键技术5:物体识别,机器人借助摄像头对自己所处环境的各种事物进行识别,比如流行的人脸识别、车牌识别、手势识别等等。
关键技术1:机器人移动底盘
关键技术2:机械手臂
关键技术3:SLAM导航
关键技术4:语音交互
关键技术5:物体识别
本人在这里总结归纳了机器人上的5大关键技术,由于个人能力和篇幅限制原因,接下来的内容将主要涉足机器人SLAM导航领域的相关技术。
SLAM导航技术,主要用来解决机器人的定位、环境建图、自主导航、动态避障等问题。SLAM这项技术其实已经有几十年的历史了,SLAM最早是出现在军事应用中,比如勇气号火星探测车,在不能实时遥控的未知环境行星上的探测车为了执行任务,需要借助SLAM技术来导航和避障。后来慢慢的SLAM技术就从军用转民用了,有了我们现在看到的小到家里的扫地机器人大到无人驾驶汽车的各种SLAM应用,还有各种AR和VR应用很多也用到了SLAM技术。
其实单独的定位技术我们日常生活中能见到很多,比如最常用的GPS定位技术、wifi定位技术、磁条导轨定位技术。单独的环境建图技术也有很多成熟的应用,比如医学中的CT对人体的全方位扫描技术、电影制作中对某个三维物体的扫描建模、隧道勘探测绘等。但是面对机器人这样一个复杂的应用,单独的定位技术和单独的环境建图技术都不能很好的解决问题,于是结合了定位与建图的SLAM技术就出现了。接下来,简单的梳理一下定位、建图、SLAM同时定位于建图、SLAM导航技术的理论发展过程。
(1)机器人中的不确定性
机器人所处的环境存在大量不可预测性,机器人中传感器的测量存在噪声和干扰,电机等执行机构也存在一定程度的不可靠性,还有一些不确定性是由机器人的软件导致的。要研究机器人的感知和行为就必须对这些不确定性进行建模,利用概率理论可以明确的表示这种不确定性,并且可以利用概率算法来对概率分布进行推理计算,以数学的方式合理的表示机器人的模糊性和置信度。简单点说,就是通过对机器人的概率建模,可以对机器人的不确定性进行明确的可计算性的表示。
(2)机器人中的状态估计
处理机器人中的这种不确定性的概率技术我们称之为概率机器人技术,其核心是用传感器数据来估计状态的思路。
图1.1.2 机器人与环境交互
机器人通过传感器对机器人自身状态和环境状态进行测量,这里的机器人状态包括机器人位姿、运动里程计信息、线速度和角速度信息等,而环境状态包括环境中物体的位置、物体的特征等。机器人同时利用控制动作来调用执行机构和环境进行交互,这里的控制动作包括机器人运动、物体操纵等。这样,机器人在通过传感器测量和控制动作与环境进行交互的过程中,对环境模型和机器人位姿进行估计。对环境模型的迭代估计就是我们常说的环境建图,对机器人位姿的迭代估计就是我们常说的机器人定位。
利用传感器测量和控制动作对环境模型和机器人位姿进行估计由概率法则迭代计算来完成。控制动作的概率模型我们称之为运动概率模型,传感器测量的概率模型我们称之为测量概率模型,这里的概率法则迭代计算过程就是大名鼎鼎的贝叶斯迭代网络。
图1.1.3 贝叶斯迭代网络
(3)贝叶斯滤波及其各种实现算法
通过对机器人中状态估计的了解,我们知道了贝叶斯概率法则起着重要的作用,而且大部分计算置信度的通用算法都是由贝叶斯算法给出的。这里说的贝叶斯算法也称作贝叶斯滤波,该算法根据测量和控制数据计算置信度分布bel()。贝叶斯滤波是一种递归算法,也就是说t时刻的置信度由t-1时刻的置信度来计算。
贝叶斯滤波算法具有两个基本步骤,即预测和更新。根据运动概率模型,可以对初步的预测置信度分布;然后利用测量概率模型,对上一步预测得到的置信度分布做进一步的更新计算。贝叶斯滤波的具体实现算法有多种,根据置信度表示方式的不同,贝叶斯滤波的具体实现算法可以分为参数化实现算法和非参数化实现算法两种。参数化实现算法,就是将置信度分布用多元高斯分布的参数进行表示。根据采用不同高斯分布的参数,又可以分为卡尔曼滤波和信息滤波。非参数化实现算法,就是将置信度分布用有限数量的具体值来近似表示。根据采用不同具体值近似的方法,又可以分为直方图滤波和粒子滤波。
图1.1.4 贝叶斯滤波及各种具体实现算法
由于贝叶斯滤波理论及各种具体实现算法涉及到大量深奥的数学知识,由于篇幅和个人能力受限,就不展开了,有兴趣的朋友可以参阅《概率机器人》这本书,这里面有细致的讲解和推导。为了加深大家在阅读和编写代码时的理解,这里贴出了贝叶斯滤波的伪代码实现,和机器人中广泛应用的卡尔曼滤波和粒子滤波的展示实例。
图1.1.5 基础贝叶斯滤波的伪代码实现
图1.1.6 卡尔曼滤波的伪代码实现
图1.1.7 卡尔曼滤波对置信度分布的更新过程
图1.1.8 粒子滤波的伪代码实现
图1.1.9 粒子滤波对置信度分布的更新过程
(4)机器人中的运动与测量概率模型
了解了机器人中的状态估计及各种滤波概率算法后,我们发现机器人的运动和测量概率模型对算法中的预测和更新步骤起着至关重要的作用。
运动模型我们都知道,就是机器人一个地方运动到另一个地方,位姿变化与运动控制量之间的关系。那什么叫运动概率模型呢?由于控制量作用在机器人上使机器人的位姿变化的过程是一个存在误差的不确定过程,所以控制量作用后产生的结果需要用一个概率分布来描述,这就是运动概率模型。根据运动控制量的不同,可以分成速度运动模型和里程计运动模型。速度运动模型中,控制量是线速度和角速度;里程计运动模型中,控制量是机器人的前后时刻的相对位姿。速度运动模型中,线速度和角速度会受到机器人底盘构造的约束。实验表明,里程计运动模型虽然仍存在误差,但比速度运动模型要更精确。
图1.1.10 机器人的运动概率模型
同样的道理,机器人上的传感器在测量过程中存在误差,所以测量结果需要用一个概率分布来描述。主要讨论当下最流行的机器人测距仪,即激光扫描测距仪。由测距仪的近似物理模型,可以沿着一个波束测量到附近物体的距离,也就是波束模型。另一种测距仪模型不依赖任何传感器的物理模型,而是将传感器扫描到的终点值映射到地图的全局坐标空间,这就是似然域模型。估计一个测量和地图之间的相关性中,测距仪用到了地图匹配模型。还有一种是从传感器原始测量中提取特征,提取出来的特征我们可以称之为路标,这就是路标模型。
图1.1.11 机器人的测量概率模型
(5)移动机器人定位与建图
图1.1.12 移动机器人定位与建图
在了解了机器人中的状态估计、状态估计的各种概率实现算法、机器人运动与测量概率模型,我们再来重新理解上面这样一个经典的贝叶斯迭代网络,就很好理解了,这个里面包含了机器人定位和建图两大问题。机器人的定位其实就是位姿估计问题,位姿估计的概率实现算法可以有上面提到的EKF、AMCL等算法来实现,由于这两种算法在机器人位姿估计中都很流行,所以就不多展开了。机器人的建图其实就是环境特征估计问题,同样也可以用概率的方法就行估计。
(6)SLAM同时定位与建图
上面已经单独的提出了机器人定位与机器人建图的方法,但是独立的定位问题是建立在地图已知的情况下的,单独的建图问题也是建立在定位已知的情况下的。当机器人不能得到环境地图,也不知道自身位姿的时候,SLAM问题就出现了。也就是说SLAM要同时的进行机器人定位和建图,这个问题比单独的定位和单独的建图都要难得多。
在讨论具体的SLAM算法之前,我们先要了解SLAM的两种主要形式:在线SLAM问题和全SLAM问题。
图1.1.13 在线SLAM问题和全SLAM问题
在线SLAM算法的代表是EKF SLAM,历史上最早并可能是最有影响力的SLAM算法,可以说是SLAM研究的元老级算法。EKF SLAM中的地图是基于特征的,地图由点地标组成。除了估计机器人当前的位姿,EKF SLAM算法还估计路径上遇到的所有地标的坐标,也就是机器人位姿和地图地标点包含进联合状态矢量里,算法对该联合状态矢量进行估计。
图1.1.14 EKF SLAM伪代码实现
全SLAM算法的代表是GraphSLAM,该算法将机器人的运动路径和测量组件成一个软约束的图,利用图论中的优化算法对整个图中的轨迹点和测量点进行估计。由于图的稀疏性特点,可以大大加快计算。
图1.1.15 GraphSLAM伪代码实现
EKF SLAM和GraphSLAM是两个极端。EKF SLAM需要取得每一时刻的信息,把信息分解为概率分布,因此每一步的计算代价都非常昂贵。而GraphSLAM刚好相反,只是简单的积累每一时刻的信息,也就是简单的将收到的信息存储下来,然后可以离线的进行推理的步骤,加之存储下来的信息的稀疏性,因此GraphSLAM计算的开销是比较小的,但是随着地图规模扩大算法会消耗越来越多的内存直至崩溃。面对这两个极端问题,当然就会有介于EKF SLAM和GraphSLAM是两个极端之间的折中的方法,就是SEIF SLAM。SEIF SLAM算法继承了EKF SLAM信息表示的高效性,也保留了GraphSLAM计算代价小的优点,可以说SEIF SLAM是高效和可实现的SLAM算法。还有另外一种高效和可实现的SLAM算法,就是FastSLAM,该算法使用粒子滤波估计机器人的路径,我们都知道粒子滤波和众多基于参数化的滤波算法相比存在计算开销小和便于处理非线性模型的优势,基于FastSLAM的多个变种算法在机器人已经得到广泛的应用了,比如gmapping等等,由于篇幅限制就不展开了。
(7)现今主流的SLAM算法
现今在机器人上使用最广泛的应该算激光SLAM了,在扫地机器人、服务机器人、AGV智能车上普遍搭载了单线激光雷达SLAM算法,像无人驾驶汽车、户外机器人则普遍搭载了多线激光雷达SLAM。另一种热门的研究是视觉SLAM,视觉SLAM有配备单目、双目、深度相机的多种形态,并且根据采用视觉特征点的区别还有直接法、半直接法、稀疏法之分。然后还有就是各种复合式的SLAM算法,比如激光与视觉融合的SLAM、融合了IMU的视觉SLAM。最后,就是一些最新颖的SLAM算法,比如用深度学习来做的端到端的SLAM、基于物体识别的语义SLAM。由于本文的重点不是SLAM综述,所以具体的算法性能比较就不展开了,有兴趣的朋友可以参阅相关SLAM综述文章。
图1.1.16现今主流的SLAM算法
(8)机器人自主导航与动态避障
机器人用SLAM构建出了环境的地图,在已知了环境地图的情况下,可以用SLAM的重定位功能或者单独的基于已知地图的定位算法比如AMCL来进行机器人的定位。环境地图和机器人位姿都有了,就可以开始来做自主导航和避障了。机器人自主导航可以分成两个实现部分,第一个部分就是路径规划,第二个部分就是控制策略。路径规划利用地图信息寻找一条能到达目标的全局路径,全局路径在机器人导航过程中起到全局战略性的指导。理想情况是,机器人完全按照全局路径移动到目标,但是实际环境往往是多变和复杂的,而且机器人实际控制也会存在偏差,所以机器人的实际运动控制需要有一套控制策略来最终实现。控制策略需要尽量逼近全局路径、尽量远离障碍物、最快时间到达目标等因素,这些因素可以用一个回报函数来评价,寻找最佳控制策略的过程中递归的计算每一次行动的回报函数值。这样控制策略在回报函数的指引下,就可以给出最佳的控制策略,控制策略控制机器人完成实际的移动。
图1.1.17 主流路径规划算法
1.2.关于ROS
ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便。
ROS是一个适用于机器人的开源的元操作系统。其实它并不是一个真正的操作系统,其底层的任务调度、编译、寻址等任务还是由Linux操作系统完成,也就是说ROS实际上是运行在Linux上的次级操作系统。但是ROS提供了操作系统应用的各种服务(如:硬件抽象、底层设备控制、常用函数实现、进程间消息传递、软件包管理等),也提供了用于获取、编译、跨平台运行代码的工具和函数。ROS主要采用松耦合点对点进程网络通信,目前主要还是支持Ubuntu系统,windows和Mac OS目前支持的还不好,所以推荐在Ubuntu系统上安装使用ROS。
总结起来就是,使用ROS能够方便迅速的搭建机器人原型。ROS使用了BSD许可证,这是一个很宽松的开放许可证,允许在商业和闭源产品中使用,这一点对开发产品的创业公司很重要。ROS当前的代码统计量,总行数超过1400万,作者超过2477名。代码语言以C++为主,63.98%的代码是用C++编写的,排名第二的是python,占13.57%,可以说ROS基本上都是使用这两种语言,来实现大部分的功能。
图1.2.1 ROS的图标
大家一听到ROS机器人操作系统,就被操作系统几个字给吓到了。其实,ROS就是一个分布式的通信机制,帮助程序进程之间更方便的通信。由于机器人是一个多部件的设备,四肢、视觉、听觉等部位都有配套的程序进行控制,那么要协调这些部位怎么办呢?就需要让这些分散的部位能够互相的通信,这正是ROS被设计的最初目的。随着越来越多的人参与到ROS的开发完善,ROS才发展成今天很完善很系统的样子来,涵盖了大量的第三方工具和大量的实用的开源算法软件包。搞懂了ROS的通信机制后,机器人的各种算法的开发还是基于我们常见的C++和Python的。
节点是主要的计算执行进程,功能包中创建的每个可执行程序在被启动加载到系统进程中后,该进程就是一个ROS节点,node1、node2、node3等都是节点(node)。节点都是各自独立的可执行文件,能够通过主题(topic)、服务(server)或参数服务器(parameter server)与其他节点通信。ROS通过使用节点将代码和功能解耦,提高了系统的容错力和可维护性。所以你最好让每一个节点都具有特定的单一的功能,而不是创建一个包罗万象的大节点。节点如果用c++进行编写,需要用到ROS提供的库roscpp;节点如果用python进行编写,需要用到ROS提供的库rospy。
图1.2.2 ROS网络通信的架构
如果你是刚刚接手ROS方面的开发或项目,你肯定会觉得ROS中的各种概念非常奇怪,但是当你对ROS的使用熟练之后,你就觉得这些概念很好理解了。与其他操作系统相似,一个ROS程序的不同组件要被放在不同的文件夹下,这些文件夹是根据不同的功能来对文件进行组织的。
图1.2.3 ROS程序的组织形式
1.3.SLAM与ROS的关系
SLAM最核心的地方在算法,侧重点在于如何构建出效果好的地图,并为机器人导航提供更好的数据保障。ROS帮忙解决传感器驱动、显示、各种核心算法间的沟通协调问题。如果做商用产品就另当别论了,商业的产品一般会专门开发自己的一套驱动、调度、显示的系统,或者拿ROS系统来裁剪以保障稳定性和效率。