Wi-Fi based positioning
Accurate Wi-Fi based indoor positioning
![[Picture: Calibration points, heatmap, and test route]](Testbed.gif)
Although Wi-Fi (IEEE 802.11) has not been designed for positioning, its radio signals can be used for location estimation by exploiting the Received Signal Strength (RSS) values measured in any off-the-shelf mobile device equipped with Wi-Fi facilities. It can be done either through proximity detection via radio signal propagation models or using location fingerprinting techniques.
This page provides access to location fingerprinting data collected in the RSS measurement session reported in AICT2010 paper. The data is in Matlab .mat format. It contains measurements for 82 calibration points (training data set) and 68 test points (test data set).
The first figure shows layout of the testbed environment (approximately 860 square meters) and the locations where RSS measurements were performed to create the radio map.
The second figure shows the test points and their corresponding estimated locations (for two opposite directions). The average positioning error here is 1.8 m. The estimated locations almost always fall in the correct room providing a near 100% accuracy on the room-level granularity.
For details see AICT2010 paper
Download the data here
Accessing Wi-Fi signal strength readings from Java code
This should work on Windows XP (starting from SP1), Windows Vista, Windows 7 and GNU/Linux environments (although I fully tested it only on Windows XP).
The main idea here is using C code and Java Native Interface (JNI) to create a .dll file (or .so file in GNU/Linux) which includes all the required Wi-Fi signal strength reading functionality and then access this functionality from Java code. The Wi-Fi API used in the .dll is the adapter-independent wlan-api created by Moritz Mertinkat.
The general steps required to build everything from scratch:
Download and unzip wlan-api library.
Download: here
Some documentation: here
Presentation: hereDownload and install Cygwin.
Step-by-step installation walkthrough: hereTest wlan-api and Cygwin installation by compiling example_list_aps.cpp found in wlan-api archive.
Download and install Java Development Kit (I used JDK 6 Update 17).
Create a .dll file accessable from Java code (see a nice tutorial on how to do it on InOnIt.com):
- Create a Java class (Wlan.java) with the required native methods and compile it.
- Create a C header file from the created Wlan.class file automatically using javah from the SDK (i.e. "javah -o Wlan.h Wlan").
- Write the C code (Wlan.c) providing the required functionality by calling the different wlan-api functions and compile it as a stand-alone .dll (remember to use the "-mno-cygwin" parameter for the compiler so that the compiled .dll would not depend on Cygwin).
- Complete the Java class so that it loads the Wlan.dll and calls its methods.
Use your favourite IDE to develop the rest.
You are done. Have fun.
The wlan-api library supports four kinds of Wi-Fi driver interfaces:
- NDIS User-Mode I/O (NDISUIO) driver (recommended on Windows XP);
- Wireless Zero Configuration (WZC) service (not recommended on Windows XP);
- Native WiFi API (for Windows Vista and 7; do not use it on Windows XP);
- (K)NetworkManager over D-BUS (for GNU/Linux).
Native WiFi API is useless on Windows XP as it is not fully implemented (see e.g. the presentation of wlan-api). Use either NDISUIO or WZC. However, in my experiments WZC turned out to be also mostly useless as it tends to either provide incomplete acesss point (AP) list or no list at all. For the best results, kill the WZC service right before accessing wlan-api and use NDISUIO. If you comment-out Native WiFi initialization code in wlanapi.cpp before compiling it, the library will do exactly that (except that the killing of WZC must be performed separately (e.g. using command "net stop "Wireless Zero Configuration"").
One of the remaining problems is that apparently the AP list cannot be refreshed at will (at least on Windows XP). This means that the AP list with its signal strength values will either be refreshed by the driver/service itself once per about a minute or might be even never refreshed. Although the wlan-api (as well as some APIs developed by other authors) includes AP list scanning functionality, i.e. using OID_802_11_BSSID_LIST_SCAN, it seems that the functionality usually does not work (because of the inner workings of the different versions of Windows drivers, unstandardized behaviour of different Wi-Fi adapters etc.). However, you can also use a different approach - while using your program, use some other Wi-Fi scanning software in the background (e.g. NetStumbler, Ekahau Heatmapper etc.). This way the AP signal strength readings of the Wi-Fi adapter can be refreshed once per second by the scanning software and there is no additional programming required.
You may run into yet another problem: APs may not dissapear from the AP list although they are actually turned off or are already too far away. One way of dealing with this is to try running a different scanning software in the background which actually deletes the dissapeared APs. The other way is to periodically automatically disable and re-enable Wi-Fi adapter (e.g. using devcon.exe). If you know a better solution to any of these problems, please let me know.
Now, if you are using Windows XP, you can skip right to the 6th step in the list above - the archive provided here already includes the ready-to-use .dll file with all the functionality provided by the wlan-api library. I also made some small modifications to the library and fixed a bug (detailed information about the modifications can be found in the archive).
Download archive containing the modified wlan-api library, other source files, and ready-to-use .dll file here
