热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

室内定位——卡尔曼滤波原理、Matlab与javascript实现

前言:在基于Beacon的室内定位中,由于获取的RSSI值中含有大量噪声,故对RSSI值进行去噪是非常有必要的。1.卡尔曼滤波࿰

  前言:在基于Beacon的室内定位中,由于获取的RSSI值中含有大量噪声,故对RSSI值进行去噪是非常有必要的。

  1.卡尔曼滤波(Kalman Filter, KF)简介

  卡尔曼滤波(Kalman Filter, KF)算法是1960年美国科学家卡尔曼提出的一种线性最小方差统计估算方法,卡尔曼滤波器适用于对时变信号的实时处理(RSSI值就是一种时变的信号)。Kalman滤波是目前应用最为广泛的滤波方法,在通信,导航,制导与控制等多领域得到了较好的应用。

  2.卡尔曼滤波原理

  作为一个卡尔曼滤波的小白,我在查阅关于卡尔曼滤波的相关资料时发现很多优秀且通熟易懂的文章,如果你想弄懂卡尔曼滤波的原理强烈推荐下面两篇文章,我自己就不赘述了。

  (1). 【传感器融合】扩展卡尔曼滤波的逐步理解与实现(上)
  (2) 扩展卡尔曼滤波新手教程(一)----中文版

  如果你不想看复杂的原理推导,想直接上手的话,可以看下面两篇文章。

   (1). 卡尔曼(Kalman)滤波算法原理、C语言实现及实际应用这篇文章中包含有C语言代码。
   (2). 卡尔曼滤波的简单实现(Matlab & OC)这篇文章中包含了Matlab代码。

  3.卡尔曼滤波(一维)Matlab实现

  我利用手机在距离id为AC:23:3F:20:D3:75的Beacon 1米处和2米处各采集了50组RSSI值,其中前50组是距离1米处,后50组是距离2米处。
  (1)首先在Matlab中创建名为kalman_filter_1mand2m_75_50.m的文件,代码如下:

% kalman_filter_1mand2m_75_50.m
% AC:23:3F:20:D3:751m和2m处各获取50个rssi值
clear;
data = [-57,-55,-59,-58,-68,-56,-55,-59,-70,-68,-59,-55,-57,-68,-55,-58,-55,-68,-69,-56,-57,-69,-68,-55,-58,-67,-66,-55,-67,-54,-55,-58,-67,-68,-55,-57,-67,-54,-57,-65,-69,-58,-68,-66,-54,-55,-57,-58,-66,-65,-70,-73,-74,-94,-77,-76,-75,-72,-73,-69,-70,-83,-74,-84,-73,-78,-71,-83,-80,-72,-75,-74,-73,-71,-76,-74,-70,-75,-70,-76,-74,-72,-74,-76,-70,-76,-69,-82,-78,-76,-75,-70,-73,-72,-70,-71,-68,-74,-72,-68];
%调用kalman_filter函数对data中的RSSI值进行滤波
%我这里选择的Q0.000001,R0.0001,初始的最佳估计值x0为-61,P1
%注:其中QR可以根据自己获取的RSSI值不断进行调整,通过不断试验找到RSSI值滤波后拟合最好的QR,而P的初始值则不能设置为0,x0和P的初值是可以随便设的,强大的卡尔曼滤波器马上就能抹除不合理之处。
result = kalman_filter(data,0.000001,0.0001,-61,1);
i = 1:length(data);
plot(i,data,'bo--',i,result,'r*-');
disp(result);
legend('信号测量值','卡尔曼滤波后','Location','northwest')
xlabel('采集序号')
ylabel('RSSI值/dBm')

  (2)其次在Matlab中创建名为kalman_filter.m的文件,即写上面的kalman_filter()函数的代码,代码如下:

% kalman_filter.m
%获取传过来的RSSI值
function X = kalman_filter(data,Q,R,x0,P0)N = length(data);
K = zeros(N,1);
X = zeros(N,1);
P = zeros(N,1);X(1) = x0;
P(1) = P0;for i = 2:N%k为卡尔曼增益K(i) = P(i-1) / (P(i-1) + R);%x(i)为i时刻的最优估计值,data(i)为i时刻的测量值X(i) = X(i-1) + K(i) * (data(i) - X(i-1));%P(i)为i时刻的最优协方差误差P(i) = P(i-1) - K(i) * P(i-1) + Q;
end

  (3)最后在Matlab中的kalman_filter_1mand2m_75_50.m中执行,就得到如下效果,卡尔曼滤波后的RSSI值拟合效果较好:在这里插入图片描述

  3.卡尔曼滤波(一维)Javascript实现

  我在做基于Beacon的室内定位时是基于微信小程序的,故以下js代码是在微信小程序中的js中写的。在实际应用中,RSSI值是一个时变的信号,卡尔曼滤波是对时变信号进行处理,所以不可能像Matlab中代码一样先把所有的RSSI值获取放在数组中,再对其进行滤波。下面的代码涉及到三个js代码页面,index.js是专门获取RSSI值的(如果不会可以看我的这篇文章室内定位——如何在微信小程序中获取Beacon的RSSI值),position.js是用来进行室内定位的,还有App.js。
  (1)首先在App.js中设置全局变量:

