# Transform a GForce Vector

1. Sep 8, 2010

### MyNameIsTaken

Hi there.

I have a GForce sensor (accelerometer to be precise). If I hold it in its initial orientation then x = 0G, y = 0G, z = 1G (x = left and right, y = forwards and backwards, z = up and down)

Now i'd like to calibrate it (perhaps the wrong term, but u get the idea)... meaning that if I for example hold it up a little (45 degrees up on the Y Axis), i'd like that to be the "zero" position (x = 0, y = 0.5, z = 0.5). Notice how Z decreases because when I tilt Y upwards, Z is no longer facing directly up anymore.

Essentially, if I receive a reading from the device that says (0,0.5,0.5), I know that I need to apply the offset and the net result should be (0,0,1).

Real world example: If the user sticks the accelerometer on their car windscreen so they can see the output screen, it should correct the values to tell them the GForce values from the car's perspective, not the accelerometer's. So under braking, even though the accelerometer is experiencing acceleration on Y and Z, in reality the car is experiencing only Y (well, in simplified reality if we ignore the downward movement from shock absorbers).

The problem is that my understanding of vectors and geometry etc is very limited, and I don't know where to start with coming up with an approach that will work for any orientation. I have been exposed to vectors etc at university, but that was a while back, only in first year math, and i'm VERY rusty.

I can't seem to find a resolution on the net, and i've been trying different calculations in excel that only seem to work for a 2 axis scenario (not using any trig, just simple math).

Any assistance would be greatly appreciated.

Last edited: Sep 8, 2010
2. Sep 8, 2010

### Alibeg

You need to use trigonometry if you want to make your transformations. In some special cases like 30, 45 or 60 degree tilt, you could get through with simple geometry.

First of all, when you tilt accelerometer by 45 degrees (rotation around x-axis), your readings will actually be: (0, 1.4142, 1.4142), that is (0, square root(2), square root(2))

Trigonometry can explain it.

If you want detailed explanation post again, because here is just solution to your problem:

Xnew = X (note that x is unaffected by rotation around x-axis)
Ynew = Y * cos(alpha) - Z * sin(alpha)
Znew = Y * sin(alpha) + Z * cos(alpha)

where alpha is angle of tilt

I have assumed that positive z axis is downward, and that positive y-axis is backward, so you will need to turn the device in the appropriate position or change the sign of appropriate coordinate.
You can turn device several times to detect positive direction of any axis. If you get positive reading on any axis while holding still, that means that positive direction is downward (gravity pull)

Post back so I know this works....
Thanks. ;)

3. Sep 8, 2010

### MyNameIsTaken

Thanks for the reply Alibeg... i'm trying it out now, and will get back to you in a bit. I will probably want to understand the detailed stuff too (just because I like to know how things work).

4. Sep 10, 2010

### MyNameIsTaken

Ok, so after a lot of learning, i've managed understand your answer (and a lot more). I couldn't quite make sense of your observation that the reading would be 1.4142 (how could the unit experience more than 1G in any orientation). I realise some math went astray there and the values are 0.707 and 0.707 for Y and Z.

The 3 most useful of a number of articles i've read recently can be found here (for anyone else with the same problem):
http://www.instructables.com/id/Accelerometer-Gyro-Tutorial/
http://en.wikipedia.org/wiki/Rotation_matrix

It turns out that I was trying to find the new values using on formula per axis, when in reality I needed to rotate around X, find the new values, then feed them into the rotation around Y, then feed those results into the rotation around Z.

Thanks again. It just took a while to understand what you put down there. Much appreciated.

5. Sep 10, 2010

### Alibeg

Hmmm. My mistake, it is not 1.4142 but 1/1.4142 (I multiplied instead of division)

I think that you use same data to feed in Ynew and Znew, but I could have made a mistake...

I will post later Insallah

6. Sep 11, 2010

### Alibeg

You could have taken the device in your hands looking at the display.

Call the:
front face - face A
back face - face B
right face - face C
left face - face D
top face - face E
bottom face - face F

Now you turn each face to be on bottom side of device (facing earth)
And by seeing the readings, you can define x,y and z-axes and their positive and negative directions.
Once you do this it is much easier....

But I guess you have already done this, or something like it... :)
Anyway, I hope I didn't cause much confusion and problems to you...

Last edited: Sep 12, 2010
7. Sep 13, 2010

### MyNameIsTaken

You actually cleared up quite a lot for me.

The only thing I am struggling with now is the following:

I get a GForce reading from the accelerometer. I can convert this to degrees using the math found here: http://www.instructables.com/id/Accelerometer-Gyro-Tutorial/

