Monday, July 16, 2012

What’s the Difference between the Accelerometer and the Gyroscope?

Measurements

The accelerometer measures foce in the X, Y, and Z dimensions. Think of holding the device directly in front of you… moving the device vertically in space changes the y value, horizontally changes x, and moving the device towards and away from you changes the z value.
The gyroscope measures orientation in the a, b, and g dimensions. Think of holding the device directly in front of you… moving the device like you would steer a car changes the Alpha value, tilting the device forwards and backwards will effect the Beta value, and twisting the device like you’re opening a soda will change the Gamma value.

Force vs. Orientation

When executing the codeblocks below, you’ll notice that the X, Y, and Z values will read zero, or close to zero, when holding the device motionless. This is because the accelerometer only outputs the force of a a change in orientation, not the orientation itself. Modern browsers also supply the “accelerationincludinggravity” property when emitting the ondevicemotion event which works differently and we will not be using it in this post.
Unlike the accelerometer, all of the channels of the gyroscope will continuously read the orientation of the device, even when motionless. Try moving the phone in space without any twisting force… you’ll notice little to no effect in the gyroscopic values.

The Code

I’m starting with an entirely blank html file. The only things we’ll need to include are a reference to Zepto and a series of DOM elements to hold the textual information we’ll be logging out. You can download the final zip package here – http://joelongstreet.com/blog_files/ios_accelerometer_1/package.zip.
All I’m doing here is associating DOM elements with JavaScript variables. Nothing special.





var x_dom = $('.x');
var y_dom = $('.y');
var z_dom = $('.z');
var a_dom = $('.a');
var b_dom = $('.b');
var g_dom = $('.g');
Accelerometer – The “ondevicemotion” event is native to browsers that support the accelerometer. We can use this event to constantly track the changes in motion related to the X, Y, and Z dimensions. After collecting the data from the event, we write the information to the DOM.








window.ondevicemotion = function(event) {
    var x = event.acceleration.x;
    var y = event.acceleration.y;
    var z = event.acceleration.z;

    x_dom.text(x);
    y_dom.text(y);
    z_dom.text(z);
}


Gyroscope – We’re doing the same thing here with the gyroscope. Like the accelerometer, this method is native to devices that support the respective
instrument.










window.ondeviceorientation = function(event) {
    var a = event.alpha;
    var b = event.beta;
    var g = event.gamma;

    a_dom.text(a);
    b_dom.text(b);
    g_dom.text(g);
}



If you log the above code, you’ll notice the instruments are very, very sensitive and the strings returned are somewhat long. Since it’s kind of difficult to look at that kind of information in the DOM, I’ve added a rounding function to display a single whole number. Also, adding a + sign to the string makes switches between positive and negative numbers less visually striking.
The Final Product:




















var x_dom = $('.x');
var y_dom = $('.y');
var z_dom = $('.z');
var a_dom = $('.a');
var b_dom = $('.b');
var g_dom = $('.g');

//This is only for devices that support the use of a gyroscope (iPhone 4, iPad2, iPod Touch)
window.ondeviceorientation = function(event) {
    var a = Math.round(event.alpha*1/1);
    var b = Math.round(event.beta*1/1);
    var g = Math.round(event.gamma*1/1);
    if(a >= 0) { a = '+' + a}
    if(b >= 0) { b = '+' + b}
    if(g >= 0) { g = '+' + g}
   
    a_dom.text(a);
    b_dom.text(b);
    g_dom.text(g);
}

window.ondevicemotion = function(event) {
    var x = Math.round(event.acceleration.x*1/1);
    var y = Math.round(event.acceleration.y*1/1);
    var z = Math.round(event.acceleration.z*1/1);

    if(x >= 0) { x = '+' + x}
    if(y >= 0) { y = '+' + y}
    if(z >= 0) { z = '+' + z}
   
    x_dom.text(x);
    y_dom.text(y);
    z_dom.text(z);
}
Finished, not a whole lot to it and pretty easy overall. I’m really looking forward to seeing how people use these new technologies to build web applications. Note: In real life scenarios it’s probably overkill to collect/broadcast information on device motion and orientation change, you’ll want to use some kind of intervalled data collection to prevent the browser from killing itself.

No comments: