Compensating compass lag with the gyroscope on iPhone 4
I've been experimenting with the compass and gyroscope on iPhone 4 and would like some help with an issue I'm having. I want to compensate for开发者_StackOverflow社区 the slowness of the compass by using data from the gyroscope.
Using CMMotionManager
and its CMDeviceMotion
object (motionManager.deviceMotion
), I get the CMAttitude
object. Correct me if I'm wrong (please), but here is what I've deduced from the CMAttitude
object's yaw
property (I don't need pitch
nor roll
for my purposes):
yaw
ranges from0
toPI
when the phone is pointing downwards (as indicated bydeviceMotion.gravity.z
) and swinging counterclockwise and0
to-PI
when swung clockwise- when the device is pointing upwards,
yaw
ranges from-PI
to0
andPI
to0
, respectively - and from the compass data (I'm using
locationManager.heading.magneticHeading
), I see that the compass gives values from0
to360
, with the value increasing when swinging clockwise
All right, so using all of this information together, I'm able to get a value I call horizontal
that, regardless of whether the device is pointing up or down, will give values from 0
to 360
and increase when the device is swung clockwise (though I am still having trouble when deviceManager.gravity.z
is around 0
-- the yaw
value freaks out at this gravity.z
value).
It seems to me that I could "synchronize" the horizontal
and magneticHeading
values, using a calculated horizontal
value that maps to magneticHeading
, and "synchronize" the horizontal
value to magneticHeading
when I feel the compass has "caught up."
So my questions:
- Am I on the right track with this?
- Am I using the gyro data from
CMDeviceMotion
properly and the assumptions I listed above correct? - Why might
yaw
freak out whengravity.z
is around0
?
Thank you very much. I look forward to hearing your answers!
Just trying to answer... correct me if i'm wrong..
1.Yes you are on the right track
2.gravity in CM is already "isolated" from user gravity (gravity value caused by user acceleration) thats why there is two gravity, the "gravity" and "userAcceleration" its on apple CM documentation // Note : not entirely isolated //
3. if you have a gravity 0 it mean that the coresponding axis is perpendicular with gravity. gravity.z is the iPhone screen thats why it -9.82m/s2 if you put on the desk with screen upright, actualy it hard to get 0 or maximum value of the gravity due to the sensor noise (it's normal, all sensor has a noise expecially cheap sensor).
what i do on my apps is I will switch my reference axis to other axis (in your case may be x or y) for certain limits, how the strategy is depend on the purpose or which side is your reference.
the other thing is, gyro is fast but its not stable, you need to re-calibrate the value for several interval. In my case every 5 second. I've experiment with gyro for calculating angle between two plane, i try with exacly 90 degree ruler and it will give an error about 0.5 degree every second try and keep increasing, but thats is mine, maybe others have a better method for avoid the error.
below is my steps "
- Init
- Read gravity XYZ -> Xg Yg Zg
- Check if Xg < 0.25 If TRUE try Yg then Zg // Note 1 = 1g = 9.82 m/s^2
- Read the compass and gyro
- Configure and calibrate the gyro using the compass and calulate based on which axis i use in point 3.
- If 5 second is pass then recalibrate, read the compass
- If the the difference with gyro reading is > 5 degree skip recalibartion the gyro.
- If the the difference with gyro reading is < 5 degree calibrate the gyro using compass value
Note: for number 7 : is to check if the phone affected with magnetic field or near huge steel such or high voltage electrical line or in noisy and heavy equipment in factory plant.
Thats all... Hope this could help you... And sorry for my english..
Here is an example of an iPhone app where the compass get compensated with the gyroscope. Code and project can be seen here: http://www.sundh.com/blog/2011/09/stabalize-compass-of-iphone-with-gyroscope/
The direction of the yaw axis vector is undefined when in zero gravity (or free fall, or close enough).
In order to do synchronization while in motion, you need to create a filter for your "horizontal" value that has the same lag/delay response characteristics as the magnetic compass. Either that, or wait until motion stops long enough for both values to settle before recalculating the offset.
Answer to question 1 is Yes, question 2 you are on the right track but you could use a variable name that is not 'horizontal', question 3 is answered by hotpaw2 and also a yaw in a chopper or helicopter at near zero altitude would alert the pilot with an alarm. There is a time lag because part of the software is local while there are other factors which can slow it down including access to a sensor for detecting magnetic waves, the device position and direction, preparing the graphic output for the compass display, computing and outputting data from the gyro and sensors through a relatively slow interface, using a general purpose handheld device not custom designed for the type of task being asked of it.
精彩评论