The idea is very simple. The accelerometer and the compass both measure vectors fixed to the Earth. These vectors are different - gravity and ambient magnetic field - but we hope that their angle is constant because they are both fixed to the same coordinate system. But while the accelerometer is sensitive to the motion acceleration, the compass is not. If we manage to rotate and scale the magnetic field vector into the gravity vector, we have a reference while the accelerometer is subject to motion acceleration and we can extract the motion acceleration. Plus, we have a reliable gravity vector and an "in motion" indication.
So the process is the following:
- Calibrate the compass to the location and figure out the offsets we discussed in the limitation part. Also measure the reference gravity vector length.
- If we find that the acceleration vector's length is close enough
to the reference gravity vector length, we assume that this means "no
motion" (see the discussion of this issue here). Find then the rotation axis and angle to rotate the compass
vector into the acceleration vector. We call these values reference
rotation axis, reference rotation angle, reference magnetic vector and
reference acceleration vector, respectively. Keep updating these values
as long as we are in "no motion" state.
- If we find, that the acceleration vector's length is significantly shorter or longer than the reference gravity vector length, we are in "motion" state. Then we use the previously recorded reference values and the actual magnetic field value measured by the compass to calculate a simulated gravity vector. Using the measured acceleration vector and the simulated gravity vector, we extract the motion acceleration vector.
The steps are:
- Calculate the rotation operation that rotates the reference
magnetic vector to the reference acceleration vector. The rotation
operation has two components: an axis around which one vector is
rotated to the other and a rotation angle. The rotation axis is the vector cross product of the two vectors. The angle can be obtained by resolving the equation of two different representations of the two vectors' dot product. This yields reference rotation axis and reference rotation angle.
- The reference rotation axis nicely rotates the reference magnetic vector to the reference acceleration vector but we need to apply the rotation to the current magnetic vector. We need a new rotation axis for this and we obtain it by rotating the reference rotation axis by the rotation operation that rotates reference magnetic vector to the current magnetic vector. This yields a current rotation axis.
- Then we simply rotate the current magnetic vector around the current rotation axis with the reference rotation angle. This yields a simulated gravity vector. We also have to scale this vector so that its length is equal to the reference gravity.
Let's see the example Android program then that implements all this!
Click here to read the post further.