Example application for accelerometer/compass processing on Android

7 replies [Last post]
paller's picture
Offline
Joined: 11 Apr 2010
Points: 191
0
0

I hope you are well prepared by now what you can expect from the compass-accelerometer sensor fusion - if not, please read my thoughts about the limitations. This time we are going to see, how to compensate the accelerometer with the compass.

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". 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.

Simple, isn't it? Yes, it is, the only part requiring attention is the rotation bit. The task is the following: we have a reference magnetic vector and a reference acceleration vector from an earlier measurement. During that earlier measurement the acceleration vector length was close to reference gravity so we can assume that the reference acceleration vector mostly contains gravity component. Now we have a current magnetic vector and a current acceleration vector. The acceleration vector, however, seems to contain motion acceleration component too. How to simulate a gravity vector from the current magnetic 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.

Once we are done with this, we can subtract the simulated gravity vector from the current acceleration vector and we have the motion acceleration.

Let's see the example Android program then that implements all this!

The example program is attached to this post. You have to be logged into the Sfonge site to access it.

The program is really just a variation of the gyroscope/accelerometer example program. The main difference is that when the sampling is started, you have to calibrate the compass first. The application instructs you, which edge/side of the device should be turned toward the Earth and the calibration steps already passed disappear from the screen. This is really a major annoyance compared to the gyroscope version but that's the price we pay for having a widely available sensor instead of the rare gyroscope.

After the calibration you see the familiar ball that visualizes the measured motion acceleration (the size of the ball is proportional with the z component of the motion acceleration). As with the gyroscope case, the motion acceleration is rotated into the Earth's coordinate system. If you need the motion acceleration in the device's coordinate system, just remove the rotateToEarth() method invocation.

If you set DEBUG to true in SamplingService.java, the program creates a (potentially large) file containing measurement data as /sdcard/capture.csv. You can analyze it with the Sage script attached to this post.

Now we have two methods of extracting motion acceleration. The gyroscope is more convenient because it is not subject to external magnetic fields or metal objects but is available in less devices. There are more hassles with the compass but at the end it works nicely too. The next step is to recognize movement patterns in the 3D motion acceleration vectors.

sasebt's picture
Offline
Joined: 4 Feb 2014
Points: 6
Software gyro through other sensors

Hi,

Is it possible to implement a gyro type sensor values (rotation speeds around the 3 axes) using accelerometer/gravity/magnetic/orientation sensors?

Thanks,
Saso

paller's picture
Offline
Joined: 11 Apr 2010
Points: 191
Maybe

Interesting question, I haven't done rotation speed calculation yet but I did do motion acceleration calculation based on accelerometer and compass. Compass is a very problematic sensor, however. Due to external magnetic fields compass can be used reliably inside buildings only if the device is used at one particular location. Outside of buildings is better but there may still be surprises, see slide 28 in this presentation.

kadoudal's picture
Offline
Joined: 16 Dec 2013
Points: 8
calibrating

Is the calibrating page mandatory before each measuring phase or could it be stored

thanks for sharing ...

paller's picture
Offline
Joined: 11 Apr 2010
Points: 191
Calibration

Simple answer: this example program was written in a way that the calibration is mandatory.
Complicated answer: compass is not a simple sensor. It is subject to all sorts of external magnetic sources and in a human habitat there's plenty of those (think about a refrigerator or a microwave oven). Buildings can also play nasty tricks on you (like bulky iron rails quite commonly built into innocent-looking brick houses). If the application is used in an environment where external magnetic forces may be present (a flat almost surely belongs to this category) then it's best to calibrate the sensor to the actual location.
I have done more research on the compass calibration in the presence of magnetic field (this time in a car), see this presentation about the results.
 

kadoudal's picture
Offline
Joined: 16 Dec 2013
Points: 8
Calibration

Got it

We plan to use our pilot app in a .. swimming-pool ( yes, in the water, but in the device will be in a waterproof pocket..) we'll calibrate it..
my question was relative to keeping the calibration data as setting if the user will use the app always at the same place ( same swimming pool in this case for training)

thanks for your feedback, I'll look at the presentation now

paller's picture
Offline
Joined: 11 Apr 2010
Points: 191
Swimming pool structures

The project sounds familiar. :-)
I am not knowledgeble in the engineering of those swimming pools. Are you sure that in a typical case there are no significant iron structures or electric instruments below or beside the pool? It is easy to measure, check out this post. Basically you walk over the area and measure the absolute value of the magnetic vector. It should be reasonably constant.
Are you sure you don't have the luxury of a gyro? Gyro is much less problematic when it comes to external disturbances.

kadoudal's picture
Offline
Joined: 16 Dec 2013
Points: 8
calibrating

Yes, we'll work with a Gyro... ma question was more related to the calibration process in this case , if a user is going to run an app in specific places , I guess it should be possible to store the various calibration data and reuse them upon user selection of a specific place...
thanks for your answer... Yes, I work with David and Jannick on the project...