Calculate how many degrees a physical device is off centre (offset) given X, Y, Z

Let's say I have a physical device that I can rotate with my hands and receive X Y Z coordinates of that device. What I need to calculate is the offset - how far is the pendulum of gravity straight down. Basically how many degrees I am off centre. Is there a way of doing so? I've googled a lot of questions but so far I'm struggling.

Thanks.

Updated:

There is a physical device (sensor) which I can rotate. The device sends its X Y Z coordinates and a calculated acceleration vector in mg (mill mg). I can read this data from this device using BLE. The device should lie flat while transportation, so I need to calculate how many degrees the device is off centre (which is the laying flat on table).

Updated x2:

I need to calculate the angle between the device's centre vector and a gravity pendulum (the blue angle) on the photo. • X, Y and Z are coordinates that convey position, they don't convey orientation. They'll be relevant only if you provide other positions. If you could provide us the code you have used to figure this out, or an image representing what you're trying to achieve, maybe we could help you further, including better defining the question you're asking. May 21 '21 at 15:35
• Are these X Y Z coordinates data coming from a 3-axis accelerometer measuring the force of gravity in the device's frame of reference? Or some other sensor? Give us any details you can about it. May 21 '21 at 15:39
• Hello and thank you so much for your answers. I have updated my question. Hope it's now more understandable. There is no code so far because I am only trying to figure this out.
– lipa
May 24 '21 at 8:00

First, note that accelerometer sensors tend to be noisy — giving rapidly varying values that jitter around the true measure, even when the device is at rest. So you'll likely want to gather up several measurements into a windowed average to smooth out this noise and get a more consistent orientation estimate.

Next you'll want to measure what value the device reports when lying stationary and flat. This will probably correspond to a vector along one of the axes of the sensor, whose magnitude corresponds to 1 g of acceleration. Something like (0, 1000, 0) if your sensor uses units of 1/1000th of 9.8 m/s².

Discard the magnitude to make a unit vector, like (0, 1, 0) in the example above, but keep the sign (ie. if we had (0, 0, -1234) we'd normalize it to (0, 0, -1)). Store this in your program as your "reference direction"

Now you can compute a degree offset from it like so:

direction = averageAccel
* 1/Sqrt(Dot(averageAccel, averageAccel))

cosine = Dot(direction, referenceDirection)

degreeError = Acos(cosine) * 180/PI

Here we're using the fact that the dot product between two unit vectors gives the cosine of the angle between them. So we can use the inverse cosine function to turn that into an angle in radians, then rescale that to change the units into degrees.

• Hi @DMGregory and thank you a lot for sharing an answer! I will try this one, it will take some time. Thank you once again!
– lipa
May 25 '21 at 9:14
• I am extremely grateful for your answer @DMGregory. I've finally made it work in my code. I accepted your answer as the correct one, although, I cannot vote up for it (I don't have enough reputation here). Thank you once again for understanding my question and writing such a detailed answer for it!
– lipa
Jun 1 '21 at 11:36
• Hi @DMGregory, could you please be so kind to check this question? Perhaps, you can share any ideas? gamedev.stackexchange.com/questions/193914/… It would be very much appreciated. Thank you!
– lipa
Jun 5 '21 at 11:11
• Hint: I already showed you how to compute your angular distance from a reference vector. Repeat for two more reference vectors to get your other two angles. Jun 5 '21 at 11:15
• HI @DMGregory! Could you explain to me what are we doing exactly when we calculate direction and what formula is used for it, please?
– lipa
Jun 14 '21 at 13:40