2

I'm using code from here and here to determine which way the phone is facing when looking through the camera.

After initialization, the code seems very fluid and consistent. The problem is that it seems no matter which way my device is pointing when I load the code, that becomes 90 degrees (actually 89.7ish). This is an obvious issue because now I can't simply say dir < 45 && dir > 315 = "south".

Is this due to my specific hardware/software? (Pixel XL, Chrome mobile) or am I doing something wrong in the code?

update: I experience the same behavior with complex compasses like this one from ArcGIS and this Marine Compass demo.

Here is the full code:

function compassHeading(alpha, beta, gamma) {

    // Convert degrees to radians
    var alphaRad = alpha * (Math.PI / 180);
    var betaRad = beta * (Math.PI / 180);
    var gammaRad = gamma * (Math.PI / 180);

    // Calculate equation components
    var cA = Math.cos(alphaRad);
    var sA = Math.sin(alphaRad);
    var cB = Math.cos(betaRad);
    var sB = Math.sin(betaRad);
    var cG = Math.cos(gammaRad);
    var sG = Math.sin(gammaRad);

    // Calculate A, B, C rotation components
    var rA = - cA * sG - sA * sB * cG;
    var rB = - sA * sG + cA * sB * cG;
    var rC = - cB * cG;

    // Calculate compass heading
    var compassHeading = Math.atan(rA / rB);

    // Convert from half unit circle to whole unit circle
    if(rB < 0) {
        compassHeading += Math.PI;
    }else if(rA < 0) {
        compassHeading += 2 * Math.PI;
    }

    // Convert radians to degrees
    compassHeading *= 180 / Math.PI;

    return compassHeading;

}


document.addEventListener("DOMContentLoaded", function(event) {

    if (window.DeviceOrientationEvent) {
        window.addEventListener('deviceorientation', function(eventData) {
            let tiltLR = eventData.gamma;
            let tiltFB = eventData.beta;
            let dir = eventData.alpha;

            deviceOrientationHandler(tiltLR, tiltFB, dir);
        }, false);
    }

    function deviceOrientationHandler(tiltLR, tiltFB, dir) {
        document.getElementById("tiltLR").innerHTML = 'tiltLR: ' + Math.ceil(tiltLR);
        document.getElementById("tiltFB").innerHTML = 'tiltFB: ' + Math.ceil(tiltFB);
        let heading = compassHeading(dir, tiltFB, tiltLR);
        if (heading >= 0 && heading < 90) {
            document.getElementById("direction").innerHTML = 'direction: S (' + heading + ')';
        } else if (heading >= 90 && heading < 180) {
            document.getElementById("direction").innerHTML = 'direction: W (' + heading + ')';
        } else if (heading >= 180 && heading < 270) {
            document.getElementById("direction").innerHTML = 'direction: N (' + heading + ')';
        } else if (heading >= 270 && heading <= 360) {
            document.getElementById("direction").innerHTML = 'direction: E (' + heading + ')';
        } else {
            document.getElementById("direction").innerHTML = 'direction: ? (' + heading + ')';
        }

    }

});
  • Possibly related bug report in Chromium: https://bugs.chromium.org/p/chromium/issues/detail?id=397824&q=compass&colspec=ID%20Pri%20M%20Stars%20ReleaseBlock%20Component%20Status%20Owner%20Summary%20OS%20Modified – Morrison Chang Jul 24 '17 at 17:48
  • Are you implying I have a magnet interfering? –  Jul 24 '17 at 17:50
  • Or just need to reset the compass. I tried out the marine compass demo on Chrome Mobile (ver 59) on One Plus One (6.0.1) and had to go through the usual figure 8 stuff to get it and Google Maps to point to the compass directions correctly. – Morrison Chang Jul 24 '17 at 18:35
  • I did try the standard orientation protocol, it did not help. I was able to test this on a Galaxy Note 4 and it worked as expected. I also downloaded a compass app from the Google Play store and after requesting the magnetometer permissions, it worked as expected. Is this a permissions issue? I tried adding "magnetometer" to the manifest.json file and it never prompted and still doesn't work properly. –  Jul 24 '17 at 19:10

0 Answers0