본문 바로가기

[IT/Programming]

To correct inaccurate location measured by GPS with Wi-Fi RSSI (Received Signal Strength Indicatior). (Wi-Fi 신호세기를 이용해 GPS 튀는거 잡는 방법.)

반응형
# To correct inaccurate location measured by GPS with Wi-Fi RSSI (Received Signal Strength Indicatior). (Wi-Fi 신호세기를 이용해 GPS 튀는거 잡는 방법.) Wi-Fi (와이파이) 신호 세기로부터 거리를 추측하는 법을 알아봅시다.
ps. License | Patent (특허권) : 상업적으로 사용을 금합니다. 상업적 사용을 원하시면 이 글에 댓글을 달거나 open kakao talk :: kipid 로 알려주세요. (우선 특허는 보류중.)
GPS 가 가끔씩 튈 때가 있는데, 이 때 Wi-Fi rssi 를 이용해서 위치가 튀지 않았다는 것을 보정해주면 좋음. 거리가 얼만큼 변한건지 min, max 를 추측하려면 약간은 생각을 좀 해야되는 수학이 들어가는데, 이거에 관련된건 나중에 시간이 되면 더 정리할 예정. (공책에다 유도 했던걸로 기억하는데, 이 공책 안버렸겠지? ㅡ,.ㅡ;;;;;) ## PH
  • 2023-06-05 : License | Patent (특허권).
  • 2017-08-01 : First posting.
