CMDeviceMotion userAcceleration drift - iphone

I'm getting the acceleration data using the -[CMDeviceMotion userAcceleration]
I've noticed one interesting thing: I always get a small bias on the Z axis. It is about 0.0155 (with variance of 0.002). While on other axes the average values are near 0.
I'm testing this with iPod Touch 4G (and it is just laying on the table during testing). The question is: where this bias is from and is it device specific?

I noticed similar values although CoreMotion tries to eliminate bias. If you rotate your device so that x (or y) is parallele to gravity you will probably see the bias in x direction. Using raw sensor data showed the same tendency but with larger values and some more super-imposing effects like temperature dependency, time based shifting, ...
18 months ago I read a specification of the iPhone 3 devices' accelerometers and according to this the accuracy was about 1.8 % of g. (what a pity the bookmark to STM product page I set now leads to 404).
Basically this should not be a problem as long as you don't try to estimate exact positions (displacements) and this seems to be impossible with an acceptable accuracy - see the several discusion here on SO.

Related

How to calculate displacement from Accelerometer reading?

I have accelerometer readings of three axis X, Y and z, will be getting data in a frequency of (62 records per second). Could you please suggest me how can I calculate the displacement.
Data in hand:
Accelerometer readings with respect to time.
Do I need to calculate the displacement using time domain data or need to convert into frequency domain. Which one will give a accurate results?
You can double integrate the acceleration vector over time to obtain the displacement. In theory this is a perfectly sensible solution.
But in practice, there will always be a component of g (acceleration due to gravity) acting on at least one of the axes all the time. Let's say you subtract the g component from your xyz vectors. The problem is that any slight error in readings (even off by a small order of magnitude) when double integration will lead to the error adding up over time rendering the displacement wildly inaccurate.
According to the integrated values, you will most likely see even an idle object fly off into space. You'll need an additional sensor to tell you the orientation - like a gyroscope, and have some point of reference (the Wiimote does this with an IR sensor).
This is primarily a time domain problem, but you could have a frequency domain stage where some amount of filtering is done to remove measurement error or process error.
tl;dr Positional tracking with acceleration sensors alone is a hard problem.

Trying to filter (tons of) noise from accelerometers and gyroscopes

My project:
I'm developing a slot car with 3-axis accelerometer and gyroscope, trying to estimate the car pose (x, y, z, yaw, pitch) but I have a big problem with my vibration noise (while the car is running, the gears induce vibration and the track also gets it worse) because the noise takes values between ±4[g] (where g = 9.81 [m/s^2]) for the accelerometers, for example.
I know (because I observe it), the noise is correlated for all of my sensors
In my first attempt, I tried to work it out with a Kalman filter, but it didn't work because values of my state vectors had a really big noise.
EDIT2: In my second attempt I tried a low pass filter before the Kalman filter, but it only slowed down my system and didn't filter the low components of the noise. At this point I realized this noise might be composed of low and high frecuency components.
I was learning about adaptive filters (LMS and RLS) but I realized I don't have a noise signal and if I use one accelerometer signal to filter other axis' accelerometer, I don't get absolute values, so It doesn't work.
EDIT: I'm having problems trying to find some example code for adaptive filters. If anyone knows about something similar, I will be very thankful.
Here is my question:
Does anyone know about a filter or have any idea about how I could fix it and filter my signals correctly?
Thank you so much in advance,
XNor
PD: I apologize for any mistake I could have, english is not my mother tongue
The first thing i would do, would be to run a DFT on the sensor signal and see if there is actually a high and low frequency component of your accelerometer signals.
With a DFT you should be able to determine an optimum cutoff frequency of your lowpass/bandpass filter.
If you have a constant component on the Z axis, there is a chance that you haven't filtered out gravity. Note that if there is a significant pitch or roll this constant can be seen on your X and Y axes as well
Generally pose estimation with an accelerometer is not a good idea as you need to integrate the acceleration signals twice to get a pose. If the signal is noisy you are going to be in trouble already after a couple of seconds if the noise is not 100% evenly distributed between + and -.
If we assume that there is no noise coming from your gears, even the conversion accuracy of the Accelerometer might start to mess up your pose after a couple of minutes.
I would definately use a second sensor, eg a compass/encoder in combination with your mathematical model and combine all your sensor data in a kalmann filter(Sensor fusion).
You might also be able to derive a black box model of your noise by assuming that it is correlated with your motors RPM. (Box-jenkins/Arma/Arima).
I had similar problems with noise with low and high frequencies and I managed to decently remove it without removing good signal too by using an universal microphone shock mount. It does a good job with gyroscope too especially if you find one which fits it (or you can put it in a small case then mount it)
It basically uses elastic strings to remove shocks and vibration.
Have you tried a simple low-pass filter on the data? I'd guess that the vibration frequency is much higher than the frequencies in normal car acceleration data. At least in normal driving. Crashes might be another story...

