iPhone Orientation Expressed as Rotation - iphone

Ola Folks,
This might not be the right place for this. Let me know where I should post if I should post it elsewhere.
I want to get the orientation of the device. I am thinking I can use something like this:
float fAngleX = atan2(acceleration.y, acceleration.z);
float fAngleY = atan2(acceleration.x, acceleration.z);
float fAngleZ = atan2(acceleration.y, acceleration.x);
First, is my formula right?
Second, is this going to work for the device?
Third, I'm going back and forth about filtering out gravity. Any thoughts?
Lastly, is there a better way to get the devices orientation expressed as rotation for all three axis?
Thanx
-isdi-

To give the rotation of the device as three numbers like that, is actually ambiguous. This kind of thing can get quite confusing. I think this might be the best place to start: http://en.wikipedia.org/wiki/Euler_angles

As long as you're careful you can use angles, though it would probably be way easier to use vectors directly.
You'll almost certainly want to do filtering; a simple low-pass would be great, but don't filter out gravity, as it is the orientation of the device :).

Related

iOS Get Subview's Rotation

I'm using CGAffineTransformMakeRotation to rotate a subview using its transform property. Later, I need to find out how far the subview has been rotated. I realize that I could simply use an int to keep track of this, but is there a simple way to get the current rotation of the subview?
CGAffineTransformMakeRotation is explicitly defined to return a matrix with cos(angle) in the transform's a value, sin(angle) in b, etc (and, given the way the transform works, that's the only thing it really could do).
Hence you can work out the current rotation by doing some simple inverse trigonometry. atan2 is probably the thing to use, because it'll automatically figure out the quadrants appropriately.
So, e.g.
- (float)currentAngleOfView:(UIView *)view
{
CGAffineTransform transform = view.transform;
return atan2f(transform.b, transform.a);
}
Because that'll do an arctangent that'll involve dividing the a and b fields in an appropriate manner, that method will continue to work even if you apply scaling (as long as it's the same to each axis) or translation.
If you want to apply more complex or arbitrary transformations then things get a lot more complicated. You'll want to look how to calculate normal matrices. From memory I think you'd want the adjugate, which is about as much fun to work out as it sounds.

Getting level of rotation with UIAccleration

Games like FroggyJump for iPhone figure out the rotation of the iphone. I'm getting confused with the acceleration values. How do I calculate the level of rotation? I suppose I need to consider when the iphone isn't perfectly upright.
Thank you.
I'm also wanting to use the new Core Motion framework with the "Device Motion" for iPhone 4 for extra precision. I guess I'll have to use that low pass filter for the other devices.
It's the yaw.
Having given Froggy Jump a quick go, I think it's likely directly using the accelerometer's x value as the left/right acceleration on the frog. If it is stationary, you can think of an accelerometer as giving you the vector that points upward into space, relative to the local axes. For something like a ball rolling or anything else accelerating due to tilt, you want to use the values directly.
For anything that involves actually knowing angles, you're probably best picking the axis around which you want to detect rotation then using the C function atan2f on the accelerometer values for the other two axes. With just an accelerometer, there are some scenarios in which you can't detect rotation — for example, if the device is flat on a table then an accelerometer can't detect yaw. The general rule is that rotations around the gravity vector can't be detected with an accelerometer alone.

Using iPhone/iPod Touch acceleration to rotate a 3D object

I'm trying to use an iPhone/iPod acceleration to manipulate directly a 3D object.
For that I've been searching lot's of stuff (Euler angles, Quaternions, etc).
I'm using OpenSG, where I have a 3D environment and want to manipulate a certain object (just rotating in all possible iPhone/iPod degrees of freedom using only accelerometer).
So, I tried to figure it out a solution for this problem but it still doesn't have the expected result and get some weird rotations in some angles.
Can someone tell me what I'm doing wrong? Or, is there a better way of doing this without using quaternions?
The acceleration variable is a Vec3f containing the accelerometer values from iPhone/iPod filtered with a low-pass filter.
acceleration.normalize();
Vec3f reference = OSG::Vec3f(0, 0, 1);
OSG::Vec3f axis = acceleration.cross( reference );
angle = acos( acceleration.dot( reference ) );
OSG::Quaternion quat;
quat.setValueAsAxisRad(axis, angle);
After this code, I update my scene node using quaternion quat.
I wanted to do the exact same thing and just tried it, I hadn't played around with an accelerometer before and it seemed like it should be possible.
The problem is that if you set your iPhone on a table and then slowly spin it around and observe the output of the accelerometer it basically doesn't change (one gravity down). If you tilt it up/down on any of the four edges you will see the output change.
In other words you know that your table top is tilting top/bottom or left/right, but you can't tell that you are spinning it. So you can map this tilt to two rotations of a 3D object.
You could probably use the compass for the horizontal rotation, I couldn't try because I was prototyping in the Unity Game Engine and it doesn't seem to support compass yet.
The ever wonderful Brad Larson posted an excellent description of his initial experiences of a 3d viewer while writing his Moleculs app.
His method for rotations was achieved as follows:
GLfloat currentModelViewMatrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, currentModelViewMatrix);
glRotatef(xRotation, currentModelViewMatrix[1], currentModelViewMatrix[5], currentModelViewMatrix[9]);
glGetFloatv(GL_MODELVIEW_MATRIX, currentModelViewMatrix);
glRotatef(yRotation, currentModelViewMatrix[0], currentModelViewMatrix[4], currentModelViewMatrix[8]);
but whether or not this is helpful I can't recommend this blog entry enough Brad learns a lesson or two
Editing to add that I may have misread the question, but will keep the post here as it will likely help people searching with similar keywords.

