建设网站的公司专业服务,html5移动端网站开发,在哪里做网站设计,做百度网站需不需要备案室内定位技术的商业化必将带来一波创新高潮#xff0c;尤其是在O2O领域#xff0c;各种基于此技术的应用将出现在我们的面前。我们可以想象一些比较常见的应用场景#xff0c;比如在大型商场里面借助室内导航快速找到目标商铺#xff0c;商店根据用户的具体位置向用户推送更… 室内定位技术的商业化必将带来一波创新高潮尤其是在O2O领域各种基于此技术的应用将出现在我们的面前。我们可以想象一些比较常见的应用场景比如在大型商场里面借助室内导航快速找到目标商铺商店根据用户的具体位置向用户推送更多关于商品的介绍等等这些应用会极好的服务于O2O提高用户体验。 目前室内定位技术有很多如A-GPS、蓝牙、超声红外、信标、射频、Wi-Fi、计算机视觉等这些技术综合比较其中以基于Wi-Fi的室内定位技术最为突出无论从硬件投入、软件投入、实施难度、可控性还是定位效果方面考察都是有优势的。 本文描述了作者在美团总部从零开始构建基于Wi-Fi的室内定位系统的过程具有广泛的借鉴意义。 基于Wi-Fi的室内定位原理 为提供Wi-Fi服务室内会部署有热点AP每一个无线AP都有一个全球唯一的MAC地址,并且一般来说无线AP在一段时间内是不会改变的。设备可以程序控制扫描并收集周围的AP信号无论是否加密是否已连接甚至信号强度不足以显示在无线信号列表中,都可以获取到AP广播出来的MAC地址。对应每个AP这里有两个重要数据AP的MAC地址和信号强度MAC地址可以决定是哪个AP信号强度理论上是和AP之间的距离有函数关系的就是根据信号强度可以算出和AP的距离。设备将这些数据发送到位置服务器服务器就可以用一个算法计算出设备的地理位置并返回到用户设备。定位的精度取决于AP的个数信号的稳定程度以及算法的选择。美团总部Wi-Fi部署情况 美团总部于2014年1月搬入了望京科技园3期新的办公室地上共4层建筑面积一万多平米共部署有86台无线AP覆盖很充分没有死角这为良好的定位效果打下了基础。 无线AP使用的是ArubA AP-135这是一款优秀的商用无线路由器2.4-GHz/5-GHz双频。 基础数据测绘 第一步建立AP的基础数据库是关键至少需要如下信息 AP的MAC地址这里是双频的AP就是有2个无线MAC地址AP的物理位置关于AP的物理位置这里因为范围太小加之无法找到足够精度的参考点所以AP的物理位置无法使用GPS坐标只能使用自定义坐标系。 这里有2种选择 以建筑的东南角为参考点坐标原点这样就可以测绘AP相对原点的坐标包含Z轴单位是米以测绘图的图片为参考以AP在图中的像素位置为坐标单位是1像素点这里选用了后一种方法因为后一种方法容易测绘大部分工作在电脑上操作即可前一种方法需要更多的实地测绘工作。 关于AP的MAC地址从IT那里要到了一个列表如图所示 但是很不幸这里的MAC地址是路由器的WAN口的MAC地址而我们需要的是两个无线模块的MAC地址。 这里只能自己测绘了我写了一小段android程序可以排序出最近的AP的MAC地址然后挨个跑到各个AP下运行程序记下两个MAC地址同时记录下AP的真实物理位置。 WifiManager wm (WifiManager) getSystemService(Context.WIFI_SERVICE);
wm.startScan(); //开始扫描AP
//等待一段时间时间可长可短
ListScanResult results wm.getScanResults(); //拿到扫描的结果
Collections.sort(results,this); //this是个Comparator按照level排序
//去掉非sankuai的SSID
//在UI线程中显示到界面上
int maxMath.min(30,results.size());
for(int i0;imax;i) {ScanResult one results.get(i);text1.append(\none.BSSID\t\tone.level);
}图中信号最强的就是当前AP的MAC地址然后地址与它相近的是这个AP另一个频段的MAC地址两个MAC地址都是0结尾尾数相差1容易辨认。 MAC地址后面的数字是信号强度单位是dBm是个负数。 然后在底图中标注好AP的准确的物理位置图中红色圆点即是AP位置其圆心的像素坐标当作AP的坐标。 测绘的数据应该存入数据库这里设计了一个POJO服务器端程序可以使用 public class MtApLoc {private int id; //数字ID 人工定有一定含义private String id1; //字符串ID 从IT给表中来private String mac1; //WAN MAC地址有线口的private String sn; //AP的 SN 从IT给表中来private String sku; //资产编号 N 从IT给表中来private String mac2; //无线MAC 1 测绘得来private String mac3; //无线MAC 2 测绘得来private int pn; //图号 对应楼层private float x; //物理坐标 x 自定义坐标系中private float y; //物理坐标 y 自定义坐标系中}然后将测绘的数据录入数据库最后得到的数据如 其中的xy是此AP在对应楼层的测绘图的图片中的坐标。 MAC2和MAC3是AP的两个MAC地址这里没有区分2.4G和5G和上面的测绘客户端的截图比较能看出当时我是站在AP7下的。 把所有86个AP的物理位置和MAC地址测绘收集全后测绘过程完成。 Android客户端示例 这里写了一个Demo用的android客户端来测试定位结果先看客户端运行截图 点击定位按钮系统会扫描AP然后把结果请求到服务器。 HttpPost post new HttpPost(BaseUrl /gar/locate/ap-locate.html);
ListNameValuePair parameters new ArrayListNameValuePair();
for (ScanResult result : results) {parameters.add(new BasicNameValuePair(mac, result.BSSID.toUpperCase()));parameters.add(new BasicNameValuePair(rssi, String.valueOf(result.level)));
}
post.setEntity(new UrlEncodedFormEntity(parameters, UTF-8));
String res;
synchronized (hc) {HttpResponse response hc.execute(post);res EntityUtils.toString(response.getEntity(), UTF-8).trim();
}
Log.w(TAG, res);服务器返回其所在位置是一个JSON字符串 {accuracy:0.0,message:ok Least Squares,pn:1,status:0,x:237.97249473061038,y:1241.8270604002646}然后客户端显示pn对应的底图然后在底图的xy位置上显示定位到的标志即图中跳动的红心。 客户端大部分代码都是UI相关代码这里不贴出了。 定位算法 常见的室内定位的算法主要分为两类基于测距技术的定位算法和距离无关的算法。基于测距技术的算法一般是通过节点之间的距离或者角度来计算出未知节点的位置实际运用中常见的有基于接收信号强度指示算法RSSI、到达角度算法AOA、到达时间算法TOA等。距离无关的算法有质心法、APIT算法、凸规划算法等。这些算法都是利用节点之间的邻近关系实现定位的。一般来说基于测距技术的算法比无需测距的精度要高这里适合采用。 首先确定一个信号强度和距离之间的关系这需要了解电波传播模型。在自由空间环境中不考虑阻挡和多径传播设发射端与接收端的距离为d则接收端的接收功率Pr可表示为 其中Pt为发射功率Gt和Gr分别为发射和接收天线增益λ为电波波长Pt和Pr的单位是瓦特Gt和Gr无量纲。由上式可以看出在自由空间中接收功率与距离d2成反比。 在实际环境中由于存在多径、障碍物、绕射等随机因素无线电传播损耗与上式相比还是有较大变化。此时常采用对数-常态分布模型更为合理 其中Pr单位为dBm d0一般取1。在一般室内定位中考虑到环境、成本、定位精度要求等因素所使用的RSSI测距信号衰减模型进一步简化为 d为定位节点与参考点之间的距离单位mA为定位节点与参考点之间的距离d为1m时测得的RSSI值n为信号衰减因子范围一般为24。 在美团的环境中我们取A为-50n为2.1。 这样根据信号强度就能估算设备和AP之间的距离。 定位方法一般是根据几何模型建立方程然后求解方程得到节点坐标。 只有一个AP的情况 这里目标点坐标只能取AP的坐标精度取半径 两个AP的情况 这里取AB的中间位置精度取AB的长度。 三个AP的情况 这里取三个圆的一个共同交点。 不过实际没有这么简单因为距离都有误差两个AP时可能是这种情况 三个AP可能是这种情况 甚至这种 这只是三个AP有更多AP时怎么办 这里考虑一般的情况 考虑一般的情况设有n个APAP1AP2…APn坐标是xi,yi)。目标点到这n个AP的距离是di。 设目标点的坐标是XY则可列一个方程组有n个等式 大家都减第一个等式就消去了二次项得到另一个方程组有n-1个等式 常数项换个名字得到 等式除以X的系数ai变量换个名字得到 等式有n-1个现在问题变成了已知一组点uivi满足puqv求最合适的系数pq这是典型的最小二乘法 Java里可以用Apache Commons Math3这个library来解决最小二乘法文档见 SimpleRegression 这里还有一个问题AP的坐标xiyi是像素坐标,那di相应的需要是像素距离需要做一个比例尺变换 比例很容易算相关代码 public double getPicLen(double rssi) {double f(-rssi-50)/22.0;return 41.785*Math.pow(10,f);
}服务器端代码示例 通过上面的描述服务器端代码就很容易写了这里给出主要代码 private String[] macs; //输入mac地址
private float[] rssis; //输入信号强度
private int pn; //输出楼层
private double x,y,accuracy; //输出定位到的坐标 和 精度ListMtApLoc apsnew ArrayList(map.keySet());
MtApLoc firstaps.get(0); //信号最强的那个ap
for (MtApLoc one : aps) { //以信号最强的ap的楼层作为最终楼层因为可能搜到其它楼层的信号if(one.getPn()!first.getPn()) { //干掉其它楼层的apmap.remove(one);}
}
aps.clear();
aps.addAll(map.keySet());
sizeaps.size();
this.pnfirst.getPn();
if(size1) {setStatus(0);setMessage(ok one point);this.xfirst.getX();this.yfirst.getY();this.accuracygetPicLen(map.get(first).floatValue());return JSON;
} else if(size2) {setStatus(3);setMessage(to impl);
} else {float minRssi-65; //信号强大要达到 -65 才参与运算int min4; //至少需要4个ap这个条件比上个条件优先size0;for(IteratorMtApLoc it aps.iterator();it.hasNext();) {MtApLoc ap it.next();if(map.get(ap).floatValue()minRssi sizemin) {it.remove();} else {size;}}//map的key之前是信号强度现在变为 像素距离aps.forEach(ap - map.put(ap,getPicLen(map.get(ap).floatValue())));double[][] psnew double[size-1][4]; //看 size-1double r1map.get(first).doubleValue();r1r1*r1;double r2first.getX()*first.getX()first.getY()*first.getY();int n0;for (MtApLoc ap : aps) { //生成数据if(ap!first) {ps[n][0]ap.getX()*ap.getX()ap.getY()*ap.getY()-r2;ps[n][1]2*(first.getX()-ap.getX());ps[n][2]2*(first.getY()-ap.getY());double rmap.get(ap).doubleValue();ps[n][3]r*r-r1;n;}}assert n(size-1);for(int i0;in;i) { //生成数据double kps[i][1];ps[i][1](ps[i][3]-ps[i][0])/k;ps[i][0]ps[i][2]/k;}SimpleRegression regnew SimpleRegression(true); //最小二乘法reg.addData(ps);setStatus(0);setMessage(ok Least Squares);this.xreg.getIntercept();this.yreg.getSlope();
}效果检验 系统完成了这里需要检验一下定位效果。为了简化过程我是这样操作的 我选择了一个固定点就是我的座位上面客户端截图中跳动的红心所在的位置然后用手机客户端做100次定位操作同时服务器做log记录下100次的定位结果然后做分析。 我座位这个点被3个AP包围着定位效果应该不错所以结论可能会偏乐观实际应该选择不同的点。 不过选择不同的点要记录真实的点的坐标稍显麻烦。后面做进一步改进和测试时可以选择不同的点做测试这算作一个todo。 然后就得到100个定位结果然后可以计算和真实点的偏差结果如 其中x、y是定位到的坐标单位是像素坐标diff是计算出的偏差单位是米。 然后按距离排序得到如下表是全部数据 从这个表可以大致分析定位效果 100个点中误差小于1米的有4个点大部分点误差在1米到4米有93个点大致呈均匀分布态势误差大于4米的有3个点而且误差极大明显属于失败的噪声点去掉3个失败的点剩下的97个点可以用excel画一个分布图 分析上面数据以及实际测试过程能发现这个系统应该有一个系统误差。就是测试中定位结果总是分布在距我大概2米处的某一点周围应该是系统编码某个地方缺陷造成的。 这是待改进的To Do预计找到问题解决后重复上面的测试过程定位效果能达到95%的点误差小于2米的水平。 另外上面我选的点应该属于定位效果较好的点一般情况的点的定位精度得进一步详细测试得出。这里我拍脑袋估计系统应该在90%的点误差小于5米的水平。 进一步工作改进与设想 整个系统正在应用到移动组开发的一个找会议室的手机应用“会议室”中为其增加定位自身的功能。 为了完善系统现在能想到的改进有 找到并改进上面说到的 系统误差完善后做进一步的评测考虑2.4G和5G信号的定位差别目前是不区分的信号强度和距离的公式的系数做进一步精确核心定位算法目前采用的是最小二乘法目前在考虑用更智能的一个方法叫“位置指纹”这个算法预计效果更好也容易实施目前坐标系统用的自定义的坐标系这个不利于使用者使用考虑用更好的坐标系光有定位接口是不够的还应该有 坐标和地址相互转换的接口还应该有导航的接口推广应用到更多实际的系统中这些改进会逐步完善敬请期待本系列的下篇。