Indoor positioning with WiFi RTT and Google WiFi
Android Pie was released back in August 2018 and one of the exciting new features was native support for Indoor positioning with Wi-Fi RTT, also known as 802.11mc. Google also subsequently released a development guide for “ranging with RTT” as well as a sample app (now moved to here) and an image showing an example use case in an office. All very exciting stuff but I didn’t have much time to investigate further when it first launched.
Flash forward to today and I am hearing more and more interest in Wi-Fi RTT so I finally found some time to properly look at the technology. Firstly, there is no shortage of online blogs and articles about Wi-Fi RTT but as far as I could tell most of them are just rehashing what Wi-Fi RTT is, how it works or the potential it offers – in over a year since Pie introduced most of the android community to the technology I could not find any actual deployments or real world experience so I would have to start from scratch.
A Wi-Fi RTT deployment needs 3 pieces of hardware / firmware:
- An Android device running Pie or higher
- A network stack in your Android device that supports Wi-Fi RTT
- Multiple access points in range of your device that support 802.11mc
I had a Pixel 2 running Android Pie (later upgraded to Android 10) so that took care of the first two bullets. Finding an access point that claimed support for 802.11mc was harder than I thought it would be. There is a closed issue from the original sample app where the sample author points the poster to the filet2 or the Wild and searching in September 2019 I could not find any other APs that officially supported 802.11mc. At around $265 plus taxes plus any import duties to the UK those recommended APs were a bit out of my price range, especially since I would need 4 of the things to accurately find my position in 3D space.
Like anybody able to use Google I stumbled across an archived MIT post which stated that many “mesh” type APs will work with Wi-Fi RTT but will not necessarily advertise or support the technology. I had heard rumours that Google WiFi worked with 802.11mc. Despite a forum post from August 2019 on the official support forum stating that the July firmware did not support Wi-Fi RTT and no claims of support in the tech specs I bought a single Google WiFi unit to do some testing.
After updating the Google WiFi firmware I was happy to see that the official sample app was returning ranging requests from the AP so I bought a few more WiFi units to do some testing.
The official sample app will only get you so far, it returns the distance to a single specified AP as well as the standard deviation of that measurement, to give you an indication of the accuracy of that distance.
Before discussing AP location any further it is important to note that the Wi-Fi RTT Android API was enhanced in API level 29 (Android 10) to include the ResponderLocation API – this attempts to alleviate the most labour intensive part of indoor positioning which is associating hardware (APs in this case but the principle also applies to BLE beacons etc) to that hardware’s physical location in the real world. It is no good knowing you are 3 meters from an AP without knowing where that AP is located. Even after upgrading my APs to the latest firmware and my device to Android 10, Google WiFi did not report any ResponderLocation in response to ranging requests. I didn’t really expect it to but given Google’s uncanny ability to locate their users I wasn’t sure what to expect.
The development guide glosses over the process of determining a user’s position in 2D or 3D space based on their distances to several known objects with a passing reference to ‘use a multilateration algorithm’. I had never heard of multilateration but I quickly found it is one of those words which once you use it, people will start using it back at you (like ‘disposition’ or ‘cognizant’).
Anyway, see Wikipedia for more information but given my Mathematics ‘A-level’ was nearly 20 years ago I didn’t fancy creating my own – luckily there is a great library that performs multilateration and is released under an MIT license, https://github.com/lemmingapex/trilateration. The library takes as inputs an array of distances to objects (which we have from the Android Wi-Fi RTT API) and a 2D array of where those objects are located – the algorithm can cope with multiple dimensions but I restrained myself to 3D space for my initial tests. Although I felt silly when I realised you couldn’t just pass in lat/long into the algorithm, I was pleased to see I wasn’t the first person to assume this.
Surveying & Mapping the indoor space
My first instinct was to convert the physical lat/long coordinates of my Access Points into cartesian coordinates and there is a simple formula you can follow as long as the curvature of the earth is not an issue (StackOverflow post) however this quickly became very complicated. Firstly determining the elevation of the surveyed location is non-trivial but you quickly realise that determining the exact lat/long location of an object indoors is very difficult. I quickly abandoned this approach and just defined my own coordinate system.
I was testing at home and was able to find a map of my property from the original estate agents brochure but the disclaimer that “all measurements were approximate” did not fill me with confidence. Nonetheless, it was easier than drawing my own map, so I placed the APs around the house and got the tape measure out.
I put 4 access points around the house, 2 on each floor. I started out with a 3-dimensional space because the first question that always comes up when discussing indoor location is “what about floors?”. In a realistic deployment there will be a lot more metal to interfere with the AP signal propagation, but I thought I would test in a residential environment first to give me a better chance of success.
My coordinate system stated from the lower left-hand corner of the house with x+ being right and y+ being up (on the diagram). Z+ was obviously the height. This aligns with the 3D cartesian system described on Wikipedia and I wanted to ensure my x+ and y+ directions matched convention since I’m sure it matters to the multilateration algorithm. I kept the coordinate system values in millimetres to match the units returned from the Wi-Fi RTT Android API.
I wrote my own application to test the performance of Wi-Fi RTT with Google WiFi. It is available on Github at https://github.com/darryncampbell/WiFi-RTT-Trilateration but be aware a lot of the logic for displaying a pin on a map is hard-coded.
This sample app uses a weighted average of the past 10 readings to determine the user’s position. See the ReadMe file of the project for more information on setting it up for your own environment, the configuration step is manual, and the project contains some sample configurations that I used for my own testing.
- The distance returned by the Wi-Fi RTT Android API only seems to be accurate in a 2D plane when ranging against a Google WiFi AP in my tests. The measurement when both my phone and the AP were on the same plane was reasonably accurate (±0.5m) but as soon as I lifted my phone above the plane the distance dropped (you would expect it to increase, since the hypotenuse is always longer)
- Wi-Fi signal propagation through walls, even in my residential property, had a significant impact on the accuracy of the range returned from the Android API. This is not surprising as signals must bounce around corners so the ranged distance will appear longer than a direct line but without reading the technical implementation of RTT I only found this out via testing.
The combination of the above two points meant that the accuracy I observed in my residential property for 3D tests was very poor. Wi-Fi is best suited to an open plan environment like an office or a mall where your current floor can be determined without relying on the distance to an AP on some other level.
- The accuracy of any single call to the Wi-Fi RTT Android API was not necessarily very accurate, only by taking rapid measurements and removing the noise in those readings can you arrive at an accurate measurement of distance. My sample app uses a weighted mean of the last n readings which should be slightly more accurate than the official Google sample which takes the average of all readings since you started ranging. You might also consider using a Kalman filter if the subject being measured is moving at a known velocity, e.g. you are tracking a robot in a warehouse.
- I found that calling the Wi-Fi RTT Android API frequently gave me more accurate results, since I was able to combine the averages of more readings to determine the user’s “current” position.
- I attempted to improve the distance readings by turning off my residential Wi-Fi and putting the Google WiFi APs on different channels. The former had little if any effect and the latter is not actually possible with Google WiFi, which I found surprising (they seem to choose their own channels).
Wi-Fi RTT does work today with Google WiFi but understand the inherent limitations:
- Google WiFi is a consumer product, not designed for industrial deployments. It is good to understand Wi-Fi RTT and for proof of concept testing.
- Avoid signal propagation delays which will be introduced by walls, doors, obstacles or by ranging between floors. Testing in an open plan environment, I was seeing accuracy well within Google’s claim of “within 1-2 meters”.