CMDeviceMotion userAcceleration is upside down?
I'm seeing some unexpected readings from the userAcceleration field in CMDeviceMotion. When I look at the raw accelerometer data from CMAccelerometerData, I see that if the iPhone is flat on a table the reading is 1G straight down (1G in -Z axis) and if I drop the iphone (on a soft surface of course) then the acceleromtere reading goes to zero as expected. That's all fine. When I instead use the CMDeviceMotion class, the userAcceleration reading is zero as expected when the iPhone is flat on table. Again this is fine. But when I drop the iPhone and read the CMDeviceManager userAcceleration, the userAcceleration values are 1G straight up (+Z) not down (-Z) as expected. It appears that the userAcceleration readings are actually the exact opposite of what acceleration the device is really experiencing. Has anyone else observed this? Can I just invert (multiply by -1) all the userAcceleration values before I try to integrate for velocity and position, or am I misunerstanding what userAcceleration is reading?
- Raw accelerometer data is just the sum of all accelerations measured i.e. a combination of gravity and current acceleration of the device.
- Device motion data is the result of sensor fusion of all 3 sensors i.e. accelerometer, gyroscope and magnetometer. Thus bias and errors are eliminated (in theory) and the remaining acceleration data is separated into gravity and acceleration to be used conveniently.
So if you want to compare both you have to check CMAccelerometerData.acceleration against CMDeviceMotion.userAcceleration + CMDeviceMotion.gravity to compare like with like.
In general CMDeviceMotion is your first choice in most cases when you want precise values and hardware independency.
Another thing to consider is the CMAttitudeReferenceFrame you provide when starting Device Motion updates via startDeviceMotionUpdatesUsingReferenceFrame. I am not sure what is the default when using the basic version startDeviceMotionUpdates
You stated that you want to integrate the values to get velocity and position. There are several discussions about this and at the bottom line I can say it's impossible to get reasonable results. See:
- Finding distance using accelerometer in iPhone
- Getting displacement from accelerometer data with Core Motion
- How can I find distance traveled with a gyroscope and accelerometer?
If your app concept forces you to rely on precise results for more than half a second, try to change it.
It turns out the CMAcceleration is not obey the right hand rule, which x is point to left, y is point to the screen bottom, in that case, with a typical right hand system, z axis should point to the upper side,but its not. It makes me uncomfortable when dealing with motion sensors!
3 years after but still thinks this is an unresolved matter. I don't think it is "all fine" for CMAccelerometerData to read approx 1g in -Z axis, because according to their doc (https://developer.apple.com/library/content/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/motion_event_basics/motion_event_basics.html) +Z is from the screen outwards. When the phone is laying on a table, with screen facing up, it means it is experimenting the upward force of the table. See This google talk at 09:15. The same happens with x and y.
The gyro readings are behaving like described in the documentation, with x to the right, y to the top, and z from the screen outwards.
My conclusion is, you have to invert all accelerometer axes, and you will have the same right hand coordinate system like the gyro and like the documentation.
As a stack overflow newbie, I apparently don't have enough reputation to comment on some of the other posts... But I have reached the same conclusion as cduguet. Based on the advertised iPhone coordinate system (https://developer.apple.com/documentation/coremotion/getting_processed_device_motion_data/understanding_reference_frames_and_device_attitude#2875084), the attitudinal data is consistent with the advertised coordinate axes. That is, a positive rotation of the phone (in a "right hand rule" sense) about any axis registers an appropriately positive gyro velocity increase. What makes sense and what I would expect.
However, when you impart an linear acceleration in the positive direction on any axis, the CMmanager records the data as a negative value. I've done this test dozens of times on all the axes and keep finding the same counterintuitive result.
I can change the sign of all the linear acceleration values to make the equations of motion consistent with the phone coordinate system, but I keep trying to understand why Apple would choose this sign convention. It just doesn't make sense to me.