Android - Acceleration down (smash)
Asked Answered
J

2

25

Video explaining for those who does not understand


THIS ANSWER IS NOT CORRECTLY ANSWERED PLEASE TRY TO ANSWER IT WITH ANOTHER SOLUTION (100 Bounty is out of date)

Same question but better explained

This questions was accepted as a correct but it is not at all, I tried it with my old device ZTE and it worked most of time, but now I have a Samsung Galazy A5 2016 and it doesn't work, neither on a LG G3.

The thing is trying using Accelerometer and some Sensors I have to be able to detect any of those two moviments that I made on the Video.

There are two moviments :

  • Smashing it (with a little bit of velocity)
  • Free fall

I let you to decide and convince me what's the better option and EASIER one to do, with better I mean that works on most of devices.

Joung answered 25/1, 2016 at 16:39 Comment(22)
There's a good example of Accelerometer here: github.com/aporter/coursera-android/tree/master/Examples/…Hesperian
I saw it, but it doesn't explain how to detect the "action down" event...Orthopter
According to the docs developer.android.com/guide/topics/sensors/sensors_motion.html the force going down 'z' is SensorEvent.values[2] - when I wrote a simple app for acelerometer easiest way way to output the figures verbose to the screen as your moving the device around.Hesperian
But how to get that force I mean, if this Y increases negativitly it's the down event? with the app that I've created now, if I do this move the Y goes for example from 4 to 0 or -0 so I've to compare this?Orthopter
Sorry 'z' axis is up and down - this post will prove useful - #4848990 as I understand it if a phone is falling and it approaches terminal velocity (9.8ms) then the sensor should be near 0 value, faster than that (ie forced down) a negative value.Hesperian
Yes, that's what I understand too, but ... how to compare it as code?Orthopter
You cannot do that with event.values[2] since this is the value for the z-axis. If the phone is held up in portrait mode then the down acceleration is the value for the y-axis instead, thus using accelerator value is device orientation dependent. Using gravity and set mDeviation to .5f I got the correct result every time. I have code for all these sensors which include stable compass and others. It has been a few years since, let me clean up the code and then publish it on Github in a few days.Decipher
Alright... Do you have tested on differents devices? I mean the problem that you thought(if the device doesnt have accelerator uses gravity, etc..) will it work?Orthopter
I tested on 2 devices both do not have TYPE_GRAVITY. In one device it work pretty well. In the other the mDeviation is two large so it does not detect moving down. You have to adjust mDeviation per device.Decipher
Thats what I mean, I didnt want to hardcorde nothing ia there any algorithm to get mdeviation?Orthopter
@HoanNguyen Did you get the way to get the mDeviation dynamically? I mean for each device get the mDeviation to get it works?Orthopter
I do not have TYPE_GRAVITY in my devices and using low pass filter the gravity norm depends on the device orientation. That is the gravity norm of a device laying flat and still is different than the gravity norm of a device held up and still. This should not be the case since the only force acting on the device is gravity. I will try the world z-linear acceleration to see if it will work better, that means I will need to also register for TYPE_MAGNETIC_FIELD. I will post to Github when it is done.Decipher
@Skizo do your device has TYPE_GRAVITY? if so does the gravity norm is different depending on device orientation?Decipher
@HoanNguyen Alright, thanks... thank you so much for your effort man.. :) I'm also trying to understand how to do it correctlyOrthopter
How do I know if I have TYPE_GRAVITY?Orthopter
getDefaultSensor(Sensor.TYPE_GRAVITY) and see if it is not nullDecipher
Let us continue this discussion in chat.Orthopter
Can't understand anything from the video what you want to achieve.Tetravalent
One of those events, smashing or free falling but always only moving downOrthopter
I recommend first having the user "calibrate" the device so that you can determine what the standard accelerometer readings are with the device laying down on it's back, then you'll have your at rest measurement. Then you can determine if that measurement falls below a threshold (approaches or passes 0), it's moving down and trigger that event. Adjust the threshold for sensitivity.Caption
I thought the same first user has to see if his accelerometer or other sensors are fine, and then do it but u don't know how to do thisOrthopter
Please explain the issue..you want to catch the speed of device in downword motion? If it is more than 9.18 m/s2 then you can give alert to the user.Tetravalent
D
14

