Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
302 views
in Technique[技术] by (71.8m points)

objective c - Detect when an iphone has been bumped

I want to be able to detect if an iphone has been bumped into something...would it be best to listen to the gyroscope / accelerometer and judge how fast its moved or if its moved and stopped suddenly.

In fact how would I judge if the device has moved then stopped suddenly?

This answer is great but in reverse iOS: Accurately determining energy of a bump from accelerometer output - it smooths out the movement, if anything I want to detect a sharp movement.

Also are both the Gyroscope and Accelerometer available for 3GS ?

UPDATED WITH CODE

From the Apple doc http://developer.apple.com/library/iOS/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/MotionEvents/MotionEvents.html#//apple_ref/doc/uid/TP40009541-CH4-SW26

Isolating Instantaneous Motion from Acceleration Data If you are using accelerometer data to detect just the instant motion of a device, you need to be able to isolate sudden changes in movement from the constant effect of gravity. You can do that with a high-pass filter.

Listing 4-6 shows a simplified high-pass filter computation. The acceleration values from the previous event are stored in the accelX, accelY, and accelZ member variables of the class. This example computes the low-pass filter value and then subtracts it from the current value to obtain just the instantaneous component of motion.

Listing 4-6 Getting the instantaneous portion of movement from accelerometer data

define kFilteringFactor 0.1

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
    // Subtract the low-pass value from the current value to get a simplified high-pass filter
    accelX = acceleration.x - ( (acceleration.x * kFilteringFactor) + (accelX * (1.0 - kFilteringFactor)) );
    accelY = acceleration.y - ( (acceleration.y * kFilteringFactor) + (accelY * (1.0 - kFilteringFactor)) );
    accelZ = acceleration.z - ( (acceleration.z * kFilteringFactor) + (accelZ * (1.0 - kFilteringFactor)) );

   // Use the acceleration data.
}

How would I then 'Use the acceleration data' to work out if an instantaneous motion is detected?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The proper way would be to use a high-pass filter and linear acceleration after sensor fusion. Check Sensor.TYPE_LINEAR_ACCELERATION here, it is for Android. As far as I know iPhone does not have sensor fusion. As Kay pointed it out, Core Motion provides sensor fusion, see the comment below.

If you are interested, here is an excellent video on sensor fusion, start at 32:10.

A somewhat messy workaround is to use a high-pass filter and to use the accelerometer data without sensor fusion. If you bump to phone into something you might get spikes in the gyro data too but in my experience the accelerometers are better as they detect sudden velocity changes.

It is messy because you can fool this by quickly rotating the phone.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...