iBeacon蓝牙定位技术原理及实现

蓝牙定位是iBeacon技术最常被应用的方向之一,基于蓝牙定位可以实现诸如寻路、寻车、向导等很多商业需求,觅迹导航的定位系统也是基于iBeacon技术实现的。蓝牙定位又可以分为一维定位和二维定位,本文将介绍两种蓝牙定位技术的实现原理及实现方法。

一维定位

原理

蓝牙定位的底层技术是蓝牙测距,关于蓝牙测距在《微信小程序iBeacon测距及稳定程序的实现》一文中已经做了详细介绍,这里不再赘述。

所谓一维定位其实就是对蓝牙测距技术的最简单应用,只要将蓝牙信标设备部署在指定点,当接收设备(手机)足够靠近信标时,就认为用户到达了指定点。之所以称之为一维定位,是因为定位结果完全依附于信标设备的位置,没有任何其他维度上的扩展。

应用

这种方式通常用在固定路线的沿途部署,为路线上的用户提供定位信息。

优点是部署成本和开发成本很低,缺点是只能应用在路线固定,并且定位点间隔不太密集的场景。典型的例子就是景区或者园区,景区内的路径都是经过设计的,固定而且几乎唯一;景点之间的距离也不会很近,至少在50m以上的间距。只要沿途以大致固定的间距部署信标设备,就可以为用户提供相对实时而且准确的定位信息。

实现

一维定位的部署非常简单,如上文所述,只要确定好信标设备的有效覆盖范围,然后沿途部署就可以。部署同时收集每个或部分信标设备的位置信息,作为程序的定位检索依据。

开发方面,移动设备只要将收到的信号做距离排序,找到距离最近的一个信标设备,如果距离在指定范围内,就检索该设备的位置信息,认为用户到达了该地区。

太简单了,就不多说了。

二维定位

原理

二维定位顾名思义,就是可以实现二维空间中的任意定位。定位的主要理论依据三角形三边关系公式。

如上图,已知三角形三边长度,CD是底边AB的垂线,AD和BD的长度计算公式分别为

1
2
BD = (AB2+CB2-AC2)÷2AB
AD = (AB2-CB2+AC2)÷2AB

整体思路是,将信标设备在场地内按指定间距做网状部署,使用户在场地内任意点都可以接收到3个距离最近而且连线构成直角的定位点信息,如下图

通过三角形三边关系公式,可以计算出上图中px和py的长度,也就是当前点在当前正方形网格中的坐标。

再根据当前所在正方形在整个矩阵中的位置,结合部署间距,算出当前点在整个矩阵中的坐标。

应用

二维定位理论上适用于任何场景,通常用在用户活动路径不固定的自由空间中,比如展会、商场。

优点是场地适应性更强,缺点是部署成本和开发成本相对较高。以商场为例,严格按照固定间距部署蓝牙信标,往往需要结合实地情况选择合适的距离,程序也要根据实际间距做相应的计算调整。另外还要考虑不规则区域的处理,往往会将一维定位和二维定位结合使用。

实现

上面原理部分说起来有点啰嗦,看图其实很简单。

假设现在有一个30m * 30m的场地,将信标设备以10m为间距网状部署,共需要16个信标,每个信标都按下图所示标注上坐标信息

此时用户无论在场地内的任何位置,都将身处9个正方形网格中的一个(暂不考虑临界情况),那么移动设备收到的距离最近的4个信标点,应该就是当前所在正方形的4个顶点。

假设当前用户此时在左上角第一个正方形中,根据蓝牙测距结果,得到距离最近的3个信标点,对应的距离分别为distance1, distance2, distance3,如图

三个顶点距离已知,部署间距已知,根据三边关系公式可以得px, py的值,也就是当前点在当前网格中的坐标。

在这之前先要解决一个问题,那就是三个点之间的关系。我们知道三个点肯定两两连线互为直角,但到底哪两个点在横轴上,哪两个点在纵轴上。这需要结合点的坐标信息做进一步处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//判断三点(points)的关系
let xAxisPoints = [];
let yAxisPoints = [];
for (let i = 0; i < points.length; i++) {
let point = points[i];
//找到Y轴点
let xNO = point.x;
let yPoints = points.filter(e => e.x === xNO)
if (yPoints.length >= 2) {
yAxisPoints = yPoints.sort((a, b) => a.y - b.y)
if (xAxisPoints.length) {
break;
}
}
//找到X轴点
let yNO = point.y;
let xPoints = points.filter(e => e.y === yNO)
if (xPoints.length >= 2) {
xAxisPoints = xPoints.sort((a, b) => a.x - b.x)
if (yAxisPoints.length) {
break;
}
}
}

至此,就很容易算出定位点的横轴坐标和纵轴坐标了,再分别加上当前网格在整个矩阵中的横坐标和纵坐标,就得到了最终的定位坐标。

上例中的xAxisPointsyAxisPoints已经对坐标信息做了排序,横轴数组第一个点的x值,以及纵轴数组第一个点的y值,就是网格在整个矩阵中的横坐标和纵坐标。

总结

一维定位和二维定位分别有各自的应用场景,其中二维定位对实施能力提出了较高的要求。现实环境中往往还需要将一维定位和二维定位结合使用,这里需要程序设计上处理好两种情况的兼容。

得到定位信息,往往只是项目的第一步。比如在导航系统中,定位信息需要匹配最近的目标点,整个导航功能才可以开始使用。有机会后面会对导航系统的实现,做进一步的分享。

前端路上原创技术文章,转载请注明出处:https://refined-x.com/2019/04/01/IBeacon-Location-Technology/

看风景-公众号

不甘平庸的你,快来跟我一起充电吧,关注看风景,获取更多精彩内容。