Basically I calculate the vector using R = SQRT( Rx^2 + Ry^2 + Rz^2).
Then I can calculate the angle of x as arccos(Rx/R). y = arccos(Ry/R) etc

This is all fine and well, but it gives me angle of the axis, not rotation around the axis. If I tilt the accelerometer up 45 degrees (so that the Y-Axis reads 45)... the accelerometer tells me that Y is 45 degrees... but according to the eular rotation... there has been a rotation around the X Axis, resulting in the change in Y.

Trying to figure out what the rotation around the axis is for each axis given static X Y and Z values is breaking my head.

Any ideas? Let's say I present the same values in their example (x = 0.5g, y = 0.79g, z = 0.33g), how do I calculate the rotation around X, rotation around Y and rotation around Z?

I don't now how to get the rotation around the axes, but I can calculate the angles as follows:
Rx = 0.5, Ry = 0.79, Rz = 0.33
R = Sqrt(Rx^2 + Ry^2 + Rz^2)

x = ArcCos(Rx/R) = 59.71 degrees
y = ArcCos(Ry/R) = 37.17 degrees
z = ArcCos(Rz/R) = 70.5586 degrees

Getting this to rotation (which is what I think the Eular calculation requires)? That's where i'm clueless.

8. Sep 13, 2010

### Alibeg

Ok...we need to know one thing. Consider following readings:

x = 0 g
y = 0 g
z = 3 g

You will say: "This is easy - device is in its regular position, and is suffering 1g from gravitation and 2 more Gs because of its acceleration..."

But I will tell you: "That's true. Partially. Because it CAN be in its regular position, but DOESN'T have to. Why? Well, device could be turned upside-down, so gravity is creating -1g and the device itself is suffering 4g, so final result is 3g..."

Point is: for every reading of a device, there is unlimited number of accelerations the body can be suffering. It depends on its rotation. If body is in regular position, we now what is acceleration, if it is upside-down, we will again calculate the acceleration. But knowing only the readings is not enough to determine acceleration, or rotation.

You need to know any of these two parameters (rotation or acceleration) to calculate the other one. So...you can either:

1) Fix the device in way you like, measure the angles yourself, and then using the readings, calculate the acceleration
2) Fix the device in any way, but have other instrument to measure acceleration (or get the acceleration by rule of thumb :P), and then using the readings, calculate the rotation.

First solution is nice if you want to measure acceleration of moving body.
Second solution is nice if you want to measure rotation of body that is still, or at least, moves with very small acceleration - smoothly...

I hope this helps a bit.

