There are hundreds of Wi-Fi access points at our campus. They're constantly broadcasting a beacon signal that identifies each station by a MAC address. The signals can be passively received by any Wi-Fi equipped device. Exploiting this fact, I wrote a program to help locate lost students and staff wandering around the campus. I submitted it as a project for my positioning class.
Before the positioning would work, I could be seen walking around with my computer and mapping the Wi-Fi signal at various places. I would stay in one place for several minutes and collect signal strengths of all devices in range. I would then take each pair of access points and calculate a power ratio every few seconds; then assume a normal distribution and fit a Gaussian curve onto it; and save the Gaussian parameters in a database along with discrete location information input manually. (Kjaergaard, M.B. "Hyperbolic Location Fingerprinting: A Calibration-Free Solution for Handling Differences in Signal Strength", Pervasive Computing and Communications, 2008, Sixth Annual IEEE International Conference on, pp. 110–116)
To determine the position of a computer, a script is run that lists all signal strengths of all stations in range. Again, power ratios are calculated, and the fitted Gaussians are compared to Gaussians saved in the database. A location with the highest probability is determined using Bayesian inference and plotted on a map inspired by the Harry Potter realm.
Hearing 40 APs ┌─────────────────────────────┐ │═ │ 9.417e-217 24 Haxxorointiluokka │═════════════════════════════│ 2.011e-207 28 Navetta │══════════════════ │ 2.607e-211 27 Gurulan sohva │════ │ 8.437e-216 25 Gurulan pöytä │═══════════════════ │ 8.032e-211 25 Unicafe Exactum (Gurulan puoli) │═══════════════ │ 1.079e-212 25 CK112 takaosa │══════════════════════ │ 1.107e-209 25 CK112 keskiosa │═════════════════ │ 9.121e-212 25 CK112 etuosa │════════════════ │ 1.986e-212 24 Unicafe Exactum (Normaali puoli) │ │ 0.000e+00 2 BK107 │═════════════ │ 4.054e-214 27 D123 │═ │ 6.020e-218 18 C127 │ │ 0.000e+00 12 C222 │ │ 0.000e+00 10 D234 │ │ 0.000e+00 9 Linus Torvalds -auditorio │ │ 0.000e+00 0 Liikuntakeskus │ │ 0.000e+00 0 Unicafe Physicum │ │ 0.000e+00 0 Chemicumin aula │ │ 0.000e+00 2 Lars Ahlfors -auditorio │ │ 0.000e+00 4 B221 │ │ 0.000e+00 0 Unicafe Protoni │ │ 0.000e+00 0 Unicafe Neutroni │ │ 0.000e+00 5 B222 │ │ 0.000e+00 12 C323 │══════ │ 8.308e-215 25 CK110 │ │ 0.000e+00 0 Puutarha │ │ 0.000e+00 0 Kirjasto: yläkerran lukumesta │ │ 0.000e+00 0 Kirjasto: hiljainen lukusali │ │ 0.000e+00 0 Kirjasto: alakerran lukumesta (ikk.) │ │ 0.000e+00 0 Kirjasto: alakerran lukumesta └─────────────────────────────┘ we're in: --> Navetta <-- done
This is fun but presents a few problems. To get low-level access to the Wi-Fi interface on Linux, iwlist wlan0 scan needs to be run as a privileged user (i.e. root). Also, the prerecorded model of signal strengths gets out of sync with the real world in a few weeks, probably because of minute changes in room interiors. The positioning still works, but room-level resolution is lost. An automatically updating model would be practical, since the manual recording phase is pretty tedious.
The Perl source is on GitHub [hox: for scientific interest only; it's not a complete, working program].