Android linear accelerometer's values are different on several devices - android

I'm working on Android navigation app which uses complex of sensors to determine position changes. In some cases device cannot achieve GPS signal for a while (tunnel or multilevel parking) and I want to compensate these gaps using INS approach.
Yes I know that there're another approaches like cell-id or data got from device's carrier, but currently I'm focused on sensors.
Well, INS approach can be divided into two big tasks:
1. attitude determination (gyro or accelerometer + magnetometer or some combination)
2. velocity and distance calculation. Here I double integrate linear accelerometer values.
Now I try to resolve the second task.
I prepared all calculation and made contrastive analysis of data got from linear accelerometer on different Android devices: Sensation, Motorola Xoom and Nexus S. I put all devices on a platform and moved the platform on 8 meeters with an acceleration on Y axis.
After that I built graphics and they really confused me - all 3 graphics has the same amplitude but peak values are different.
For example at the same moment I have 0.2 m/s^2 on Xoom and 1.2 m/s^2 on Sensation.
Hence after calculation I had a big difference in distance.
Official documentation doesn't explain it. I surfed the web but didn't find any answer about that issue.
So my question is: did someone faced to it? Or maybe you know an advice which will help me to solve it?
In addition, android Sensor class has few parameters. I found that Sensation and Xoom has different RESOLUITON values - Sensor.getResolution().
Sensation - 1.0
Xoom - 0.009576807
I'm stack with it, so any help will be really good!
Thanks in advance.

You cannot solve your second task with MEMS sensors.
You would need a fibre optic gyroscope or a ring laser gyroscope to solve your second task.
Although I talk about calculating position in the above linked answer, the same holds for velocity.

Related

Android Sensor.TYPE_LINEAR_ACCELERATION reporting wrong values on Galaxy S5

I am developing an app that needs to be able to recognize if the phone is lying somewhere (without moving).
To do so, i used the Sensor.TYPE_LINEAR_ACCELERATION which reports the acceleration without the gravity component. On my test device (Nexus 5) it reports something like: x=0,002, y=-0,02, z=-0,005
To detect if the device is lying still, i calculate the average:
avg =sqrt(sqr(x)+sqr(y)+sqr(z))
If the value is below a threshold, i report to the user, that the device is lying still. Works fine on my Nexus 5.
However, the Galaxy S5 reports something like that when lying still:
x=-0,761, y=0,167, z=19,923
So the z value is clearly wrong... As I googled for an answer to this problem I found that the sensor values for TYPE_LINEAR_ACCELERATION are calculated as follows:
Sensor.TYPE_LINEAR_ACCELERATION = Sensor.TYPE_ACCELEROMETER - Sensor.TYPE_GRAVITY
As the accelerometer as well as the gravity sensor should contain the earths gravity (~9,81m/s2) I can only assume, that Samsung made some calculation errors or mountet some sensor reverse on the phone....
Does anybody have the same problem?
Does that happen on other (Samsung) phones?
Is there any fix for this?
=== New answer ===
I have seen that a change the sampling rate of the sensor did the trick in avoiding this error. From the probable SensorManager.SENSOR_DELAY_FASTEST to SensorManager.SENSOR_DELAY_UI
=== Old Answer ===
Given my 2 comments on your question and because of having the same problem on 2 other Galaxy 5S', at the present moment, and with regard to the goal which is detecting the telephone's stillness, I can only suggest 2 workarounds: a peak-to-peak value consideration, and a high pass filter.
Peak-to-peak Value Consideration: just measure the difference between the last 2 readings; if this is bigger than a threshold then a movement event can be triggered.
High Pass Filter: slightly more complicated, but more professional, implement in your code such a filter that will only bring forward rapid changes in the acceleration, while suppressing the constant value of 19.

Uneven number of samples between Accelerometer, Gyro and Magnetometer on Android

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.