//app.js
App({globalData: {//从index.js中获取的实时Beacon的rssi值BeaconInfo:[],//k-1时刻的系统协方差last_p:1,//k时刻系统估算协方差now_p:0,//卡尔曼增益k:0,//k时刻状态变量的最优值,即滤波后的值,初始值设置为-61out:-61,//过程噪声协方差Q:0.000001,//观测噪声协方差R:0.0001,}})

  (2)然后在positon.js中写一个卡尔曼滤波函数:

//卡尔曼滤波器KalmanFilter: function (rssi) {//预测协方差方程:k时刻系统估算协方差 = k-1时刻的系统协方差 + 过程噪声协方差app.globalData.now_p = app.globalData.last_p + app.globalData.Q;//卡尔曼增益方程:卡尔曼增益=k时刻系统估算协方差/(k时刻系统估算协方差+观测噪声协方差)app.globalData.k = app.globalData.now_p / (app.globalData.now_p + app.globalData.R);//更新最优值方程:k时刻状态变量的最优值=状态变量的预测值+卡尔曼增益*(测量值-状态变量的预测值)app.globalData.out = app.globalData.out + app.globalData.k * (rssi - app.globalData.out);//更新协方差方程:本次的系统协方差付给lastp为下一次运算准备app.globalData.last_p = (1 - app.globalData.k) * app.globalData.now_p;return app.globalData.out;},

  (3)在positon.js的中写一个执行卡尔曼滤波函数:

//卡尔曼滤波执行函数
exKalmanfilter:function(){var that=this;//用来获取卡尔曼滤波前的RSSI值var RSSI=0;//卡尔曼滤波后的RSSI值var FilterRssi=0;//获取从index.js中传来的第一Beacon的RSSI值RSSI = app.globalData.BeaconInfo[0].rssis;//将RSSI传入 卡尔曼滤波函数中进行滤波FilterRssi = this.KalmanFilter(RSSI);console.log(FilterRssi);
},

  (4)最后在positon.js中的onLoad函数中执行并隔1秒中刷新一次,实时对RSSI进行卡尔曼滤波:

/*** 生命周期函数--监听页面加载*/onLoad: function (options) {setInterval(this.exKalmanfilter, 1000);},

  4.总结

  由于本人水平有限,故只做了一维的卡尔曼滤波的代码实现。如果上面中有什么错误或者您有什么更好的实现方法,欢迎您批评指正和评论交流。最后我也非常感谢上面我提到的四篇优秀的文章的作者,感谢他们的分享!


推荐阅读
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 本文介绍了在Win10上安装WinPythonHadoop的详细步骤,包括安装Python环境、安装JDK8、安装pyspark、安装Hadoop和Spark、设置环境变量、下载winutils.exe等。同时提醒注意Hadoop版本与pyspark版本的一致性,并建议重启电脑以确保安装成功。 ... [详细]
  • 判断数组是否全为0_连续子数组的最大和的解题思路及代码方法一_动态规划
    本文介绍了判断数组是否全为0以及求解连续子数组的最大和的解题思路及代码方法一,即动态规划。通过动态规划的方法,可以找出连续子数组的最大和,具体思路是尽量选择正数的部分,遇到负数则不选择进去,遇到正数则保留并继续考察。本文给出了状态定义和状态转移方程,并提供了具体的代码实现。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 本文介绍了Java数组的定义、初始化和多维数组的用法。通过动态初始化和静态初始化两种方式来初始化数组,并讨论了数组的内存分配和下标的特点。同时详细介绍了Java二维数组的概念和使用方法。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • Go语言实现堆排序的详细教程
    本文主要介绍了Go语言实现堆排序的详细教程,包括大根堆的定义和完全二叉树的概念。通过图解和算法描述,详细介绍了堆排序的实现过程。堆排序是一种效率很高的排序算法,时间复杂度为O(nlgn)。阅读本文大约需要15分钟。 ... [详细]
author-avatar
杨兰波欣
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有