OpenHPS v0.4 - Sensors, Web source nodes, RDF and more ...

We have released the @openhps/web-bluetooth, @openhps/web-sensors, @openhps/webxr and @openhps/web-geolocation modules for OpenHPS in the monorepo OpenHPS/openhps-web on GitHub. This repository will be used to contain future web modules that leverage the increasing power of the core Web API's for indoor and outdoor positioning via web applications. Developers will be able to use these modules right away to create web applications that can scan for Bluetooth beacons, compute dead reckoning using an accessible IMU sensor or even develop geomagnetic fingerprinting applications.

Web-based positioning has always been one of our main design goals since the early alpha releases of OpenHPS in 2020 due to its interoperability between different operating systems and devices, as well as the large working groups that develop the API's that build the future of the Web. Many of the existing modules of OpenHPS are already compatible with web applications but can now access core APIs to access native sensors.

In September 2022 we presented a novel method to decentralise location data of users using semantic linked data. The paper can be found here. We have since expanded the vocabulary of this publication in the POSO ontology and implemented this in our @openhps/rdf component that enables serialisation of data frames and objects to semantic linked data.

Our core framework (@openhps/core) has been updated to version 0.4 which facilitates the addition of sensors in regular DataFrames. Before this release a custom data frame had to be created for different sensor data. For example, the IMUDataFrame was a data frame included in the @openhps/imu package that added the ability to send IMU sensor data to other nodes. Unfortunately, this method of adding sensor data did not scale very well.

Sensors

In OpenHPS v0.4, sensors are created as DataObjects that contain their own spatial information and sensor values. By default the following sensors are available: Accelerometer, LinearAccelerationSensor, GravitySensor, Gyroscope, Magnetometer, LinearVelocitySensor, RelativeOrientationSensor and AbsoluteOrientationSensor.

import { DataFrame, Accelerometer, Acceleration } from '@openhps/core';

const frame = new DataFrame();
// Add an accelerometer sensor with uid "accelerometer" a default acceleration value and a frequency of 50 Hz
frame.addSensor(new Accelerometer("accelerometer", new Acceleration(1, 2, 3), 50));

/* ... */

// Get any sensor of a specific type
const sensor = frame.getSensor(Accelerometer);
console.log(`${sensor.value.x}, ${sensor.value.y}, ${sensor.value.z}`); 
// Expected output: 1, 2, 3
ts
import { DataFrame, Accelerometer, Acceleration } from '@openhps/core';
 
const frame = new DataFrame();
// Add an accelerometer sensor with uid "accelerometer" a default acceleration value and a frequency of 50 Hz
frame.addSensor(new Accelerometer("accelerometer", new Acceleration(1, 2, 3), 50));
 
/* ... */
 
// Get any sensor of a specific type
const sensor = frame.getSensor(Accelerometer);
console.log(`${sensor.value.x}, ${sensor.value.y}, ${sensor.value.z}`);
// Expected output: 1, 2, 3

When needed, new sensors can be created.

ts
import {
SerializableObject,
LuminanceIntensityUnit,
SensorObject,
SensorValue,
} from '@openhps/core';
 
@SerializableObject()
export class AmbientLightSensor extends SensorObject<SensorValue<LuminanceIntensityUnit>> {
constructor(uid?: string, value?: SensorValue<LuminanceIntensityUnit>, frequency?: number, displayName?: string) {
super(uid, value ?? new SensorValue(), frequency, displayName);
}
}

Web components

One of our new components is @openhps/web-bluetooth which adds support for the experimental Web Bluetooth Scanning API. With this API, web browsers are able to scan for raw advertisements packets. OpenHPS can leverage this API to create web-based beacon positioning systems that do not need a proprietary application.

In addition to the Bluetooth component we created @openhps/web-sensors which adds all generic W3C sensors using the new sensor API in data frames and finally the @openhps/web-geolocation component.

html
<!DOCTYPE HTML>
<html>
<head>
<title>Web Example</title>
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<button id="start">Start Test</button>
<div id="result">
Click the start button to test the component.
</div>
<script type="module">
import {
ModelBuilder,
CallbackSinkNode,
DataObject
} from './js/openhps-core.es.min.js';
import { BLESourceNode } from './js/openhps-web-bluetooth.es.min.js';
const sourceObject = new DataObject("web");
const source = new BLESourceNode({
uid: "source",
source: sourceObject,
interval: 100
});
document.getElementById("start").onclick = () => source.start();
source.on('error', console.error);
ModelBuilder.create()
.from(source)
.to(new CallbackSinkNode(frame => {
document.getElementById('result').innerHTML = `
<b>Timestamp: </b> ${frame.createdTimestamp} </br>
${frame.getObjects().filter(o => o.uid !== frame.source.uid).map(object => {
return `${object.uid} RSSI=${frame.source.getRelativePosition(object.uid).rssi}`;
}).join("</br>")}
`;
}))
.build().catch(console.error);
</script>
</body>
</html>

Semantic linked data

Since our presentations at IPIN2022 and ISWC2022 we have improved the serialization of location data to linked data. To demonstrate this we showcase serialization of our new sensor data objects to JSON and RDF. Adding support for linked data offers a generic way to represent sensor data and location data that is not only supported by OpenHPS.

ts
import { DataSerializer } from '@openhps/core';
import { RDFSerializer } from '@openhps/rdf';
 
const serializedJSON = DataSerializer.serialize(sensor);
const serializedRDF = RDFSerializer.serialize(sensor);