Chipmunk physics: Velocity question

I'm making an iPhone game where the main actor is a ball that rolls depending on the device's accelerometer rotation.
I haven't started on this part of the coding yet, but I was wondering if you guys had a nice way of solving this:
I tried looking a little into chipmunk, and I noticed that bodies have the property v, which is a point containing x and y velocities.
I was thinking it'd be a bad idea to just do like:
playerBody->v = ccp(accelerometer.x * 5, playerBody->v.y);
because it'd just roll up of walls and stuff,
is there a better solution to do this?
Basically, in a perfectly elastic collision (no energy lost) with a wall, which I'm guessing is what you want, the component of the velocity that is normal (perpendicular) to the wall is reversed (inverted). The tangential components stay the same. For instance, if the wall is along the x-axis, then v_y = -v_y. I haven't used Chipmunk so I won't attempt to tell you the actual syntax for doing this.

iPhone accelerometer changing senstivity

I'm trying to use the accelerometer to move a UIImage. I works well but my problem is that with my code
self.character.center = CGPointMake(160+acceleration.x*175, 230-acceleration.y*175);
my picture moves even on a stable surface because of the precision of the acceleration.x value. So I decided to use a workaround by multiplying it with a value, casting it to an INT and then dividing it and cast it to a float (i.e i just remove some numbers after the coma)
self.character.center = CGPointMake(160+(float)((int)((acceleration.x*100000))/100000)*175, 230-(float)((int)((acceleration.y*100000))/100000)*175);
But after i use this code, my little picture isn't moving anymore.
So my question is : do you know why it doesn't work anymore ?
Is there a proper way to remove numbers after the coma in a float ?
Thanks a lot
Fred.
Instead of trying to remove decimals after the comma, you should better use a low pass filter. A lowpass filter will let only pass changes to your acceleration that happen below a certain cutoff frequency. Therefore, it will keep steady changes to the acceleration but remove fluctations and jitter with very high frequencies.
Wikipedia has a good explanation how a simple RC Lowpass filter works and shows a possible implementation. Apple shows a similar implementation in the AccelerometerGraph sample code.