How to get the actual acceleration via CMMotionManager in iOS - ios

I am getting x,y and z device acceleration using startDeviceMotionUpdates(), and reading the userAcceleration data structure with a Timer. Apple documentation states
The total acceleration of the device is equal to gravity plus the acceleration the user imparts to the device.
The values that I am getting even if I jerk the phone around are at the most 5.7nnnn on the X axis for example. Now, if the gravity acceleration is 9.81 m/sec squared, what does the value 5.7nnnn represent in m/sec squared? That is, how do I get the actual m/sec squared value from the raw axis values that userAcceleration gives? How does one interpret the difference between acceleration and deceleration?

CoreMotion (CM) outputs acceleration in g's. So, you'd need to multiply the values with ~9.81 m/s^2.
Also, CM acceleration readings are reversed compared to a more conventional accelerometer; i.e., when the device is stationary on a table, CM measures approximately -1.0 on the z axis, while a conventional accelerometer would measure approximately 9.81 m/s^2 (note that the former value is negative, while the latter is positive). So, if you multiply the CM readings with -9.81, you would get intuitive results: a positive value along an axis would mean acceleration and a negative value would mean deceleration.

Related

what is the value of G used to normalize CMAccleration?

I'm trying to determine the user acceleration in m/s^2.
The documentation for the CMAcceleration datatype, as included as a field of CMDeviceMotion for example indicates that the acceleration values are measured in 'G's
A G is a unit of gravitation force equal to that exerted by the earth’s gravitational field (9.81 m s−2).
'g' is not the same everywhere, it can vary by some small fraction-- but that fraction is significant when it's double integrated.
Are the values in CMAcceleration measured normalized by a fixed 9.81, or are they normalized by the value for gravity estimated by the CoreMotion fusion engine?
If it's the measured gravity, is there a place to access it? The gravity field of CMDeviceMotion also appears to be normalized.

UIAccelleration value range

The AppleDeveloper guide seem to imply that UIAccelerationValue can range between a double value of -1.0 and +1.0.
I have logged the values from a real device whilst "shaking" with crazy gestures my iPod touch and got x values above 2.0 (e.g. +2.1, -2.1) and NO y value above 2.0f.
Could anyone explain this?
Has anyone identified the MAX and MIN values for UIAccelerationValue?
My take on this is that Apple has implemented some algorithm that approximates the force of gravity and takes as 1.0 values that are above a standard speed approximation (e.g. have values 9.8 m/s of speed).
Any other guesses?
You may be misunderstanding a part of the documentation. Nowhere does it say that the value ranges between -1.0. and 1.0, as far as I can see. It says that:
The device accelerometer reports values for each axis in units of
g-force, where a value of 1.0 represents acceleration of about +1 g
along a given axis. When a device is laying still with its back on a
horizontal surface, each acceleration event has approximately the
following values:
"g" is used in a particular technical sense here; 1 g is one standard gravity; a phone accelerating faster than this will register readings higher than 1. Violent shaking in the hand is easily enough to cause acceleration and deceleration values higher than 9.8m/s2.

Sphero concept of "Shake"?

What would be the best way tell the user is shaking the Sphero?
I need to differentiate when the user tilts the Sphero left/right/up/down and when they shake it rapidly a few times in any direction.
Is there a sample project that would be good to look at?
If you're collecting the accelerometer filtered values, and also the "IMU" values, the accelerometer values would be best for detecting shaking, while the IMU values (roll, pitch, yaw) are best for detecting tilt.
If you don't care on which axis it is shaken, then normalize the axis' by getting a square of the sum of their squares: sqrt(x^2 + y^2 + z^2) > 2000. This will give you a magnitude of the acceleration vector. It's a good value for "general acceleration-ness", and it's great for detecting shaking.
If you want to isolate on which axis it is being shaken, then for each axis, evaluate whether its absolute value of acceleration is above a threshold: abs(x) > 2000, since the positive or negative value of an axis is its own vector magnitude.
Then, just use the IMU data's roll, pitch and yaw values to determine the tilt of the Sphero.

Detect programmatically if iPhone is dropped using CoreMotion/Accelerometer