If you could tell me, what for do you need the device, maybe we could come up with a solution.... (actually, I'm interested in - what could you possibly want with accelerometer...maybe you are a mythbuster :D)

9. Sep 14, 2010

### MyNameIsTaken

Not quite a mythbuster, more like a hobbiest but this is a rather interesting problem none the less:P

Ok, let's see if I can go through this from start to finish. You may want some coffee / popcorn as this will take a while to get through:P

I'm putting together a simple 3-axis accelerometer that can allow me to measure GForce. If I had to leave it on a table in front of me then x = 0g, y = 0g and z = 1g.

If I had to lift it off the table giving it 1g upwards movement, x = 0g, y = 0g, z = 2g.

Now it's great having the accelerometer in a flat position, but sometimes it's not practical to mount it at that orientation. For example, if I climb into my car and I want to stick the accelerometer to the windshield so that I can see the screen, then when the car is stopped, x and y are no longer 0g, and z is no longer 1g, they will measure the GForce in the new orientation.

I am, however, not interested in the GForce experienced by the accelerometer, but the GForce experienced by the car. So what I am trying to do is take the GForce experienced by the accelerometer and rotate it so that it represents the GForce experienced by the car.

So what I want to do is zero the accelerometer when the vehicle is stationary. This will effectively give me an X angle, Y angle and Z angle that I can then use to "correct" any readings that I receive. Once I click a button to zero the accelerometer, it must correct all the values from then on, meaning that even though the product is stuck on the windshield in a strange orientation, it must read x= 0g, y = 0g, z = 1g when the vehicle is stationary.

There are basically two different approaches that I have seen that can accomplish this. The first is Euler Rotation (http://en.wikipedia.org/wiki/Euler_angles) and the second is using Quaternions (http://en.wikipedia.org/wiki/Quaternions).

The approach you mentioned previously was based on euler rotation. Perhaps I should go into detail on how I approached the problem this way.

Step 1: Convert the GForce readings when stationary to angles.

To do this, I used the Direct Cosine rule (http://en.wikipedia.org/wiki/Direction_cosine).
Lets say that Rx = 0.5g, Ry = 0.79G and Rz = 0.33g

(I am using the example here as it has pictures for you to follow: http://www.instructables.com/id/Accelerometer-Gyro-Tutorial/#step1)

R = SQRT( Rx^2 + Ry^2 + Rz^2)
-->R = SQRT(0.5^2 + 0.79^2 + 0.33^2)
-->R = 0.99146356

Now to get the Angle of X, Y and Z, I use the arccos operator:
Axr = arccos(Rx/R) = 59.71477 degrees
Ayr = arccos(Ry/R) = 37.17422 degrees
Azr = arccos(Rz/R) = 70.5586 degrees

These readings as far as I can tell are the angles of each axis.

From here I would like to perform the Euler rotation, but the problem is that these angles that i've calculated are not Euler angles. They are measurements of the tilt of the axis, not the rotation around the axis.

So I stumbled on this website: http://www.stellarsoftware.com/rotation-sequences-and-euler-angles

There they have a formula that converts X, Y and Z angle to pitch, tilt and roll (Euler angles from what I understand).

So the calculation goes as follows:

tilt = -arctan[(-sin(ax)*cos(az) + cos(ax)*sin(ay)*sin(az)) / (cos(ax)*cos(ay))]
pitch = arcsin[ cos(ax)*sin(ay)*cos(az) + sin(ax)*sin(az) ]
roll = -arctan[(-cos(ax)*sin(az) + sin(ax)*sin(ay)*cos(az)) / (cos(ay)*cos(az))]

So at this point, I should be able to use the inverse of these values when applying the Euler rotation to any new GForce value that I receive on order to rotate them into the correct orientation.

This does not seem to be the case though. Using the Euler rotation logic found here (http://www.c-sharpcorner.com/uploadfile/vckicks/eularangle01052008154724pm/eularangle.aspx), I would do the following:

// Step 1: Rotate around the X Axis:
newY = (Y * cos(pitch)) + (Z * sin(pitch));
newZ = (Y * -sin(pitch)) + (Z * cos(pitch));

// Step 2: Rotate around the Y axis:
newX = (X * cos(tilt)) + (newZ * tilt(tilt));
newZ = (X * -sin(tilt)) + (newZ * cos(tilt));

// Step 3: Rotate around the Z axis:
newX = (newX * cos(roll)) + (newY * sin(roll));
newY = (newX * -sin(roll)) + (newY * cos(roll));

So now we should have the newX, newY and newZ after the rotation.

Before I continue, perhaps I should ask if I am approaching the problem from the right direction?

The values that I am getting for pitch, tilt and roll seem to be realistic, but I have learned my lesson and no longer apply logic to these problems (it was logic after all that told me if I tilt the product so that y = 45 and z = 45 that they would both experience 0.5g:P).

Last edited by a moderator: Apr 25, 2017
10. Sep 14, 2010

### Alibeg

Hmmm....
First of all, we need to solve the logic problem you have mentioned at the bottom of your post. You see, I do believe in God, but still, I try to learn as much stuff as I can with a logical explanation, that is the way He created the world...
__________________________________________________________________________
Take two matches. They will represent vectors in following discussion (phosphorous part is vector arrow). If we take that both of these vectors have magnitude 0.5, you will see that placing one after another yields a new vector with magnitude 1.

If you make a normal triangle, you will have angles 45, 45, 90. (Same situation you were talking about). But what is the magnitude of the vector that is hypotenuse of the triangle? c = sqrt(0.5^2 + 0.5^2) = sqrt(0.25+0.25) = sqrt(0.5) = ... and this is definitely, not 1 ---> 1g vector, cannot be dissolved in two vectors of magnitude 0.5. It can, but only if one vector follows the other in the same direction...but we don't need that...

Using this logic, you can see that only vectors that have magnitudes sqrt(2), can make 1g vector if they are placed at 90 degrees.
__________________________________________________________________________
Now, I hope you have no doubts about dissolving 1g vector at angles of 45 deg.
If you still have, please do write, so we can try to find someone who ca give you better explanation... :)
__________________________________________________________________________
I do not have much time left at the moment so I will try to be short but precise.

You need to use both methods I have mentioned in previous post.

First, you use method 2, to get the rotation of the device since you already know that acceleration is 1g directed downwards...

You start your car and drive it....

Second, you use method 1 to calculate the acceleration of your car, since you have already calculated the angles.

As I am looking at the problem, it seems a bit complicated...I think I could find the solution, but I don't know whether I will be able to explain anything (if I find a solution at all :D)

11. Sep 19, 2010

### Alibeg

I really don't have much time because my college starts. I was trying a bit but I couldn't solve it. I guess I would need more time, or task is too difficult.

Try to ask on other places also. This is now a math problem, not physics, so consider asking math experts about these coordinate conversions...

I hope you'll find a solution.