2

what i have here works exactly how i want it. My question is that it seems overly complex, is there a faster/better way of doing the pitchAngleRadians calculations i am showing below?

the code is shown... (along with two images)

the first image is how the atan2 calculation comes out of the iPad naturally, "pitchAngleRadians = atan2(accel[0], accel2);" (what the accelerometer puts out normally)

what i want is to shift "Zero" to a new degree angle, in the second image i've shifted it a -135 degrees as an example. (everything in code is radians) so for instance the variable "pitchNeutralAngle" in this example is the radian equivalent of (-135) degrees

this code produces exactly what i want for the variable "pitchAngleRadians", which is the second image, but seems too long, and this code is in a tight run loop, so it would speed up if i can get this cleaner/faster.

i go through an intermediate step of "ranging" the degrees between 0 and 360, so that crossing the boarder of 180 degrees does not mess up the calculation, however i still have to get it back to the 0 to 180 form, so that is what the next calculation is.

i've tested this code a little bit, and it does appear to work.

//------------------------------------------------------------------------------------
- (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration
{
    accel[0] = (acceleration.x * kFilteringFactor) + accel[0] * (1.0 - kFilteringFactor);
    accel[1] = (acceleration.y * kFilteringFactor) + accel[1] * (1.0 - kFilteringFactor);
    accel[2] = (acceleration.z * kFilteringFactor) + accel[2] * (1.0 - kFilteringFactor);

    pitchAngleRadians = (atan2(accel[0], accel[2]) - pitchNeutralAngle);
    pitchAngleRadians = pitchAngleRadians - floorf(pitchAngleRadians/6.28318f)*6.28318f;
    if (pitchAngleRadians > 3.14159) pitchAngleRadians = -6.28318f + pitchAngleRadians;

//float a = atan2(accel[0], accel[2]);
//NSLog(@"a = %f", a);
}

naturally comes out of the accelerometer

after re-"neutralizing" zero angle

hokkuk
  • 675
  • 5
  • 21

1 Answers1

1

Are you bound to old 3.x devices or can you rely on iOS 4.x? In general the "old" UIAccelerometerDelegate will be deprecated soon because it is replaced by new Core Motion framework (s. Why is accelerometer:didAccelerate: deprecated in IOS5?)

Next, you are talking about iPad which has IMO a gyroscope (or is it iPad 2 only?). If you can rely on devices having one, you are done with Core Motion DeviceMotion which provides Euler angles ready to use without any problems (OK bear in mind Gimbal lock). See Simple iPhone motion detect especially:

You can check out WWDC2010 sample code: WWDC 2010 Sample Code

If not, any chance to convince you or your business partners? OK, you are still there :-) hmmh, atan and atan2 have some discontinuities, are you sure that it works out for all combinations of small x and y values i.e. if the device is lying on the table without or with just small motion but some sensor noise?

Regarding perfomance: Yes atan is quite expensive so you can check out using alternatives like FastMath.h (it's in French but no worries follow the link at C++ en un simple fichier header FastMath.h contenant.

Community
  • 1
  • 1
Kay
  • 12,918
  • 4
  • 55
  • 77
  • ah, they are always replacing something... i'll look into the core motion way of doing it... thanks. (i'm afraid the calculation will be similar though.. correct?).. i'll look into it. i'll limit the devices to 4.x and above. – hokkuk Aug 02 '11 at 18:24
  • It's really easy and you don't have to calculate anything. CMDeviceMotion's property attitude contains pitch, roll and yaw (the Euler angles) ready to use or rotation rate or quaternion - if you like maths ;-) – Kay Aug 02 '11 at 21:33
  • I looked at the links to the documentation. the core motion area showed an example that was extremely similar to the old way of doing it, (i.e. they showed an x, y, and z output)... which would mean similar calcs? I'm still looking at the different things you can do. but i haven't found examples other than what i mentioned. – hokkuk Aug 03 '11 at 13:04
  • ahh, now i am finding examples of the CMAttitude class,(now that i know what to look for) looks good, i'll mark this as answered. thanks. one question, it says something about it is not a good idea to have this running on the "main" thread. Right now i have two threads, one is the normal main UI thread, and then the game run loop is on a second thread. i'm wondering if that comment above meant to also not have it running on the run loop thread? in other words should i have a third thread? – hokkuk Aug 03 '11 at 16:21
  • I am not totally sure. I've read that NSOperationQueues are managed in its own thread, but I ran into trouble when I had a performance bottleneck at another place, because the queue couldn't be emptied that fast. So I decided to put sensor reading in its own thread. But if your run loop performs well I recommend running in main UI thread. – Kay Aug 03 '11 at 17:37