iOS iBeacon室內(nèi)定位的簡單實(shí)現(xiàn)之分步定位法

說到定位算法聘鳞,一般我們第一個(gè)想到的方案就是三邊測(cè)量法(Trilateration)悟狱,通過三個(gè)信號(hào)點(diǎn)(Beacons)和分別對(duì)應(yīng)的距離玄糟,形成三個(gè)圓并相交于一點(diǎn)此蜈。但是實(shí)際情況并沒有那么理想化即横,有可能會(huì)出現(xiàn)兩圓不相交、圓包含圓裆赵、只有兩個(gè)信號(hào)點(diǎn)或者多個(gè)信號(hào)點(diǎn)排成一列的情況(過道里)东囚,這都是一些比較常見的場(chǎng)景。所以我們需要一個(gè)能同時(shí)解決上面這些問題的計(jì)算方法——分步定位法战授。

分步定位法

在iOS開發(fā)中页藻,使用CLLocationManagerstartRangingBeaconsInRegion:方法監(jiān)聽Beacons,并通過代理回調(diào)中獲得Beacons列表植兰。取出rssi信號(hào)值最強(qiáng)的三個(gè)點(diǎn)份帐,取accuracy值作為圓半徑(需要減去高度差),用major楣导、minor值從后臺(tái)返回的數(shù)據(jù)中取出對(duì)應(yīng)的坐標(biāo)點(diǎn)數(shù)據(jù)即為三個(gè)圓的圓心废境。

圖1-1,分步定位法.png

該算法比較簡單,如圖1-1噩凹,不相交時(shí)巴元,按比例取中點(diǎn)(O_{AZ}O_{BZ})。當(dāng)兩圓相交時(shí)驮宴,就是拆分成幾個(gè)三角形逮刨,通過一系列三級(jí)函數(shù)計(jì)算出未知的兩個(gè)交點(diǎn)。最后將三點(diǎn)連成三角形堵泽,此三角形的重心(即點(diǎn)M)就是最終定位點(diǎn)禀忆,步驟如下:

  1. 通過勾股定律用a、b長度計(jì)算出線段AB長度(即點(diǎn)A到點(diǎn)B距離)落恼,使用 ra + rb 與AB對(duì)比即可得知兩圓的對(duì)應(yīng)情況箩退,一共有三種情況:兩圓相離ra + rb < AB、兩圓相切ra + rb == AB佳谦、兩圓相交ra + rb > AB戴涝。
  2. 兩圓相離:按照兩圓半徑的比例在線段AZ上求O_{AZ}點(diǎn),即ra : rz = |AO_{AZ}| : |O_{AZ}Z|钻蔑;因?yàn)椤皟蓤A相切ra + rb == AB”在實(shí)際程序中出現(xiàn)的幾率太小啥刻,所以直接使用“兩圓相離”相同的求法。
  3. 兩圓相交:求出相交點(diǎn)C的坐標(biāo) {Cx, Cy}咪笑,可通過\arccos( \frac {a} {AB} )得出Q1可帽,通過\arccos( \frac {AO_{AB}} {ra} )得出Q2,最后計(jì)算出點(diǎn)C的坐標(biāo):
    Cx=Ax + (ra + \cos(Q1+Q2))
    Cy=Ay + (ra + \sin(Q1+Q2))
    同理可求出點(diǎn)D的坐標(biāo)窗怒。得到C映跟、D兩交點(diǎn)后取距離圓心Z點(diǎn)近的交點(diǎn)作為最后三個(gè)參考點(diǎn)中的一點(diǎn)。
  4. 將最后求得的三個(gè)參考點(diǎn)連接成一個(gè)三角形扬虚,該三角形的重心即為最后的定位點(diǎn)M:
    Mx = \frac{Dx + O_{AZ}x + O_{BZ}x}{3}
    My = \frac{Dy + O_{AZ}y + O_{BZ}y}{3}

采用分步定位法測(cè)量一個(gè)移動(dòng)節(jié)點(diǎn)的位置努隙,只需要3個(gè)參考節(jié)點(diǎn)。該定位法還避免了采用三邊測(cè)量法可能無解的情況辜昵,使得該方法的適應(yīng)性更強(qiáng)荸镊。

相關(guān)代碼

    CGPoint pointA = [self sidePointCalculationWith:x1 :y1 :r1
                                                   :x2 :y2 :r2
                                                   :x3 :y3 ];
    CGPoint pointB = [self sidePointCalculationWith:x2 :y2 :r2
                                                   :x3 :y3 :r3
                                                   :x1 :y1 ];
    CGPoint pointC = [self sidePointCalculationWith:x1 :y1 :r1
                                                   :x3 :y3 :r3
                                                   :x2 :y2 ];
 
    double Mx = (pointA.x + pointB.x + pointC.x) / 3;
    double My = (pointA.y + pointB.y + pointC.y) / 3;
