Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DeviceOrientationEvent: how to deal with crazy gamma when beta approaches/hits 90deg?

Anyone with DeviceOrientationEvent experience and a phone/tablet handy?

Running the following code snippets on a gyroscope-having device, I notice gamma (rotating left/right along y-axis) gets large and unpredictable as beta approaches 90deg (device pointing straight up). I assume this is gimbal-lock.

var data, raf, alpha = document.getElementById("alpha"),
  beta = document.getElementById("beta"),
  gamma = document.getElementById("gamma");

window.addEventListener("deviceorientation", processData);
window.addEventListener('click', togglePause);
updateText();

function processData(e) {
  data = e;
}

function updateText() {
  if (data) {
    alpha.textContent = Math.round(data.alpha);
    beta.textContent = Math.round(data.beta);
    gamma.textContent = Math.round(data.gamma);
  }
  raf = requestAnimationFrame(updateText);
}

function togglePause(e) {
  if (raf) {
    cancelAnimationFrame(raf);
    raf = null;
    window.removeEventListener("deviceorientation", processData);
  } else {
    window.addEventListener("deviceorientation", processData);
    raf = requestAnimationFrame(updateText);
  }
}
body {
  font: normal 30px/200% sans-serif;
  margin: 20px;
  cursor: default;
}
span {
  font-size: 50px;
  vertical-align: middle;
}
<body>
  alpha: <span id="alpha">null</span>
  <br>beta: <span id="beta">null</span>
  <br>gamma: <span id="gamma">null</span>
  <br>[tap to pause/resume]
</body>

https://jsfiddle.net/1us8p1ad/show

My question: How can I predictably track left/right device orientation using gamma? Gamma is the only value I care about - no 3d space needed.

I looked into using rotation matrix and quaternion as discussed here, but not getting valid results. In fact, the examples on the author's github page also break when beta hits 90deg! Same with this MDN tutorial - check it on your device: when it's straight up, the ball goes bonkers. How have these aberrations gone unnoticed!

like image 849
calipoop Avatar asked Jan 05 '17 18:01

calipoop


1 Answers

It seems gimbal lock is a known real-world obstacle, and many applications avoid it by restricting device motion (not possible in my case).

My solution was to convert the alpha/beta/gamma values into a rotation matrix, and then pull data from one of the matrix values. The code I used was given here from W3C.

Note, I tried using Quaternions but the resulting values were not helpful for motion in just 1 direction.

like image 107
calipoop Avatar answered Oct 16 '22 16:10

calipoop