Unlocking the future: How mobile indoor positioning transforms navigation

by Chong Hong Lok & Vitti Ng

Problem Statement

Navigating inside a building is challenging, as ceilings and other obstructions in the building are having major impact on ability of GPS to ascertain a ground device’s position successfully.

Even in situations where GPS signals are able to penetrate a building and provide a strong connection with a ground device, there is another significant factor to consider when using GPS indoors, which is the overall accuracy that GPS is able to achieve. GPS in ideal situations is routinely able to pinpoint a ground device’s position to an accuracy of between 5 and 10 meters.

In indoor environments, this level of potential discrepancy between a user’s reported position and their actual position presents enormous issues. This is due to the much smaller dimensions of the average indoor space versus the average outdoor environment. A user being told to turn left immediately when they’re actually 10 meters further down a corridor than their device thinks they could be led into a room that is multiple rooms away from the one they intended to enter.

Options for Indoor Navigation/Positioning

Stable and accurate indoor navigation and positioning can be achieved by using technologies similar to GPS. Bluetooth® Low Energy, Wi-Fi, and UWB are the most effective ones.

Bluetooth® Low Energy (BLE)

One of the most convenient tools for tracking objects indoors is the Bluetooth Low Energy technology. To set up indoor positioning Bluetooth® Low Energy beacons should be installed inside the facility. The beacons then will emit Bluetooth® LE signals at a predefined frequency.

Wi-Fi

Wi-Fi technology is sometimes used as an alternative to GPS for indoor positioning. The reason for its popularity is its widespread occurrence. Access points can be found in any building, which allows leveraging of existing infrastructure.

The active range of access points is up to 150 m and positioning is carried out using smartphones.

Ultra-wideband (UWB)

The UWB technology has a great potential for indoor positioning. It is the most accurate among the existing systems. Achievable accuracy is up to 20 cm. Calculations are performed with the help of ultra-wideband signals that are sent at a frequency of up to several GHz. The reception of these signals doesn’t require direct visibility and can be performed by a limited number of components.

Our Choice

Bluetooth® Low Energy (BLE)

Autonomy and insignificant size the Bluetooth® LE technology is supported by most modern smartphones. It is the most economical one among similar systems on the market and provides high accuracy localization inside buildings.

Highlight of advantages:

  • low energy consumption.
  • affordable.
  • possibility to localize an object with an accuracy of up to several meters.
  • simple deployment and minimal maintenance.

Build the Indoor Positioning System (IPS)

We chose the indoor map making solution from Mappedin , and Teltonika Eye Beacon to build an indoor positioning system.

Highlight for Mappedin:

  • Ready-made solutions: Mappedin offers an SDK for easy integration.
  • Interactive map: Provides a 3D view with interactive functionalities.
  • Automate map navigation: Automatically provide indoor navigation with every map created.
  • Resourceful: Well-documented with readily available customer support.

Highlight for Eye Beacon:

  • Battery life: Up to 10 years lifetime without the need to replace battery
  • Smart and compact design: Compact EYE devices can be conveniently mounted in 4 different ways, while IP67-rated casing ensures reliability and durability

On software and development side, we are using Flutter, known for its cross-platform capabilities and ease of use. With mappedin Web SDK, we are providing users with an interactive and engaging map experience and reducing the cost of maintaining it, as compared to native iOS and Android SDK.

Here’s a simplified diagram illustrating the process flow for the IPS solution:

Technical Implementation

Web app with Mappedin Web SDK (angular)

  1. Create a new angular web app project and integrate the Mappedin web sdk. Be sure to modify the file to include your own client Id, secret and venue.
import {
  getVenue,
  showVenue,
  TGetVenueOptions,
  STATE,
  E_SDK_EVENT,
  CAMERA_EASING_MODE
} from "@mappedin/mappedin-js";

