Wifibased localization with skyhook Skyhook wifibased localization GPS
Wifi-based localization with skyhook
Skyhook wifi-based localization • GPS has several drawbacks – GPS uses significant energy (not good for battery powered things) – GPS does not work indoors • GPS uses satellites with high frequency radios. These signals are absorbed by walls • Wifi based localization – Collect a wifi signature • A set of base station MAC addresses (and signal strengths) • approaches – Look up in a table to determine the location of each base station, and then estimate location. – If wifi signatures are known in some known locations (e. g, known from gps), then we can interpolate between these wifi signatures to estimate the location of a different wifi signature – Different methods are examined in a different lectures – But how to collect all these signature-locations pairs • Drive around in cars and record pairs (common approach) • Use GPS to get location (also common) • Neither of these techniques will give location indoors. – In theory, you could do this yourself indoors. But that is expensive
• Get skyhook SDK from skyhookwireless. com and decompress • Start a new project with two buttons (start and stop) and on. Click. Listeners • Import Sky. Hook. Wireless. jar In eclipse, right click on src folder Select build path Select configure Select Libraries tab click “add external jar” button Navigate and select the Sky. Hook. Wireless. jar file, which is in the Sky. Hook. Wireless/lib folder where the Sky. Hook SDK was decompressed – THEN, select Order and Export tab, and select wpsapi. jar – Go to your java source, at the top type import com. skyhookwireless. *; – – –
• (see skyhookwireless quick start information for up to date information) • Set permissions – Internet – CHANGE_WIFI_STATE – ACCESS_WIFI_STATE – ACCEESS_CORSE_LOCATION – ACCESS_FINE_LOCATION
In Sky. Hook. Test. Activity • Add member variables – WPS wps = null; // for wifi only – //XPS xps = null; // for wifi and gps • In on. Create (optional) – wps = new WPS(this); – //xps = new XPS(this); – // make directory to save skyhook location maps. In theory, you can save enough of them so that you do not need network access and can still determine location. Android localization always requires network access, even GPS requires network access – // make dir – File external. Storage = Environment. get. External. Storage. Directory(); // get path to sdcard – File skyhook. Cache. Directory = new File(external. Storage. get. Absolute. Path()+"/skyhook/"); – skyhook. Cache. Directory. mkdir(); – // set up tiling – int _max. Data. Size. Per. Session = 10000; // a lot of data, so we should get everuthing we need. – int _max. Data. Size. Total = _max. Data. Size. Per. Session; – wps. set. Tiling(skyhook. Cache. Directory. get. Absolute. Path(), _max. Data. Size. Per. Session, _max. Data. Size. Total, null); – //xps. set. Tiling(skyhook. Cache. Directory. get. Absolute. Path(), _max. Data. Size. Per. Session, _max. Data. Size. Total, null);
In Sky. Hook. Test. Activity • In Sky. Hook. Test. Activity – Add variables • WPSAuthentication auth = null; – In on. Create, add • auth = new WPSAuthentication("bohacek", "udel"); • // bohacek = the user name and udel = domain I used to get sdk – And make start button on. Click. Listener • Button start = (Button)find. View. By. Id(R. id. start); • start. set. On. Click. Listener(new View. On. Click. Listener(){}); – In on. Click. Listener, add • wps. get. Location(auth, WPSStreet. Address. Lookup. WPS_NO_STREET_ADDRESS_LOOKUP, callback); • // callback is defined on the next slide
• My. WPSLocation. Callback callback = new My. WPSLocation. Callback(); • class My. WPSLocation. Callback implements WPSLocation. Callback { • int cnt = 0; • public void done() { • cnt = 0; • Log. d("skyhooktest", "done"); // after done() returns, you can make more WPS calls. • } • public WPSContinuation handle. Error(WPSReturn. Code error) { • switch (error) { • case WPS_ERROR: Log. d("skyhooktest", "error Soe other error occurred. "); break; • case WPS_ERROR_LOCATION_CANNOT_BE_DETERMINED: Log. d("skyhooktest", "error: A location couldn't be determined. "); break; • case WPS_ERROR_NO_WIFI_IN_RANGE: Log. d("skyhooktest", "error: No Wifi reference points in range. "); break; • case WPS_ERROR_SERVER_UNAVAILABLE: Log. d("skyhooktest", "error: The server is unavailable. "); break; • case WPS_ERROR_UNAUTHORIZED: Log. d("skyhooktest", "error: User authentication failed. "); break; • case WPS_ERROR_WIFI_NOT_AVAILABLE: Log. d("skyhooktest", "error: No Wifi adapter was detected. "); break; • case WPS_OK: Log. d("skyhooktest", "error: ok"); break; • } • if (cnt++<10) • return WPSContinuation. WPS_CONTINUE; //try again • else • return WPSContinuation. WPS_STOP; • }
• class My. WPSLocation. Callback continued • public void handle. WPSLocation(WPSLocation skyhook. Location) { • Log. e("skykooktest", "lat="+ skyhook. Location. get. Latitude()+" long="+ skyhook. Location. get. Longitude() ); • if (skyhook. Location. has. HPE()) • Log. e("skykooktest", "accuracy in meters: "+ skyhook. Location. get. HPE ()); • else • Log. e("skykooktest", "unknown accuracy"); • Log. e("skykooktest", "altitude="+ skyhook. Location. get. Altitude()+" number of cell towers used="+ skyhook. Location. get. NCell()+" number access pts used: "+ skyhook. Location. get. NAP()); • Log. e("skykooktest", "speed: "+skyhook. Location. get. Speed()+" bearing (degrees): "+skyhook. Location. get. Bearing()); • }; • run
Periodic location • In the start button on. Click. Listener, replace – wps. get. Location(auth, WPSStreet. Address. Lookup. WPS_NO_STREET_ADD RESS_LOOKUP, callback); – With – wps. get. Periodic. Location(auth, WPSStreet. Address. Lookup. WPS_NO_STREET_ADD RESS_LOOKUP, 0, 0, callback);
• Replace – class My. WPSLocation. Callback implements WPSLocation. Callback …. – With – class My. WPSLocation. Callback implements WPSLocation. Callback, WPSPeriodic. Location. Callback … • In My. WPSLocation. Callback, add function – @Override – public WPSContinuation handle. WPSPeriodic. Location(WPSLocation skyhook. Location) { • Log. d("skykooktest", "lat="+ skyhook. Location. get. Latitude()+" long="+ skyhook. Location. get. Longitude()+” accuracy: “+ skyhook. Location. get. HPE ()); • return WPSContinuation. WPS_CONTINUE; • // return WPSContinuation. WPS_STOP; // if we wanted to stop • In on. Create, make a on. Click. Listener for stop button and add code – wps. abort();
• Instead of wps, use xps to include gps, i. e. , – Instead of • WPS wps = null; – Use • XPS xps = null; – Instead of • wps = new WPS(this); – Use • xps = new XPS(this); – Instead of • wps. abort – Use • xps. abort() – Instead of • wps. get. Location(auth, WPSStreet. Address. Lookup. WPS_NO_STREET_ADDRESS_LOOKUP, callback ); – Use • xps. get. Location(auth, WPSStreet. Address. Lookup. WPS_NO_STREET_ADDRESS_LOOKUP, callback ); – But use the same callback
• Test some more Add textbox – Open res/layout/main. xml – Drag text. View to layout – Change id to skyhook. Info • In Sky. Hook. Test. Activity, add member variable – Text. View skyhook. Info. Text. View = null; • In on. Create, add – skyhook. Info. Text. View = (Text. View)find. View. By. Id(R. id. skyhook. Info); • Problem: My. WPSLocation. Callback is called from some other trhead, not the UI (user interface thread). So you cannot access UI components from the callback – If you do, weird things happen that you will never debug (you’ll be lucky if things crash. But they , might not!) • Two solutions – Use broadcast. Receiver. We’ll do this often later. So let’s try something else – Use run. On. Ui. Thread function • Make function in Sky. Hook. Test. Activity – public void set. Text(String str) { • final String text. To. Show = str; • run. On. Ui. Thread(new Runnable() { – – }); } @Override public void run() { » if (text. To. Show!=null) • skyhook. Info. Text. View. set. Text(text. To. Show); }
Get output when location is updated • In My. WPSLocation. Callback: : handle. WPSPeriodic. Location, add – String str = new String(); – str += "lat="+ skyhook. Location. get. Latitude()+" long="+ skyhook. Location. get. Longitude()+"n"; – if (skyhook. Location. has. HPE()) • str += "accuracy in meters: "+ skyhook. Location. get. HPE ()+"n"; – else • str += "unknown accuracyn"; – str += "altitude="+ skyhook. Location. get. Altitude()+" number of cell towers used="+ skyhook. Location. get. NCell()+"number access pts used: "+ skyhook. Location. get. NAP() + "n"; – str += "speed: "+skyhook. Location. get. Speed()+" bearing (degrees): "+skyhook. Location. get. Bearing()+"n"; – set. Text(str); • Also, add something similar to done and error • Run • Just to test, try calling skyhook. Info. Text. View. set. Text(str) from handle. WPSPeriodic. Location. Check out logcat to see if anything weird happens (it should) • Run some more and watch location, accuracy, and see if it stops
sky. Hook vs Android Location services • Sky. Hook uses wifi, so, in theory, one can get location indoors – However, skyhook seems to only record wifi access points from outside (they drive cars around) • – • On the other hand, these access points are usually indoors, and so they can be received indoors and skyhook can give a rough location. GPS gives you nothing indoors. Skyhook can only get location through polling, whereas android location services can provide proximity alerts (so your app is called only when you exit or enter a region) – – I don’t know how android proximity alerts are implemented. For example, they might poll, in which case skyhook is the same (except that the android code might be better than your own polling code) Advanced proximity alerts could do things like • • • adjust the polling frequency according to how close you are to the region (if you are very far from the region and not moving, don’t poll for along time, allowing the phone to sleep and save energy) Use the accelerometer to determine if the phone is moving. If not moving, then don’t poll location. Skyhook also requires a license. Skyhook uses wifi, which uses more energy than using cell towers. I’m not sure if gps of skyhook uses more power Both approaches use energy to get map information, – – For android, once you have the gps or cell phone tower, you need to use data connection to get the map information For skyhook, you need to download the wifi map. However, you can download wifi maps for a large region, reducing the time between accessing the network • • However, it is possible to register access point locations You might even be able to download the full datebase Skyhook is a bit buggy. – – Try it and let me know. Walk around and watch for error messages in periodic mode • – In periodic mode, you might get some errors, but it should keep on going Watch is periodic mode gives up (it should just keep on going)
Deployment models • See http: //www. skyhookwireless. com/devices/deploymen tmodels. php • Tiling – http: //groups. google. com/group/skyhook/browse_thread /thread/d 024 a 13 b 8 e 4 a 8 fef? hl=en • get. HPE gives accuracy in meters • http: //grail. cba. csuohio. edu/~matos/notes/cis 493/lecture-notes/Android-Chapter 24 Location. Services. pdf
- Slides: 15