Beaconで位置推定するときにどうすりゃええねんって人の為に簡単にメモっておきます。
# 測量法
フィンガープリントとか三角測量とか三辺測量とかGPS測量とかいろいろな測量法があります。正直よくわかりません。
フィンガープリントは一般的に精度が高いっていうけど事前学習が面倒だったりするので、今回はGPS測量で使われている方式を利用します。
GPS測量は座標が既知の3点(衛星)からの距離が分かれば、受信する端末の相対座標が分かるって原理です(実際は時刻同期の為に4機の衛星が必要ですが今回は考えません)。この衛星をBeaconに変えることで屋内での位置推定が可能です。
つまり以下の計算が出来ればおkです。
- Beaconからの距離
- 相対座標
Beaconからの距離は電波強度(RSSI)から求めることができます。
相対座標も座標が既知の3つのBeaconとRSSIから求めた距離を用いて求めることができます。公式とかは参考文献が分かりやすかったのでを参照してください。以下に実装例をメモっておきます。
# 実装
ここでは例としてObjective-cで表記しておきます。
- RSSIを距離へ変換 -
/*RSSIを距離へ変換*/
-(CGFloat)value:(float)num power:(int)val{
CGFloat ans,x,k;
k = 2; //フリスの伝達公式(自由空間では2くらい)
x = (num+val)/(-10*k);
ans = powf(10, x);
return ans;
}
- 位置座標を計算 -
/*位置座標を計算*/
- (CGPoint)manPoint:(CGPoint)a beaconB:(CGPoint)b beaconC:(CGPoint)c distanceA:(CGFloat)dA distanceB:(CGFloat)dB distanceC:(CGFloat)dC {
CGFloat Va, Vb, x, y ;
Va = ((powf(dB,2)-powf(dC, 2))-(powf(b.x, 2)-powf(c.x, 2))-(powf(b.y, 2)-powf(c.y, 2)))/2;
Vb = ((powf(dB,2)-powf(dA, 2))-(powf(b.x, 2)-powf(a.x, 2))-(powf(b.y, 2)-powf(a.y, 2)))/2;
y = (Vb*(c.x-b.x)-Va*(a.x-b.x))/((a.y-b.y)*(c.x-b.x)-(c.y-b.y)*(a.x-b.x));
x = (Va-y*(c.y-b.y))/(c.x-b.x);
return CGPointMake(x, y);
}
# 参考文献
[1] http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.684.6710&rep=rep1&type=pdf
[2] https://pdfs.semanticscholar.org/69b0/a4b23d06f5244975394542fd6829a0e92658.pdf