A stationary device will have an gravity value of +9.81, which corresponds to the acceleration of the device (0 m/s2 minus the force of gravity, which is -9.81 m/s2). Thus if the device is moving downward from stationary then the gravity will be less than 9.81. A free fall device will have gravity equals 0.

Below is how to determine if the device starts moving downward. It will not be able to determine whether the device is moving downward if the device is already moving downward with constant speed, since in this case there is no acceleration downward and the gravity norm should be around 9.81.

You need to use TYPE_GRAVITY. If the device does not have TYPE_GRAVITY, then low pass filter TYPE_ACCELEROMETER to get the gravity vector.

As above a stationary device will have a gravity vector with norm equal 9.81. However, this value will vary slightly with devices. Thus you need first to determine this stationary gravity norm. You can do this by register for TYPE_GRAVITY or TYPE_ACCELEROMETER and ask the user to lay the device flat and then press a button. Once the button is pressed the app will calculate the norm of the gravity in onSensorChanged.

private float mStationaryGravityNorm;
private float mDeviation = 0.01;
private float mCount;
private boolean mIsCalculatingStationGravityNorm = true;

Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener( {
    @Override
    public void onClick(View v) {
        // register sensor
    }
    });

@Override
public void onSensorChanged(SensorEvent event) {
// Will average out 100 gravity values.
if (mIsCalculatingStationGravityNorm) {
    if (mCount++ < 100) {
        mStationaryGravityNorm += Math.sqrt(event.values[0] * event.values[0] + event.values[1] * event.values[1] + event.values[2] * event.values[2]);
    } else {
        mStationaryGravityNorm /= 100;
        mIsCalculatingStationGravityNorm = false;
} else {
    float gravityNorm = Math.sqrt(event.values[0] * event.values[0] + event.values[1] * event.values[1] + event.values[2] * event.values[2]);
    if (gravityNorm < mStationaryGravityNorm - mDeviation) {
    // moving down
    }
}

PS For moving up an down you do want to calculate gravity. When the device is stationary, the gravity norm is approximately 9.81 (depending on device). Now if the device is moving down, there is an acceleration downward, thus the gravity norm will be less than 9.81 and if the device is moving up the gravity norm will be more than 9.81. So by comparing the gravity norm against this stationary gravity norm, you will know if the device moving up or down. This is independent of the device orientation. TYPE_GRAVITY will give better accuracy but if the device does not have this type then low pass filter TYPE_ACCELERATOR will give you the gravity vector.

Decipher answered 26/1, 2016 at 18:0 Comment(2)
@Skizo I was literally was doing testing .. I looked at the figures produced and deduced I could detect a shake in that manner, easily able to change based on requirements, I.e. moving down or up .. Also I use an alert to sound when the desired event occurs .. At the end of the day, it doesn't matter what code you use as long as you understand it and it works :)Hesperian
@MarkKeen Yes, but I'd like to run this app in more than my device and make it works...Orthopter
I
-1

if you want to see if the device is in free fall, you should check if the normal is closer to zero. http://developer.android.com/guide/topics/sensors/sensors_motion.html

public void onSensorChanged(SensorEvent event) {
    double noraml = Math.sqrt(Math.pow(event.values[0].getX(),2)+
                    Math.pow(event.values[1].getY(),2)+
                    Math.pow(event.values[2].getZ(),2));
    if (normal < 0)
        return true;
    return false;

}
Iatry answered 26/1, 2016 at 15:30 Comment(2)
What do you mean with .getY()< getX() and getZ()? Where I can find those methods?Orthopter
It is mathematically impossible to get negative number from square root of xx + yy + z*z.Paintbox

© 2022 - 2024 — McMap. All rights reserved.