cannot hide :) ļµ Should I use Android? ļµ Why not :) ļµ Come on... ļµ OK! Android contains everything you need to compose an indoor localization system ļµ Multiple Sensors, Multiple Wireless Interfaces ļµ And yes, you should use it! ļµ There is huge adoption of Android devices ļµ Android day to day evolves (some time backwards, but we can deal with it)
way to achieve this ļµ Android gives you the tools, and we have to use them ļµ OK then, what are these tools? ļµ WiFi Networks: SSID, RSSI (Received Signal Strength Indicator) ļµ Bluetooth: Beacons ļµ Magnetic Field: x, y, z coefficients (what??) ļµ Multiple Sensors: Gyroscope, Accelerometer, ā¦
be hurry. As in many questions, it depends. Let me first describe some options ļµ WiFi ļµ Triangulation: the classic method that GPS is using. We need coverage at each point from at least 3 Access Points (actually, it is 4 as we need one extra for time) AP 1 AP 2 AP 3 ME
Phase 1 (offline or training): Create a Radio Map ļµ Phase 2 (online): Find me based on the radio map and real measurements ļµ Beacons ļµ Triangulation ļµ Fingerprinting ļµ Nearbys: Room level identification. Low level transmit power results in room identification for each beacon reception
Pros ļµ No training phase needed ļµ Cons ļµ Simultaneously coverage of at least 4 APs for each point ļµ Bad results (more times worse than 5 meters off, based on the chosen propagation model ļµ Fingerprinting ļµ Pros ļµ No need of multiple receptions at point ļµ Good accuracy ļµ Cons ļµ Need a training phase (the more extensive the better)
accuracy ļµ Low battery consumption ļµ Coverage everywhere (earth on duty!) ļµ No infrastructure ļµ Cons ļµ Need a training phase (the more extensive the better) ļµ There are serious differences of what each device measures
have all of them, or most of them :) ļµ There are plenty of options and day to day research on that, but 2 well established ways to do this, are: ļµ Extended Kalman Filters (adds memory to the system) ļµ This is not new, as Android uses Kalman Filter before it serves each application with sensor data for example. The main use in Android is to smooth the sensor values ļµ The Extended Kalman Filter is a common approach on sensor fusion ļµ Particle Filters ļµ A promising technique newly applied to combining multiple data
ļµ Beacons Fingerprinting ļµ Magnetic Field ļµ Modified/Extended Kalman Filters + Pattern Search Algorithm ļµ There is the need of a robust measurements campaign ļµ Multiple different devices ļµ Different orientations at same point ļµ Multiple measurements at same point ļµ No initial user interference
Retrieve WiFi, Beacons and Magnetic Fields measurements every period of 'X' ļµ I can read the developer.android.com for that... ļµ Sure! But there are a couple of issues I faced with each measurement which is good to know...
ļµ Cannot get measurements as frequent as you want ļµ Actually, you can, but you will get the same results ļµ You are always based on the chipset and the Android kernel ļµ Examples of minimum period for different Android versions: ļµ Android 4: 5 seconds ļµ Android 4.4.2: less than 2 seconds ļµ Android 5/6: less than 1 second ļµ What to use? 1, 2 or 5? ļµ Let the system decide...
measurement ļµ In that way you get new results as soon as the kernel has new ones ļµ After your desired number of measurements continue with next job: wifiCount++; if (wifiCount > wifiTotalCount) { System.out.println("WiFi Measurement Finished!"); ⦠}
calibration for broadcasting intervals ļµ Default 1 sec and minimum 0.2 sec ļµ There are different ways to capture Estimote Beacons ļµ Use the RangingListener from BeaconManager and do your job inside: public void onBeaconsDiscovered(Region region, final List<Beacon> beacons) { ā¦... if (beaconCount < beaconTotalCount) { for (Beacon beacon : beacons) { DeviceBeaconMeasurements deviceBeaconMeasurement = new DeviceBeaconMeasurements(); deviceBeaconMeasurement.setMinor(String.valueOf(beacon.getMinor())); deviceBeaconMeasurement.setRssi(String.valueOf(beacon.getRssi())); deviceBeaconMeasurements.add(deviceBeaconMeasurement); Log.i("INFO", "Beacon Minor: " + beacon.getMinor() + " RSSI: " + beacon.getRssi()); } beaconCount++; } else { // Finished beacons measurements, so, go on... } }
faster measurements but we cannot ļµ In Magnetic Field (MF) Measurements we want slower measurements ļµ The MF measurements arrive extremely fast from the continuous magnetometer of the smartphone ļµ We need a better channel sampling for each point, so, we want to slow down our values ļµ There are multiple ways to achieve that ļµ Get all the values and filter out only those with specific intervals ļµ Register and unregister to sensor in specific intervals ļµ ...
get continuous values and filter out, otherwise you can do something like: CountDownTimer magneticCountDownTimer = new CountDownTimer(3000, 1000) { @Override public void onTick(long millisUntilFinished) { sensorManager.registerListener(magneticListener, sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),SensorManager.SENSOR_DELAY_NORMAL); } @Override public void onFinish() { retrieveBLEStats(); } }; ļµ And then in onSensorChanged do your job as usual @Override public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) { DeviceMagneticMeasurements deviceMagneticMeasurement = new DeviceMagneticMeasurements(); deviceMagneticMeasurement.setxValue(String.valueOf(event.values[0])); deviceMagneticMeasurement.setyValue(String.valueOf(event.values[1])); deviceMagneticMeasurement.setzValue(String.valueOf(event.values[2])); deviceMagneticMeasurements.add(deviceMagneticMeasurement); sensorManager.unregisterListener(magneticListener); } }
help you: ļµ Log-Normal for RSSI WiFi and Beacons ļµ Normal for Magnetic Field (in general the orientation will also follow the Normal distribution) ļµ In that way you will be able to: ļµ Export an estimated error for each measurement estimation ļµ Assist the algorithm to apply weights where we are more confident ļµ If there is high error in WiFi estimation we will apply small weight
conditions ļµ Make as much measurements per point ļµ Use different orientations per point ļµ Use different devices ļµ Create a density grid ļµ Preferably remotely control the application, e.g.: ļµ Proof of Concept: Socket ļµ Production: GCM ļµ Production: MQTT Paho at Android side and RabbitMQ + MQTT Adapter at Server side ļµ ...
(4 APs) Combination (6 APs) Error (m) 1.3 1.6 1.5 1.1 0.5 ļµ Very good results from WiFi ļµ Beacon is lost packets due to latency and predefined intervals. For that reason, this year Estimote released dedicated beacons for localization ļµ Magnetic field is really promising but the device needs an 8-figure calibration first ļµ The combination alongside with a modified Extended Kalman filter with system memory may increase the accuracy of the system
Server or even on the mobile if the radio map is in an appropriate light format and the algorithm is efficient as well ļµ For research reasons, in order to try different algorithms, we connected Server with Matlab via socket, so, this was the final architecture of the online phase
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); sensorManager.registerListener(mySensorEventListener, sensor, SensorManager.SENSOR_DELAY_NORMAL); ļµ In onSensorChanged get and update the azimuthal value: azimuth = event.values[0]; float degree = Math.round(event.values[0]); ļµ Continuously Broadcast the up to date azimuthal in the WiFi network's broadcast address (most of times you can get it from DHCP): ... socket.setBroadcast(true); socket.setReuseAddress(true); String messageStr = "azimuth=" + String.valueOf(azimuth); InetAddress local = InetAddress.getByName(broadcastAddress); int msg_length=messageStr.length(); byte[] message = messageStr.getBytes(); DatagramPacket p = new DatagramPacket(message, msg_length, local, SERVER_PORT); socket.send(p); ...
to listen for sensor updates ļµ Setup a UDP Socket Server to retrieve the reference azimuthal ļµ Continuously Perform the combination: float degree = azimuthLocal - azimuthReference; ļµ Update any graphical staff such as compass
ļµ The users may be passive or active. Till now we mostly discussed the passive way ļµ Some other solutions may contain: ļµ Barcode/QR scanner: the user scan tags in walls for example to identify his/her exact location ļµ RFID tags: the user keeps a tag (such as wristlet) and passes it in various entry points, for room level localization ļµ And many other solutions...