Is there any method of calculating linear distance using accelerometer and gyroscope sensor data as double integral on acceleration seems to give lot of drift.
Note : Image processing techniques using the camera / GPS seem to be a heavy duty on battery.
Since you wish to calculate linear distance, you should not read from raw Accelerometer data. In API 9. android introduced Sensor.TYPE_LINEAR_ACCELERATION, which is nothing but the gravity component deducted from raw accelerometer values.
The drift can build up much quickly if there is even a single degree error in your own calculations for finding linear component in raw data. Check out an experiences from Google: SensorFusion.
The question is very similar to Calculating distance using Linear acceleration android
Related
we are proposing a project of measuring the length and width of object using android's accelerometer and gyroscope sensors.
we plan to implement it by simply hovering the smartphone over the object, with start and stop buttons.
i know there are a lot of articles about measuring distance but there isnt an exact one about measuring lengt and width, added to the fact that measuring distance using these 2 sensors give out measurements with great error percentages and need filters like kalman.
so in this day, is it possible for us to accurately measure objects using these 2 sensors?
Both the gyro and the accelerometer measure rates of change. i.e. derivatives of distance and/or angle. Integrating these values to get distances (length) is very noisy and errors accumulate very very fast. So unless you have some additional way to correct for drift errors your measurements will quickly become irrelevant.
GPS and magnetometer, measure absolute values relative to some global frame of reference. If your distances are large enough, then you may be able to use these as absolute reference points.
I'm developing a tool which receives motion sensor data and sends it to a machine learning algorithm, which ultimately will deduce different types of movement.
I read the Motion sensor guide and it seems like there is some redundancy in the data you can get from the sensors. For example: the accelrometer data contains gravity data and the linear acceleration data shows acceleration without acceleration due to gravity.
So my question is: do i really need all the sensors to get all forms of motion or can I give up some of them?
EDIT: (clarifying the question)
I want to collect the minimal data that will allow me to deduce the same things. What I'm looking for is user behavior: the angle which the user holds his phone, the way the user moves while using his phone, etc..
The answer I'm looking for should include the sets of sensors that have high correlation within them, such that only some of the sensors in this set are required to deduce the same type of motion\movement\rotation\acceleration\etc..
The term "Motion" in the question have no precise meaning. So I answer more generally.
"The way one holds his phone" is nothing but the orientation of the phone.There are three sensors which individually tells the orientation of the phone.
Accelerometer sensor
Orientation sensor
Rotation Vector sensor
Among them only the accelerometer is physical sensor and other two are virtual sensors (they don't have special piece of hardware, they use accelerometer data and report the orientation in different formats).
The orientation sensor is deprecated so you can't use it.
Rotation vector sensor tells the orientation encoded in a quaternion. If your code is based on quaternions then normalize the sensor output using SensorManager.getQuaternionFromVector() and continue. If your code is based on rotation matrix then obtain rotation matrix by calling SensorManager.getRotationMatrixFromVector() passing sensor output and continue. If you want the orientation alone get it by calling SensorManager.getOrientation() passing rotation matrix obtained previously.
Using accelerometer sensor we can find the orientation, but the recommended approach is to combine it with magnetic field sensor output. Call SensorManager.getRotationMatrix() by passing the output of accelerometer output and magnetic field sensor output and get the rotation matrix. If your code is based on rotation matrix, just continue. If you want the orientation alone get it by calling SensorManager.getOrientation() passing rotation matrix obtained in previously. If your code is based on quaternion call SensorManager.getQuaternionFromVector() by passing rotation vector (orientation) obtained previously.
"The way one moves his phone" - Here I consider four motions.
Change of position (Simple translation) and rate change of position (velocity) - No sensor to detect them.
Rate of change of velocity (Simple acceleration) - Accelerometer detects it. But it also contains the gravity component. Normally we need acceleration without gravity component. This could be calculated simply as explained here. However there is another virtual sensor called Linear Acceleration which does the job for us.
Change of orientation (Rotation) - Whenever the orientation changes the accelerometer, orientation and rotation vector sensors report us (gyroscope also reports, but is explained in next point). How to use this sensor to get the current orientation is explained in first part of the answer.
Rate of change of orientation (Angular velocity) - Whenever the orientation changes the gyroscope sensor reports. The output is three numbers representing angular acceleration along x, y and z axes. The unit is radians per second.
Output of the gyroscope sensors is not accurate in long term and the output of accelerometer is not accurate in short term, so combine them to get steady output. For details see this question.
Now it is clear that the gyroscope and accelerometer is required in minimum. However using wide range of sensors minimizes our work.
You can't decide what you get - each sensor's data is already defined, and you get all or nothing. If you see closely, there isn't a place in public API which would let you ask for specific things.
To back this up here's quote from Google's document explaining sensor types:
An accelerometer sensor reports the acceleration of the device along the 3 sensor axes. The measured acceleration includes both the physical acceleration (change of velocity) and the gravity. The measurement is reported in the x, y and z fields of sensors_event_t.acceleration.
If you see into android source, the structs here are strictly defined, and struct for acceleration contains specific fields. So even if you would get 0 in fields you don't like, you won't gain anything.
But what you're referring to are two things - base sensors, which are roughly equivalent to physical sensors on the device, and composite sensors, which combine readings from various physical sensors to get more useful data.
So while you can't decide what you get for a particular sensor (like "only gravity" or "only acceleration in Y axis"), composite sensors do give you data that you can compute by yourself using only base sensors. So linear acceleration is composition of data from accelerometer and gyroscope (or magnetic sensor), after some calculations. Similarly step detector "sensor" uses only accelerometer, but interpretes the data automatically to just give you an event that "yes, someone has made a step" with single value 1.
If you're feeding raw motion data to some algorithms, I would guess base sensors are what you're looking for. That said, I believe you can still safely register for all sensors (both base and composite ones) that combined give you all data that you need (and maybe more), without meaningful battery impact.
For more detailed information on each of the sensors refer to Sensor types on Android website, and if you're curious, you can read up short summary on sensors stack as well.
No, you don't need every sensor. Some of the sensors exist as a convenience to the user. Your example of the linear acceleration sensor is one- it tells you the results of the accelerometer with gravity taken out. You could do this yourself from the raw accelerometer data, but that takes a bit of math (you need to subtract the vector gravity over all 3 axes) and a bit of knowhow (did you remember to calibrate the sensor? It may not read 9.8 at rest. For that matter, 9.8 may not be your gravity if you're not at sea level). That's a lot of work that would need to be repeated by each app, so they created a software "sensor" that sits on top of the accelerometer and provides the computed data. It would be unusual for an app to use raw and linear accelerometers in the same app, generally its one or the other. The step counter is another example of this, it guesses at what a step is based on the accelerometer data. You also wouldn't want calibrated and uncalibrated gyroscope data.
As for what you do need- no clue, you don't say enough about what you're trying to do. One warning though- you said you're trying to detect motion. YOu can't do that. You can detect accelerations and rotation. You cannot detect motion at a constant speed. If you're developing any type of app using these it pays to use the correct terminology and think in terms of physics and how the physical accelerometer and gyroscope work, otherwise you're going to cause yourself bugs.
I want to measure distance travelled in a moving car from an android app. The distance is typically between (0-60 metres). How can I calculate the distance using sensors on an android device.Thanks.
Your best bet is GPS. Get the location of the start and finish and use Location.distanceTo.
If you mean you want to try and calculate when you start and stop as well- I'd look for a siginificant acceleration event and correlate with GPS position at those times.
If you mean you want to not use GPS at all- give up now. The sensors are far too noisy to try and solve using acceleration equations.
You could (try) to integrate accelerometer values, but as Gabe Sechan said, it'll be mostly hopeless. If you spend some time analyzing your accelerometer and calibrating it manually (by this I mean compensating by your measured bias and scaling errors) you can reduce the error, but you're still stuck with a (significant) growing error that gets worse quicker over time.
As a side note, if you're constantly turning (say, in a spiral ramp), you can get the velocity directly from a combination of gyroscope and accelerometer (basically combining equations of centripetal motion "a = v^2 / r" and angular velocity "v = w * r" to get "v^2 = a^2 / w^2"). I've tried doing this with an Android device, and as long as the angular velocity "w" is high enough, the values returned are very consistent and fairly accurate (and the error doesn't grow exponentially with time as when integrating acceleration data twice).
Is it possible to use the accelerometer to detect height? For instance, if I'm holding the phone on my hand and then detect the height after raising my arm?
Thanks
Assuming you mean you want to detect the height the phone was raised from its staring point, yes. The android accelerometer measures force, more info on how to use it can be found here. Keep in mind that the accelerometer isn't a perfect device, and so your results will be approximations of how much the phone was really moved.
The inaccuracy of the accelerometer will be insignificant when compared to the error caused by an unstable accelerometer. What I mean by this is the fact that as you move your phone you will not be able to keep the accelerometer orientated perfectly i.e. you will 'naturally' rotate it about its longitudinal,lateral and azimuth axes. This means that a vertical acceleration will partly be felt in all the above axes and result in an error if you were to just integrate twice the vertical acceleration measurement.
There are ways to eliminate this error which involve gyroscopes but that requires some complicated mathematics and gyros to be fitted in your phone as well.
In theory you can integrate an accelerometer's output but in a real-world device there are practical issues you must overcome.
You get position by integrating the linear acceleration twice but the error is horrible. It is useless in practice.
Here is an explanation why (Google Tech Talk) at 23:20. I highly recommend this video.
Similar questions:
track small movements of iphone with no GPS
What is the real world accuracy of phone accelerometers when used for positioning?
how to calculate phone's movement in the vertical direction from rest?
iOS: Movement Precision in 3D Space
How to use Accelerometer to measure distance for Android Application Development
How can I find distance traveled with a gyroscope and accelerometer?
Distance moved by Accelerometer
Yes, bt you need to integrate the output twice and add in the two integration constants - initial velocity and displacement.
Rgds,
Martin
First of all you measure Linear acceleration and gravity together (also some noise)
So it means when you are using accelerometer you will get
Accelerometer Readings = Linear Acc. + Gravity + Noise
Here you just only need Linear Acc. but the Accelerometer reads all the values
Reading here: Android Sensors - Which of them get direct input? ,
I am wondering if anyone has experience or a technically detailed link about the accuracy of the linear acceleration versus just manual processing of the acceleration raw data. E.g., do the new phones have dedicated hardware chips for filtering out gravity, or are most devices just going to filter the same raw source?
Update, proposed answer for someone to confirm if they have such a device (Xoom,Nexus S,?):
"If the device has gyro, or possibly multiple accelerometers, then the returned values for gravity (G) versus external linear acceleration (L) can be fundamentally more accurate than any processing on accelerometer data alone. Without extra sensors, e.g. as on most phones, one could in principle post-process the Acceleration (A) to attempt separation as accurately as what the device is returning for A = G+L"
It seems, the gravity/lin. acceleration can be calculated by a low-pass-filter - just as described in the Android-Documentation.
However only filtering the last value will not do it. I get acceptable results by averaging the accelerometer values of ca. 200ms (for moderate movement, this will still screw up, e.g. when you flip your phone fast between your fingers).
Your proposed answer is most likely correct.
You can check the statistics of several smartphone models on Android fragmentation.
For many models the power consumption of the lin. acceleration and gravity sensor is just the sum of accelerometer, gyroscope and magnetometer.
The gyroscope lets you recognize fast angular movement and it can be used to improve the gravity value, which is not possible with just the low-pass-filter. For the magnetometer im not sure if it really gets you more information.
On my phone (HTC One S) the gravity sensor uses just as much power as the accelerometer, but is still better than my simple filter. So either it is another hardware sensor or probably they use different weights on it. I tried to weight acc-data stronger, if their absolute value is closer to gravity, which is nice but was still not as good as the actual gravity sensor.
For compatibility reasons I would suggest to use a low-pass-filter for gravity if possible, as still not every smartphone has a gyroscope or mentioned sensors.