I have observed the accelerometer data in several android devices are different in same place with same orientation.
I am developing a game based on accelerometer X and Y data and it is working fine with tablet, but unusual result in android phones.
Please suggest to overcome this issue.
Thanks,
Biplab
This is natural because every device has different hardware specifications, that means that they also have different accelerometer implementations each having different noises in their readings. Even the time bettween two consecutive polls intitialized with the same sensor delay flag (such as SENSOR_DELAY_GAME) will probably differ in different devices. I suggest you apply filtering in your data for smoother readings.
See here for low pass filter.
See here for high pass filter.
The examples are not in java but they will give you the idea.
Related
I'm currently using android devices to develop an application that uses sensor values to get information about the environment. I'm using a Samsung S6 Edge and a Nexus 7 tablet and the sensor values i get from the devices are very different.
One example:
These are the Gyroscope values (x-axis) from both devices sitting still on a table. This is one of the best in values similarity, most of them are not even close.
A couple of the bad value similarities:
Magnetic Field:
Accelerometer:
I'm wondering why values are so different across devices?
Thanks.
I'm wondering why values are so different across devices?
They are not particularly different. Those are values in radians/second, where a "360-degree turn" is ~6.28 radians. Your values range from ~-0.002 to +0.004. ~0.004 radians/s is ~0.229 degrees/s. This is tiny. IOW, your values are all similar to 0.
Plus, as the documentation states:
In practice, the gyroscope noise and offset will introduce some errors which need to be compensated for. This is usually done using the information from other sensors, but is beyond the scope of this document.
More generally, different hardware will have different sensors from different manufacturers.
With respect to accelerometer, again, your values are tiny. Earth's gravity is 9.8 m/s2; your values are between ~0.15 and ~-0.05.
With respect to magnetic field... your Samsung seems messed up.
I am developing an Android app that records the inertial data on a smartphone to then further processes it. Different Android devices have different behaviors depending on the firmware interfacing the inertial sensors to Android and that's crystal clear. One thing I cannot answer myself though is, how come only the moto g 2nd gen yet showed that when the app is recording I have significantly different numbers of sensors samples?
For example, few second of recording and I see:
~6000 samples for the gyro
~5200 samples for the acc
~2000 samples for the magnetometer
Assume as well that the activity I am recording affects all sensors at all time and hence I'd expect the onSensorChange function to be called evenly. That happens for every other smartphone I tried (5 or 6 different ones).
Any suggestions how come the magnetos mostly seem to not change values as often as the other sensors in order for the onSensorChange to record it?
The obvious answer is because of the firmware, but do you have any idea how to mitigate the effect I am seeing?
Thanks folks!
This question is really old, but I figured I'd answer it for the community's sake:
I work as an app developer at a startup that specializes in sensor processing on smartphones. We have a couple 2nd Gen Moto G's and we've found that they do a really bad job of giving uniform sampling rates both for one sensor as well as across sensors.
To mitigate the problems, we write a whole row of samples at once with the most recent data, every time we get a sample from the accelerometer. If a new sample hasn't come in on any other sensors since the last accelerometer sample, the same values get printed twice.
ie.)
Accel (3-axis) | Gyro (3-axis)
0,0,0|0,0,0
<new accelerometer sample>
1,1,1|0,0,0
<5 gyro samples and 1 accelerometer>
2,2,2|5,5,5
...
Anyways, hope this helps someone!
TLDR; The 2nd Gen Moto G has inconsistent sampling rates both for one sensor and across multiple sensors.
I'm working on Sensor fusion with Accelerometer, Gyroscope and Magnetic Field on Android. Thanks to SensorsManager I can be noticed for each new value of theses sensors.
In reality and this is the case for my Nexus 5 (I'm not sure for others Android devices), acceleration, rotation rate and magnetic field are sampled in same time. We can verify it using event.timestamp.
On others systems (like iOS, xSens...), Sensor SDK provides a notification with these 3 vectors in same time.
Of course, when I receive an acceleration(t), I can write some lines of codes with arrays to wait rotationRate(t) and magneticField(t). But if there is a way to have an access directly to these 3 vectors together it could be very interesting to know!
An other question relative to sensors data:
Is there advices from Android team to device constructors to provide data in chronological order ?
Thank you,
Thibaud
Short answer, no, Android doesn't provide a way to get all the sensor readings as it reads them.
Furthermore, the behavior that you've observed with SensorManager, namely that readings from different sensors happen to have the same timestamp suggesting that they were read together - should not be relied upon. There isn't documentation that guarantees this behavior (also, this is likely a quirk of your testing and update configuration), so relying upon it could come to bite you in some future update (and trying to take advantage of this is likely much more difficult to get right or fast than the approach I outline below).
Generally, unless all results are generated by the same sensor, it is impossible to get them all "at the same time". Furthermore, just about all the sensors are noisy so you'd already need to do some smoothing if you read them as fast as possible.
So, what you could do is sample them pretty quickly, then at specific intervals, report the latest sample from all sensors (or some smoothed value that accounts for the delta between sample time and report time). This is a trivial amount of extra code, especially if you're already smoothing noisy sensor data.
There is a workaround for this particular problem. When multiple registered listeners are present in an activty at the same time, timestamp for those event may be misleading. But you can multiple fragment objects into the said activity which have different context's. Then listen to every sensor in these fragments. With this approach the sensor reading timestamps become reliable.
Or listen in parallel threads if you know about concurrency...
I am trying to determine the benefit of making use of Android's Linear Acceleration data as opposed to simply applying a low pass filter as presented in Androids API reference and discussed in this other stackoverflow question.
I am asking as I am trying to get hold of a free app that records Linear Acceleration (as well as fullfils my other requirements (sampling rate, writing data to file etc...)). I haven't been able to find one, so I have considered just using an app that records using the standard accelerometer and then I'll simply apply the low pass filter to the data. Alternatively I could just write my own app to do what I need - but I don't have much experience in Android dev and this will take some time.
I have explored this subject at some length and I may be able to help point you in the right direction.
As others have mentioned, only some phones have implemented TYPE_LINEAR_ACCELERATION and TYPE_GRAVITY and they usually are equipped with a gyroscope. A Droid Razr even has a gyroscope, but they never bothered to implement it or TYPE_LINEAR_ACCELERATION. I believe the GS2 has TYPE_LINEAR_ACCELERATION implemented, but no gyroscope so they must have used the magnetic sensor or some sort of low-pass filter. It can be frustrating.
On most phones with a gyroscope there is some sort of fusion between the acceleration sensor and gyroscope (probably a complementary filter to compensate for drift and then quaternions or cardan angles to isolate gravity). These fusions and filters can be implemented differently and use different hardware, etc... Latency and accuracy are going to vary among devices, so TYPE_LINEAR_ACCELERATION isn't always going to produce the same results.
If you do not have a phone with TYPE_LINEAR_ACCELERATION, you are stuck with TYPE_ACCELERATION, which cannot separate gravity (tilt) from linear acceleration.
One option is to apply the low-pass filter. This may or may not work depending on your application. I have written a free application to help developers and other interested parties explore the low-pass filter option.
Another option is to just measure the tilt of the device when it is static and then apply that gravity measurement while the device is not static. If the device isn't changing the orientation often, this can be an excellent option because it is really fast and simple.
An excellent alternative sensor fusion option is to use the magnetic sensor instead of a gyroscope. This option will work on almost all devices assuming the magnetic field isn't under the effects of hard or soft iron distortions.
I have implemented all of these approaches in the open source project Acceleration Explorer
I am needing to implement a shake recognizer, and I am using the accelerometer on the device to that. However, when I check the values I get from the sensor, it appears that they vary wildly from device to device. For instance, I get a value range of 0-8 as force (after some calculations) on one device, and on the other 0 - 4.
So it looks like they have very different ranges.
Is there anything I can do to make these ranges equal. Or are there some variables that I can use to somehow calculate what a fairly hard shake would be?
According to specification accelerometer should return Measures the acceleration force in m/s2. So it should be calibrated. One thing you could check however is the Sensor class's getMaximumRange() and getResolution()
The physical placement of the chip on the pcb and the securing of the pcb within the device and the construction of the device could all lead to different damping effects in responce to your shaking input force.
You don't say how your processing the sensor data there may well be effects related to sampleing and filtering performed at the driver level.
You clearly need to be flexible in your code with the range of values you expect and test on a good range of devices.
The sensor should be calibrated.
Apparently it isn't. If the gain in the different directions (that is x, y, z) is not significantly different then it is enough to look for sudden changes in the length^2 of the accelerometer vector: x^2+y^2+z^2.
If the gains are also significantly different then you have no choice but to write an app for accelerometer calibration...
By the way, you are not the first one to report gross inaccuracies, see for example Android: the range of z-value in the accelerometer sensor are different on different devices.