开发者

Android - How to approach fall detection algorithm

I want to be able to feature a fairly simple fall detection algorithm in my application. At the 开发者_如何学运维moment in onSensorChanged(), I am getting the absolute value of the current x,x,z values and subtracting SensorManager.GRAVITY_EARTH (9.8 m/s) from this. The resulting value has to be bigger than a threshold value 10 times in a row to set a flag saying a fall has been detected by the accelerometer, the threshold value is about 8m/s.

Also I'm comparing the orientation of the phone as soon as the threshold has been passed and the orienation of it when the threshold is no longer being passed, this sets another flag saying the orientation sensor has detected a fall.

When both flags are set, an event occurs to check is user ok, etc etc. My problem is with the threshold, when the phone is held straight up the absolute value of accelerometer is about 9.8 m/s, but when i hold it still at an angle it can be over 15m/s. This is causing other events to trigger the fall detection, and if i increase the threshold to avoid that, it won't detect falls.

Can anyone give me some advice here with what possible values i should use or how to even improve my method? Many thanks.


First, I want to remind you that you cannot just add the x, y, z values together as they are, you have to use vector mathematics. This is why you get values of over 15 m/s. As long as the phone is not moving, the vector sum should always be about 9.8 m/s. You calculate it using SQRT(x*x + y*y + z*z). If you need more information, you can read about vector mathematics, maybe http://en.wikipedia.org/wiki/Euclidean_vector#Length is a good start for it.

I also suggest another algorithm: In free fall, all three of the x,y,z values of the accelerometer should be near zero. (At least, that's what I learned in physics classes a long time ago in school.) So maybe you can use a formula like if the vector sum of x,y,z <= 3 m/s than you detect a free fall. And if the vector sum then raises to a value over 20 m/s, than you detect the landing.

Those thresholds are just a wild guess. Maybe you just record the x,y,z values in a test application, and then move around the phone, and then analyze offline how the values (and their normal and vector sum) behave to get a feeling for which thresholds are sensible.


I have acutally published a paper on this issue. Please feel free to check out "ifall" @ ww2.cs.fsu.edu/~sposaro

We basically take the root sum of squares and look for 3 things 1. Lower threshold broke. Ie fallinging 2. Upper threshold broke. Ie hitting the ground 3. Flatline around 1g, ie longlie, laying on the ground for an extended period of time


I forgot to update this thread, but iFall is now available on the Android Market. Also check out ww2.cs.fsu.edu/~sposaro/iFall for more information


Its possible using the Accelerometer sensor.

Write this in the sensor changed listener..

if (sensor == Sensor.TYPE_ACCELEROMETER) {
        long curTime = System.currentTimeMillis();
        // only allow one update every 100ms.
        if ((curTime - lastUpdate) > 100) {
            long diffTime = (curTime - lastUpdate);
            lastUpdate = curTime;

            x = values[SensorManager.DATA_X];
            y = values[SensorManager.DATA_Y];
            z = values[SensorManager.DATA_Z];

            float speed = Math.abs(x + y + z - last_x - last_y - last_z) / diffTime * 10000;
            Log.d("getShakeDetection", "speed: " + speed);
            if (speed > DashplexManager.getInstance().SHAKE_THRESHOLD) {
                result = true;
            }
            last_x = x;
            last_y = y;
            last_z = z;
        }
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