## TOC ## Definitions
BSSID BSSID (Basic Service Set Identifier) :: `숫자값` (물리적 식별용) :: 무선 LAN 표준인 802.11 에서 기본 서비스 열역 (BSS) 를 식별하는 48비트의 식별자 또는 네트워크 ID 를 말한다. (통상 MAC 주소).
SSID SSID (Service Set Identifier) :: `문자값` (논리적 식별용) :: 무선 LAN 에서 서비스 제공자가 여러 다른 무선 셀 (BSS) 들을 구분하는데 사용하는 무선 단말과 AP 간에 접속용 ID (식별자) 를 말한다.
RSSI RSSI (Received Signal Strength Indicatior) :: Wifi 의 신호세기.
## Distance guessed from RSSI (Received Signal Strength Indicatior) ### Power law 1 Here d is distance in meters, s is signal strength (rssi) in dBm, and P is TxPower in dBm (the power received at a 1 meter distance). The below formula is from . 그런데 이 식 틀린것도 같은데... 밑하고 지수하고 바뀐거 아닌가? 그래프는 얼추 비슷하긴 하지만... \begin{align*} d &= \begin{cases} (\frac{s}{P})^{10} & \text{ if } \frac{s}{P} < 1 \\ 0.89976 (\frac{s}{P})^{7.7095}+0.111 & \text{ if } \frac{s}{P} \geq 1 \end{cases} \\ s &= P (\frac{d-0.111}{0.89976})^{1/7.7095} \end{align*} ### Power law 2 Here d is distance in meters, s is signal strength (rssi) in dBm, and P is TxPower in dBm (the power received at a 1 meter distance). The below formula is from . \begin{align*} s &= -N \log_{10} d+P \\ d &= 10^{\frac{P-s}{N}} \text{ where } 20 \leq N \leq 40 \end{align*} ### Guessed graphs of some candidate variables $P$, $N$.
RSSI to distances. Eq. , Eq. .
경험적으로 $P=-40$, $N=25$ 일 때의 그래프가 대부분의 요즘 wifi 의 RSSI vs distance 를 잘 예측하는 것으로 생각되어 매개변수들로 이 값들을 택함. ## 시간 변화에 따른 Wifi rssi 들로부터 내 위치가 어떻게 변하였는지 어떻게 알아낼 수 있을까? Wifi rssi 로부터 알아낼 수 있는 정보는 내 스마트폰과 해당 Wifi 기기까지의 절대 거리값 뿐이기 때문에, 다른 두 시간대 $t_1$, $t_2$ 와 한 개 이상의 Wifi 로부터의 rssi 로 거리값을 각각 추측하여 내 위치가 어떻게 변하였는가를 추측하여야 한다. $t_1$ 일 때의 $\text{Wifi}_k$ 으로부터의 거리를 $d_{1k}$, $t_2$ 일 때의 $\text{Wifi}_k$ 로부터의 거리를 $d_{2k}$ 라고 하자. 내 스마트폰의 위치는 $\vec{r}(t_2)$, $\vec{r}(t_1)$ 으로 표현하고, $\text{Wifi}_k$ 의 위치는 $\vec{p}_k$ 라고 표현하기로 하자. 이 때 $|\vec{r}(t_2)-\vec{p}_k| \equiv d_{2k}$, $|\vec{r}(t_1)-\vec{p}_k| \equiv d_{1k}$ 로 정의되게 된다. 계산을 간단하게 하기 위해 $\vec{r}(t_1)$ 의 위치를 $(-d, 0)$, $\vec{r}(t_2)$ 의 위치를 $(d, 0)$ 이라고 한다면,
짧은 시간 간격안에서는 wifi 가 추가되거나 사라지지 않는다고 가정할 수 있을 것이다. 하지만 Wifi 와 내 스마트폰 사이에 벽이 있다던지 (ㄱ자로 벽이 있다고 했을때 왼쪽 윗 벽면에 Wifi 가 있는 경우 내가 오른쪽 북쪽에서 남쪽으로 벽에 어느정도 붙어 이동하는 경우 Wifi rssi 가 갑자기 확 떨어지는 경우가 생긴다. 이런 경우 rssi 로 거리를 추측하는 것의 오차가 매우 커지는 상황이 생기게 된다.), 또한 중간에 다른 통신기기가 끼어들어서 Wifi rssi 로 추측한 내 스마트폰과 Wifi 사이의 거리추측이 조금은 틀려질 수 있는 가능성도 생각해야 한다.
여기서 우리가 아는 정보들은 (but 틀릴수도 있는) :: 시간 $t_1$ 에서의 각 $\text{Wifi}_k$ 들과의 거리인 $|\vec{r}(t_1)-\vec{p}_k|$ ($\equiv d_{1k}$) 와 시간 $t_2$ 에서의 각 $\text{Wifi}_k$ 들과의 거리인 $|\vec{r}(t_2)-\vec{p}_k|$ ($\equiv d_{2k}$) 이다. 이 $\text{Wifi}_k$ 하나의 rssi 로부터 추측할 수 있는 최소 이동거리와 최대 이동거리는 다음과 같이 나타나게 된다. | d_{2k}-d_{1k} | \leq | \vec{r}_2-\vec{r}_1 | \leq | d_{2k}+d_{1k} | $\text{Wifi}_k$ 가 $(-d, 0)$ 보다 왼쪽에 있거나 $(d, 0)$ 보다 오른쪽에 있어서 내 이동으로 변화한 rssi 로 추측한 거리가 $\text{Wifi}_k$ 로부터 같은 방향의 변위가 되는 경우, 이 경우가 $| \vec{r}_2-\vec{r}_1 |$ 의 최소값이 된다. 반대로 $\text{Wifi}_k$ 가 $(-d, 0)$ 보다는 오른쪽에 있고 $(d, 0)$ 보다는 왼쪽에 있을때, 즉 내가 $\text{Wifi}_k$ 를 통과하여 이동한 경우, 이 경우가 $| \vec{r}_2-\vec{r}_1 |$ 의 최대값이 된다. 그 외에 $\text{Wifi}_k$ 가 x 축 위에 있는 경우가 아니라면 $\vec{p}_k=(x_k, y_k)$ 라 했을 때, \begin{align*} d_{1k} &= |\vec{r}(t_1)-\vec{p}_k|=\sqrt{ (x_k+d)^2+y_k^2 } \\ d_{2k} &= |\vec{r}(t_2)-\vec{p}_k|=\sqrt{ (x_k-d)^2+y_k^2 } \end{align*} 가 된다. 보통 스마트폰에서 Wifi 의 위치를 정확히 알수가 없기 때문에 $\vec{p}_k=(x_k, y_k)$ 값은 우리가 모르는 값이라고 가정하고 진행하는 것이 좋다. 이 Wifi 의 위치값을 알고 있다고 가정하고 삼각측량으로 스마트폰의 위치를 알아내려는 시도도 많긴 하지만 아직까지 Wifi 의 GPS (절대적인 위치) 값을 스마트폰으로 쏴주는 기능들은 잘 보급이 안되어 있기 때문에, 이런 방법을 이용하기는 아직 시기상조라 생각된다.
내가 $(-d, 0)$ 에서부터 $(d, 0)$ 으로 이동했을때, $\text{Wifi}_k$ 로 부터의 거리.
Fig. 에서 보이듯 삼각현 세 변의 길이 관계성을 이용해 Eq. 가 나오게 된다. 조금 더 명확한 계산으로 위 결과를 바라보자면, | \sqrt{ (x_k-d)^2+y_k^2 }-\sqrt{ (x_k+d)^2+y_k^2 } | \leq 2d \leq | \sqrt{ (x_k-d)^2+y_k^2 }+\sqrt{ (x_k+d)^2+y_k^2 } | 와 같이 표현된다. ### Wifi 가 m 개 정도 있을때 (일반적인 | 대부분의 경우) Wifi 가 m 개 있을 때, 우리가 얻을 수 있는 정보는 각 Wifi 의 bssid 와 rssi 로부터 Eq. 를 이용해 추측한 거리들로 다음과 같다. \begin{align*} &| \vec{r}(t_2)-\vec{p}_k | ~~~~~ \text{for} ~~~ k=1, 2, \cdots, m \\ &| \vec{r}(t_1)-\vec{p}_k | ~~~~~ \text{for} ~~~ k=1, 2, \cdots, m \end{align*}
하지만 이 값들이 정확하지 않을 수 있다는 사실도 명심해 놔야 한다. 일 예로 시간 $t_1$ 에는 $\text{Wifi}_k$ 와 내 스마트폰 사이에 벽이 없었는데, 시간 $t_2$ 에는 내가 어디 구석으로 이동해서 $\text{Wifi}_k$ 와 내 사이에 벽이 생겨 rssi 가 확 떨어지는 경우가 있을 수 있다. 이 경우 rssi 만으로 추측한 $t_2$ 와 $\text{Wifi}_k$ 사이의 거리 $d_{2k}$ 가 확 늘어난 것처럼 계산되어 질 수 있다.
아무튼 이 값들로부터 삼각형의 세변의 길이 관계를 이용, 우리가 알 수 있는 정보는 다음과 같다. | d_{2k}-d_{1k} | \leq | \vec{r}_2-\vec{r}_1 | \leq | d_{2k}+d_{1k} | ~~~~~ \text{for} ~~~ k=1, 2, \cdots, m. 위 조건들은 AND 조건이기 때문에 왼편에는 $\max$ 를 오른쪽엔 $\min$ 을 취할 수 있다. 즉, \max_{k} | d_{2k}-d_{1k} | \leq | \vec{r}_2-\vec{r}_1 | \leq \min_{k'} | d_{2k'}+d_{1k'} | . 만약 측정오차들로 인해 $\max_{k} | d_{2k}-d_{1k} | > \min_{k'} | d_{2k'}+d_{1k'} |$ 경우가 생긴다면, | \vec{r}_2-\vec{r}_1 | \simeq \min_{k'} | d_{2k'}+d_{1k'} | 란 뜻일 것이다. 혹은 양쪽값을 적당히 평균낸 | \vec{r}_2-\vec{r}_1 | \simeq 0.8 \times \max_{k} | d_{2k}-d_{1k} |+0.2 \times \min_{k'} | d_{2k'}+d_{1k'} | 라고 추측할수도 있겠다. 더 가능성이 큰 값인 $\max_{k} | d_{2k}-d_{1k} |$ 에 비중을 더 주었다. (보통 Wifi 들은 구석에 위치하고 이런 Wifi 를 지나치면서 이동하는 경우보다 Wifi 의 한쪽 방향 방위각 180도 내에서 이동하는 경우가 훨씬 많다고 생각되어지기 때문이다.) 간혹 $| \vec{r}_2-\vec{r}_1 | >$ SOME_MAX 로 측정되었다면 rssi 값이 차이가 엄청나게 났다는 뜻으로 $| \vec{r}_2-\vec{r}_1 |$ 은 생각보다 더 멀수도 있다. 이럴땐 그냥 GPS 를 믿어야 할수도 있다. ### 결론 우선적인 결론은 Eq. 이지만, 실제 사용할 때는 $| \vec{r}_2-\vec{r}_1 |$ 가 대충 얼마라고 알려주는게 더 편할때가 많다. 따라서 적당히 두 range 사이의 weighted 평균값을 취해 대략 얼만큼을 이동했는지 값으로 알려주는게 좋다. 보통 Wifi 들은 구석에 설치되어 있는 경우가 많고, 따라서 사람들이 이동할때 이런 Wifi 들을 통과해서 이동하기 보단 Wifi 가 비슷한 방향에 놓인채로 몇 m 에서 몇백 m 정도를 움직인다고 생각된다. 따라서 Eq. 에서 앞쪽에 weight 를 0.8 정도 두고, 뒷쪽에 weight 를 0.2 주고 평균낸 값을 Wifi rssi 로 추측한 이동값이라고 보면 적당할 것이다. | \vec{r}_2-\vec{r}_1 | \simeq 0.8 \times \max_{k} | d_{2k}-d_{1k} |+0.2 \times \min_{k'} | d_{2k'}+d_{1k'} | 그런데 혹 갑자기 한 개의 Wifi 가 전원이 나갔다던가 내가 이동을 하면서 한두개의 Wifi 사이에 벽이나 장애물이 생기면서 rssi 로 부터 추측한 $| \vec{r}-\vec{p}_k |$ 값이 갑자기 튀는 (보통 200 m 이상으로 나오는) 경우가 생길때도 있다. 이 경우 \max_{k} | d_{2k}-d_{1k} | > \min_{k'} | d_{2k'}+d_{1k'} | 와 같은 상황이 발생하는데, $\max_{k} | d_{2k}-d_{1k} |$ 에 오차가 난 것이라 생각해야 하기 때문에 앞쪽 항 (term) 은 무시한채 뒷 항 (term) 만으로 거리를 추측하는 것이 더 합당하다고 생각된다. 즉, Condition 일 때에는 | \vec{r}_2-\vec{r}_1 | \simeq \min_{k'} | d_{2k'}+d_{1k'} | 가 된다. ## Example Codes ### WifiUtil.java ```[.scrollable.lang-java] package kipid.test; import kipid.test.SignalProto.Wifi; import java.time.Instant; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.Nullable; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; public class WifiUtil { /** * Use this to get a {@link String} of wifi informations in human-readable form. * Scanned-wifi-infos are truncated with {@code VALID_RSSI_LOWER_BOUND} (exclusive) * and sorted by the strongest signal strength (rssi). */ public static String toDebugMessage(@Nullable Wifi wifi) { if (wifi==null) { return "Wifi 신호가 없습니다."; } final int VALID_RSSI_LOWER_BOUND=-80; Wifi.Info currentWifi=wifi.getConnectedInfo(); List<Wifi.Info> scannedWifi=wifi.getScannedInfosList().stream() .filter(info -> info.getRssi()>VALID_RSSI_LOWER_BOUND) .sorted((w1, w2) -> w2.getRssi()-w1.getRssi()) .collect(Collectors.toList()); return new StringBuilder() .append("[Wifi 상태]\n" +DEBUG_TIME_FORMATTER.format(ZonedDateTime.ofInstant( Instant.ofEpochMilli(wifi.getTimestamp()), ZONE_ID_SEOUL)) +"-"+wifi.getState().name()+"\n") .append("[연결된 Wifi]\n"+(wifi.hasConnectedInfo()?toString(currentWifi):"없음.")) .append("[Scan 결과]\n"+scannedWifi.stream() .map(WifiUtil::toString) .reduce(String::concat) .orElse("없음.")) .toString(); } private static String toString(Wifi.Info info) { return String.format("SSID: %s, 세기: %d, BSSID: %s\n", info.getSsid(), info.getRssi(), info.getBssid()); } // Default parameters used to guess the distance from wifi. private static final double RSSI_AT_1M=-40.0; private static final double DECAY_EXP=25.0; /** * Guesses the distance from wifi, by wifi info (rssi), in meters. * When the signal is too weak (rssi less than -109, or null {@link Wifi.Info}) to determine the * distance, this returns max distance, 200 m, where wifi signal can reach. * On the other hand, when the signal is stronger than {@code RSSI_AT_1M}, this returns min * distance, 1 m, since the accuracy within 1 meter is not our concern. * * @param info {@link Wifi.Info} including rssi (Received Signal Strength Indication). * @return The guessed distance from the specified wifi, in meters. */ static double guessDistanceFromWifi(@Nullable Wifi.Info info) { if (info==null) { return 200.0; // Max distance where wifi signal can reach. } int rssi=info.getRssi(); if (rssi>=RSSI_AT_1M) { return 1.0; // Min distance since the accuracy within 1 meter is not our concern. } if (rssi<-90) { return 200.0; // Max distance since the signal is too weak to get the accurate distance. } return guessDistanceFromWifi(rssi, RSSI_AT_1M, DECAY_EXP); } /** * Helper function (private) to guess ths distance from wifi, through rssi. * See * https://stackoverflow.com/questions/20416218/understanding-ibeacon-distancing/20434019#20434019 * https://forums.estimote.com/t/use-rssi-measure-the-distance/3665 * Recommended keyword for deeper investigation is "rssi to distance". * * @param rssi Received Signal Strength Indication in dBm. * @param txPower RSSI at 1 meter, in dBm. * @param decayExp Decay exponent, usually from 20 to 25. * @return The distance from wifi, in meters. */ private static double guessDistanceFromWifi(final double rssi, final double txPower, final double decayExp) { return Math.pow(10.0, (txPower-rssi)/decayExp); } /** * <p>Guesses the distance between two scanned-wifi-informations, in meters. * If the guessed distance is over 140 m, it means that the distance is * over 140 m, not the guessed distance. In that case, use another measure to guess * the distance between two. * * <p>우리가 알 수 있는 정보는 어딘가에 고정된 wifi (k) 로부터 대략 어느정도 떨어져 있었느냐 (d_k) 이기 때문에, * 이 거리가 어떻게 변하였는지를 보고 이동거리를 추측할 수 밖에 없다. 이 경우 두개의 원 (반지름 d1_k, d2_k) 이 그려지고 * 이동거리 (d21) 는 {@code |d2_k-d1_k| < d21 < d2_k+d1_k} 일 수밖에 없는데, 여러 고정점에서부터의 거리정보가 * 있을 경우 and 조건이기 때문에 이 범위가 줄어들 수 있다. * 즉, {@code max_k |d2_k-d1_k| < d21 < min_k' (d2_k'+d1_k')} 란 조건이 나온다. * * <p>단, wifi rssi 로부터 추측한 wifi 로부터의 거리값이 장애물 유무나 wifi 특성 (rssi at 1m), temporal dead * 등에 따라 오차가 클 수 있기 때문에, 위의 and 조건이 안 찾아지는 경우 (d21 의 range min 값이 max 값보다 큰 경우) 가 * 있을 수 있다. 이 경우 range min 값에 오차가 있을 확률이 매우 크기 때문에 range min 값을 무시하도록 디자인 하였다. * * <p>또한 d21 의 경우 range 의 max 값 근처일 경우보다 min 값 근처일 경우가 많다고 경험적으로 여겨지므로, * min 추측값에 더 큰 비중 (0.8) 을 두고 평균을 낸 값을 리턴하도록 디자인 하였다. * * @return The guessed distance between two scanned-wifi-informations, in meters. */ public static double guessDistanceBtw(Wifi wifi1, Wifi wifi2) { Map<String, Wifi.Info> scannedWifi1=collectWifiInfosToMap(wifi1.getScannedInfosList()); Map<String, Wifi.Info> scannedWifi2=collectWifiInfosToMap(wifi2.getScannedInfosList()); Map<String, Pair<Wifi.Info, Wifi.Info>> pairsOfWifiInfo=new HashMap<>(); for (String bssid1:scannedWifi1.keySet()) { // Common wifi infos. And wifi1's exclusive infos. pairsOfWifiInfo.put(bssid1, ImmutablePair.of( scannedWifi1.get(bssid1), scannedWifi2.get(bssid1) )); } for (String bssid2:scannedWifi2.keySet()) { if (!scannedWifi1.containsKey(bssid2)) { // wifi2's exclusive infos. Wifi.Info info2=scannedWifi2.get(bssid2); pairsOfWifiInfo.put(bssid2, ImmutablePair.of(null, info2)); } } double maxD2D1Diff=0.0; double minD2D1Add=1000.0; for (Pair<Wifi.Info, Wifi.Info> pairOfWifiInfo:pairsOfWifiInfo.values()) { double d1=guessDistanceFromWifi(pairOfWifiInfo.getLeft()); double d2=guessDistanceFromWifi(pairOfWifiInfo.getRight()); maxD2D1Diff=Math.max(Math.abs(d2-d1), maxD2D1Diff); minD2D1Add=Math.min(d2+d1, minD2D1Add); } if (maxD2D1Diff >= minD2D1Add) { return minD2D1Add; } return 0.8 * maxD2D1Diff+0.2 * minD2D1Add; } /** * Calculates similarity between two scanned-wifi-informations. * The value of similarity is from 0.0 (least similar) to 1.0 (most similar). * When both have no scanned-wifi-informations, this returns -1. * * @return The similarity between two scanned-wifi-informations. [0.0 ~ 1.0] */ public static double similarityBtw(Wifi wifi1, Wifi wifi2) { Map<String, Wifi.Info> scannedWifi1=collectWifiInfosToMap(wifi1.getScannedInfosList()); Map<String, Wifi.Info> scannedWifi2=collectWifiInfosToMap(wifi2.getScannedInfosList()); double similaritySum=0.0; int count=0; for (String bssid1:scannedWifi1.keySet()) { // Common wifi infos. And wifi1's exclusive infos. if (scannedWifi2.containsKey(bssid1)) { int rssiDiff=scannedWifi2.get(bssid1).getRssi()-scannedWifi1.get(bssid1).getRssi(); similaritySum+=1.0/(rssiDiff*rssiDiff/2500.0+1.0); } count++; } for (String bssid2:scannedWifi2.keySet()) { if (!scannedWifi1.containsKey(bssid2)) { // wifi2's exclusive infos. count++; } } return (count==0)?-1.0:similaritySum/count; } private static Map<String, Wifi.Info> collectWifiInfosToMap(List<Wifi.Info> scannedInfos) { return scannedInfos.stream() .collect(Collectors.toMap(Wifi.Info::getBssid, Function.identity())); } } ```/ ### signal.proto ```[.scrollable] syntax="proto3"; package signal; option java_package="kipid.test"; option java_outer_classname="SignalProto"; message Tick { // User ID. string uid=1; // Installation ID. string iid=2; // The UTC timestamp in milliseconds since January 1, 1970. int64 timestamp=3; } // Next ID: 11 message Location { // User ID. string uid=8; // Installation ID. string iid=9; // The UTC timestamp in milliseconds since January 1, 1970. int64 timestamp=1; // The latitude, in degrees. double latitude=2; // The longitude, in degrees. double longitude=3; // When stored to MongoDb, we encrypt latitude and longitude values to this field. string encryptedLatLng=10; // The altitude if available, in meters above the WGS 84 reference ellipsoid. double altitude=4; // The estimated horizontal accuracy of this location, radial, in meters. float accuracy=5; // The bearing, in degrees. float bearing=6; // The speed if it is available, in meters/second over ground. float speed=7; } message Locations { repeated Location locations=1; } // Next ID: 7 message Wifi { // User ID. string uid=1; // Installation ID. string iid=6; int64 timestamp=2; // The UTC timestamp in milliseconds since January 1, 1970. enum State { STATE_DISABLING=0; STATE_DISABLED=1; STATE_ENABLING=2; STATE_ENABLED=3; STATE_UNKNOWN=4; } State state=3; message Info { string bssid=1; // The address of the access point. string ssid=2; // The network name. int32 rssi=3; // The signal level in dBm. int64 timestamp=4; // Timestamp when connection is detected. } Info connected_info=4; // Information about wifi channel currently connected. repeated Info scanned_infos=5; } ```/ ## TESTS ### TEST0 : Completely same Wifi infos $\rightarrow$ $d_{2k}=d_{1k}$ 내 스마트폰에 잡힌 Wifi list 들과 rssi 들이 모두 같은 경우라면, \max_k | d_{2k}-d_{1k} |=0 이란 뜻이고, \min_{k'} | d_{2k'}+d_{1k'} |=2 \min_{k'} d_{1k'} 가장 가까운 wifi 까지의 거리의 2배란 뜻이다. 이 값을 우리의 결론 방정식인 Eq. 에 대입하면 \begin{align*} | \vec{r}_2-\vec{r}_1 | &\simeq 0.2 \times 2 \times \min_{k'} d_{1k'} \\ &= 0.4 \times \min_{k'} d_{1k'} \end{align*} 가장 가까운 Wifi 까지의 거리가 대충 10 m 였다고 친다면, Wifi infos 가 하나도 안 바뀌었을때 이동값으로 4 m 정도를 추측하는 것을 알 수 있다. 상당히 합리적인 (reasonable) 한 값이라 생각한다. | \vec{r}_2-\vec{r}_1 | \approx 4 \text{m} . ### TEST1 : Small differences between Wifi infos $\rightarrow$ $| d_{2k}-d_{1k} | \ll L (\simeq 100 \text{m})$ 내 스마트폰에 잡힌 Wifi list 들과 rssi 들이 모두 비슷한 경우라면, \max_k | d_{2k}-d_{1k} | \ll L 이란 뜻이고 \min_{k'} | d_{2k'}+d_{1k'} | \leq 2 \max_{k'} d_{1k'} ~~~ \text{or} ~~~ \leq 2 \max_{k'} d_{2k'} 이란 뜻이다. 이 값들을 결론 방정식 Eq. or Eq. 에 대입하면, ($\max_{k} | d_{2k}-d_{1k} | \approx 20 $m, $\min_{k'} | d_{2k'}+d_{1k'} | \approx 40 $m 라 하면) \begin{align*} | \vec{r}_2-\vec{r}_1 | &\simeq 0.8 \times 20 \text{m}+0.2 \times 40 \text{m} \\ &=24 \text{m} . \end{align*} Wifi 하나가 갑자기 $t_1$, $t_2$ 사이에 꺼져서 이 Wifi 의 rssi 로 추측한 거리값이 튀었다면, $\max_{k} | d_{2k}-d_{1k} | \approx 200 $m 정도로, $\min_{k'} | d_{2k'}+d_{1k'} | \approx 40 $m 정도로 나왔을 것이므로, Condition 이 되었을 것이다. 따라서 Eq. 써서 결론을 내본다면, | \vec{r}_2-\vec{r}_1 | \simeq 40 \text{m} 정도가 나왔을 것이다. 이것도 매우 합리적인 (reasonable) 한 값이라 추측된다. ### TEST2 : Some differences between Wifi infos $\rightarrow$ $| d_{2k}-d_{1k} | \approx L (\simeq 100 \text{m})$ 내 스마트폰에 잡힌 Wifi list 들과 rssi 들이 어느정도 차이가 나는 경우라면, \max_k | d_{2k}-d_{1k} | \approx L (\simeq 100 \text{m}) 라는 뜻이고, \min_{k'} | d_{2k'}+d_{1k'} | \approx 2L (\simeq 200 \text{m}) 란 뜻일 것이다. 이 결과를 Eq. 에 대입하면, \begin{align*} | \vec{r}_2-\vec{r}_1 | &\simeq 0.8 \times 100 \text{m}+0.2 \times 200 \text{m} \\ &= 120 \text{m} \end{align*} 정도로 합리적인 (reasonable) 한 값이 나온다. #### 특이한 상황을 가정해보자.
일부 Wifi 들이 벽에 가로막히는 상황.
위 Fig. 와 같이 내가 움직임에 따라 특정 Wifi 들과의 rssi 가 벽이나 장애물에 가로막혀 $d_{11} \equiv | \vec{r}_1-\vec{p}_1 |$, $d_{12} \equiv | \vec{r}_1-\vec{p}_2 |$, $d_{13} \equiv | \vec{r}_1-\vec{p}_3 |$ 들은 20 m 정도였다가, $d_{21} \equiv | \vec{r}_2-\vec{p}_1 |$, $d_{22} \equiv | \vec{r}_2-\vec{p}_2 |$, $d_{23} \equiv | \vec{r}_2-\vec{p}_3 |$ 가 갑자기 200 m 정도로 튀었다고 가정해보자. 대신 $\text{Wifi}_5$ 는 다른 위치에 있어서 $d_{15} \equiv | \vec{r}_1-\vec{p}_5 |$ 는 30 m 정도였다가 $d_{25} \equiv | \vec{r}_2-\vec{p}_5 |$ 가 10 m 정도로 바뀐 상황을 생각해보자. 이런 상황이 condition 에 해당하기에 대충의 이동거리를 구할때 우리는 Eq. 을 써야 한다. 즉 결론적으로 이런 특이한 경우에도 우리의 계산 방식은 \begin{align*} | \vec{r}_2-\vec{r}_1 | &\simeq \min_{k'} | d_{2k'}+d_{1k'} | \\ &= | d_{25}+d_{15} |=30 \text{m}+10 \text{m}=40 \text{m} \end{align*} 로 합리적인 (reasonable) 값이 나오는 걸 알 수 있다. ### TEST3 : Completely different from each other Wifi infos $\rightarrow$ $| d_{2k}-d_{1k} | \approx L_{MAX} (\simeq 200 \text{m})$ 마지막으로 내 스마트폰에서 얻은 Wifi infos 가 시간 $t_1$, $t_2$ 에 거의 완벽히 다르다고 가정해보자. 즉 대부분의 bssid 가 겹치지 않고 같은 bssid 가 잡혔어도 rssi 차이가 너무 많이 차이 나는 경우라고 하자. 이 경우 | d_{2k}-d_{1k} | \gg L_{MAX} (\approx 200 \text{m}) ~~~~~ \text{for all} ~~~ k 라고 할 수 있고, Eq. 을 적용했을 때, \begin{align*} | \vec{r}_2-\vec{r}_1 | &\simeq 0.8 \times 200 \text{m}+0.2 \times 200 \text{m} \\ &= 200 \text{m} \end{align*} 이 나온다. Wifi rssi 를 이용한 이동거리 추측은 적은 거리 차이 ($\leq 150 \text{m}$) 에만 거의 맞다고 할 수 있기 때문에 이렇게 200 m 정도가 나온 거리는, 이 정도 거리를 이동했다고 추정하기 보단, 특정 거리 (150 m) 이상 이동했다라는 의미로 받아들여야 한다. 즉, 이 방법으로 150 m 이상으로 이동거리가 추정된다면 그 이상 이동했을 경우가 많단 뜻이고, GPS 가 튀어 이동한 것도 어느정도 맞는 것일 수도 있다는 의미가 된다. ## 한계점 : 움직이고 있는 Wifi 기계 (예 : 지하철에 설치된 Wifi 같은 것들) 실제로 내가 지하철을 타고 움직이고 있을지라도 지하철에서 나와 같이 이동하는 Wifi 의 rssi 는 거의 변하지 않을 것이기 때문에 이 Wifi rssi 를 이용한 이동거리 추측은 이런 경우 완전히 빗나갈 수 있다. 이 경우는 GPS 를 믿어야 하고 움직이고 있는 Wifi 에서는 특히나 자신의 GPS 위치를 주기적으로 Wifi receiver 들 (주로 스마트폰들, Tablet PC, Labtop) 에게 전달해 주는 시스템을 구축하는 것이 여러모로 좋아보인다. 특히나 지하철 같은 경우 지하로 다니기 때문에 GPS 로 자신의 위치를 정확히 알아내기가 쉽지 않다. 따라서 요즘 지하철을 타고 가면서 지도앱을 켜고 내 현 위치를 살펴볼때에 지하를 달리고 있다면 내 위치가 실제 위치와 수십 km 차이가 나는 것도 종종 볼 수 있다. 다수의 편의를 위해 지하철이나 동굴 등에서도 GPS 가 잘 작동하도록 시스템을 만들어 줄 필요성이 있어보이고, 이것은 5G 통신망이나 Wifi 에서 통신기의 위치를 주기적으로 사방에 뿌려주는 것으로 해결하는 것이 가장 간단하고 비용이 적게 드는 방법이라는 생각이 든다. ## RRA
  1. gist.github.com/eklimcz-RSSI to Distance Conversion
    stackoverflow.com-Understanding ibeacon distancing
  2. forums.estimote.com-Determine accurate distance of signal
    forums.estimote.com-Use rssi measure the distance
    www.academia.edu-Wi-Fi Indoor Positioning System Based on RSSI Measurements from Wi-Fi Access Points –A Tri-lateration Approach
  3. academia.edu :: Wi-Fi Indoor Positioning System Based on RSSI Measurements from Wi-Fi Access Points –A Tri-lateration Approach, by Onkar Pathak, published when???
  4. academia.edu :: A Passive WiFi Source Localization System based on Fine-grained Power-based Trilateration, by Desislava Dimitrova, published when???
반응형