Tracking position in 3d space using 10-DOF IMU

I need to track the position and orientation of a pistol in 3d space. I purchased a 10-DOF IMU sensor (GY-87) in order to properly learn how to implement a solution to my problem. I cannot find the correct guide due to my lack of knowledge in electronics and sensors. I found some good examples but couldn't implement it in arduino.

3D tracking with IMU

Gait-Tracking-With-x-IMU

I can currently detect the Yaw, Pitch and Roll from the sensor from which I can determine the correct orientation of my pistol. But I cannot find a way to calculate the position (x, y, z).

I would be grateful if someone can help me in this regard.

thank

PS: I can't find many resources for the GY-87, it might be outdated. But due to lack of resources in my country, I had to use this sensor. I am a computer science student and new to electronics, so please correct me if I am not using a suitable term.

+3


source to share


2 answers


The accelerometer will never give you position, it will give you ... acceleration.
But acceleration has to do with speed related to position.
If you look at the units, you will see this relationship. Acceleration is expressed in meters per second squared (m / s²), and speed in meters per second (m / s) and meters (m).
So if
t is the time elapsed since the last calculation of the position (for example, in a loop),
a is the acceleration that you read from the sensor,
at the old speed, with the new speed,
p is the old position and p is the new position,

s = s + a * t
p = p + s * t



You need to do the same calculation on 3 axes (x, y, z). Assuming you know the starting position and the starting velocity is zero, you can track your object in real time.

+3


source


Integration is like calculating the area below the curve. Consider only one X direction. If you are plotting acceleration over time, you have time as abscissa (horizontal) and acceleration as ordinate (vertical).

If you have two scalar values ​​a1 and a2 representing the acceleration at times t1 and t2, and imagine a linear transition between the two in the middle (at the moment of (t1+t2)/2

acceleration (a1+a2)/2

...) the shape you can draw with this curve is a rectangular trapezoid of bases a1 and a2 and one side (with rectangular corners) of length t2-t1 (i.e. also height).

Area (base1+base2)*height/2

= (a1+a2)*(t2-t1)/2

or(a1+a2)/2 * delta_t

where delta_t is, (t2-t1), the time interval between the sensor readings and (a1 + a2) / 2 is the average of the last two readout values.

To do this, you can get an approximate speed difference starting from the initial speed s0 (which you can assume to be zero if you start anyway)

s(n) = (a(n-1)+a(n))/2 * delta_t + s0

By integrating again in the same way, you can get the "space" x or the distance from the starting point x0



x(n) = (s(n-1)+s(n))/2 * delta_t + s0x + x0

If you start at point 0, you can safely assume that s0 = 0 and x0 = 0

s(n) = (a(n-1)+a(n))/2 * delta_t

x(n) = (s(n-1)+s(n))/2 * delta_t

Or programmatically, keeping only the latest values:

old_a=a;
old_s=s;
a=getAccelerationX();

s = (old_a+a) * delta_t / 2.0;
x = (old_s+s) * delta_t / 2.0;

      

Note that this assumes a fixed stationary (velocity = 0) known (x = 0) starting position, the ability to track one component of acceleration (no matter how the sensor rotates in space), and this will inevitably get more and more errors across for a while, as minimal errors will add up, so it is ideal for positions that can be tested in other ways after a while.

PS if you are performing operations on a microcontroller (Arduino) in C, be careful with how you express formulas: if old_a and a are integers, / 2 will truncate the division result, discarding decimal places (bad idea), while /2.0 will generate float. (old_a + a) / 2 * delta_t is worse than (old_a + a) * delta_t / 2. The latter has fewer bugs, but be careful not to overflow. It's just to say that each error will add up, so be careful with how you calculate it.

0


source







All Articles