4

Similar to this question: CMDeviceMotion userAcceleration drift

I'm using CMDeviceMotion.userAcceleration in iOS5 SDK to plot its x, y, z components over time. Like the above post, I see z acceleration component shows always small positive values (0.005 - 0.015) while x and y components are centering along zero (-0.005 - 0.005) when my iPhone 4s is sitting on a flat surface.

This small bias keeps adding up to the estimated velocity (which I compute by integrating the acceleration data) even when my phone is not moving a bit. Is there any known way to remove this bias from the accelerometer data? I cannot simply subtract the bias from z component because it seems that the bias spreads over x y and z along the gravity axis if the device is in some arbitrary orientation.

I know that the data in CMDeviceMotion.userAcceleration has already factored out the gravity using Gyro data but wonder if there is any effective way to remove this residual bias?

Community
  • 1
  • 1
atisman
  • 1,187
  • 1
  • 11
  • 16

3 Answers3

2

Old question, but I wanted to share some insight. Part of the bias in the accelerometers actually does not come from any inaccuracies in the sensors, but from an oversight in the calculations that Apple does. The calculations assume that gravity always is 1 G (which is by definition 9.80665 m/s2). Any left-over must then be user acceleration.

However, gravity varies slightly all over the world. If the gravity in your area is not exactly 9.80665 m/s2, then there will be a small bias in the user acceleration, which is detectable with a low-pass filter. Such a bias can removed with the following calculation:

- (void) handleDeviceMotion:(CMDeviceMotion *)m atTime:(NSDate *)time
{
    // calculate user acceleration in the direction of gravity
    double verticalAcceleration = m.gravity.x * m.userAcceleration.x + 
                                  m.gravity.y * m.userAcceleration.y +  
                                  m.gravity.z * m.userAcceleration.z;

    // update the bias in low pass filter (bias is an object variable)
    double delta = verticalAcceleration - bias;
    if (ABS(delta) < 0.1) bias += 0.01 * delta;

    // remove bias from user acceleration
    CMAcceleration acceleration;
    acceleration.x = m.userAcceleration.x - bias * m.gravity.x;
    acceleration.y = m.userAcceleration.y - bias * m.gravity.y;
    acceleration.z = m.userAcceleration.z - bias * m.gravity.z;

    // do something with acceleration
}

Mind you, even with that bias removed, there is still a lot of noise, and there could also be a manufacturing bias different for each accelerometer chip. Therefore, you will still have a hard time deriving velocity and certainly position from this.

fishinear
  • 6,101
  • 3
  • 36
  • 84
2

First, you need some external reference that does not drift such as GPS. Then you have to perform sensor fusion (Kalman filter comes to mind). Otherwise you cannot remove the bias and the integration error will grow indefinitely.

UPDATE: You cannot get relative displacement just by integrating the acceleration, see my answer to Android accelerometer accuracy (Inertial navigation). However, I give some examples there what you actually can do.

If you check my answer you will see that it is the gyro white noise that makes the integration hopeless.

Community
  • 1
  • 1
Ali
  • 56,466
  • 29
  • 168
  • 265
  • Thanks for the reply. To be clear, I'm looking for a way to effectively cancel out the bias in the raw accelerometer data (not the integration error for now). It's OK if it requires any calibration step but not sure how Kalman filter will help for this case. – atisman Feb 01 '12 at 05:49
  • @atisman MEMS sensors will always drift, they are sensitive to temperature changes among others and there is not too much you can do about it... If you are not integrating then why does a small bias cause you problems? What would you like to do? – Ali Feb 01 '12 at 08:40
  • At this moment, I'm just trying to understand these sensors and related iOS APIs and what I can get from them. My initial goal is to get the relative displacement of two arbitrary positions of iPhone as accurate as possible. But with this constant positive bias, the error in the displacement seems to be too large even without considering any error in the integration step. For example, with the amount of 0.0015 g/s^2 will give about 7.35 cm displacement after 1 second (based on the formula 1/2at^2) without any movement of the phone. – atisman Feb 02 '12 at 00:31
  • OK, I updated the answer. I tried the integration myself and the conclusion is: surprisingly it is the gyro white noise that makes it impossible, not the accelerometer bias. Please check my updated answer. – Ali Feb 02 '12 at 08:57
-1

Thanks Ali for updating your answer and other references. They certainly helped my understanding on this issue (and I was surprised to see how many people are interested in this issue). I may sound a bit stubborn but I still think I didn't find the answer for my original question from anywhere. Let's forget about integration now. With more experiments I see some constant biases (though even smaller) on x and y axes as well when I averaged the user acceleration data over time. I was just wondering if there's any way to remove these biases from "user" acceleration data which I get from iOS5 CMDeviceMotion. If they were caused by the white noise of the gyroscope in the process of filtering out the gravity, I guess we may see random noise in the user accelerometer data but not those biases. But based on my impression so far, it seems that those biases were caused by the limited "accuracy" of both accelerometer and gyroscope and there's nothing we can do about that although I'm not 100% sure. I was trying to put my impression in comment (not in answer section) but SO didn't allow because it was too long but I was wondering how many people would back up my impression by voting so I decided to put it in answer section... Sorry if I was rambling a bit.

atisman
  • 1,187
  • 1
  • 11
  • 16
  • Averaging the acceleration to obtain a "bias" and then applying `1/2 at^2` *is* integration. The formula `1/2 cx^2` is the general result of integrating a constant `c` twice. Please accept Ali's answer. By the way, unless the error is measured to be the same each time, it is not a bias. – Potatoswatter Feb 27 '12 at 03:43