I am developing a simple game which involves a character moving up and down only along the Y axis.
Currently I am using the accelerometer readings to change the Y velocity of the character. The game works fine but the biggest problem is that you have to keep the device horizontal in order to play the game properly.
What I really want is to change the characters Y velocity only when there is a change in the rate of rotation along the Y axis. I need to be able to translate this rate of change into the Y velocity of the character. In this way it will not matter how much the device is tilted and the user can play the game while holding the device normally.
Since the accelerometer is mandatory in every device, therefore older devices can run my game I want to be able to calculate this rate of change using the data retrieved from the accelerometer.
I found this link which explains how to get pitch and roll from accelerometer data. I used the exact code and came up with this,
final double alpha = 0.5;
double fXg = 0;
double fYg = 0;
double fZg = 0;
fXg = game.getInput().getAccelX() * alpha + (fXg * (1.0 - alpha));
fYg = game.getInput().getAccelY() * alpha + (fYg * (1.0 - alpha));
fZg = game.getInput().getAccelZ() * alpha + (fZg * (1.0 - alpha));
double pitch = (Math.atan2(-fYg, fZg) * 180.0) / Math.PI;
double roll = (Math.atan2(fXg, Math.sqrt(fYg * fYg + fZg * fZg)) * 180.0) / Math.PI;
pitch = (pitch >= 0) ? (180 - pitch) : (-pitch - 180);
With this piece of code I am unable grasp how to calculate the RATE of change.
Am I going in the right direction with this or is this completely different from what I want?
Also is it better if I just use the gyroscope instead of relying on the accelerometer?
Thanx in advance.
There are two parts to this answer. (1) What sensor data to read. (2) How to get the motion change info that you want.
(1) What sensor data to read
You'll get much better data from Android's software-derived Motion Sensors (than from just the accelerometers) since they combine signals form the accelerometers, magnetometers, and (if available) gyroscopes. The motion sensors might also correct for known biases and use a Kalman filter to remove noise. Gyros are more accurate and faster at detecting rotational changes than the other two sensors, but they only detect changes faster than some threshold. They don't detect absolute position or orientation.
The "rotation sensor" is a software-derived indication of Android's best information about the device's rotation. My recollection is that it includes the gyroscope signals if available, else it just uses the accelerometers (to measure linear forces including gravity) and magnetometers (to measure the orientation within the earth's magnetic field).
Caveat: This paragraph in the Motion Sensors Guide says something tricky:
I think that means that on Android 4.0 and later, these three software-based sensors are only available on devices that have gyros, while they're always available on earlier versions of Android. Do some quick tests on various devices to find out, and please report back here.
Note: It helps to calibrate the magnetometers. Do this by moving the device in a large figure-8 shape for several cycles. The magnetometer hardware will detect this, track what range of values that it measures, then adjust its calibration parameters.
(2) How to get the motion change info that you want
To control your game character, consider reading the Rotation Vector Sensor. The rotation about the X-axis minus the initial X-axis rotation should indicate how much the device has been tilted up or down relative to when you captured the initial rotation value.
Or you can use Acceleration Sensor to gauge how much the user has moved the device up and down along the device's Y-axis. The Y-axis points up to the top of the screen. The code sample on this Guide page shows how to use a high-pass filter to subtract out the force of gravity.
That would measure how fast (not how much) one tilts the phone left and right (not up and down). If you need some background on the mathematics of change in a value, see the Khan Academy for short lectures on derivatives [in calculus, not finance] and integrals. Wikipedia should also be helpful. In short, compute a value's change by subtracting its reference value, compute the rate of change (e.g. compute acceleration from velocity) by subtracting the previous value sampled at a regular time interval, and compute the integral (e.g. compute velocity from acceleration) by summing the sampled values.
See also the Sensor API reference and the Sensor Event reference.