I´m trying to figure out how to calculate the inclination angle of head movement, just up-down movement, not moving right-left side. I have a wearable device (I guess the problem would be the same for mobile devices) with an accelerometer sensor and it is placed on my forehead.
So far, I think is better to leave the linear acceleration out and just work with the gravity acceleration. I´m reading and reading trying to understand better what exactly I´m looking for, but my brain is not maths material. In a starting position of standing still (stationary position), all the gravity acceleration falls into an axis, lets say X. When I start producing movement with my head, for instance moving my head down (like looking to the ground), the aceleration gravity does not fall only into an axis, but two axes (would be shared, for instace between X and Z). If I´m right and this is the right approach (is it?)...
- How can I calculate this angle without doing crazy maths?
- This problem is exactly the same than calculating the pitch angle of an accelerometer?
- Can I use for this raw data or I need to calibrated data?
To make it clear, let´s imagine that my device axes are placed in the same position than this photo and that in the starting position the gravity falls into X axis (landscape position).
EDIT
Using the following formulas for pitch and roll (thanks to @Nuclearman link)
Roll = atan2(Y, Z) * 180/M_PI;
Pitch = atan2(X, sqrt(Y*Y + Z*Z)) * 180/M_PI
And this code I wrote:
/**
* Function to calculate the inclination angle or pitch of the head movement
*/
float calcInclinationAngle(int iDataPos){
float xVal = fAccel[0][iDataPos];
float yVal = fAccel[1][iDataPos];
float zVal = fAccel[2][iDataPos];
float pitch = 0;
//Pitch in rad format
pitch = atan2(xVal, sqrt(pow(yVal,2)+pow(zVal,2)));
//Pitch in degrees
pitch = pitch * 180/PI;
return pitch;
I always get wrong angles. When the gravity force is entirely on the X axis, I get around 45 degrees (instead of 0) and if I move the device 180 degrees (just changing the gravity force signal), I get around 17-18 degrees. I have been playing with atan2 parameters, but the angles range is always the same (25-35 degrees). Just throwing a question...should I be working with calibrated data instead of raw data?
Edit 2
I have done some progress "cheating" a bit, due to I'm totally stuck. Now I normalize the data and instead of using atan, I do pitch = 1/sin(xVal), which actually gives me a range of 90 degrees which seems to fit with my device rotation (although for example it gives me 135 degrees instead of...45, but I "fix" that substracting 90 degrees to all the angles). Anyway, I need a 180 degrees range because at the moment moving backwards or forward does not make a difference in the obtained angles.
Edit adding some pictures and information
Calculating the pitch as pitch = atan2(xVal, sqrt(pow(yVal,2)+pow(zVal,2))) * (180/PI), I obtain the following angles. Just in case is useful, the accelerometer values (raw data) in the position 1 are: ACCX 2936 ACCY 2152 ACCZ 1883
Position 1 (gravity falls into X axis): 45-46 degrees
Position 2 (rotating aprox 45 from starting point): 38
Position 3 (rotating aprox 90 from starting point): 28
Position 4 (rotating aprox 180 from starting point): 18-19
Position 5 (> 180 < 360): 18-46.
SOLUTION
Just in case someone bumps into something similar in the future. The main problem was the range of the raw data. Once I mapped this into a [-1g, 1g] range and fixed a few things about the coordinates it worked.