This might be hard to explain the geometry so I will be careful in spelling it out. This is visible in the standard compas app and from the data in CLLocationManager.
1) When holding the phone in portrait orientation, consider the pitch angle to be 0°
2) When pointing the camera up into the sky (such as taking a picture of a cloud) the pitch angle goes from 0° -> 90° where 90 degrees is straight up.
3) when the phone is tilted upward (> 0 degrees and rotating on the "X" magnetometer axis) and when the phone is at about (but not exactly) 45 degrees, the compass heading rotates 180 degrees. So while the camera is still point "N", the compass will report "S".
4) for the next (roughly) 90 degrees, the compass heading is rotated 180 degrees.
This rotation of the heading is destructive for me and it does not align perfectly with the accelerometers. Is there a good tutorial (I did not find one off the bat) on using the the RAW data (X, Y, Z) from the CLHeading data to calculate heading data?
The end result is I want the heading of the compass to always match the heading of the camera.
You can't rely on solely the compass heading. See this answer for what you're looking for, and in particular the CMAttitude object's yaw property to compensate for the pitch angle you're talking about:
Compensating compass lag with the gyroscope on iPhone 4
Related
On my top down 2.5D shooter game, I am usingQuaternion.LookRotation() and Quaternion.Lerp() to change the rotation of my player towards a click. The player rotates just fine, but I need more control over the rotation path. The issue here is that the LookRotation() always returns the shortest path to complete the rotation. I need the player to always rotate only in the X axis until its either +90 or -90 and then flip in the Y axis to the other side. It doesn't matter if the player rotate + or - 90 degrees over the X axis, but the idea is to always rotate in the X axis, before flipping from 1 frame to another, then rotating again in the X axis towards the click.
Here are some images illustrating the above. The "X" in red below, is where the "click" happened.
How can i use the yaw/pitch/roll to estimate the tilt angle of a motorbike, assuming the iphone is in the pocket. I'm thinking along the lines of storing the baseline yaw/pitch/roll when the user begins riding in the upright position then any deviation from that will give me rotations about all 3 axis, but how do i use this to figure out the lateral tilt angle of a motorbike? Thanks.
I currently detect movement on the y axis. How does one calculate the direction it moved on the axis?
I get the same values when moving up or down.
Is the Gyro needed for this?
Do remember that the accelerometer will reflect the force of gravity. So movement up and down will generally be reflected as 9.81 m/s2 plus or minus the actual acceleration of the device relative to the Earth.
I am struck with a problem. I want to convert the CMAttitude information of an iPhone to Altitude (0 to 90deg) and Azimuth (0 to 360 deg). I have googled around and hit some threads which discuss about it, but none of threads turn out with a positive answer and most of the articles discussing Quaternion and Euler angles are too much mathematics to stuff into my brain!
Is there some open source material which does this task easy? Or someone has written code to perform this conversion?
Edit:
First off, sorry for being so abstract!
Azimuth is the direction on the surface of the earth towards which the device is pointing. Like North = 0 deg, North East = 45deg, East = 90 deg, South = 180 deg and so on. Ranges between 0 deg to 360 deg:
Altitude is the angle made from the plane of the earth to an object in the sky:
Thanks,
Raj
Using CMDeviceMotion, you can get a CMAttitude object with "roll, pitch and yaw" - where for example, given a phone held in portrait mode "yaw" is "azimuth", "pitch" is the tilt of the phone with respect to ground, or zenith, and "roll" is about the vector pointing through the screen and not what you're interested in.
Things get a bit tricky because "azimuth" is a projection of the 3D magnetic vector (pointing towards the magnetic north pole) on to the flat "ground" plane, which changes depending on device orientation, but given this understanding of the terms, threads like this one should be much more understandable. If you only need your application to work in one orientation things get much simpler.
P.S. "altitude" is almost exclusively used to refer to elevation or height about a given reference (sea level, geodetic height etc). "Zenith" or "pitch" are preferable, and since you're on iOS, you should stick to their coordinate scheme: (lat, lon, alt), (pitch, yaw, roll).
I noticed a really puzzling behavior on iPhone:
If I hold the phone in the vertical, and tilt it, the compass change.
I already figured the amount it changes is the same amount it would change for the same amount of tilting if it was in horizontal (ie: suppose that a vector coming from the screen is called Y, turning around Y does not matter the attitude of the iPhone results in a compass change).
I want to compensate that, my app was not made to you hold the phone in the horizontal (although I do plan also to allow some tilting in the X axis let's call it, from like 10 degrees to 135)
But I really could not figure how iPhone calculate the heading, thus where the heading vector actually points...
After some scientific style experiments, I found:
The iPhone has magnetometer, it has 3 axis, X, that goes from left to right from the screen. Y, that goes from bottom to up. And Z, that comes from behind the phone and comes to the front.
Earth magnetic field is as expected by the laws of physics not a sphere, in the location I am (brazil), it is slanted about 30 degrees. (meaning that I have to hold the phone in a 30 degrees angle to zero 2 axis).
One possible technique to calculate north, is use cross product of a vector tangential to the magnetic field (ie: the vector the magnetometer reports to you), and gravity. The result will be a vector that points east. If you wish you can make another cross product between east and gravity, resulting in a vector that points north.
Know that iPhone sensors are quite good, and every minor fluctuation and vibration is caught, thus it is good idea to use a lowpass filter, to remove the noise from the signal.
The iPhone itself, has a complex routine to determine the "true heading", I don't figured it completely, but it uses the accelerometer in some way to compensate for tilt. You can use the accelerometer and compensate back if that is your wish, for example if the phone is tilted 70 degrees, you can change the true heading by 70 degrees too, and the result will be the phone ignoring tilting.
Also the routine of true heading, verify if the iPhone is upside down or not. If we consider it in horizontal, in front of you as 0, then more or less at 135 degrees it decides that it is upside down, flipping the results.
Note the same coordinate system also apply to the accelerometer, allowing the use of vectors operations between accelerometer and magnetometer data without much fiddling.