14

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.

bobby123
  • 1,006
  • 4
  • 14
  • 24

4 Answers4

16

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.

MarkusSchaber
  • 757
  • 1
  • 8
  • 16
  • That's fantastic Markus, I was getting so confused by the values that i was getting they didn't make sense, i started using vector mathematics and it's working much better now. I have set it so that vector sum of x,y,z <= 5m/s 6times in a row, had to increase threshold as phone will be in users pocket won't have full free fall. I'm viewing the values in DDMS using Log.d("ACCEL", Float.toString(vectorTotal)); Do you know anything about the orientation sensor, would checking if one of pitch, yaw or roll has changed from more than 50 than what is was be sufficient for a change in orientation? – bobby123 Feb 01 '11 at 02:12
  • Hi, bobby123! I'm sorry, I don't know anything about the orientation sensor yet. My own experiments on my android phone are still in the basics. – MarkusSchaber Feb 01 '11 at 07:18
  • Ok no bother, the fall detection algorithm you gave was a serious improvement anyways, thanks again! – bobby123 Feb 01 '11 at 10:15
7

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

Frank Sposaro
  • 8,511
  • 4
  • 43
  • 64
  • I have actually read a few papers and saw a lot of sites have referenced your app, was due for a summer release but isn't on the market currently? I'll be sure to check out that paper more thoroughly, thanks for the info, that's a good method – bobby123 Feb 25 '11 at 04:27
  • Yeah. FSU has held the project up a little. However, I can 100% assure you that it will be released by the end of this semester. My advisor has been on me about it. We are still waiting to perform human tests, but you can clearly see that if you drop the phone it will detect it. (Pending that the upper and lower thresholds are configed to good values) – Frank Sposaro Mar 05 '11 at 01:37
  • That's good, i'm very interested in it and looking forward to seeing the outcome of your app. One of the main problems I had with mine is the accelerometer not working when the phone goes into standby, even with a partial wakelock it seems to be a firmware problem. How have you gotten around that issue? Currently i'm using a screen dimmed wakelock but that chews through batttery – bobby123 Mar 14 '11 at 02:42
  • @bobby123 I actually did run into that problem I believe when like 1.6 or 2.0.1 released on my G1. I simply did a test that wrote the accelrometor to a txt file on the sdcard. On the G1, just like you said it stopped working when it when to sleep. However, on my Droid 2 I did not have that problem anymore. I got all the data when it was sleeping. What phone are you using? – Frank Sposaro Mar 15 '11 at 18:58
  • @Frank Sposaro - I have been developing using a HTC Desire, it seems to be a prominent problem on that device, I read it wasn't on some other phones but wasn't sure. I could see it in the DDMS when i was logging accelerometer values that it stopped as soon as the phone went on standby. That's good to know it's possible to work around, cheers mate – bobby123 Mar 20 '11 at 23:00
  • can you tell me how do i get acceleration only when mobile fall down, not when it shake. – Abhishek Apr 12 '16 at 06:28
  • You're going to get both, so you'll need to detect the difference and trigger off that. Typically falls only have one valley (freefall) followed by a peak (hitting the ground). If you're seeing several, it's probably either walk, run, or shake. The main differences being longer wavelengths(walk/light shake) and higher amplitudes (run/hard shake) – Frank Sposaro Apr 12 '16 at 22:39
4

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

Frank Sposaro
  • 8,511
  • 4
  • 43
  • 64
  • I just played around with it there and commented your vid, the app turned out great. Hopefully the next firmware upgrade will fix the partial wakelock issue so it works when on standby on all Android phones – bobby123 May 12 '11 at 03:39
  • @bobby123 Thank you. I've found in my testing that it does work in the background on my Droid2, Samsung Galaxy, and Droid X, but not on the G1. I will test this further once I can get my hands on devices. But it seems like this isn't a problem on new phones. – Frank Sposaro May 12 '11 at 19:21
  • That's good to hear, I got unlucky with the phone I picked so. Hopefully I will get my app on the market too but it will be months yet before it'll be completely finished. If/When I do I'll drop you a line to check it out, cheers for your help and interest Frank. – bobby123 May 13 '11 at 01:57
  • @Frank Sposaro. Have you done any research into differentiating between an actual fall and a phone drop? Most falls occur with some lateral movement as the user falls forward/backward/left/right, which would differentiate it from a free fall drop. – cortijon Jan 20 '15 at 22:22
  • 1
    I have something that I haven't published yet. Additional research I did after this. It's actually pretty easy to see a dropped device. When you graph it out, you'll see a sharp spike and decline. The wavelength is noticeably shorter that any other readings. It literally almost looks like a vertical line drawn on the accelerometer graph. – Frank Sposaro Jan 21 '15 at 21:36
0

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;
        }
    }
Varun Chandran
  • 647
  • 9
  • 23