So I am writing a piece of code where I have to detect different movement gestures using Accelerometer and gyroscope in iOS 4.3 above.
Q1: Is there any existing opensource code which has achieved any movement/gesture detection?
If not
Q2: For now I want to detect if the iPhone is dropped.
What I have achieved so far:
CoreMotion API gives userAcceleration, which (afaik) is the acceleration that the user is giving to the device or the acceleration of device in some direction (x, y or z) with out considering the gravity so what I can do is: store, let's say, previous 5-6 values of acceleration parameters and can check where any of them hits large negative value, which basically represents the sudden deceleration.
But this solution is not very optimal, I think I need to somehow detect the freefall/downwards motion of the device too first. Any idea how to approach this problem?
UPDATE:
Thanks Misch for sharing your approach. I was not at all thinking about total acceleration. I did exactly what you said:
"You would however have to test yourself, what means "total acceleration corresponds
approximately to earth acceleration" and "for some time" in your case."
The acceleration value is actually in G's so I tested the "total acceleration" values with in range of 0.9 - 1.1. And I checked them over some time, initially I checked four consecutive values when updateInterval is set to 1/20.0. For now I have relaxed the condition of consecutiveness a little.
Here's a sample output:
Acceleration = 0.090868
Acceleration = 0.074473
Acceleration = 0.159797
Acceleration = 1.157513
Acceleration = 1.224588
Acceleration = 1.036272
Acceleration = 0.914698
Acceleration = 0.904093
Acceleration = 0.941516
Acceleration = 0.046362
Acceleration = 0.045109
Acceleration = 0.060045
I think, I still have to keep on testing and adjusting values. If you have any optimization in mind kindly do share, I know in order to help you'd need to see the many samples of freefall acceleration values. For now I am thinking to:
round off the values of acceleration to 3 decimal places and play with the acceleration range I am using.
May be check if, after the freefall condition is met, total acceleration value suddenly goes down.
Do you think the acceleration values I have quoted are a bit noisy?
To Q2:
Checking for large negative values does not tell you whether the phone is being dropped.
First, the user could just move the phone with a rapid gesture, this would also result in a large (maybe negative) value.
Secondly, the phone could fall in another direction than you imagine, and therefore, the acceleration could be positive, although the phone is moving towards the ground.
You could just calculate the total acceleration (a = sqrt(ax^2 + ay^2 + az^2)) and check whether this total acceleration corresponds approximately to earth acceleration (9.81). The phone is falling if the acceleration corresponds to earth acceleration for some time.
You would however have to test yourself, what means "total acceleration corresponds approximately to earth acceleration" and "for some time" in your case.
The physics behind this:
Let's assume you drop your phone in a way, that the y axis of the phone shows upwards. Then the x and z accelerations will be 0 and the y acceleration will be like this:
The acceleration will be 0 in the beginning, will then reach -9.81 the moment, you release your phone. Then it will hit the ground, which you see in the small acceleration peak, and then the acceleration is zero again.
However you can't use only the acceleration in y direction, because your phone may fall in a different angle.
So you have to watch the total acceleration of your phone:
Here you don't see a negative acceleration anymore. However, here it doesn't matter anymore in which direction your phone is facing, as a free fall will always be characterized by an acceleration of 9.81.
To your edits:
1. Why would you want to round off the values of acceleration to 3 decimal places? If you test 0.9 < x < 1.1, it doesn't matter if x is 0.914698 or 0.915.
2. What if someone drops the phone but then catches it again, so the total acceleration does not necessarily have to go down again. Additionally, there should be a large acceleration value (a sudden deceleration) the moment the phone hits the floor. Maybe the reason one does not see this in your values is that it is so short, that it falls between two consecutive measurements. However this could be measured, so don't suppose that immediately after the free fall, the acceleration should decrease again.

is IPad accelerometer normalized to gravity

While porting my Android app to iOS I was confused with one thing, so I want to find out: am I right or mo code works wrong. At Android device accelerometer returns values in physical measure units: m/s2. On ipad i get summary force approximately = 1.0 for still device(and i expect 9.8). My first explanation is that returning value is normalized to 9.8, so I must multiply it with 9.8 to get real force. My second idea - my code is totally wrong, but it's hard to believe.
From the Docs on CMAcceleration:
CMAcceleration
The type of a structure containing 3-axis acceleration values.
typedef struct {
double x;
double y;
double z;
} CMAcceleration;
X-axis acceleration in G's (gravitational force).
Y-axis acceleration in G's (gravitational force).
Z-axis acceleration in G's (gravitational force).
A G is a unit of gravitation force equal to that exerted by the earth’s gravitational field (9.81 m s−2).

Resources