Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
I’ve begun a project trying to using magnetometers to detect a user’s behaviour, so to begin to understand how to use them I built a simple compass.
Step 1 — Raw Magnetometer data:
Using the PowerSense app for iPhone, I recorded the 3-axis magnetometer readings at various compass headings and device orientations. With the device constrained to the horizontal plane, the following (very promising) reading are obtained:
X & Y magnetometer readings at different headings
Besides from the x-axis being reversed, these points are very usable to give us a compass heading! A conversion to spherical co-ordinates is used to make the output more usable:
As the magnitude of the magnetic field vector in 3D space is constant with changing device orientation, r value can be ignored in this application. In the horizontal plane, the rho value is also constant due to constant z-axis readings, so is also ignored for now. Theta is calculated using:
def direction(vec): #vec = [x,y,z] from imported data
x = -vec[0] #negate x y = vec[1] z = vec[2] if y > 0 and x > 0: #if in Q1 theta = math.atan(x/y) elif y < 0: #if in Q2 or Q3 theta = math.atan(x/y) + math.pi else: #if in Q4 theta = math.atan(x/y) + math.pi*2 return theta
This gives us a heading which is consistent with the angles that the data was recorded at! Now all that is needed is to get this magnetometer data from a mobile device.
Step 2 — Realise that iPhones don’t give raw magnetometer data to web apps…
Probably should have checked this part first. Oh well.
Step 3 — Discover the wonder of the deviceorientation event
deviceorientation allows a website to gather data of how a device is being held, which is reported in 3 different axis:
alpha — Rotation around the z axis, from 0 to 360 degrees
beta — Rotation around the x axis, from -180 to 180 degrees
gamma — Rotation around the y axis, from -90 to 90 degrees
The caveat is that this information is specified in a subtly different way between iOS and Android devices. Before chrome 50, Android devices would report alpha as an ‘absolute’ value, constant in the reference frame of the earth’s surface. This means that alpha = 0 corresponds to the device being pointed due north, which is really handy. As seen in the magnetometer data, the rotation direction is reversed. This can be solved by taking heading = 360 - alpha
function deviceOrientationListener(event) { var alpha = event.alpha; //z axis rotation [0,360) var beta = event.beta; //x axis rotation [-180, 180] var gamma = event.gamma; //y axis rotation [-90, 90] var heading = 360 - alpha; //heading [0, 360)}
if(window.DeviceOrientationEvent){ //Check if device is compatible window.addEventListener("deviceorientation", deviceOrientationListener); }
However, now Android has gone the way of iOS, reporting alpha as a ‘relative’ value, where 0 is defined as the device’s direction when the page is loaded. This makes is substantially less useful as a compass…
Luckily, hidden in the depths of google developer pages lies a solution! Some devices will still report a absolute alpha value in the form of a compass heading through event.webkitCompassHeading. The application checks if the device will report this value, and if so uses that. Otherwise, relative alpha values are used to show the page, just not pointing north.
...if (typeof event.webkitCompassHeading !== "undefined") { alpha = event.webkitCompassHeading; //iOS non-standard var heading = alpha document.getElementById("heading").innerHTML = heading.toFixed([0]); } else { alert("Your device is reporting relative alpha values, so this compass won't point north! "); var heading = 360 - alpha; //heading [0, 360) document.getElementById("heading").innerHTML = heading.toFixed([0]); }...
if (window.DeviceOrientationAbsoluteEvent) { window.addEventListener("DeviceOrientationAbsoluteEvent", deviceOrientationListener); } // If not, check if the device sends any orientation data else if(window.DeviceOrientationEvent){ window.addEventListener("deviceorientation", deviceOrientationListener); } // Send an alert if the device isn't compatible else { alert("Sorry, try again on a compatible mobile device!"); }
All of the code is given at the bottom of the page.
The compass can be tested here, but if your device doesn’t work, have a look below:
<!DOCTYPE html><html> <head> <style> p { font-family: verdana; font-size: 400px; color: #FFFFFF; } </style>
<title>Compass</title>
<script> // Get event data function deviceOrientationListener(event) { var alpha = event.alpha; //z axis rotation [0,360) var beta = event.beta; //x axis rotation [-180, 180] var gamma = event.gamma; //y axis rotation [-90, 90]
//Check if absolute values have been sent if (typeof event.webkitCompassHeading !== "undefined") { alpha = event.webkitCompassHeading; //iOS non-standard var heading = alpha document.getElementById("heading").innerHTML = heading.toFixed([0]); } else { alert("Your device is reporting relative alpha values, so this compass won't point north :("); var heading = 360 - alpha; //heading [0, 360) document.getElementById("heading").innerHTML = heading.toFixed([0]); } // Change backgroud colour based on heading // Green for North and South, black otherwise if (heading > 359 || heading < 1) { //Allow +- 1 degree document.body.style.backgroundColor = "green"; document.getElementById("heading").innerHTML = "N"; // North } else if (heading > 179 && heading < 181){ //Allow +- 1 degree document.body.style.backgroundColor = "green"; document.getElementById("heading").innerHTML = "S"; // South } else { // Otherwise, use near black document.body.style.backgroundColor = "#161616"; } } // Check if device can provide absolute orientation data if (window.DeviceOrientationAbsoluteEvent) { window.addEventListener("DeviceOrientationAbsoluteEvent", deviceOrientationListener); } // If not, check if the device sends any orientation data else if(window.DeviceOrientationEvent){ window.addEventListener("deviceorientation", deviceOrientationListener); } // Send an alert if the device isn't compatible else { alert("Sorry, try again on a compatible mobile device!"); } </script> </head>
<body> <br><br> <p id="heading" style="text-align:center"></p> </body></html>
Building a compass web app was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.