Is the iPhone accelerometer calibrated? Gravity measurement changes depending on orientation

I'm doing some test with iPhone 4S accelerometer. If I take the raw data in Z-axis (telephone rest over desktop) I get an acceleration 9.65-9.70 m/s2 (after g conversion by 9.8261).
But if i have the telephone resting over edge, the measurement of the accelerometer value in the X-axis is so different, aprox. 9.80-9.85 m/s2 (after the same g conversion).
My question is, if the gravity is the same, why this difference? It is not callibrated?
On the other hand, I check the module value at both situations and the difference is the same.
Thanks.
I don't know what kind of answer you expect, but you should be more precise when you're talking about calibration.
Of course, the g-sensors are calibrated and as always: every calibration comes with an error. In your case the error is under 1%.
So if you want an answer:
Yes, the iPhone accelerometer is calibrated and has an error under 1% in your case. If you collect measurements from other (hundreds of) users, you could calculate the mean error of the device (I guess it's about 1% though).
The problem is that it's not possible to determine gravity 100% exactly when all of the sensors (gyro and compass as well) show an intrinsic error. The lack of a precise external reference system leads to this error. Accelerometer and gyroscope are corrected mutually and if there is a slight drift it does affect the direction where the sensor fusion algorithm (Kalman-Filter or others) calculates gravity should be.
While gyroscope is very fast in detecting the direction it tends to drifting effects. Accelerometers are slower in reaction but provide a way to detect gravity. Magnetometers are even slower but can contribute to stabilising the overall result. Combine Gyroscope and Accelerometer Data shows some graphs of the raw and the processed sensor data.
I continued working with accelerometers. The results are not bad. About iPhone accelerometers calibrating, I can say that STMicroelectronics does calibration over his own sensor. Later, iPhone factory assemblies accelerometer onto circuit board. The soldering affects to accelerometer accuracy (thermal effects) and probably, the accelerometer requires a new calibration, but for consumer requirements, the accuracy is already good, but if you need high requirements, you need a new calibration.

iPhone - core motion rotationRate

Using just the rotationRate property of Core Motion or Gyroscope is it possible to extract how much radians (or degrees if you like) the device rotated?
I have tried to do a timed sampled of Core Motion data, for example, sampling it 5 times per second so I know that there's 0.2seconds between each reading. Then if I have a rotationRate of 0.5 radians per second from one read to another, in theory I could divide this by 5 and know now much radians the device rotated since the last time.
This seems logical, but the results have nothing to do with reality. Rotating the device 90 degrees will produce results telling me that the device rotated 100 times less than that.
Is it possible to extract how much the device rotated just by looking at rotationRate?
What am I missing?
Need more space than a comment ;-) iOS retrieves all data in radians and if your other calculations are correct, I thought it might be the angle measured in radians.
In general your approach seems to be alright: Take every signal's angle velocity, multiply it with time delta and you will have the angle delta for this timeframe. Then sum all your angles and the result should be the covered distance as angle in radians. Angle phi is the integral of angle velocity omega over the elapsed time and doing numerical integration with the trapezoidal rule (i.e. like described) is OK for gyroscope's data (not for accelerometer).
In general I would recommend to use the timestamp delivered by core motion instead of the defined period (1/5) as recommended by Apple, because device motion data is often delivered in a lower frequency than expected (see What is the official iPhone 4 maximum gyroscope data update frequency and or Push method for core motion and frequency of Accelerometer/Gyroscope Data.
Furthermore you should take a higher frequency to avoid errors in your numerical integration.
[Update from comments section:]
If your are interested in integrating via extended Simpson's Rule I recommend this paper (German only, p. 173 ff.) and An Extension to Newton-Cotes Formulae. Some sample code as extracted snippet taken from an existing project can be found here: DevicePosition.m Note that it might not compile, no warranty, as is, ... you know this from other sites ;-)
A free app displaying sensor input as graphs for iPhone: Sensor Monitor

Accelerometer to relative position

Before I reinvent the wheel I wanted to see if anyone can share code or tips for the following:
In order to get relative position of the iPhone, one needs to
Set the accelerometer read rate
Noise filter the accelerometer response
Convert it to a vector
Low pass filter the vector to find gravity
Subtract gravity from the raw reading to find the user caused acceleration
Filter the user caused acceleration to get the frequencies you are interested in ( probably bandpass depending on the application)
Integrate to find relative speed
Integrate to find position
So what I'm hoping is that people have already written some or all of the above and can provide tips, or better yet code.
A few questions I haven't found the answer to:
What is the frequency response of the iPhone accelerometer? What hardware filters exist between the accelerometer and the analog to digital converter?
What is the fastest reading rate the accelerometer delegate can be called without duplicating reading values?
Differences in the above for the various phones?
Any good tips for designing the filters, such as cutoff frequency for separating gravity and user motion?
Any code or tips for the integration steps? Any reason to integrate in the cartesion coordinate system rather than as vector, or vise versa?
Any other experiences, tips, or information that one should know prior to implementing this?
As I find information out, I'll be collecting it in this answer.
Hardware
The 3GS uses an ST LIS331DL 3-axis ±2g/±8g digital accelerometer.
The iPhone 4 and iPad use an ST LIS331DLH 3-axis ±2g/±4g/±8g digital accelerometer.
They are both capable of being read at 100Hz and 400Hz, although on the iPhone 3G (under iOS 4.1) the accelerometer delegate is not called more frequently than 100Hz even if setUpdateInterval is set for faster updates. I do not know if the API permits faster updates on the iPhone 4, and Apple's documentation merely states that the maximum is determined by the hardware of the iPhone. (TBD)
The A/D converter is on the same silicon as the MEM sensor, which is good for noise immunity.
The DL version is 8 bits (3GS) while the DLH version is 12 bits (iPhone 4). The maximum bias (offset) in the DL version is twice the bias of the DLH (0.04g vs 0.02g) version.
The data sheet for the DLH reports acceleration noise density, but that value is not reported on the DL datasheet. Noise density is reasonably low at 218 μg/√Hz for the DLH.
Both sensors give either 100Hz sampling or 400Hz sampling speeds, with no custom rate. The sensor discards values if the iPhone doesn't read the output register at the set sampling rate.
The "typical" full scale value for the DL sensor is ±2.3g, but ST only guarantees that it's at least ±2g.
Temperature effects on the sensor are present and measurable, but not very significant.
TBD:
Is the hardware filter turned on, and what are the filtering characteristics?
How noisy is the power supply to the accelerometer? (Anybody just happen to have the iPhone schematic laying around?)
The accelerometer uses an internal clock to provide timing for the sample rate and A/D conversion. The datasheet does not indicate the accuracy, precision, or temperature sensitivity of this clock. For accurate time analysis the iPhone must use an interrupt to sense when a sample is done and record the time in the interrupt. (whether this is done or not is unknown, but it's the only way to get accurate timing information)
API
Requesting lower than 100Hz sampling rates results in getting selected samples, while discarding the rest. If a sampling rate that is not a factor of 100Hz is requested in software, the time intervals between real sensor readings cannot be even. Apple does not guarantee even sampling rates even if a factor of 100 is used.
It appears that the API provides no software filtering.
The API does scale the raw accelerometer value into a double representing Gs. The scaling factor used is unknown, and whether this is different for each phone (ie, calibrated) and whether the calibration occurs on an ongoing basis to account fo sensor drift is unknown. Online reports seem to suggest that the iPhone does re-calibrate itself on occasion when it's lying flat on a surface.
Results from simple testing suggest that the API sets the sensor to ±2g for the 3GS, which is generally fine for handheld movements.
TBD:
Does Apple calibrate each unit so that the UIAccelerometer reports 1G as 1G? Apple's documentation specifically warns against using the device for sensitive measurement applications.
Does the reported NSTimeInterval represent when the values were read from the accelerometer, or when the accelerometer interrupt indicated that new values were ready?
I'm just dealing with the same problem. The only difference to your approach is that I don't want to rely on the low pass filter to find gravity. (TBH I don't see how I can reliably tell the gravity vector from the accelerometer readings)
Am trying it with the gyros right now.