import { MapView } from "@mappedin/mappedin-js";
import { Mappedin } from "@mappedin/mappedin-js";
import { Marker } from "@mappedin/mappedin-js";
import { TConnectionTemplateFn } from "@mappedin/mappedin-js";
import "@mappedin/mappedin-js/lib/mappedin.css";
import "./styles.css";
// See Trial API key Terms and Conditions
// https://developer.mappedin.com/guides/api-keys
const options: TGetVenueOptions = {
  venue: "{venue}",
  clientId: "{clientId}",
  clientSecret: "{clientSecret}"
};
var mapView: MapView;
var venue: Mappedin;
async function init() {
    venue = await getVenue(options);
    mapView = await showVenue(document.getElementById("app")!, venue);
    //Display Floating Labels on all locations.
     mapView.FloatingLabels.labelAllLocations();
    mapView.setState(STATE.FOLLOW);
}
init();

2. Create a getter function to retrieve and return the list of locations from mappedin map using window.flutter_inappwebview.callHandler function.

Get Location List

async function getLocationList() {
  const sortedCategories = Mappedin.categories;

  let sortedLocationList = [];

  sortedCategories.forEach((category) => {
    let sortTags = category.locations;

    let mappedValue = sortTags.map(location => {
      return {id: location.id, name: location.name}
    });

    sortedLocationList.push(...mappedValue);
  });

  let tempValue = sortedLocationList;
  window.flutter_inappwebview.callHandler('locationListRetrievedHandler', ...tempValue);
}

Sample web app showing a successful run for mappedin web sdk:

Figure 5: Web (Angular) implemented with Mapped in Web

Mobile App (Flutter)

  1. Created a new Flutter project and integrate with the following packages:
  • flutter_reactive_ble: Enables scanning for BLE Beacons.
  • permission_handler: Requests necessary permissions (Bluetooth and Location services) for the scanner to function.

2. Create a stream listener to scan for active BLE Beacons

Streaming scanner

flutterReactiveBle
        .scanForDevices(withServices: [], scanMode: ScanMode.lowLatency).listen((DiscoveredDevice device) {
      // TODO: To add on action when discovered (sort beacons, etc.)
    });
3. Register the Javascript callback to receive location list from web app. The location list is then shown as a start and end location for user to choose in mobile app.
Widget build(BuildContext context) {
  ...
  InAppWebView(
   initialUrlRequest:
       URLRequest(url: WebUri.uri(Uri.parse('Your hosted web url'))),
    initialOptions: groupOptions,
    onWebViewCreated: webViewCreated,
  ),
}
...

