views:

515

answers:

1

I'm asking them at 50Hz / 50 times per second for data. When I suddenly flip the device on the x-axis by 90 degrees while the device was flat on a table with display facing up bevore, the values move pretty slowly to the "target" value for that position.

Now the weird thing is: If I increase the measurement-rate, the value will move faster to that new value upon suddenly flipping the device by 90 degrees. But if I just ask once per second for the new value, it take's very long until the value reaches the target. What can be the reason for this?

I don't do any kind of data aggregation, and don't accumulate anything. I just do some simple filtering to get rid of the noise. My method looks like this:

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
    // Use a basic low-pass filter to only keep the gravity in the accelerometer values for the X and Y axes
    // accelerationX is an instance variable
    accelerationX = acceleration.x * 0.05 + accelerationX * (1.0 - 0.05);

    // round
    int i = accelerationX * 100;
    float clippedAccelerationValue = i;
    clippedAccelerationValue /= 100;

    [self moveViews:clippedAccelerationValue];
}

later on, in my -moveViews: method, I do this:

-(IBAction)moveSceneForPseudo3D:(float)accelerationValue {
    if(fabs(lastAccelerationValue - accelerationValue) > 0.02) { // some little treshold to prevent flickering when it lays on a table
     float viewAccelerationOffset = accelerationValue * 19 * -1;

     newXPos = initialViewOrigin + viewAccelerationOffset;
     myView.frame = CGRectMake(newXPos, myView.frame.origin.y, myView.frame.size.width, myView.frame.size.height);

     lastAccelerationValue = accelerationValue;
    }
}

As a result, of the device gets turned 90 degrees on the x-achsis, or 180 degrees, the view just moves pretty slowly to it's target position. I don't know if that's because of the physics of the accelerometers, or if it's a bug in my filtering code. I only know that there are fast paced games where the accelerometers are used for steering, so I almost can't imagine that's a hardware problem.

+8  A: 

This line:

accelerationX = acceleration.x * 0.05 + accelerationX * (1.0 - 0.05);

is a low-pass filter, which works by computing a moving average of the x acceleration. In other words, each time that callback is called, you're only moving the accelerationX by 5% towards the new accelerometer value. That's why it takes many iterations before accelerationX reflects the new orientation.

What you should do is increase the 0.05 value, to say 0.2. I'd make a global #define and play around with different values along with different refresh rates.

Daniel Dickison
Thanks!! That was exactly the solution to the problem.
Thanks
It should be added that the phase shift created by a RC LowPass filter (which this code implements) is significant. Other implementations of a low pass filter (such as one implemented using FFT) are a little better and that regard. They're much harder to implement though.
Johannes Rudolph