MATLAB实现一个EKF-2D-SLAM(已开源)
1. SLAM问题定义
同时定位与建图(SLAM)的本质是一个估计问题,它要求移动机器人利用传感器信息实时地对外界环境结构进行估计,并且估算出自己在这个环境中的位置,Smith 和Cheeseman在上个世纪首次将EKF估计方法应用到SLAM。
以滤波为主的SLAM模型主要包括三个方程:
1)运动方程:它会增加机器人定位的不确定性
2)根据观测对路标初始化的方程:它根据观测信息,对新的状态量初始化。
3)路标状态对观测的投影方程:根据观测信息,对状态更新,纠正,减小不确定度。
2. EKF-SLAM维护的数据地图
系统状态x是一个很大的向量,它包括机器人的状态和路标点的状态,
{\mathcal{R}} \\
{\mathcal{M}}
\end{array}\right]=\left[\begin{array}{c}
{\mathcal{R}} \\
{\mathcal{L}_{1}} \\
{\vdots} \\
{\mathcal{L}_{n}}
\end{array}\right]
\]
其中\({\mathcal{R}}\)是机器人状态,\({\mathcal{M}} = \left({\mathcal{L}_{1}}, \dots,{\mathcal{L}_{n}}\right)\)是n个当前已经观测过的路标点状态集合。
在EKF中,x被认为服从高斯分布,所以,EKF-SLAM的地图被建模为x的均值\(\overline{x}\)与协方差\(\mathbf{P}\),
{\overline{\mathcal{R}}} \\
{\overline{\mathcal{L}}_{1}} \\
{\vdots} \\
{\overline{\mathcal{L}}_{n}}
\end{array}\right] \quad \mathbf{P}=\left[\begin{array}{cc}
{\mathbf{P}_{\mathcal{R} \mathcal{R}}} & {\mathbf{P}_{\mathcal{R} \mathcal{M}}} \\
{\mathbf{P}_{\mathcal{M R}}} & {\mathbf{P}_{\mathcal{M M}}}
\end{array}\right]=\left[\begin{array}{cccc}
{\mathbf{P}_{\mathcal{R R}}} & {\mathbf{P}_{\mathcal{R} \mathcal{L}_{1}}} & {\cdots} & {\mathbf{P}_{\mathcal{R} \mathcal{L}_{n}}} \\
{\mathbf{P}_{\mathcal{L}_{1} \mathcal{R}}} & {\mathbf{P}_{\mathcal{L}_{1} \mathcal{L}_{1}}} & {\cdots} & {\mathbf{P}_{\mathcal{L}_{n}} \mathcal{L}_{n}} \\
{\vdots} & {\vdots} & {\ddots} & {\vdots} \\
{\mathbf{P}_{\mathcal{L}_{n} \mathcal{R}}} & {\mathbf{P}_{\mathcal{L}_{n} \mathcal{L}_{1}}} & {\cdots} & {\mathbf{P}_{\mathcal{L}_{n} \mathcal{L}_{n}}}
\end{array}\right]
\]
因此EKF-SLAM的目标就是根据运动模型和观测模型及时更新地图量\(\left\{\overline{\mathbf{x}},\mathbf{P}\right\}\)
3. EKF-SLAM算法实施
3.1 地图初始化
显而易见,在机器人开始之前是没有任何路标点的信息的,因此此时地图中只有机器人自己的状态信息,因此\({n} = 0,{x} = {\mathcal{R}}\)。SLAM中经常把机器人初始位姿认为是地图的原点,其初始协方差可以按实际情况设定,比如:
{x} \\
{y} \\
{\theta}
\end{array}\right]=\left[\begin{array}{l}
{0} \\
{0} \\
{0}
\end{array}\right] \quad \mathbf{P}=\left[\begin{array}{lll}
{0} & {0} & {0} \\
{0} & {0} & {0} \\
{0} & {0} & {0}
\end{array}\right]
\]
3.2 运动模型
在EKF中如果x是状态量,u是控制输入,n是噪声变量,那么我们可以得到一般的状态更新函数:
\]
EKF的预测步骤为:
{\overline{\mathbf{x}} \leftarrow f(\overline{\mathbf{x}}, \mathbf{u}, 0)} \\
{\mathbf{P} \leftarrow \mathbf{F}_{\mathbf{x}} \mathbf{P} \mathbf{F}_{\mathbf{x}}^{\top}+\mathbf{F}_{\mathbf{n}} \mathbf{N} \mathbf{F}_{\mathbf{n}}^{\top}}
\end{array}
\]
其中雅克比矩阵\(\mathbf{F}_{\mathbf{x}}=\frac{\partial f(\overline{\mathbf{x}}, \mathbf{u})}{\partial \mathbf{x}}\),\(\mathbf{F}_{\mathbf{n}}=\frac{\partial f(\overline{\mathbf{x}}, \mathbf{u})}{\partial \mathbf{n}}\),\({\mathbf{N}}\)是随机变量n的协方差。
但是在EKF-SLAM中,只有一部分状态\({\mathcal{R}}\)是随运动而改变的,其余所有路标状态不改变,所以SLAM的运动方程为:
{\mathcal{R} \leftarrow f_{\mathcal{R}}(\mathcal{R}, \mathbf{u}, \mathbf{n})} \\
{\mathcal{M} \leftarrow \mathcal{M}}
\end{array}
\]
因此我们可以得到稀疏的雅克比矩阵:
{\frac{\partial f_{\mathcal{R}}}{\partial \mathcal{R}}} & {0} \\
{0} & {\mathbf{I}}
\end{array}\right] \quad \mathbf{F}_{\mathbf{n}}=\left[\begin{array}{c}
{\frac{\partial f_{\mathcal{R}}}{\partial \mathbf{n}}} \\
{0}
\end{array}\right]
\]
最终我们得到了用于运动模型的EKF稀疏预测公式
\]
\]
\]
\]
3.3 已经加入地图的状态量观测更新
在EKF中,我们有以下一般的观测方程
\]
其中\(\mathbf{y}\)是测量噪声,\(\mathbf{x}\)是全状态,\(h()\)是观测函数,\(v\)是测量噪声。
典型的EKF观测更新为:
\]
\]
\]
\]
\]
雅克比矩阵\(\mathbf{H}_{\mathbf{x}}=\frac{\partial h(\overline{\mathbf{x}})}{\partial \mathbf{x}}\),\(\mathbf{R}\)是测量噪声的协方差矩阵。
在SLAM中,观测指的是机器人上的传感器观测到某些路标点,并对路标点进行参数化的输出。每次可能对路标点有多个观测值,这里每使用一个观测值,就进行一次状态更新。
观测的结果依赖于机器人的状态\(\mathcal{R}\),传感器的状态\(\mathcal{S}\)和路标点的状态\(\mathcal{L}_{i}\),并且这里假设,传感器的状态与机器人的状态差了一个固定的坐标变化,其实也就是外参固定。当观测到路标点\(i\)时,可以得到如下关系:
\]
这就是观测方程,它不依赖于除了\(\mathcal{L}_{i}\)外的任何路标点状态。因此EKF-SLAM的雅克比\(\mathbf{H}_{\mathbf{x}}\)也是稀疏的:
{\mathbf{H}_{\mathcal{R}}} & {0} & {\cdots} & {0} & {\mathbf{H}_{\mathcal{L}_{i}}} & {0} & {\cdots} & {0}
\end{array}\right]
\]
其中\(\mathbf{H}_{\mathcal{R}}=\frac{\partial h_{i}\left(\overline{\mathcal{R}}, \mathcal{S}, \overline{\mathcal{L}}_{i}\right)}{\partial \mathcal{R}}\),\(\mathbf{H}_{\mathcal{L}_{i}}=\frac{\partial h_{i}\left(\overline{\mathcal{R}}, \mathcal{S}, \overline{\mathcal{L}}_{i}\right)}{\partial \mathcal{L}_{i}}\)。由于这里的稀疏性,EKF-SLAM的观测更新变成:
\]
{\mathbf{P}_{\mathcal{R} \mathcal{R}}} & {\mathbf{P}_{\mathcal{R} \mathcal{L}_{i}}} \\
{\mathbf{P}_{\mathcal{L}_{i} \mathcal{R}}} & {\mathbf{P}_{\mathcal{L}_{i} \mathcal{L}_{i}}}
\end{array}\right]\left[\begin{array}{c}
{\mathbf{H}_{\mathcal{R}}^{\top}} \\
{\mathbf{H}_{\mathcal{L}_{i}}^{\top}}
\end{array}\right]+\mathbf{R}
\]
{\mathbf{P}_{\mathcal{R} \mathcal{R}}} & {\mathbf{P}_{\mathcal{R} \mathcal{L}_{i}}} \\
{\mathbf{P}_{\mathcal{M} \mathcal{R}}} & {\mathbf{P}_{\mathcal{M} \mathcal{L}_{i}}}
\end{array}\right]\left[\begin{array}{l}
{\mathbf{H}_{\mathcal{R}}^{\top}} \\
{\mathbf{H}_{\mathcal{L}_{i}}^{\top}}
\end{array}\right] \mathbf{Z}^{-1}
\]
\]
\]
3.4 观测方程可逆时的状态增广
这里的状态增广指的是新发现的路标点的初始化。当机器人发现了曾经未观测到的路标点时,会利用观测方程将新的路标状态加入地图,这一步操作会增大总状态向量的大小。可以看到EKF-SLAM中的滤波器大小动态变化的。
当传感器信息可以提供新发现路标点的所有自由度,也就是观测方程是双射时,只需要根据观测方程\(h()\)的逆运算,即可以得到机器人状态\(\mathcal{R}\),传感器状态\(\mathcal{S}\),观测量\(\mathbf{y}_{n+1}\),观测噪声\(v\),它们与新路标点状态的关系:
\]
上式是单个路标点的逆观测模型。
路标点的均值和雅克比:
\]
\]
\]
显然,新加路标点状态的协方差\(\mathbf{P}_{\mathcal{L} \mathcal{L}}\),以及该状态与地图其它状态的互协方差为:
\]
\]
然后将这些结果加入到地图中,可以得到总状态的均值与协方差矩阵:
\left[\begin{array}{c}
{\overline{\mathbf{x}}} \\
{\overline{\mathcal{L}}_{n+1}}
\end{array}\right]
\]
{\mathbf{P}} & {\mathbf{P}_{\mathcal{L} \mathbf{x}}^{\top}} \\
{\mathbf{P}_{\mathcal{L}\mathbf{x}}} & {\mathbf{P}_{\mathcal{L}\mathcal{L}}}
\end{array}\right]
\]
4. 仿真实验
4.1 模型设置
4.1.1 传感器模型
传感器是一个360度的雷达,可以探测发现周围一定范围内的路标点及其类型,其探测半径为r,其观测值为(\(\xi\),s)。\(\xi\)为在当前雷达坐标系中路标点与x轴的的夹角,s为路标点与当前雷达坐标系原点的距离。
4.1.2 运动模型
将当前时刻雷达局部坐标系中的(\({u}_{1}\),0)点作为下一时刻雷达的位置,所以运动方程可以设为:
{x_{n}} \\
{y_{n}}
\end{array}
\right] =
\left[\begin{array}{cc}
cos\theta_{n-1} & -sin\theta_{n-1} \\
sin\theta_{n-1} & cos\theta_{n-1}
\end{array}\right]
\left[\begin{array}{cc}
{u}_{1} \\
0
\end{array}\right] +
\left[\begin{array}{cc}
{x_{n-1}} \\
{y_{n-1}}
\end{array}
\right] +
\left[\begin{array}{cc}
{n}_{1} \\
0
\end{array}
\right]
\]
其方位每次增加固定的\(u_2\):
\]
其中\(n_1,n_2\)为系统噪声。
4.1.3 观测模型
设路标点\(i\)的状态为\(x_{L_i}=\)(\(m_1\),\({m}_{2}\)),则其在当前雷达坐标系的坐标为:
{{{ladar}_{1}}} \\
{{{ladar}_{2}}}
\end{array}
\right] =
{\left[\begin{array}{cc}
cos\theta_n & -sin\theta_n \\
sin\theta_n & cos\theta_n
\end{array}\right]}^{-1}
\left[\begin{array}{cc}
{{{m}_{1}}} \\
{{{m}_{2}}}
\end{array}
\right] -
\left[\begin{array}{cc}
{x_n} \\
{y_n}
\end{array}
\right]
\]
则观测量为:
\]
\]
其中\(v_1,v_2\)为测量噪声。
4.2 实验结果
使用MATLAB编写程序进行仿真。
代码地址:https://github.com/liuzhenboo/EKF-2D-SLAM
4.2.1 第一次状态增广
其中左图黑色的点表示滤波器新加入的路标点状态均值,绿色椭圆表征路标状态的协方差,其椭圆方程为:
\]
其中x为路标状态, P为路标的协方差。
程序中是对P进行SVD分解,得到椭圆的方向R以及半轴到的长度,进行绘图。
4.2.2 状态增广,观测更新
如上图,黑色椭圆对应的路标点表示雷达曾经观测过它,但是当前时刻没有观测到;红色椭圆对应的路标点表示雷达曾经观测过它,并且当前时刻也观测到了;蓝色代表当前刚刚初始化的新路标点。
注意:由于数值计算的原因,图中几何元素的位置关系可能和实际有些许差别;比如有的路标点明明不在雷达范围内,却开始初始化(绿色),这是因为计算过程中matlab四舍五入导致的结果。
4.2.3 状态不再增广,只有观测更新
如上图,不再存在蓝色的协方差椭圆,代表状态增广停止,滤波器的大小不再改变。
MATLAB实现一个EKF-2D-SLAM(已开源)的更多相关文章
- 我用 go-zero 一周实现了一个中台系统,已开源!
作者:Jack 最近发现golang社区里出了一个新星的微服务框架,来自好未来,光看这个名字,就很有奔头,之前,也只是玩过go-micro,其实真正的还没有在项目中运用过,只是觉得 微服务,grpc ...
- [已开源/文章教程]独立开发 一个社交 APP 的源码/架构分享 (已上架)
0x00 背景 真不是和被推荐了2天的博客园一位大神较真,从他那篇文章的索引式文章内容也学习到了很多东西,看评论区那么多对社交APP源码有兴趣的,正巧我上周把我的一个社交APP开源了,包括androi ...
- [转]Infobright是一个与MySQL集成的开源数据仓库
[文章作者:张宴 本文版本:v1.1 最后修改:2010.05.18 转载请注明原文链接:http://blog.zyan.cc/infobright/] Infobright是一个与MySQL集成的 ...
- 打造一个高逼格的android开源项目——小白全攻略 (转)
转自:打造一个高逼格的android开源项目 小引子 在平时的开发过程中,我们经常会查阅很多的资料,最常参考的是 github 的开源项目.通常在项目的主页面能看到项目的简介和基本使用,并且时不时能看 ...
- 自写的开发框架,胜于官方的clientAPP的实战开发。(已开源)
已开源,欢迎大家fork 小弟github地址为https://github.com/10045125/vanda 好久没写博客了,这段时间主要是要做的事情太多.如今接触android有段时间了.非常 ...
- c#与JAVA利用SOCKET实现异步通信的SanNiuSignal.DLL已开源
大家好,前段时间C#的SanNiuSignal.DLL已开源;因部分用户特需要JAVA版的SanNiuSignal;现在只能把半成品先拿出来暂时给他们用了,以后再慢慢改进; JAVA版目前已实现跟C# ...
- 基于Web的CAD一张图协同在线制图更新轻量级解决方案[示例已开源]
背景 之前相关的博文中介绍了如果在Web网页端展示CAD图形(唯杰地图云端图纸管理平台 https://vjmap.com/app/cloud),有不少朋友问,能不能实现一个协同的功能,实现不同部门不 ...
- 记录一次MVC 3.0错误 HTTP 404您正在查找的资源(或者它的一个依赖项)可能已被移除,或其名称已更改,或暂时不可用。请检查以下 URL 并确保其拼写正确。
在部署到IIS7时,MVC3报了一个找不到资源的错误,文件肯定是有的,而且页面是肯定报错的,也就说内部运行错误了,而MVC把错误没有抛出来而已: 所以对症下药,发觉我的项目里面用了rexs进行多语言, ...
- 利用Matlab生成一个网格化的三维球面(生成直角坐标)
利用Matlab生成一个网格化的三维球面,分别对径向方向.经度方向和纬度方向进行网格化,代码如下: %生成一个笛卡尔坐标系下球面网格的x,y,z坐标 %r为球面距离 %nJingdu,nWeidu分别 ...
- MVC 3.0错误 HTTP 404您正在查找的资源(或者它的一个依赖项)可能已被移除,或其名称已更改,或暂时不可用。请检查以下 URL 并确保其拼写正确。
MVC3.0框架开发项目: 有时在程序运行的时候会出现“HTTP 404.您正在查找的资源(或者它的一个依赖项)可能已被移除,或其名称已更改,或暂时不可用.请检查以下 URL 并确保其拼写正确.”的错 ...
随机推荐
- OpenCV3入门(十四)图像特效—挤压、哈哈镜、扭曲
一.图像挤压特效 1.原理 图像压效果本质的图像坐标的非线性变换,将图像向内挤压,挤压的过程产生压缩变形,从而形成的效果. 挤压效果的实现是通过极坐标的形式,设图像中心为O(x,y),某点距离中心O的 ...
- Python 装饰器(无参,有参、多重))
Python装饰器介绍 在Python中,装饰器(decorator)是在闭包的基础上发展起来的. 装饰器的实质是一个高阶函数,其参数是要装饰的函数名,其返回值是完成装饰的函数名,其作用是为已经存在的 ...
- 手写redux方法以及数组reduce方法
reduce能做什么? 1)求和 2)计算价格 3)合并数据 4)redux的compose方法 这篇文章主要内容是什么? 1)介绍reduce的主要作用 2)手写实现reduce方法 0)了解red ...
- java web 中base64传输的坑
今天在项目中,前端需要向后端发送一张图片,使用toDataURL方法以base64编码的形式传输,在写好程序后,发现报错为base64不是有效的图片,反复排查后发现接口需要一张格式为png的图片,在前 ...
- 从零开始学习R语言(四)——数据结构之“数组(Array)”
本文首发于知乎专栏:https://zhuanlan.zhihu.com/p/60141207 也同步更新于我的个人博客:https://www.cnblogs.com/nickwu/p/125677 ...
- Diagnostics: File file:/private/tmp/spark-d4ebd819-e623-47c3-b008-2a4df8019758/__spark_libs__6824092999244734377.zip does not exist java.io.FileNotFoundException: File file:/private/tmp/spark-d4ebd819
spark伪分布式模式 on-yarn出现一下错误 Diagnostics: File file:/private/tmp/spark-d4ebd819-e623-47c3-b008-2a4df801 ...
- [JVM教程与调优] JVM都有哪些参数类型?
JDK本身是提供了一些监控工具,有一些是命令行,也有图形界面.本次介绍命令行如何进行监控. 命令行是非常重要的,因为在我们生产环境基本上是没有图形界面的,完全是通过命令行. 主要内容: JVM的参数类 ...
- 家乐的深度学习笔记「4」 - softmax回归
目录 softmax回归 分类问题 softmax回归模型 softmax运算 矢量表达式 单样本分类的矢量计算表达式 小批量样本分类的矢量计算表达式 交叉熵损失函数 模型预测及评价 图像分类数据集( ...
- [SQL]CASE WHEN的用法及总结
CASE WHEN的用法及总结 一.已知数据按照另外一种方式进行分组,分析 二.用一个SQL语句完成不同条件的分组 三.在Check中使用Case函数 四.根据条件有选择的UPDATE 五.两个表数据 ...
- 130ftp-python3 FTP简单实现文件下载(含中文乱码问题)
130ftp-python3 FTP简单实现文件下载(含中文乱码问题) python3 FTP简单实现文件下载(含中文乱码问题) ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...