前言
IBeacon是苹果推出的低能耗蓝牙技术。蓝牙设备发射包含指定信息的信号,然后移动设备接收信号,从而实现近场通信。微信小程序从2017年开始支持iBeacon,基于iBeacon实现了附近的抖音。此外,iBeacon还可以实现测距。本文将介绍如何基于微信小程序实现iBeacon测距。
伊贝康测距原理
蓝牙信标发射的信号强度(rssi)在一定程度上与收发设备之间的距离正相关。因此,蓝牙信标和接收设备之间的距离可以通过合理的计算和转换从rssi值中推导出来。
蓝牙信标的Rssi值是一个参考值,没有固定的标准。要计算蓝牙信标的距离,还必须知道这个信标设备的txPower值。TxPower指的是距离蓝牙信标1米时的rssi值。不同的蓝牙设备或同一设备的不同工作条件甚至不同的站点环境都会影响txPower值。因此,这个值虽然可以测量,但在一定程度上是经验值,无法准确测量。
Rssi测距公式
知道rssi和txPower后就可以计算距离了。有两个计算公式:
一个,
这个公式中的三个变量A、B、C都是经验值,需要根据手机系统或硬件型号进行精确调整。通常,所有设备的校准结果都保存为设备信息表。移动终端首先检测手机的型号,然后匹配设备信息得到相应的计算配置,然后进行计算。很明显,这个公式依赖于硬件调整,没有数据储备就很难使用。
转换为js代码:
常量计算精度=函数(发射功率,RSSI){返回(0.89976) *数学.功率(RSSI/发射功率,7.7095) 0.111}无精细校准的测距性能:
首先,你觉得这幅画怎么样?
纵轴代表测量距离,横轴代表时间,每隔一秒采样一次。图为近10个样品的数值曲线。绿线是设备收到的rssi值,反映硬件收到的实际数据;红线是应用公式计算的瞬时距离;黄线是微信小程序的即时测距结果。蓝牙信标与手机的实际距离为1m,测试设备为Redmi Note7。
从上图可以看出,rssi值比较稳定,说明硬件没有太大问题。红线和黄线波动很大,说明精度不太好。两者的波动趋势几乎一致,因此有理由怀疑微信小程序中也使用了这个测距公式。从结果来看,这个公式的准确性相对较差,这可能是由于缺乏精确的校准。
第二,
在这个公式中,a是rssi,tx是txPower,n是经验值,n的值与物理环境有关。
常量计算精度=函数(发射功率,RSSI){返回math.pow (10,math . ABS(RSSI-发射功率)/(10 * 4))}公式2的测距性能:
人比人死,货比货扔。
图中黄线仍在剧烈波动,但红线极其稳定,显示出与绿线相同的波动范围,说明测距精度可靠。这个公式只有一个参数,在生产环境中调整比较简单。这里我们选择公式2作为测距公式。
IBeacon测距稳定性计划
蓝牙信号本身具有波动性,现实环境中的很多因素也会影响信号强度,比如物体遮挡、设备方向改变、硬件稳定性等。因此,接收设备检测到的rssi值通常是“跳跃”的,直接由测距公式计算出来的结果往往不可用。需要实现一个稳定的程序,使计算结果显示出连续性和稳定性。
数据过滤
稳定程序的主要任务是“削峰填谷”波段数据,也可以称为数据过滤。最简单的过滤过程是收集一段时间内的值并取平均值。只要硬件没有问题,rssi v
//seek数组average const arrayaverage=arr=arr . reduce((ACC,val)=accval,0)/arr . length;返回数组平均值的具体实现([.】)就是当程序连续接收信标的rssi时,用公式计算瞬时测距结果,然后将结果存储在一个数组中,再计算这个数组的平均值。在静态测距中,测量结果非常准确,2m范围内的距离误差可低至0.1m。
在实际应用中,经常会用到动态测距,所以采样数据的长度要有所限制,比如最后10组数据要按照后进先出的顺序取。采样队列设置多长取决于项目的实际需要。采样队列越长,测距结果越平滑,但移动终端动态捕获越慢;相反,采样队列越短,结果越清晰,对移动终端的动态捕获越敏感。
有时由于一些偶然因素,采样队列中会出现一些与真实值偏差较大的“噪声”数据。即使平均,也很难有效抹去影响。为了消除这种影响,可以采用高斯模糊算法对取平均值前的“大值”和“小值”进行平滑处理,从而将数据噪声的干扰降到最低。
高斯模糊算法的关键是根据平均差计算权重,一维高斯模糊的权重计算公式如下:
转换为js代码:
//求高斯模糊权重@param(队列长度、目标位置、平均差值)const getonegualenterray=function(size,Kerr,sigma) {if (size% 20) {size-=1} if(!size){ return[]} if(KERR size-1){ return[]}让sum=0;让arr=新数组(大小);for(设I=0;一、尺寸;I){ arr[I]=math . exp(-((I-KERR)*(I-KERR))/(2 * sigma * sigma));sum=arr[I];} return arr . map(e=e/sum);}下面将介绍“大值”和“小值”的概念,所以我们只需要知道我们的模糊目标是那些“极端数据”。
时间加权
基于采样队列的平均处理方法不可避免地会导致结果的滞后,因此可以引入时间加权补偿算法。
所谓时间加权,是指在求平均值时,给更接近当前时间的值赋予更高的计算权重,而给更远离当前时间的值赋予更低的计算权重,实现起来也非常简单。
以最简单的权重分配为例,将采样队列一分为二,按照时间的距离将其定位为“当前组”和“过去组”。例如,如果我希望当前组的权重是过去组的两倍,我只需要复制当前组的所有数据并加入队列,然后计算新队列的平均值。
//时间加权处理队列=queue.slice (0,par sent(queue . length/2))。concat(队列)//平均返回arrayAverage(队列)动态跟进
经过时间加权处理后,数据的滞后性会得到一定的抑制,但如果距离变化剧烈,这种处理仍然会给出相对平滑的反馈。为了使稳定的程序更好地感知动态变化并做出后续响应,需要人为设置一些特殊条件。
首先,如何判断移动设备是在远离还是靠近?
这里有一个简单的思路,可以先找出采样队列中的最大值和最小值,然后找出有一定阈值的大小值。例如,如果队列中的最大值为3,最小值为1,阈值设置为0.1m,那么大于2.9m的数据将被视为过大,小于1.1m的数据将被视为过小。大值和小值的队列长度最长不得超过总队列的一半。
那么,如果大值集中在队列的前三分之一,那么我们可以认为移动设备正在果断地离开;相反,如果小值集中在队列的前三分之一,则可以认为移动设备正在靠近。
//maxCount是取值较大的序列号数组//minCount是取值较小的序列号数组//queueLength是队列长度if(array average(maxCount)par sent(queueLength/3)){ console . log(` move away `)} Elseif(array average(minCount)par sent(queue length/3)){ console . log(` approach `)}基于这种移远移近的趋势判断,我们可以人为地将数据更激进地向移动方向倾斜。怎么做?跳过时间加权逻辑,如果判断为正在远离,则过滤掉队列中的小值,否则过滤掉大值,只计算剩余数据;这种处理会得到一个明显激进的结果,但考虑到现实世界中的运动往往具有惯性,这种激进的处理可能更适合真实的运动情况,使数据响应更加“敏感”。
效果测试
目前效果如何?直接看图。
下图中,绿线仍为rssi值,红线为直接根据rssi计算的瞬时测距结果,黄线为加入稳定程序后的测距结果。
第一张图片是一个相对静止的状态。可以看出,黄线明显比红线更稳定,说明稳定方案依然有效。
第二张图模拟了快速移动离开的场景。可以看出,黄线在保证稳定的前提下跟随红线,并没有被甩,这主要反映了稳定方案的动态跟进效果。
第三张图是摆臂甩手机遮挡信号模拟的场景。看来稳定的程序受不了,有点飘忽不定。
以上是关于稳定计划实施的简要想法。生产环境肯定会面临更复杂的情况,做大量的调试是不可避免的。
摘要
蓝牙测距只是一个公式的应用,本身比较简单。基于测距,可以实现许多近场应用,如近场签到、近场推送等。甚至可以实现移动设备的定位。有了定位信息,可以实现许多与室内定位和室内导航相关的应用。
以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。