Count Steps using accelometer in android [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to Count the Number of Steps Using the Accelerometer
Are there any well known algorithms to count steps based on the accelerometer?
Hi i have developed android application. In one module I have to create a pedometer. Now at this stage I have to count the steps user walked by using accelormeter. I have search on internet and found different methods but none of that working. I have tried this
Does anyone have an idea how to achieve my goal? Any help is appreciated.
The simplest solution would be to have a time-window and a number of thresholds. The signal gets a form of a double wave, and you can split a step into several parts. You may need to have several windows and corresponding threshold values to recognise one step. But keep in mind that this signal will change if someone is walking upstairs/downstairs or running or just walking with different pace. You will get great variability if you actually going to try it with several participants.
Threshold values will differ greatly between devices. Frequency of measurements will also have an impact. Standard frequency that allows one to detect walking with normal pace is about 10Hz, some devices use 20Hz, if you go over this you will get lots of data and little information. Manufacturers do use different versions of accelerometers, so if your software works on one phone, there is no guarantee it will work on the other device even of the same model.
I would start from plotting your signal first. Also don't forget that the phone can be in different positions in a pocket (unless you fix it somehow) so the threshold values will float. All clinical pedometers are usually affixed to the leg in a certain position.
Consider using mono-axial accelerometry instead of 3-axial, the signal analysis gets much more easier to begin with. Also take a look at the Fourier transformations and wavelet analyses.
See the image below to get a basic idea of how walking looks with a 3-axial accelerometer. I made it when was doing similar task (walking is the noisy bit).
And this is how walking looks with a mono-axial accelerometer (again noisy bits)
This seems to be pretty reasonable and accurate:
Enhancing the Performance of Pedometers Using a Single Accelerometer
Anyhow, I am also interested in finding a good algorithm.

Compass give me crazy data, is calibration needed or it's the sensor broken?

I'm working with android sensor data. My application use
SensorManager.getRotationMatrixFromVector(
mRotationMatrix , event.values);
and it has been working well until this morning, when the rotation matrix started to send a lot of noise data (Change N to W in a second).
It's not a problem with my code, because on friday was working and no changes have been done. I have used a compass app from the market, and the compass is giving random data.
I have tested my app on another tablet, and it is working well.
Does someone know why is this happening? A problem with the sensor? Does it need a calibration?
I've worked quite a lot with these electronic compasses on mobile phones and its quite possible that there is nothing wrong with your code or sensor.
Instead it could very well be a problem with your environment. There are magnetic fields interfering with the earth's magnetic fields all the time. From electrical equipment interference to the metal structure holding up a building. At the end of the day a compass is just a magnet. If you stand beside a large lump of metal the compass will be attracted to it and point to it rather than the magnetic north pole.
Try this:
Install GPS status
then turn off all filtering (settings... gps & sensors...sensor filtering... no filtering).
Do the calibration (figure of 8 wavy stuff) and then move the phone around your desk.. near monitors, cables, etc. You'll see it go crazy. The information is completely unreliable. I found in the past that moving the phone a few inches to the right completely changed its reading. The same happens with a real compass. Strictly speaking there is no "problem". The device's compass is assigning itself with the strongest magnetic field. Even the magnetic content of nearby rocks can interfere with the compass.
As a further test I've just placed a real (orienteering) compass over my phone which has a compass app installed. The real compass is now pointing everywhere but magnetic North. The two devices are interfering with each other.
So my advice is.. go somewhere in the open, like a park or field, away from any potential interference and power lines, (if you have one bring a real compass to check that the GPS status app is pointing the right way), and see if your compass works as you'd expect.
Extra: The answer from #resus is also important when calibrating. Rotate the phone a few times in each axis. Looks silly but it does calibrate it properly.
Extra 2: Would it be possible/practical to use the compass bearing of your GPS? It would require that the device be moving (walking speed should be fine) but you would not need to worry about any interference. It should give an accurate reading provided your GPS signal is good.
Extra 3: Another thought just occurred to me.. You could try apply a low pass filter to the sensor. This means that the sudden changes in the sensor reading are filtered out .. have a look at this answer. And if that doesn't do a good job there are lots of algorithms on the web for you to choose from.
If you definitely haven't changed anything in your code, and it still works fine on other devices, it would suggest a problem with that particular device.
While your app is running (i.e. the compass is in use), you should be able to wave it in a figure of 8 in order to automatically recalibrate the compass. You should also make sure you aren't standing next to any large lumps of metal etc. that might interfere with readings.
You can override the onAccuracyChanged() method of SensorEventListener to flash up a message to the user when the compass requires recalibration (probably when accuracy drops to SENSOR_STATUS_ACCURACY_LOW).
In my experience of playing with the compass on android phones, they can be pretty unreliable...
If your application work on another tablet and other compass application do not work on your device, this is probably due to a bad calibration.
As said in the post above, to make the calibration, wave your device in a figure of 8. I just want to add that you should do it for EACH axis. This should fix your problem.
If it is not a calibration error, as some people have already answered, it is possible that the compass had gone through a magnetic field and now it is desmagnetized, so it is not working properly.
Where do you usually keep the tablet? Could it be that it was near big servers or magnets?
You should check the compass just in case, talk to to android's tech support.
Hope it helps.
I think the question was if calibration could be done without sending any data to compass. Because not everybody says that the compass is calibrated as shown in this video: https://support.google.com/maps/answer/6145351?hl=en and obviously you can not do anything else than advise the user to calibrate before using the program or when you get too much changes.
For example going left and right 90 degrees in about 25 ms.
Anyway I think it's good to give some seconds to the app before start taking data, because it gives some unstable values (too high and low in short time without movement) at the app loading moment.
Just let the handler onSensorChanged() coded with a conditional, and start a thread on the onCreate() handler, which will set a boolean to true, after some seconds.
Then you start to capture data on the onSensorChanged() handler.
Also this thread can help to detect the sensor accuracy, and then you can popup: In Android can I programmatically detect that the compass is not yet calibrated?
I know because I am building a robot using the compass of the smartphone, and I'm having this experience. So, if you are making a robot, make sure to give an spaced place between electronics and hardware to the smartphone, but remember that it's on any compass: electromagnetic fields can be altered by metals so heavily.
Nowadays I have the luck of developing a robot with an HMC-5983 and an MPU-6050, which can be calibrated by using its libraries with Arduino.
That code is compatible/portable to other uController but for not also so easy for smartphones, I guess that the offsets needed for calibrating the compass, the gyro and the accelerometer are inside some internals of Android, not available in the SDK.
I answered before thinking that maybe calibration was only for some devices, but realized that must be as I said before.
So, if playing with robots its possible, I mean it's also easy, but when using an smartphone maybe some custom firmware as CyanogenMod would bring the possibility of investigating the way of setting that offsets, but more important to run some program ported from sketch (following its concept only) to get them first ...
So, good luck ! What is also true, is that in both devices (smartphone and my robot) it's need to move them for them to get working well, as I showed you in the video of latest answer, also helpful on robots.
Good luck and a lot of fun with those things, are very powerful.

Indoor tracking (IMU + tags)

this is another question about indoor tracking using inertial (smartphone + aceel + gyro)
Firstly, I would like to say that I have read almost every post on stackoverflow talking about this subject.
And I know that to track a position We will have to integrate TWICE the accel and that is very useless in a real life application because of all the drift errors...
But it turned out that I don't need to build a plane or whatever And i don't need to develop an application that have to WORK to be sold or something. I just want to realize a simple Android App that use "theoretical" concept of an Indoor tracking-
What's the possibilities?
What do we need?
Basically my phone is resting on a desk screen facing UP at a known position (0,0) if a push my phone to 2 or 3 meters and then I rotate it and push it again for 2 or 3
meters I the to see after how many meters it becomes to inaccurate an so use a tag tu recalibrate the measurements <--- That's my main question
what do I need ?
- the angle ? (ok integrating the the gyro) (i don't wanna use the compass)
- the accel? (i have)
- the velocity ? (integrating the accel)
- and the position (double accel integration)
The thing that I would like to know is How can I put this number together? Is it the right way to do it? Is there another solution (to resolve my problem, not to track someone really accurately)?
I also looked at the theory of the DCM (If I understood correctly, it will give me the orientation of the phone in 6 axes right? But what's the difference about getting the angle from the Accel or the gyro (pitch, roll etc..) ?
Thank you
Your smartphone probably has a 3-axis gyro, a 3-axis magnetometer and a 3-axis accelerometer. This is enough for a good estimation of attitude. Each has its advantages and disadvantages:
The accelerometers can measure the gravity force, it gives you the attitude of your phone, but in a horizontal position, you can't know where it's pointing. And it's very sensitive to inertial noise.
The gyroscopes are fastest and the most accurate, but its problem is the drift.
The magnetometers don't have drift and they aren't sensitive to inertial forces, but are too slow.
The combination of the three give you all advantages and no disadvantages. You must read the gyro measure faster as you can (this minimizes the drift) and then use the slow and not as accurate measure of magnetometer and accelerometer to correct them.
I leave you some links that may interest you:
A Guide to using IMU: http://www.starlino.com/imu_guide.html
DCM tutorial: http://www.starlino.com/dcm_tutorial.html
I hope I've been helpful and sorry for my bad English.
With the sensors you have, not considering computational power at this point yet, I know of only one method of position / displacement estimation. This would either involve just optical flow with the onboard camera, or the above with addidional info from fused data from accels / gyros (eg. with a Kalman-Filter) to improve accuracy. I guess OpenCV has all you need (including support for Android), so I'd start there.
Start by implementing an attitude-estimator with just accels and gyros. This will drift in yaw-axis (ie. the axis perpendicular to the ground, or rather parallel to gravity vector). This can be done with a Kalman-Filter or other algorithms. This won't be any good for position estimation, as the estimated position will drift tenths of meters away in just a couple of seconds.
Then try implementing optical flow with your camera, which is computationally expensive. Actually this alone could be a solution, but with less accuracy than with additional data from an IMU.
Good luck.
EDIT: I recently found this - it may be helpful to you. If there is not a lot of noise (due to vibration), this would work (I'm on a quadrotor UAV and it unfortunately doesn't work for me).

Categories

Resources