Accelerometer - Get corrected values when tilted?

Monkey Forums/Monkey Programming/Accelerometer - Get corrected values when tilted?

MikeHart(Posted 2012) [#1]
Hi folks,

I am cracking my brain and can't seem to find a simple solution.

If your device lays flat infront of you, using the Y value is no problem at all. But if you have a more natural, means tilted starting position of your device, then you will head straight into the simple problem, that once the Y value reaches it maximum value (around 0.999), it goes back. Evne if oyu tilt the device further. I know that I need to take Z into the calculation somehow. But I can't find the solution.

Does anyone has solved this problem where you "calibrate/store" the values at start of a game/level and then correctly calculate the difference for Y and X each time you retrieve these values? If yes, I would be very happy to know how you did it.

Cheers
Michael


MikeHart(Posted 2012) [#2]
No one ran into this problem before and has a solution.


JIM(Posted 2012) [#3]
I don't fully understand your problem, but you can try 2 things:

1. Maybe accel values are incremental (like the name says). So your code should go like X_angle += AccelX() instead of X_angle = AccelX()

2. Maybe they are absolute, but not normalized. In this case, you need to make a vector out of the acceleration values and normalize it.

Sure hope that helps


Aman(Posted 2012) [#4]
I do not get the problem you're having but I will tell my experience with Accelerometer.

What I did is set default values that works for me and provide an option for the users to calibrate the device and save the new default values. I used all 3 axes. I also provided a virtual control option for those who don't like tilting their devices.

I got great feedback on the game. Some are using the virtual controls but the majority are using tilt and they love it.

My only problem is that AccelX() & AccelY() are reversed on either android or iOS so I had to make AccelH() and AccelW() that return the proper value depending on the Target.


skid(Posted 2012) [#5]
Unless you get really wild with your device (drop, throw, kick) you are effectively only measuring gravity on all three axis (how much x, y and z axis are pointing directly towards the ground) with an accelerometer.



Check the apple docs for some more interesting reading

https://developer.apple.com/library/ios/#documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/MotionEvents/MotionEvents.html

My experience is unless you force user to hold device face up only x tilt is that useful. In Driller Bunny I reversed the x value if z was negative (user is playing lying on their back).

Detecting change in the y tilt is useful but I could never get to feel right. Having user dictate a rest angle didn't work that well either.

The ultimate problem is of course when the device is vertical (tilt y = 1) the other sensors are effectively gimble locked (x and z lock to 0) so you need compass or gyroscope support to do anything creative at that orientation.

As these sensors are now standard on most devices it is possibly time mojo got support also.


dopeyrulz(Posted 2012) [#6]
WP7 Mango includes reading the compass and gyroscope (if included):

http://msdn.microsoft.com/en-us/library/hh202968(v=vs.92).aspx

For first gen devices, the gyroscope is simulated using readings from the compass and accelerator:
http://pocketnow.com/windows-phone/windows-phone-gyroscope-support-not-for-first-gen-wp7-hardware

I posted some info for the accelerator recently - will have a look at what's required for reading the compass and gyroscope.


MikeHart(Posted 2012) [#7]
Thanks folks for all the input.

@JIM, the problem is about virtual calibration. Not everyone wants to play the game with tilt controls only with an orientation where Z = -1. The problem with the accelerometer values is that they have a natural range of 1 to -1. You can see values higher than this but it is rare. When you tilt the device more and more in one direction, at one point the corresponding axxis values becomes smaller again. But depending on where your initial (calibrated) value is, you still need it virtually to grow. I went myself now with a brute force method for portrait mode. Once it is done, I will post the result here.


JIM(Posted 2012) [#8]
Ah, I understand it now. Perhaps matrices can help here:

Use a matrix to define your default calibration (define the axes when you start the game for example).

Then when the device is tilted, you get the new matrix based on current coordinates and multiply it with the inverse of your calibration matrix.

That will give you the current device orientation relative to your original calibration. Now you can just test for the angle of the axes. Unless the device is tilted 180 degrees from the original calibration, you should get accurate results.

If however you want it to work with more than 180 (I'd like to see that person playing the game :)) ) you can remember the angle somehow (if differences are greater than 90 degrees from last frame, then use the angle as 360 - angle) or anything similar.

After thinking about it a little bit, I came up with this: Keep a variable for "Rolls". Start with zero. If current angle is positive and the next one negative, increment. If current angle is negative and next one positive, decrement. Angle = current angle + 360 * Rolls.

Let me know if this works :)


MikeHart(Posted 2012) [#9]
That sounds good JIM. I will try that in the next days.


Fly-Games(Posted 2013) [#10]
Has anyone solved this problem?


Nobuyuki(Posted 2013) [#11]
This issue is dependent on orientation. Really, I believe that we'd all benefit from functions that read from the gyro rather than the accelo, or use the gyros/global gravity sensor to modify accelo values, since the accelo values are locked to an orientation.

I don't know about ios, but for android it shouldn't be that hard to hack up the mojo commands for accel and get gyro data instead. I may look into this, if samah and revills haven't already incorporated it into diddy. (If they have, you should just nick the source code from diddy!)