I was in a car accident on Tuesday evening, and am hoping someone here might be able to help.
I am wondering if it’s possible to gather position or accelerometer data from my phone to help pinpoint the time of impact, which might possibly be used in concert with traffic-light data or video from nearby cameras or other data.
Apologies for the slightly off-topic request. Posting here was recommended by some developer friends of mine.
from your question, yes it can be done by
get accelerometer to get it's value from time to time, since when your vehicle is going to crash, the force will give the very high result
from my point of view, you need to use compass sensor to help it to calculate properly, (plus GPS sensor, it world be a great help to calculate your current speed)
last one, you need to research about how the vehicle crash, when it hit force will go to forth and back, so alot of experiment or good research would be your great help
for starting of accelerometer, (not much of mobile device have this sensor)
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// to get accelerometer censor
senSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
senAccelerometer = senSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
senSensorManager.registerListener(this, senAccelerometer , SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
public void onSensorChanged(SensorEvent sensorEvent) {
Sensor mySensor = sensorEvent.sensor;
if (mySensor.getType() == Sensor.TYPE_ACCELEROMETER) {
float x = sensorEvent.values[0];
float y = sensorEvent.values[1];
float z = sensorEvent.values[2];
long curTime = System.currentTimeMillis();
if ((curTime - lastUpdate) > 100) {
long diffTime = (curTime - lastUpdate);
lastUpdate = curTime;
float speed = Math.abs(x + y + z - last_x - last_y - last_z)/ diffTime * 10000;
if (speed > MIGHT_BE_CRASHING_THRESHOLD) {
// do something
}
last_x = x;
last_y = y;
last_z = z;
}
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
Related
I am making an android project to detect when mobile fall down, can anyone tell me which sensor should I use in my app, I know accelerometer will use for this kind of purpose, but accelerometer can also detect when I shake the phone in my hand and I want to get the toast only when the mobile falls down.
here is my code:
int count = 1;
private boolean init;
private Sensor mySensor;
private SensorManager SM;
private float x1, x2, x3;
private static final float ERROR = (float) 7.0;
private static final float SHAKE_THRESHOLD = 15.00f; // m/S**2
private static final int MIN_TIME_BETWEEN_SHAKES_MILLISECS = 1000;
private long mLastShakeTime;
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
long curTime = System.currentTimeMillis();
if ((curTime - mLastShakeTime) > MIN_TIME_BETWEEN_SHAKES_MILLISECS) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
double acceleration = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)
+ Math.pow(z, 2))
- SensorManager.GRAVITY_EARTH;
Log.d("mySensor", "Acceleration is " + acceleration + "m/s^2");
if (acceleration > SHAKE_THRESHOLD) {
mLastShakeTime = curTime;
Toast.makeText(getApplicationContext(), "FALL DETECTED",
Toast.LENGTH_LONG).show();
} } }}
There is no "Fall Sensor", your guess in using the accelerometer is right. Record and measure the accelerometer data when it falls and deduct a model from there.
You have to use accelerometer. But it will detect very small movement.
The only way to do is , get the difference between two readings on change of state.
If its very very high, the mobile has traveled a longer distances say fell down from hand, or change an abnormal position say a shock.
For this we have to use little bit of Physics, any object falling under the influence of gravity has an acceleration of 9.8 m/s/s, downward (on Earth). SO with this knowledge we can get the downward direction speed
1)based on the axis(Y-axis) using accelerometer check it is downward and
2) check if it is equal to this 9.8 m/s constant and also check the
if the fall speed is approx near 9.8 m/s show the toast
Hi all i done this by myself a little change was get me rid of this , that is just taking two variable set those values negative and call them as threshold value of acceleration .
thanks everyone
I have implemented the Sensor functionality in my app.Now after 2 mins vibration is in activate mode due to which the device get some movement and sensor get work.What i want that the sensor get active only when the user manually move the device.There should be no effect of vibration on the sensor.Following is my code.Thanks for Advance...
vib= (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
sensorManager=(SensorManager)getSystemService(SENSOR_SERVICE);
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
vib.vibrate(val);
#Override
public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType()==Sensor.TYPE_ACCELEROMETER) {
float x=event.values[0];
float y=event.values[1];
float z=event.values[2];
float deltaX = Math.abs(mLastX - x);
float deltaY = Math.abs(mLastY - y);
float deltaZ = Math.abs(mLastZ - z);
if(deltaX>NOISE){
compareX();
}
else if(deltaY>NOISE){
compareX();
}
else if(deltaZ>NOISE){
compareX();
}
mLastX = x;
mLastY = y;
mLastZ = z;
}
}
private void compareX() {
mStartTime = SystemClock.uptimeMillis();
mHandler.removeCallbacks(mUpdateTimeTask);
mHandler.postDelayed(mUpdateTimeTask, 100);
vib.cancel();
stopService(new Intent(getApplicationContext(),AlarmService.class));
System.out.println("Movemenet>><><><><><><>><Occur");
}
So if I'm reading that correctly, you want to turn on the accelerometer but not get changes in it due to vibration of the device- filter it out somehow. That really wouldn't be possible. The framework has no method to do it, and any attempt to do so would be difficult- the vibrator's strength will vary from device to device, and even between calls in the same device. And they don't really calibrate those things- there's really no way to do that accurately.
in my app, i use the AccelerationSensor.accelerationchanged(xAccel, yAccel, zAccel) API
the problem is the method is called every o.oooo1 change in any axis, so the app becomes very slow, some times even becomes "non-responding"
Is there a way to check if the integer part has changed and let away any decimal change?
This is what I am doing, in my onStartCommand() of my service
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
This is the function I am handling my data, it is pretty light weight but it should give you an idea using a threshold. In my case I really just need to know the device a bit, in my case it turned out the differenceValue neeeded to be about 1.75G but it might be different for you.
#Override
public void onSensorChanged(SensorEvent event) {
if(last[0] == 0.0f &&
last[1] == 0.0f &&
last[2] == 0.0f){
last[0] = event.values[0];
last[1] = event.values[1];
last[2] = event.values[2];
return;
}
float diff = 0f;
if(Math.abs(last[0] - event.values[0]) > differenceValue ||
Math.abs(last[1] - event.values[1]) > differenceValue ||
Math.abs(last[2] - event.values[2]) > differenceValue){
Log.d(TAG,"G values are "+event.values[0]+" "+event.values[1]+" "+event.values[2]);
Log.d(TAG,"Last G values are "+last[0]+" "+last[1]+" "+last[2]);
diff = Math.abs(last[0] - event.values[0]);
if(diff < Math.abs(last[1] - event.values[1])){
diff = Math.abs(last[1] - event.values[1]);
}
if(diff < Math.abs(last[2] - event.values[2])){
diff = Math.abs(last[2] - event.values[2]);
}
Log.d(TAG,"Sensor difference: "+diff);
//Do what ever processing you need here
}
last[0] = event.values[0];
last[1] = event.values[1];
last[2] = event.values[2];
}
When you register a listener for a sensor it allows you to set a frequency. Use a slower frequency.
I'm making a game which uses the device's accelerometer to fill a progress bar.
On my Note 2 it takes me about 20 seconds shaking the phone up and down to fill the bar, however I tried on a ZTE Blade and it took me 4 seconds.
Is there any way to calibrate the accelerometers within my code? This is what I'm doing:
#Override
public void onSensorChanged(SensorEvent event) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
if (!mInitialized) {
mLastX = x;
mLastY = y;
mLastZ = z;
mInitialized = true;
} else {
float deltaX = Math.abs(mLastX - x);
float deltaY = Math.abs(mLastY - y);
float deltaZ = Math.abs(mLastZ - z);
if (deltaX < NOISE) deltaX = (float)0.0;
if (deltaY < NOISE) deltaY = (float)0.0;
if (deltaZ < NOISE) deltaZ = (float)0.0;
mLastX = x;
mLastY = y;
mLastZ = z;
if(deltaY == 0){
return;
}
sProgress += deltaY;
pb.setProgress(sProgress);
}
}
Issue may be with frequency of Accelerometer.Dont use below android constants while registering.
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
these valuse are different for different device.
int SENSOR_DELAY_FASTEST get sensor data as fast as possible
int SENSOR_DELAY_GAME rate suitable for games
int SENSOR_DELAY_NORMAL rate (default) suitable for screen orientation changes
int SENSOR_DELAY_UI rate suitable for the user interface
Use Hard coded values in microseconds like for frequency 1 Hz
mSensorManager.registerListener(this, mAccelerometer,1000000);
Hope it solves.
Another solution to making the frequency equal is something like the following solution.
#Override
public void onSensorChanged(SensorEvent sensorEvent) {
if(sensorEventTooQuick(sensorEvent.timestamp)) {
return;
}
mLastSensorEventTime = sensorEvent.timestamp;
// process sensor
}
private boolean sensorEventTooQuick(long sensorTime) {
long diff = sensorTime - mLastSensorEventTime;
return diff < MINIMUM_SENSOR_EVENT_GAP;
}
Things to consider:
You want to make sure you choose MINIMUM_SENSOR_EVENT_GAP to be small enough as to not lose information. The accelerometer is very quick so this is usually not a problem, but could be an issue for other sensors depending on the application.
Make sure to test different values across different devices.
I do this since it guarantees that you will not receive events faster than your limit.
I am developing an application where I would require to retrieve the angle between the device and the vertical axis (the axis pointing to the center of the Earth).
So far, all the documentations and tutorials I found were not very conclusive.
Could you please explain me how can I do this or provide me with a link to a clear tutorial to help me find a solution to this problem?
First, I created a SensorEventListener implementation
private SensorEventListener sensorEventListener =
new SensorEventListener() {
/** The side that is currently up */
//private Side currentSide = null;
//private Side oldSide = null;
private float azimuth;
private float pitch;
private float roll;
public void onAccuracyChanged(Sensor sensor, int accuracy) {}
public void onSensorChanged(SensorEvent event) {
azimuth = event.values[0]; // azimuth
pitch = event.values[1]; // pitch
roll = event.values[2]; // roll
//code to deal with orientation changes;
//pitch is the angle between the vertical axis and the device's y axis (the one from the center of the device to its top)
}
};
Then, I register this listener to an Orientation Sensor
SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
Sensor sensor;
List<Sensor> sensors = sensorManager.getSensorList(
Sensor.TYPE_ORIENTATION);
if (sensors.size() > 0) {
sensor = sensors.get(0);
sensorManager.registerListener(
sensorEventListener, sensor,
SensorManager.SENSOR_DELAY_NORMAL);
} else {
//notify the user that there's no orientation sensor
}