فهرست منبع

直线距离数据测试正常

zachary 4 سال پیش
والد
کامیت
f0ca7ab8bd
2فایلهای تغییر یافته به همراه128 افزوده شده و 23 حذف شده
  1. 87 13
      components/map-sense/map-sense.js
  2. 41 10
      utils/util.js

+ 87 - 13
components/map-sense/map-sense.js

@@ -14,13 +14,14 @@ const STATUS_PIC = {
   '3': 'fail'
 };
 
+// 选择6档
 const TXPOWER = 0
 
 // 距离经验值(调试所得)
 const N = 14
 
 
-let AveLength = 10
+let AveLength = 12
 
 Component({
   /**
@@ -43,7 +44,8 @@ Component({
     api_base_url: API_BASE_URL,
     // 是否是扫码播放
     isScanPlay: false,
-    cdn_url:CDN_URL
+    cdn_url:CDN_URL,
+    classfiy:{}
   },
 
   /**
@@ -67,30 +69,102 @@ Component({
       
       this.openBluetooth(()=>{
         startBeaconDiscovery({uuids: ['FDA50693-A4E2-4FB1-AFCF-C6EB07647825']}).then((res)=>{
+          
           wx.onBeaconUpdate(data=>{
-            if (aveArr.length == AveLength) {
-              aveArr[0] = data.beacons
-            }
-            else{
-              aveArr.push(data.beacons)
+            
+            //打印最新收集到的信号
+            console.log('beacon',data.beacons)
+            // 需要收集十组数据,索引号最大的组是最旧的
+            if (aveArr.length > AveLength) {
+              // aveArr[0] = data.beacons
+              //当超过十组时,应该将索引号大的组淘汰掉
+              aveArr.pop()
             }
+
+            aveArr.unshift(data.beacons)   //在队列前面插入
+            
+            // console.log('aveArr',aveArr);
             let all = []
             aveArr.forEach(item => {
-              all = all.concat(item)
+                // console.log(aveArr.length,item)
+                all = all.concat(item)
             });
-
+            // classfiy = {10003:[{},{},···],10002:[{},{},···],10001:[{},{},···]}
+            // console.log('all',all)
             let classfiy = BeaconUtils.classification(all,'major')
+            let accuaryList = {}         // 存放处理后的accuary
+            // let dataArr = []    //记录各信标的信号收集数目
             Object.keys(classfiy).forEach(key=>{
-              //每个major的AveLength个元素数组
+              //每个major的AveLength个元素数组,元素为rssi
               let arr = classfiy[key].map(item=>{
-                return item.accuracy
+                return item.rssi
               })
-              //每个major的平均值
+              //每个major的rssi平均值
+              // console.log(key,'rssi',arr)
               let ave = BeaconUtils.arrayAverage(arr)
+              // console.log('ave',ave) 
+              //计算平均差
+              let meanDeviation = BeaconUtils.getMeanDeviation(arr,ave);
+              // console.log('meanDeviation',meanDeviation)
+              //计算各rssi的高斯模糊权重
+              let guassionArr = [];
+              for(let i = 0; i < arr.length; ++i){
+                // console.log('guassionArr ele',BeaconUtils.getOneGuassionArray(arr.length,i,meanDeviation))
+                // 返回的可能是空数组
+                guassionArr.push(BeaconUtils.getOneGuassionArray(arr.length,i,meanDeviation));
+              }
+              // console.log('guassionArr',guassionArr)
+              //计算高斯模糊后的rssi值
+              let rssiArr = [];                  //模糊后的rssi数组
+              for(let i = 0; i < arr.length; ++i){
+                let sum = 0;
+                for(let j = 0; j <arr.length; ++j){
+                  sum += guassionArr[i][j] * arr[j]
+                }
+                rssiArr.push(sum);
+                // console.log('sum',sum)   
+              }
+              // console.log('rssiArr',rssiArr);
+              //时间加权后求rssi平均值
+              let aveOnTime = BeaconUtils.arrayAverage(rssiArr.slice(Math.floor(0,rssiArr.length / 2)).concat(rssiArr));
+              // console.log('aveOnTime',aveOnTime)
+              //测距
+            
               classfiy[key].forEach(item=>{
-                 item.accuracy = ave
+                  item.accuracy = BeaconUtils.calculateAccuracy(TXPOWER,aveOnTime,N)
+                  if(!accuaryList[key]){
+                    //如果还没有对应的“信标号”
+                    accuaryList[key] = [item.accuracy]
+                  }
+                  accuaryList[key].push(item.accuracy)
+                  // console.log('item',item)
               })
+              
+              // dataArr.push(classfiy[key].length)
+              
             })
+            console.log(classfiy['10001'])
+            console.log(classfiy['10002'])
+            console.log(classfiy['10003'])
+            
+            // 计算方差
+            //计算平均数
+            // let x = BeaconUtils.arrayAverage(dataArr)
+            // let variance = BeaconUtils.getVariance(dataArr,x)
+            //打印收集到各种信号数目的方差
+            // console.log('txPower=',TXPOWER," 方差:",BeaconUtils.repeat('--',Math.floor(variance)))
+
+            // 定位
+            // 将三个信标构成直角三角形,其中10002号信标为直角,10001号为基点
+            // 根据挡位设定相邻顶点信标的距离,5档,设边长为10m
+            let sideLength = 5
+            let distance1,distance2,distance3      //分别对应游客到信标10001,1002,10003的距离
+            distance1 = BeaconUtils.arrayAverage(accuaryList['10001'])
+            distance2 = BeaconUtils.arrayAverage(accuaryList['10002'])
+            distance3 = BeaconUtils.arrayAverage(accuaryList['10003'])
+            let px = (Math.pow(2.8,2) - Math.pow(distance2,2) + Math.pow(distance1,2)) / (2.8 * 2)
+            let py = (Math.pow(5.6,2) - Math.pow(distance3,2) + Math.pow(distance2,2)) / (5.6 * 2)
+            // console.log('px',px,' py',py)
 
             this.setData({
               classfiy,

+ 41 - 10
utils/util.js

@@ -36,7 +36,8 @@ arrayAverage:function (arr) {
    return tmp
 },
 
-//数组分类
+//数组分类:按照关键词key
+//data = {1003:[{},{},···],1002:[{},{},···],1001:[{},{},···]}
 classification:function (list,key) {
   let data = {}
   for(var i = 0; i < list.length; i++) {
@@ -54,25 +55,55 @@ classification:function (list,key) {
 
 //求一维队列某点的高斯模糊权重 @param(队列长度,目标位置, 平均差)
 getOneGuassionArray: function(size, kerR, sigma) {
-    if (size % 2 > 0) {
-      size -= 1
-    }
-    if (!size) {
-      return []
-    }
+    // if (size % 2 > 0) {
+    //   size -= 1
+    // }
+    // if (!size) {
+    //   return []
+    // }
     if (kerR > size-1){
       return []
     }
     let sum = 0;
     let arr = new Array(size);
-
+    //进来的列表的元素可能是一样的,防止平均差为0的情况
+    if(sigma == 0){
+      let weight = 1 / size;
+      return arr.fill(weight)
+    }
     for (let i = 0; i < size; i++) {
-      arr[i] = Math.exp(-((i - kerR) * (i - kerR)) / (2 * sigma * sigma));
+      arr[i] = Math.exp(-((i - kerR) * (i - kerR)) / (2 * sigma * sigma)) / (sigma * Math.pow(2*Math.PI,0.5));
       sum += arr[i];
     }
 
     return arr.map(e => e / sum);
-  }
+  },
+
+  //计算数组平均差
+  //list:rssi数组
+  //average:rssi平均值
+  getMeanDeviation: function(list,average){
+    let length = list.length;
+    //数组的每一个数都要减去一个平均数,结果取绝对值
+    let arr = list.map(num=>Math.abs(num-average))
+    return arr.reduce((prev,curr)=>prev+curr) / length;
+  },
+
+  //计算数组方差
+  // list:待计算数组
+  // average:数组元素平均值
+  getVariance:function(list,average){
+    let sum = 0;
+    for(let element of list){
+      sum += Math.pow((element - average),2)
+    }
+    return sum / list.length
+  },
+
+  //js实现字符串重复的repeat函数
+  repeat:function(src, n) {
+    return (new Array(n + 1)).join(src);
+}
 }
 
 module.exports = {