// components/map-sense.js const innerAudioContext = wx.createInnerAudioContext(); import http from '../../utils/http'; import {promisify,BeaconUtils} from '../../utils/util'; let openBluetoothAdapter = promisify(wx.openBluetoothAdapter) let startBeaconDiscovery = promisify(wx.startBeaconDiscovery) import { CDN_URL, CONNECT_STATUS, STATUS_TEXT, API_BASE_URL } from '../../config/index'; const STATUS_PIC = { '0': 'default', '1': 'loading', '2': 'success', '3': 'fail' }; // 选择6档 const TXPOWER = 0 // 距离经验值(调试所得) const N = 14 let AveLength = 10 Component({ /** * 组件的属性列表 */ properties: { }, /** * 组件的初始数据 */ data: { status: "0", cdn_url: CDN_URL, connect_status: CONNECT_STATUS, status_text: STATUS_TEXT, status_pic: STATUS_PIC, targetObj: {}, audio_address: {}, api_base_url: API_BASE_URL, // 是否是扫码播放 isScanPlay: false, cdn_url:CDN_URL, classfiy:{} }, /** * 组件的方法列表 */ methods: { openBluetooth(cb) { openBluetoothAdapter().then(res=>{ cb(res) },()=>{ wx.showToast({ title: '请打开蓝牙', icon: 'error', duration: 2000 }) }) }, toHandle() { let aveArr = [] this.openBluetooth(()=>{ startBeaconDiscovery({uuids: ['FDA50693-A4E2-4FB1-AFCF-C6EB07647825']}).then((res)=>{ wx.onBeaconUpdate(data=>{ //打印最新收集到的信号 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 => { // console.log(aveArr.length,item) all = all.concat(item) }); // classfiy = {10003:[{},{},···],10002:[{},{},···],10001:[{},{},···]} // console.log('all',all) let classfiy = BeaconUtils.classification(all,'major') let accuracyList = {} // 存放处理后的accuary // let dataArr = [] //记录各信标的信号收集数目 Object.keys(classfiy).forEach(key=>{ //每个major的AveLength个元素数组,元素为rssi let arr = classfiy[key].map(item=>{ return item.rssi }) //每个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 { item.accuracy = BeaconUtils.calculateAccuracy(TXPOWER,aveOnTime,N) if(!accuracyList[key]){ //如果还没有对应的“信标号” accuracyList[key] = [item.accuracy] } accuracyList[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']) console.log(classfiy) // 筛选器,筛选出配对的一组信标 let aveAccuracys = new Map() //信标的平均距离,用于判断是否在范围内 let matchSigns = [] //匹配的信号 let prologue = ['1000110002'] //序厅 let annexHall = ['1000310004'] //附厅 let mainHall = ['1000510006'] //主厅 let area = [prologue,annexHall,mainHall] const R = 3.8 //设定范围半径 Object.keys(accuracyList).forEach(key=>{ let aveAccuracy = BeaconUtils.arrayAverage(accuracyList[key]) if(aveAccuracy < R){ aveAccuracys.set(key,aveAccuracy) } }) //理想情况下只有两个信标的信号,刚好匹配为一组 //判断编号是奇数偶数 let result = '' for(let key of aveAccuracys.keys()){ let num = parseInt(key) if(num % 2 == 0){ if(aveAccuracys.has(String(num - 1))){ num-- result = key + num break } }else if(aveAccuracys.has(String(num + 1))){ num++ result = key + num break } } console.log('result',result); for(let i = 0; i < area.length; ++i){ if(area[i].includes(result)){ console.log(i) } } // 计算方差 //计算平均数 // 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(accuracyList['10001']) // distance2 = BeaconUtils.arrayAverage(accuracyList['10002']) // distance3 = BeaconUtils.arrayAverage(accuracyList['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, status:'2' }) }) }).catch(()=>{ wx.showToast({ title: '连接失败', icon: 'error', duration: 500 }) }) }) }, stopBeaconDiscovery() { var that = this; console.log('这是取消连接') wx.showToast({ title: '取消连接成功', icon: 'error', duration: 1000 }) wx.stopBeaconDiscovery({}) // 取消连接 停止播放音乐 目标对象置为{} 设置为第一次进入 innerAudioContext.stop(); that.setData({ status: '0', targetObj: {} }) }, // 扫一扫 toScanCode() { var that = this; that.setData({ isScanPlay: true }) wx.scanCode({ success(res) { console.log('success', res) console.log('result', res['result']) console.log('innerAudioContext', innerAudioContext) that.setData({ targetObj: {} }) innerAudioContext.autoplay = true; innerAudioContext.src = res['result'] innerAudioContext.loop = true; innerAudioContext.play(); }, fail: function (res) { console.log('fail innerAudioContext', innerAudioContext) that.setData({ isScanPlay: false }) innerAudioContext.play(); return; }, complete(){ // console.log() that.setData({ isScanPlay: false }) } }) }, getAudios() { http.get('/api/web/getAudioIndex') .then(res => { let { data } = res,target = {}; data.forEach(item => { switch (item.type) { case 1: target['10001'] = `${this.data.api_base_url}/data/${item.audio}`; break; case 2: target['10002'] = `${this.data.api_base_url}/data/${item.audio}`; break; case 3: target['10003'] = `${this.data.api_base_url}/data/${item.audio}`; break; default: break } }) this.setData({ audio_address: target }) }) } }, lifetimes:{ attached: function () { innerAudioContext.stop(); //获取语音 this.getAudios(); var that = this; // wx.onAccelerometerChange(function (e) { // console.log('手机咚咚咚给') // if (Math.abs(e.x) > 1.1 && Math.abs(e.y) > 1.1) { // //         wx.showToast({ title: "摇一摇" }) // } else if (Math.abs(e.x) > 0.07 && Math.abs(e.y) > 0.02 && that.data.status === '2') { // // 扫一扫播放的话 移动无效 // if (that.data.isScanPlay) return; // that.startBeaconDiscovery() // } else { // //         wx.showToast({ title: "静止" }) // } // }), innerAudioContext.onEnded(() => { console.log('播放结束了') if (this.data.isScanPlay) { innerAudioContext.stop() this.setData({ isScanPlay: false }) this.targetObj = {} console.log('innerAudioContext', innerAudioContext) if (this.data.status == 2) { console.log(2222222222222222) this.startBeaconDiscovery() } } }) }, detached: function () { innerAudioContext.stop(); innerAudioContext.destroy(); wx.stopBeaconDiscovery({}) this.setData({status:"0"}) } } })