dorukeker / gyronorm.js

JavaScript project for accessing and normalizing the accelerometer and gyroscope data on mobile devices
MIT License
640 stars 65 forks source link

About setHeadDirection... How is it supposed to work exactly? #13

Closed slacktracer closed 8 years ago

slacktracer commented 8 years ago

Hi. Awesome library.

I want to have the "north" being wherever the device is pointing when the page loads so I try to use setHeadDirection.

It seems to work for a second and them it... turns... Unless, I have an alert right after setting the head direction.

prototype.gn
    .init()
    .then(function(){
        prototype.gn.start(function(data){
            prototype.alpha = toRadians(data.do.alpha);
            prototype.beta = data.do.beta;
            prototype.gamma = data.do.gamma;
            prototype.absolute = data.do.absolute;
            document.getElementById('data').innerHTML = setData(data.do.alpha, data.do.beta, data.do.gamma, data.do.absolute);
        });
        var temp = prototype.gn.setHeadDirection();
        document.getElementById('data').innerHTML = setData(prototype.alpha, prototype.beta, prototype.gamma, prototype.absolute);
        alert(temp);
        prototype.context.start();
    })
    .catch(function(e){
        alert(e);
    });

As you can see I am not finding the words to explain it so I have this two demos to show what I am talking about:

With the alert: http://anzol.biz/zatoichi/2/a/

Without the alert: http://anzol.biz/zatoichi/2/b/

What I was expecting is that wherever the device is pointing when I call setHeadDirection is alpha = zero (or 360). Am I wrong by assuming that? Because it seems to work just like that with the alert...

So, can you tell me if I am missing something? Thank you.

(I am using Chrome on Android)

(By the way, when I turn the screen off and then on again the alpha values changes abruptly.)

dorukeker commented 8 years ago

Hi, Yes you are correct. That is how it should function. Actually in this scenario you do not even need to call setHeadDirection().

You are not passing any options to the gn object. This means you use the default orientation base GAME. Meaning the alpha values will be returned with respect to the phones head direction.

So when you call the gn.init() and gn.start() methods for the first time (meaning when you load the page) the alpha values should start returning 0 (or 360).

Can you try not calling the setHeadDirection() at all. In this scenario it should work even without it.

I checked the above links on an iPhone and both works as expected. I suspect an older version of Android browser is causing the issue. Can you give specific Android and browser version?

Cheers, Doruk

slacktracer commented 8 years ago

I am on Chrome 46.0.2490.76 on Android 5.0.0; SM-G900M Build/LRX21T.

You said: This means you use the default orientation base GAME.

That's what I thought. So I expected absolute to return false but it does not. I read somewhere Android is by default absolute=true and ios is by default absolute=false...

Anyway, I started using de setHeadDirection because of that. Now I removed it.

And it worked... a few times... Is there any kind of race conditions among promises going on? I did not take the time check the code yet.

The thing is, sometimes 0 (360) is to the head of the device and sometimes it is skewed, a little or a lot!

Is absolute false on your iPhone?

Thank you very much for your time. Right now it feels like it is a glitch... I will look more into it. I still hope gyronorm will do the trick for me. =)

If you have any other suggestions I appreciate it.

Oh, it is online at http://anzol.biz/zatoichi/2/c/

prototype.gn
    .init()
    .then(function onResolve(){
        prototype.gn.start(function(data){
            prototype.alpha = data.do.alpha;
            prototype.beta = data.do.beta;
            prototype.gamma = data.do.gamma;
            prototype.absolute = data.do.absolute;
            document.getElementById('data').innerHTML = setData(prototype.alpha, prototype.beta, prototype.gamma, prototype.absolute, prototype.version);
        });
        prototype.context.start();
    })
    .catch(function onReject(reason){
        alert(reason);
    });
dorukeker commented 8 years ago

Hi,

Right now it feels like it is a glitch.

I try to have the gyronorm.js work over devices so you do not face this glitches as a developer. It is rather hard. But I really want to learn more about it and see if I can act on it :)

You said: This means you use the default orientation base GAME. That's what I thought. So I expected absolute to return false but it does not. I read somewhere Android is by default absolute=true and ios is by default absolute=false...

It actually does not matter what the device returns in this case. Since you have GAME setting by default you should always get relative value. You are right the data.do.absolute does not reflect the actual case. Should be fixed in next release.

The thing is, sometimes 0 (360) is to the head of the device and sometimes it is skewed, a little or a lot!