-(CGPoint)sidePointCalculationWith:(double)x1 :(double)y1 :(double)r1 
                                  :(double)x2 :(double)y2 :(double)r2 
                                  :(double)x3 :(double)y3{
    //勾股定理  sqrt(X)是X開根號(hào)  pow(X,n)是X的n次方
    //取beacon1圓心A 與 beacon2圓心B的距離
    double AB = sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2));
    double rAB = (r1 + r2);
    if (rAB > AB && (r1 < AB && r2 < AB)) {
        //兩圓有相交點(diǎn),兩圓相交點(diǎn)為C、D堪置。兩圓與AB的相交點(diǎn)為E躬存、F。o是EF的中點(diǎn)舀锨。
        double EF = rAB - AB;
        double Eo = EF * 0.5;
        double AE = r1 - EF;
        double Ao = AE + Eo;
        double AQ1 = acos((x2 - x1) / AB);
        double AQ2 = acos(Ao / r1);
        
        double BF = r2 - EF;
        double Bo = BF + Eo;
//        double BQ1 = acos(fabs(x1 - x2) / AB);
        double BQ2 = acos(Bo / r2);
        
        //原點(diǎn){0,0}在左上角的情況下
        double Cx = x1 + (r1 * cos(AQ1 + AQ2));
        double Cy = 0.0;
        double Dx = x2 - (r2 * cos(AQ1 + BQ2));
        double Dy = 0.0;
        if (x1 < x2) {
            Dx = x2 - (r2 * cos(AQ1 + BQ2));
            if (y1 < y2) {
                Cy = y1 + (r1 * sin(AQ1 + AQ2));
                Dy = y2 - (r2 * sin(AQ1 + BQ2));
            }else{
                Cy = y1 - (r1 * sin(AQ1 + AQ2));
                Dy = y2 + (r2 * sin(AQ1 + BQ2));
            }
        }else{
            Cy = y1 + (r1 * sin(AQ1 + AQ2));
            if (y1 < y2) {
                Dy = y2 - (r2 * sin(AQ1 + BQ2));
            }else{
                Dy = y2 + (r2 * sin(AQ1 + BQ2));
            }
        }
        
        double Cc = sqrt(pow(Cx - x3, 2) + pow(Cy - y3, 2));
        double Dc = sqrt(pow(Dx - x3, 2) + pow(Dy - y3, 2));

        return Cc < Dc ? CGPointMake(Cx, Cy) : CGPointMake(Dx, Dy);
    }else{
        //兩圓無相交點(diǎn)
        return [self midpointCalculationWith:x1 :y1 :r1
                                            :x2 :y2 :r2];
    }
}
-(CGPoint)midpointCalculationWith:(double)x1 :(double)y1 :(double)r1 
                                 :(double)x2 :(double)y2 :(double)r2{
    double a = y1 - y2;//豎邊
    double b = x1 - x2;//橫邊
    double rr = r1 + r2;
    double s = r1 / rr;
    
    double x = fabs(x1 - (b * s)) ;
    double y = fabs(y1 - (a * s)) ;
    
    return CGPointMake(x, y);
}

參考資料

三邊測(cè)量法,分步定位法比較
蘋果核 - iOS端近場(chǎng)圍欄檢測(cè)(一) ——iBeacon
iOS藍(lán)牙開發(fā)之iBeacon篇(二)

---END---

原文地址:https://www.hlzhy.com/?p=161
最后岭洲,如果此文章對(duì)你有幫助,希望給個(gè)??雁竞。有什么問題歡迎在評(píng)論區(qū)探討

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末钦椭,一起剝皮案震驚了整個(gè)濱河市拧额,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌彪腔,老刑警劉巖侥锦,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異德挣,居然都是意外死亡恭垦,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門格嗅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來番挺,“玉大人,你說我怎么就攤上這事屯掖⌒兀” “怎么了?”我有些...
    開封第一講書人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵贴铜,是天一觀的道長粪摘。 經(jīng)常有香客問我,道長绍坝,這世上最難降的妖魔是什么徘意? 我笑而不...
    開封第一講書人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮轩褐,結(jié)果婚禮上椎咧,老公的妹妹穿的比我還像新娘。我一直安慰自己把介,他們只是感情好勤讽,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著劳澄,像睡著了一般地技。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上秒拔,一...
    開封第一講書人閱讀 51,462評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音飒硅,去河邊找鬼砂缩。 笑死,一個(gè)胖子當(dāng)著我的面吹牛三娩,可吹牛的內(nèi)容都是我干的庵芭。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼雀监,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼双吆!你這毒婦竟也來了眨唬?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤好乐,失蹤者是張志新(化名)和其女友劉穎匾竿,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蔚万,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡岭妖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了反璃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片昵慌。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖淮蜈,靈堂內(nèi)的尸體忽然破棺而出斋攀,到底是詐尸還是另有隱情,我是刑警寧澤梧田,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布蜻韭,位于F島的核電站,受9級(jí)特大地震影響柿扣,放射性物質(zhì)發(fā)生泄漏肖方。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一未状、第九天 我趴在偏房一處隱蔽的房頂上張望俯画。 院中可真熱鬧,春花似錦司草、人聲如沸艰垂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽猜憎。三九已至,卻和暖如春搔课,著一層夾襖步出監(jiān)牢的瞬間胰柑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來泰國打工爬泥, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留柬讨,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓袍啡,卻偏偏與公主長得像踩官,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子境输,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354