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...