Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
tower1229 opened this issue May 9, 2019 · 0 comments
Open

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

tower1229 opened this issue May 9, 2019 · 0 comments

Comments

@tower1229
Copy link

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

一维定位

原理

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

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

应用

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

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

实现

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

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

太简单了,就不多说了。

二维定位

原理

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

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

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的值,也就是当前点在当前网格中的坐标。

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

//判断三点(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值,就是网格在整个矩阵中的横坐标和纵坐标。

总结

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

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant