概述

这个项目主要是定位50米走廊的位置,共有5个Ibeacon设备,每隔10米放置一个。显示也不像之前放在pc端上显示,而是实时显示在手机屏幕上。Android扫描到Ibeacon设备的RSSi后,先进行卡尔曼滤波,得到一个相对稳定的RSSI,再根据可调的距离算法(该距离算法是买IBeacon设备厂家提供的算法,其实也是一个衰减模型)获得距离。距离进行sma平滑后,通过5个ibeacon设备相互迭代,得到坐标。

需要源码的小伙伴:留言
最近太忙,不能一一回复最新的程序。
需要的可以看看最初的demo:https://github.com/zhoudatang/SimpleIbeacon。

Appconfig类

该类是APP所有配置的配置类,可以根据实际环境,调节这个类。配置内容有:绘图坐标点大小,蓝牙扫描时间,5个ibeacon部署位置,sma平滑精度,卡尔曼算法的误差调节以及距离衰减模型的参数调节。(注意::使用时候,由于beacon设备uuid,蓝牙地址等不同,需要在ibeacondevice中,更改你们的ibeacon设备的uuid,major,minor,以及蓝牙地址,否者不会识别你们的beacon设备)如下:代码

public class AppConfig {/*MAIN_ACTIVITY*/static private  int MAIN_ACTIVITY_SCAN_TIME=3000;/*POINT*/static private  int POINT_RADIUS=25;//绘制点半径/*CALMAN*/static private double KALMAN_Q1=16; //卡尔曼预测误差的方差static private double KALMAN_R1=100; //卡尔曼噪声误差的方差

Point类

存储坐标点的数据类

public class Point {//点的X坐标private int x;//点的Y坐标private int y;//点的半径,默认为10像素private int radius = AppConfig.getPointRadius();public Point(int x, int y) {this.x = x;this.y = y;}public Point(int x, int y, int radius) {this.x = x;this.y = y;this.radius = radius;}public int getX() {return x;}
.......
}

queue类

一个自己写的队列类,用于sma平滑数据,队列没满则会一直放即时的距离值进去,满了则计算队列(默认5个值)的平均数,为当前的距离值,然后出一个值,再进最新值

public class queue {private float[] data ;// 队列private int front;// 队列头,允许删除private int rear;// 队列尾,允许插入private int LENGTH=AppConfig.getQueueLength();private int full=0;private int t=0;//判断队列是否装满private  int relute=0;public queue() {data = new float[LENGTH];front = rear = 0;}// 入队public void offer(float date) {if (rear>=LENGTH){rear=0;}data[rear++] = date;if (t++>=LENGTH){full=1;//relute=(int)(data[0]+data[1]+data[2]+data[3]+data[4])/5;for (int i=0;i<LENGTH;i++){relute=0;relute += data[i];}}}// 出队public float poll() {if (front<LENGTH){float value = data[front];// 保留队列的front端的元素的值front++;return value;}else{front=0;float value = data[front];return  value;}}public boolean full(){if (full==1)return  true;elsereturn false;}public int getRelute() {return relute;}
}

ibeacondevice类

该类是五个Ibeacon设备数据的类,存放五个Ibeacon的uuid,蓝牙地址等信息

public class IbeaconDevice {public int major;public int minor;public String proximityUuid;public String bluetoothAddress;int x;int y;public  IbeaconDevice(String bluetoothAddress,int x,int y){this.bluetoothAddress=bluetoothAddress;this.x=x;this.y=y;major=10;minor=7;proximityUuid="fda50693-a4e2-4fb1-afcf-c6eb07647825";}public int getMajor() {return major;}public int getX() {return x;}public int getY() {return y;}

ibeacon类

该类存放扫描获得的实时beacon对象,与ibeacondevice最大的区别在于RSSI

public class iBeacon {public String name;public int major;public int minor;public String proximityUuid;public String bluetoothAddress;public int txPower;public int rssi;public double distance=0;public int x;public int y;
}

Mainactivity类

UI界面,主要进行图像的显示和蓝牙的扫描。
敲击扫描按钮,开始扫描

 //开启蓝牙扫描findViewById(R.id.mStartBtn).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mBLE.startLeScan(mScanCallback);}});

将我的蓝牙显示的函数:

    private void getBlueToothDetail() {if (mBLE == null) return;mBluetoothAdapter = mBLE.getBluetoothAdapter();if (mBluetoothAdapter == null) return;Textview1.setText("我的蓝牙:" + mBluetoothAdapter.getName() + "\n地址:" + mBluetoothAdapter.getAddress());}

对了,这次使用的扫描是使用的第三方库,扫描更快更稳定,如下是扫描的回调