void webViewCreated(InAppWebViewController controller) {
    controller.addJavaScriptHandler(
        handlerName: 'locationListRetrievedHandler',
        callback: (args) {
           args.forEach((element) => print(element.toString());
        });
  }

Start/Stop Navigation

Create the functions to allow user use navigation feature provided in Mappedin SDK, where user can select start and stop location in previous step.

  1. Create start and stop functions in angular web app
  • Start Navigation: Receives start and end location selections from the mobile app and utilizes the MappedIn SDK to calculate directions between those points. It also allows customization for accessible routes.
  • Stop Navigation: Clears the ongoing navigation path from the map view.

Start Navigation

Receive start and end location from mobile app, submit to Mappedin SDK to create interactive navigation path with prefer routes.

const markerAnimateDuration: number = 500;

window.addEventListener("startNavigation", startNavigation);

async function startNavigation(e) {
  var startPoint = e.detail.start;
  var endPoint = e.detail.end;
  var myLatitude = e.detail.latitude;
  var myLongitude = e.detail.longitude;
  var accessible = e.detail.accessible;

  const start = venue.locations.find((l) => l.name === startPoint)!;
  const destination = venue.locations.find((l) => l.name === endPoint)!;

  //Get directions between the start and end locations.
  const directions = start.directionsTo(destination, { accessible: accessible });

  mapView.Journey.draw(directions);

  mapView.Camera.focusOn({ polygons: start.polygons });
}

Stop Navigation

Stop the ongoing journey and clear the path.

async function stopNavigation() {
  mapView.Journey.clear();
}
  1. Create the functions in mobile application to call web app function using inappwebview.callAsyncJavaScript().

The functions will be called based on user action in the mobile app.

void startNavigation(String startPoint, String endPoint) {
  controller?.callAsyncJavaScript(functionBody: """
      const event = new CustomEvent('startNavigation', {
         detail: {
            start: "${startPoint.name}",
            end: "${endPoint.name}"
         }
      });
      window.dispatchEvent(event);
  """);
}

void stopNavigation() {
  controller?.callAsyncJavaScript(functionBody: """
      const event = new CustomEvent('stopNavigation', {});
      window.dispatchEvent(event);
  """);
}

Final outcome after all the implementation above:

Positioning the exact user location

  1. Create the changePosition() method to listen to latest position updates from mobile app.

The function change the position of user marker in Mappedin interactive map based on latitude, longitude, floor Id.

function changePosition(e) {
  var latitude = e.detail.latitude;
  var longitude = e.detail.longitude;
t
const coordinate = mapView.currentMap.createCoordinate(latitude, longitude);
  mapView.Markers.animate(marker, coordinate.nearestNode,
  {
    duration: markerAnimateDuration,
    easing: CAMERA_EASING_MODE.LINEAR
  });
}

2. Mobile app determine the accurate user position with latitude, longitude and floor Id
With detecting the BLE beacons, several logics take place to identify user position, such as:

  • detected BLE beacon ID with mapping to coordinates map data (pre-defined).
  • multilateration (MLAT) algorithm to determine estimate position based on TOA (time of arrival) and BLE signal strength (rssi).
  • cache-ing of BLE beacons signal for false safe estimation.
  • best case simulation and filtering on BLE beacons combination.

1. Function to map detected BLE beacons with pre-defined map data.

void _updateDetectedBeaconList(BeaconModel beaconModel) async {
    _appendBeacon(_detectedBeaconListMap, beaconModel);
    _cleanInvalidBeaconList(_detectedBeaconListMap);
}

2. Function to get estimated coordinate with multilateration algorithm

  • convert latitude and longitude to their respective radian value and cartesian x/y/z values
  • use tracker model to calculate estimate position
Future<BeaconModel?> epitaphCalculationProcessing(Tracker tracker, List<BeaconModel> nearbyBeacons) async {
    ///radius of earth in meters
    const R = earthRadius * 1000;

    final beaconsForIpsFormula = nearbyBeacons.map((value) {
      var latitude = radians(value.latlng?.latitude ?? 0);
      var longitude = radians(value.latlng?.longitude ?? 0);
      var x = R * cos(latitude) * cos(longitude);
      var y = R * cos(latitude) * sin(longitude);
      var z = R * sin(latitude);

      final beacon = MockBeacon(value.name ?? '', value.name ?? '', Point(x, y, z));
      final rssiValue = value.rssiValue?.toInt() ?? rssiDefault;
      beacon.rssiUpdate((rssiValue) >= 0 ? rssiDefault : rssiValue);
      return beacon;
    }).toList();

    final calculatedPosition = tracker.calculatePosition(beaconsForIpsFormula);
    return calculatedPosition
  }

3. Filtering function for false safe check

  • sort both new detected beacons [nearbyBeacons] and last detected beacons
  • different group of beacons detected is considered as new position
  • same beacons detected with small changes in rssi signal [rssiPowerSpikedBuffer], consider NO changes
  • same beacons detected but rssi signal changes more than [rssiPowerChangingCountBaseline], considered new position
  • ONLY [isWalking] considered as need update position, otherwise return [false] and keep last position
Future<bool> shouldUpdatePosition(List<BeaconModel> nearbyBeacons) {
    if ((lastDetectedBeaconsGroup?.length ?? 0) == nearbyBeacons.length) {
      bool sameGroupOfBeacons = true;

      ///sort the list according to name for easier comparison
      lastDetectedBeaconsGroup?.sort((a, b) => (a.name ?? '').compareTo(b.name ?? ''));
      nearbyBeacons.sort((a, b) => (a.name ?? '').compareTo(b.name ?? ''));

      ///check if it is the same group of beacons detected
      lastDetectedBeaconsGroup?.forEachIndexed((index, element) {
        if (nearbyBeacons[index].name != element.name) {
          sameGroupOfBeacons = false;
        }
      });

      int rssiPowerChangedCount = 0;

      if (sameGroupOfBeacons) {
        nearbyBeacons.forEach((nearby) {
          int lastDetectedRssi = lastDetectedBeaconsGroup
                  ?.firstWhere((lastDetected) => nearby.name == lastDetected.name)
                  .rssiValue
                  ?.toInt() ?? 0;
          var rssiDiff = (lastDetectedRssi.abs() - (nearby.rssiValue ?? 0).abs()).abs();
          if (lastDetectedRssi < 0 && rssiDiff > rssiPowerSpikedBuffer) {
            rssiPowerChangedCount++;
          }
        });
      }

      lastDetectedBeaconsGroup = nearbyBeacons;
      return Future.value(!sameGroupOfBeacons || rssiPowerChangedCount > rssiPowerChangingCountBaseline);
    }

    lastDetectedBeaconsGroup = nearbyBeacons;
    return Future.value(true);
  }

Wrapping Up

Combining Flutter’s versatility with InAppWebView allows us to effortlessly embed Mappedin Web into the app. The provided code snippet serves as a starting point for integrating Mappedin Web, which can be further extend to meet the app’s requirements.

Customization with the Mappedin Web SDK

The code snippet above shows how to include the pre-built Mappedin Web into Flutter app. But what if you desire a more custom solution? The Mappedin Web SDK could also be used in a more customisable way. A more functions web app using the Mappedin Web SDK that satisfies the use case of the problems.

Challenges

Developing this IPS solution involved overcoming several challenges:

SDK Dependencies

Although Mappedin does support some level of customisation, more effort and knowledge are required to achieve the desired presentation if the solutions are designed to provide many more bespoke functions apart from what is provided.

Accuracy

With the use of TOA (time-of-arrival) as estimation method, receiving signal strength from BLE beacons (rssi) play vital roles. A very minor different of signal strength can impact hard to the estimated position.

Due to the nature of signal travel, RSSI value are greatly impact and interfered by the obstructions around, such as ceiling, wall, doors, glasses and basically anything within the buildings. Multiple trial and measurement are being tested to get the best stable RSSI value, amongs them are cache-ing, detection queue, trilateration to multilateration.

Interference of Signal

Obstructions in venue is interfering the travelling fo signal to mobile devices in various level. Highly impacted obstructions are like:

  1. Crowded Area:
  • High density of people are interference the stability of signal travelling, unexpected signal spike and drop are identified in crowded and high dense people.
  • To overcome this, BLE Beacons are installed from top level and higher position to reduce interference of moving crowd.

2. Building Structure:

  • Different materials like large metal plate and glasses has different impact to signal travel. Fine tune on BLE beacons configuration are take place to provide a consistent RSSI.
  • Here’s a simple illustration that explains the reflection and passing of waves through different characteristics objects.

Figure 6: Waves reflecting and passing by Elexana

Final Thought

The above contents have documented the core information of Indoor Positioning System (IPS) with the leverage of Bluetooth® Low Energy (BLE)Mappedin SDK and combining with versatile Flutter mobile development.

With the combinations, we are able to create an full-flex of IPS solutions based on different use-cases and problems that the market needs. With all the advance and thorough algorithm and tech stacks implemented, we have achieved high level of satisfaction on accuracy and consistency solutions. These solutions are able to provide a highly reliable and adaptability to various problems and use-cases.