Gyronorm.js assumes the compass of the device is configured. The return values can be incorrect if the compass is not calibrated. Can you turn the Compass app and make sure the compass is calibrated?

Next week I will try to check the sample on the device and see if I can find anything more.

Cheers, Doruk

slacktracer commented 8 years ago

It is weird (or funny), the setHeadDirection does not seems to matter. The alert does the trick always. Like if locking the event loop for a moment changes something.

Like this:

prototype.gn
    .init()
    .then(function onResolve(){
        prototype.gn.start(function (data){
            prototype.alpha = data.do.alpha;
            prototype.beta = data.do.beta;
            prototype.gamma = data.do.gamma;
            prototype.absolute = data.do.absolute;
            document.getElementById('data').innerHTML = setData(prototype.alpha, prototype.beta, prototype.gamma, prototype.absolute, prototype.version);
        });
        alert('Hold on a second! Done! =P');
        prototype.context.start();
    })
    .catch(function onReject(reason){
        alert(reason);
    });

It is at http://anzol.biz/zatoichi/2/d/

It is hard to discuss this sort of problem because it is not just code, right? It is device behavior etc. You almost have to see it to believe it. =)

I tried adding an alert to the on the compassneedscalibration event but nothing. I mean, it never alerted...

I will check the compass.

If you need any other information from me, please let me know.

Thank you again for your time!

Cheers, Thiago F

dorukeker commented 8 years ago

Hello Again,

I had the time to test the sample on an Android device. And the sample without the alert() also worked fine. I cannot reproduce it here.

The alert function you are using is giving a pause to the JS. Meaning it gives more time to the browser get correct values from the sensors of the device. (And dont forget this is a wild guess :) )

So I would try to give a small pause before calling the start function. Some thing like the following. (can change depending on you implementation)

prototype.gn
    .init()
    .then(function onResolve(){
        setTimeout(onStart , 1000); // Try to reduce the time out. Smaller values might also work
    })
    .catch(function onReject(reason){
        alert(reason);
    });

var onStart = function() {
    prototype.gn.start(function (data){
    prototype.alpha = data.do.alpha;
    prototype.beta = data.do.beta;
    prototype.gamma = data.do.gamma;
    prototype.absolute = data.do.absolute;
    document.getElementById('data').innerHTML = setData(prototype.alpha, prototype.beta, prototype.gamma, prototype.absolute, prototype.version);
        });    
    prototype.context.start();
}

I hope this helps. Cheers, Doruk

slacktracer commented 8 years ago

I was going to try it... But it is working now. =P

I mean, I just tested it. A few times. (having commented out the alert)

define(
    [
        'gyronorm/gyronorm.min'
    ],
    function setGyroNorm(
        GyroNorm
    ) {
        var
            gn,
            orientation;
        gn = new GyroNorm();
        return orientation;
        //
        // functions
        //
        function orientation() {
            return gn
                .init()
                .then(function onResolve() {
                    gn.start(function (data) {
                        orientation.alpha = data.do.alpha;
                        orientation.beta = data.do.beta;
                        orientation.gamma = data.do.gamma;
                    });
                    // alert('Orientation Module Set!');
                })
                .catch(function onReject(reason) {
                    alert(reason);
                });
        }
    }
);

But I have no idea why.

Just one faint clue: previously, alpha, beta and gamma were... unstable. Even with the phone lying on the table the values kept changing (not by much). At the time I thought it was normal. (High sensibility perhaps) I had absolutely no previous experience with the orientation api or anything like it.

Well, now I am not so sure.

So this is it for now. One way or the other I do not have time to focus on this issue. I will use the alert hack if the problem shows up again. I hope it does not.

At least I know a little better now, and the more you know... =P

So, if you do not mind, I am closing this issue. I will come back if anything new comes up.

Thank you, thank you very much.

(If the problem shows up again I will make a video. I want to be sure I am not just going mad.)

Cheers, Thiago

dorukeker commented 8 years ago

Hi Thiago, Thanks for reaching out. As you said the values also depend on the device. One last thing: the values returned nicely as the compass of the device is properly calibrated. That might be the case you have faced before.

In the spec there is an event called window.oncompassneedscalibration but it is not implemented. So unfortunately there is not a way to detect this from the browser.

I will keep you updated if I learn more about this in the future. Cheers, Doruk

slacktracer commented 8 years ago

Hi Doruk, Thank you very much again.

Yeah, I had tried the window.oncompassneedscalibration thing to no avail. =P

I will let know if anything new comes up. Bye!

Cheers, Thiago