本實驗使用 beacon 進行是內定位實驗,本實驗規劃 beacon 資料欄位之中的 major 代表平面座標的 x 軸,minor 代表平面座標的 y 軸,來達到平面的定位效果(此設計模式僅供參考),定位是意圖如下:

image

 

在藍芽訊號中的 rssi 為訊號強度可以透過公式實驗校正 將其轉換成實體距離,其方法本實驗暫不討論,公式可以參考 本連結 為其他作者針對 rssi 轉換成距離之公式計算。

 

已知各個beacon的座標位值以及使用者的距離,即可透過解連立方程式即可得出使用者之座標值。由於現實環境中會有雜訊干擾以及訊號強度會有變化,因此可能導致沒有唯一解,因此透過最小二乘法 Least Squares,求解誤差最小值。
將上式距離在相減,並經過整理得到下式:

 

where   

最終可將其整理成矩陣並利用 高斯消去法 求得實際的 x,y 位置。

 


Java 實作上述公式:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
   public void translate(){
        //buildSamples();
        //List2Array();
        _row = beaconList.size()-1;
        _col = 3;
        _arr = new float[_row *_col];

        for(int i=1;i<beaconList.size();i++){
            float aj = beaconList.get(0).getX() - beaconList.get(i).getX();
            float bj = beaconList.get(0).getY() - beaconList.get(i).getY();
            double cj = Math.pow(beaconList.get(0).getX(),2) - Math.pow(beaconList.get(i).getX(),2)
                    + Math.pow(beaconList.get(0).getY(),2) - Math.pow(beaconList.get(i).getY(),2)
                    - Math.pow(beaconList.get(0).distance(),2) - Math.pow(beaconList.get(i).distance(),2);

            _arr[(i-1)*_col + 0] = aj;
            _arr[(i-1)*_col + 1] = bj;
            _arr[(i-1)*_col + 2] =(float) cj;
        }

        System.out.println("finsh.");
    }

 

Java 實作高斯消去法之程式碼:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
    private void GaussianElimination( int col_n, int row_n )
    {
        /* left-down to zero */
        for(int i = 0; i < col_n; i++) {
            for(int j = i + 1; j < row_n; j++) {
                if((j*row_n+i) >= _arr.length)  continue;

                float enlarge = _arr[j*row_n+i] / _arr[i*row_n+i];
                for(int k=col_n;k>i-1;k--){
                    _arr[j*row_n+k] = _arr[j * row_n + k] - (enlarge * _arr[i*row_n+k]);
                }
            }
        }

        /* diagonal to one */
        for(int i = 0; i < col_n; i++) {
            float tmp = _arr[i*row_n+i];
            for(int j = i; j < row_n; j++) {
                _arr[i*row_n+j] = _arr[i*row_n+j] / tmp;
            }
        }

        /* right-up to zero */
        for(int j = row_n - 2; j > 0; j--) {
            for(int i = 0; i < j; i++) {
                _arr[i*row_n+row_n-1] = _arr[i*row_n+row_n-1] - _arr[i*row_n+j] * _arr[j*row_n+row_n-1];
            }
        }
    }

 

本實驗使用 Android APP 實做出是內定之APP 此為 專案超連結

 

arrow
arrow
    文章標籤
    beacon ble
    全站熱搜

    Lung-Yu,Tsai 發表在 痞客邦 留言(0) 人氣()