   private PeriodScanCallback mScanCallback = new PeriodScanCallback(TIME_OUT_SCAN) {@Overridepublic void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {logDevice(device, rssi, scanRecord);}@Overridepublic void onScanTimeout() {mBLE.startLeScan(mScanCallback);toast("扫描超时");}};private void logDevice(BluetoothDevice device, int rssi, byte[] scanRecord) {ibeacon = iBeaconClass.fromScanData(device, rssi, scanRecord,sma1);//先通过ibeaconclass获得ibeacon类if (ibeacon == null) return;Textview1.setText("\n" +"蓝牙地址"+ibeacon.bluetoothAddress);Textview1.append("\n" + "rssi" + ibeacon.rssi);Textview1.append("\n" + "distance" + ibeacon.distance);double t=mtwoPointAlgorithm.algorithm(ibeacon);Textview1.append("\nt=="+t);mPointView.drawPoint(new Point(mPointView.getWidth()/2+30,(int)((1-t/50)*mPointView.getHeight())));//绘制坐标,x坐标默认是图像宽度的一半。走道使用x,y和只使用y差距不大}

Ibeaconclass类

主要是将获得的广播数据,解析出一个ibeacon类对象。在最开始,会调用卡尔曼算法的类,先过滤RSSi值。

class iBeaconClass {static Kalman kalman1=new Kalman(AppConfig.getKalmanQ1(),AppConfig.getKalmanR1());//5个卡尔曼滤波器分别对5个ibeacon滤波static Kalman kalman2=new Kalman(AppConfig.getKalmanQ1(),AppConfig.getKalmanR1());static Kalman kalman3=new Kalman(AppConfig.getKalmanQ1(),AppConfig.getKalmanR1());static Kalman kalman4=new Kalman(AppConfig.getKalmanQ1(),AppConfig.getKalmanR1());static Kalman kalman5=new Kalman(AppConfig.getKalmanQ1(),AppConfig.getKalmanR1());static IbeaconDevice dev1 = new IbeaconDevice("88:3F:4A:EA:50:8E", 0, AppConfig.getBeaconDevice1Y());static IbeaconDevice dev2 = new IbeaconDevice("88:3F:4A:EA:4D:CE", 0, AppConfig.getBeaconDevice2Y());static IbeaconDevice dev3 = new IbeaconDevice("88:3F:4A:EA:4D:D6", 0, AppConfig.getBeaconDevice3Y());static IbeaconDevice dev4 = new IbeaconDevice("88:3F:4A:EA:4D:B3", 0, AppConfig.getBeaconDevice4Y());static IbeaconDevice dev5 = new IbeaconDevice("88:3F:4A:EA:50:85", 0, AppConfig.getBeaconDevice5Y());//解析数据static iBeacon fromScanData(BluetoothDevice device, int rssi, byte[] scanData,sma sma1) {// rssi=sma1.run(device.getAddress(),rssi);//平滑数据算法//卡尔曼滤波if (device.getAddress().equals(iBeaconClass.dev1.bluetoothAddress))rssi=(int)iBeaconClass.kalman1.KalmanFilter((double) rssi);if (device.getAddress().equals(iBeaconClass.dev2.bluetoothAddress))rssi=(int)iBeaconClass.kalman2.KalmanFilter((double) rssi);if (device.getAddress().equals(iBeaconClass.dev3.bluetoothAddress))rssi=(int)iBeaconClass.kalman3.KalmanFilter((double) rssi);if (device.getAddress().equals(iBeaconClass.dev4.bluetoothAddress))rssi=(int)iBeaconClass.kalman4.KalmanFilter((double) rssi);if (device.getAddress().equals(iBeaconClass.dev5.bluetoothAddress))rssi=(int)iBeaconClass.kalman5.KalmanFilter((double) rssi);//这个类代码很多。。。。。。。

sma类

简单平均算法,用来平滑滤波后得到的距离。

public class sma {IbeaconDevice dev1, dev2, dev3, dev4, dev5;public ArrayList<queue> arr_queue;//存放 5个ibeacon的动态数组 每个队列有5个值public  ArrayList<IbeaconDevice> arr_ineacon_device;sma(){arr_queue=new ArrayList<>();arr_ineacon_device=new ArrayList<>();dev1 = new IbeaconDevice("88:3F:4A:EA:50:8E", 0, AppConfig.getBeaconDevice1Y());dev2 = new IbeaconDevice("88:3F:4A:EA:4D:CE", 0,  AppConfig.getBeaconDevice2Y());dev3 = new IbeaconDevice("88:3F:4A:EA:4D:D6", 0,  AppConfig.getBeaconDevice3Y());dev4 = new IbeaconDevice("88:3F:4A:EA:4D:B3", 0,  AppConfig.getBeaconDevice4Y());dev5 = new IbeaconDevice("88:3F:4A:EA:50:85", 0,  AppConfig.getBeaconDevice5Y());arr_queue.add(new queue());arr_queue.add(new queue());arr_queue.add(new queue());arr_queue.add(new queue());arr_queue.add(new queue());arr_ineacon_device.add(dev1);arr_ineacon_device.add(dev2);arr_ineacon_device.add(dev3);arr_ineacon_device.add(dev4);arr_ineacon_device.add(dev5);}public  int run(String address,int rssi){if (address.equals(dev1.bluetoothAddress)){arr_queue.get(0).offer(rssi);return 0;}else if (address.equals(dev2.bluetoothAddress)){arr_queue.get(1).offer(rssi);return 0;}else if (address.equals(dev3.bluetoothAddress)){arr_queue.get(2).offer(rssi);return 0;}else if (address.equals(dev4.bluetoothAddress)){arr_queue.get(3).offer(rssi);return 0;}else if (address.equals(dev5.bluetoothAddress)){arr_queue.get(4).offer(rssi);return 0;}else {return 0;}}

Kalman类

使用的是之前写好的类

卡尔曼类

Algorithm类

类中有,在滤波和平滑后进行的 迭代,两点距离算法,最后获得的是显示的坐标。外部调用algorithm,并传入一个即时ibeacon值,先判断队列是否满了(sma算法),满了则执行迭代算法。

public double algorithm(iBeacon now_ibeacon) {sma1.run(now_ibeacon.bluetoothAddress,now_ibeacon.rssi);//入队double buff=0;int temp=0;for(int i=0;i<5;i++)//循环遍历5个队列{if(sma1.arr_queue.get(i).full())//如果大于5){for (int j = i + 1; j < 5; j++)if (sma1.arr_queue.get(j).full())//如果大于5{buff+=twopoint(sma1.arr_ineacon_device.get(i),sma1.arr_ineacon_device.get(j),sma1.arr_queue.get(i).getRelute(),sma1.arr_queue.get(j).getRelute());temp++;}}}buff=buff/temp;return buff;}public  double twopoint(IbeaconDevice now_ibeacon,IbeaconDevice last_ibeacon,double now_dis,double last_dis){double relute = 0;double buf1, buf2;if (now_dis + last_dis > Math.abs(now_ibeacon.y - last_ibeacon.y))//如果是在两点外{if (now_ibeacon.y > last_ibeacon.y)//now是距离更远的信标{buf1 = now_ibeacon.y + now_dis;buf2 = last_ibeacon.y + last_dis;relute = (buf1 + buf2) / 2;} else//now是距离更近的信标{buf1 = now_ibeacon.y - now_dis;buf2 = last_ibeacon.y - last_dis;relute = (buf1 + buf2) / 2;}} else//在两点内{if (now_ibeacon.y > last_ibeacon.y)//now是距离更远的信标{buf1 = now_ibeacon.y - now_dis;buf2 = last_ibeacon.y + last_dis;relute = (buf1 + buf2) / 2;} else//last是距离更远的信标{buf1 = now_ibeacon.y + now_dis;buf2 = last_ibeacon.y - last_dis;relute = (buf1 + buf2) / 2;}}return relute;}

PointImageView类

用来显示的类

public class PointImageView extends AppCompatImageView {public PointImageView(Context context) {super(context);}public PointImageView(Context context, AttributeSet attrs) {super(context, attrs);}public PointImageView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}private Point mPoint = null;private Paint mPointPaint = new Paint();@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);mPointPaint.setColor(Color.RED);if (mPoint != null) {canvas.drawCircle(mPoint.getX(), mPoint.getY(), mPoint.getRadius(), mPointPaint);}}public void drawPoint(Point p) {mPoint = p;invalidate();}

Ibeacon一维小项目相关推荐

  1. 我用Python把抖音上的美女图片转字符画,期望的AI目标更进一步【机器学习算法实战小项目,k聚类算法图片转化字符画】

    大家好,我是辣条. 最近在学习算法,今天给大家带来一个机器学习实战小项目 项目效果展示 学习目标 1.cv2转换图片数据  2.numpy提取图片矩阵数据  3.k均值算法获取图片的分类 工具使用 开 ...

  2. Java小项目——家庭记账项目

    学习Java已经过了半个月左右了,所学的知识已经能够写一些小程序或者小项目,虽然它可能没有那么高级,但是也能检验你之前所学的全部内容.所以今天就与大家分享一下我的小项目经验. 一.需求说明 该软件能够 ...

  3. 仿qq左滑删除listview_Java基于Swing和Netty仿QQ界面聊天小项目

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:硬刚一周,3W字总结,一年的经验告诉你如何准备校招! 个人原创100W+访问量博客:点击前往,查看更多 来源:b ...

  4. 【敬初学者】Python基础学完了,该怎么知道自己学的怎么样呢?十个经典实战小项目附源码

    前言 1.街霸游戏 1.1 KO街霸 程序完整源码 程序的输出界面 1.2 春丽VS巴洛克 参考源码 2.猜谜游戏 2.1简单的猜数字游戏 项目要求 参考源码 2.2 进阶的猜姓名游戏 项目要求 参考 ...

  5. Java EE---使用Spring框架创建Market小项目

    通过Spring的IoC和DI思想创建一个小项目便于理解spring 题目: 1.使用Spring IOC/DI 模拟某超市管理功能,程序设计涉及: (1)Product类(商品类):含id(商品编号 ...

  6. Python练手小项目

    一.画爱心表白 1.图形都是由一系列的点(X,Y)构成的曲线,由于X,Y满足一定的关系,所以我们就可以建立模型,建立表达式expression,当满足时,两个for循环(for X in range: ...

  7. ios小项目——新浪微博客户端总结

    2019独角兽企业重金招聘Python工程师标准>>> 们还是登录不了,你们要用还是得自己申请appkey并且把回调网址设为baidu.或者是再下面留言,留下你的微博uid我把你加入 ...

  8. React+TypeScript练手小项目

    在写 关于MVC模式简单代码实现 的过程中,觉得最麻烦的就是操作 DOM.所以这次升级了,打算用 React.用过 React 的同学都知道,React 在更新视图时,必须要通过 setState 方 ...

  9. android简单app实例_Android安卓小项目实战视频教程集锦

    Android安卓小项目实战视频教程,点击进入视频教程: 一.安卓项目视频教程: 1蓝牙聊天APP介绍-分步骤介绍一个简单安卓蓝牙APP的开发过程 - 西瓜视频 2蓝牙聊天开发流程-分步骤介绍一个简单 ...

  10. java gui 项目解密,java GUI(实例小项目--列出磁盘目录)

    //java实例小项目:列出磁盘目录. import java.awt.*; import java.awt.event.*; import java.io.File; class MyWindDem ...

最新文章

  1. iOS 对UIImage进行的一些操作
  2. vim学习笔记(三)
  3. 常见面试题:为什么HashMap不是线程安全的呢?(JDK1.7和JDK1.8角度)(看完你就能和面试官笑谈人生了)
  4. 轻量级姿态估计simplepose
  5. OpenCV运行ReID网络的实例(附完整代码)
  6. 计算机系统结构怎么提高代码效率,北邮 计算机系统结构 实验报告(全部)指令流水线相关性分析 DLX 处理器程序设计 代码优化.doc...
  7. ASP.NET Core开源Web应用程序框架ABP
  8. 前端chrome浏览器调试总结??
  9. ListView的性能优化之convertView和viewHolder
  10. 26. JavaScript 计时
  11. BZOJ1397 : Ural 1486 Equal squares
  12. 大学数学新生入门学习数学方法导引 by Ph.D.王小龙
  13. 【纯java语言做RPG游戏】4.用XML导入NPC并与NPC对话
  14. EXCEL表格单元格中包含数字英文和汉字,如何自动去掉汉字,保留英文和数字...
  15. Ubuntu18.04搭建本地RTMP服务器librtmp+nginx,推送flv文件播放
  16. python逆时针画圆_python 逆时针
  17. 计算机班学生勇夺比赛第一名,北科大新闻网
  18. 浅谈 Kafka Leader Epoch
  19. Web前端开发——CSS样式之CSS选择器
  20. php做网站步骤_php建一个网站步骤

热门文章

  1. Guided Anchoring
  2. react中使用高德地图进行定位
  3. 丧心病狂的Github技巧
  4. FA_MASS_ADDITIONS Interface Table 资产成批增加
  5. 数据库中的行式存储和列式存储
  6. 插件:Could not find library corresponding to plugin……
  7. android 带刻度的滑动条_Android实现滚动刻度尺效果
  8. 达梦8初始化参数之BLANK_PAD_MODE
  9. 苹果cms10配置本地化播放器p2p加速
  10. linux sdl windows.h,SDL入门教程(十):1、多语言支持,Win32下的GetText