3D Tilt calibration

Discussion in 'Public Game Developers Forum' started by shen, Feb 20, 2009.

  1. Hi;

    I'm working on my 3rd game for the iPhone, and am having some trouble getting the accelerometer calibration to work correctly.

    What I mean by that is that I currently have controls working with the player holding the iPhone with the screen facing straight up, and reading the raw x + y accelerometer values and using them.

    I would like to have the player be able to hold the iphone in any position, calibrate using a process in my game, and then the game treats that new position as if it was lying face up.

    However, the 3d math are a bit beyond me up until now.

    Are there any developers out there who have cracked this who can give me some help?

    Shen
     
  2. arkanigon

    arkanigon Well-Known Member

    Dec 24, 2008
    439
    0
    0
    The way I do it, I ask the user to place the iphone on a flat table (it doesn't have to be... it's just any position the user wants to treat as the face up position)... then ask him to click a calibrate button... the following code is in my Settings viewcontroller...


    Code:
    - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
    	
    	self.xcalib=acceleration.x;
    	self.ycalib=acceleration.y;
    	
    }
    
    so in the above method... self.xcalib and self.ycalib are constantly changing as you tilt the iphone... when the user clicks calibrate it runs this method

    Code:
    -(IBAction)calibrate {
    
           PongControlAppDelegate *appcontrol= [[UIApplication sharedApplication] delegate];
    	
    	appcontrol.viewController.xcalibration=self.xcalib;
    	
    	appcontrol.viewController.ycalibration=self.ycalib;
    
    	self.xcalibrationvalue=self.xcalib;
    
            self.ycalibrationvalue=self.ycalib;
    
    }
    
    So the calibrate method captures the calibration values....

    appcontrol.viewController is where my game actually runs and where I need to read the acceleration values... so I have a

    Code:
    - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
    	
    	//
    	//
    }
    method there also...

    Now that you've captured the calibration values.... all you have to do is wherever you use acceleration.x or acceleration.y... you just replace those with (acceleration.x-self.xcalibration) and (acceleration.y-self.ycalibration)
     
  3. Thanks for that answer, but I am after something a bit different.

    I want to get the user to choose a particular orientation, and then treat that position as if it was flat.

    so right now the player must hold the iphone with the screen facing straight up, and move by tilting.

    I would like the player to be able to recalibrate it so they could hold the phone with the screen facing the horizon, and that is treated as flat

    Or they could recalibrate so they hold the phone at 45 degrees, and that is treated as flat.
     
  4. arkanigon

    arkanigon Well-Known Member

    Dec 24, 2008
    439
    0
    0
    Hmmm... I think that's what the code I provided does... unless I'm misunderstanding what you need... in my game, I can hold the iphone in any position... press the calibrate button... and then the iphone will treat that as the flat position...
     
  5. And all you need to do is subtract the starting value from the calibration value?

    From looking at the accelerometer output it seems like the values are sin wave based, so I thought you would need to do some more complex math to adjust for that.

    Plus it you are holding the iphone with the screen facing the horizon, and the y accelerometer is 1 (or -1) tilting forward or backward will both change the y reading the same way won't they?

    Shen
     
  6. arkanigon

    arkanigon Well-Known Member

    Dec 24, 2008
    439
    0
    0
    Yes, you're absolutely right. I was messing up. :p sorry about that.


    Yes... so here I think you'd have to use the z value to figure out which way it is tilting...
     
  7. arkanigon

    arkanigon Well-Known Member

    Dec 24, 2008
    439
    0
    0
    Would this do it?

    If we take the arcsin of the acceleration values... at the calibration position...

    ie: asin(xcalibration), asin(ycalibration), asin(zcalibration)...

    So the angles of rotation would be:

    xangle = asin(currentxacceleration) - asin(xcalibration)

    yangle = asin(currentyaccleration) - asin(ycalibration)

    zangle = asin(currentzacceleration) - asin(zcalibration)

    whereas without calibration it would have been:

    xangle=asin(currentxacceleration)
    yangle = asin(currrentyacceleration)
    zangle = asin(currentzacceleration)
     
  8. spacerage

    spacerage Well-Known Member

    Oct 21, 2008
    178
    0
    0
    Just wondering if this worked for you?
     
  9. The first thing you need to recognize is exactly what is going on...

    - You might want a tilt vector and magnitude
    - You might want two scalers an: x and y

    The rest of this is the about two scalers:

    In Armor Alley, I support 6 orientations of play.

    If you want two scalers:
    - You have 3 basic orientations: face up, face down (player on their back), vertical.
    - You have 2 variants of each: home button on the left and home button on the right.

    Once you realize you have these variants, then you realize that anything that is off of normal is increasingly less accurate.
    - In all orientations, tilting the top or bottom away from you is one value (y)
    - In horizontal orientations, tilting the left or right away is the other value (x)
    - In vertical orientations, tilting the left or right side down is the other value again (x)

    As you move between horizontal and vertical orientations you have two conflicting metaphors for measuring orientation.

    Armor Alley chooses the closest orientation for the first second of play. After that if the player moves the device with in a few degrees of normal for another orientation, it sounds a warning beep and automatically calibrates to the new orientation.

    The system is transparent and just works. Players don't even notice when they have changed orientations due to the excitement of game play. :)

    Manual calibration is possible, but I haven't received any feed back suggesting it is necessary.

    -Arthur
     
  10. arkanigon

    arkanigon Well-Known Member

    Dec 24, 2008
    439
    0
    0
    Well, I realize now that you can only do it with 2 axes... you can't measure the angle about the vertical axis (the axis along which gravity acts)...

    In my game you hold the iphone face up... I measure the tilt using this method I described with x and y (there might be minus signs or something... but basically this method worked for me) ...
     

Share This Page