Thursday, June 19, 2008

UIAccelerometer Sample Code

It is possible to use Open Tool Chain Header with the SDK and the official iPhone OS 2.0 SDK headers, the following demonstrates these two versions for the Accelerometer


Official iPhone OS 2.0 SDK headers version



SensorSDK3.app main.m : Select all


/
// main.m
// SensorSDK3.app
//
#import <UIKit/UIKit.h>

int main(int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, @"SensorSDK3AppDelegate");
[pool release];
return retVal;
}


SensorSDK3AppDelegate.h : Select all


//
// SensorSDK3AppDelegate.h
// SensorSDK3.app
//

#import <UIKit/UIKit.h>
#include <stdio.h>
#include <time.h>
#include <math.h>

#define kUpdateFrequency 10 // Hz


@interface SensorSDK3AppDelegate : NSObject {
UIWindow *window;
UITextView *textView;
UIImageView *xarrow;
}

@property (nonatomic, retain) UIWindow *window;
@property (nonatomic, retain) UITextView *textView;
@property (nonatomic, retain) UIImageView *xarrow;

- (void)acceleratedInX:(float)xx Y:(float)yy Z:(float)zz;
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration;
@end

SensorSDK3AppDelegate.m : Select all


//
// SensorSDK3AppDelegate.m
// SensorSDK3.app
//

#import "SensorSDK3AppDelegate.h"

UIImage *createImageWithText(CGSize imageSize, NSString *text);

@implementation SensorSDK3AppDelegate

@synthesize window;
@synthesize textView;
@synthesize xarrow;

- (void)applicationDidFinishLaunching:(UIApplication *)application {

self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];


self.textView = [[UITextView alloc] initWithFrame: [[UIScreen mainScreen] applicationFrame]];
self.textView.font = [UIFont systemFontOfSize:24];
self.textView.editable = NO;
self.textView.textAlignment = UITextAlignmentLeft;

UIImage *img = createImageWithText(CGSizeMake(85,40),@"-->");
self.xarrow = [[UIImageView alloc] initWithImage:img];
self.xarrow.center=self.textView.center;
self.xarrow.clearsContextBeforeDrawing = NO;


[textView addSubview:xarrow];

// Show window
[window addSubview:textView];
[window makeKeyAndVisible];

[[UIAccelerometer sharedAccelerometer] setUpdateInterval:(20.0 / kUpdateFrequency)];
[[UIAccelerometer sharedAccelerometer] setDelegate:self];

}

/*
The meaning of X, Y, Z by Erica Sadun (with modification for the range from -1.0 to 1.0 for firmware 2.0)
X = Roll X corresponds to roll, or rotation around the axis that runs from your home button to your earpiece.
Values vary from 1.0 (rolled all the way to the left) to -1.0 (rolled all the way to the right).

Y = Pitch. Place your iPhone on the table and mentally draw a horizontal line about half-way down the screen.
That's the axis around which the Y value rotates.
Values go from 1.0 (the headphone jack straight down) to -1.0 (the headphone jack straight up).

Z = Face up/face down. I expected the Z value to correspond to yaw. And it does not.
It refers to whether your iPhone is face up (-1.0) or face down (1.0).
When placed on it side, either the side with the volume controls and ringer switch, or the side directly opposite
, the Z value equates to 0.0.
*/

- (void)acceleratedInX:(float)xx Y:(float)yy Z:(float)zz
{

// Create Status feedback string
NSString *xstring = [NSString stringWithFormat:
@"X (roll, %4.1f%%): %f\nY (pitch %4.1f%%): %f\nZ (%4.1f%%) : %f",
100.0 - (xx + 1.0) * 100.0, xx,
100.0 - (yy + 1.0) * 100.0, yy,
100.0 - (zz + 1.0) * 100.0, zz
];
self.textView.text = xstring;

// Revert Arrow and then rotate to new coords
float angle = atan2(xx, yy);
angle += M_PI / 2.0;

CGAffineTransform affineTransform = CGAffineTransformIdentity;
affineTransform = CGAffineTransformConcat( affineTransform, CGAffineTransformMakeRotation(angle));
self.xarrow.transform = affineTransform;

}

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
[self acceleratedInX:acceleration.x Y:acceleration.y Z:acceleration.z];
}


- (void)dealloc {
[textView release];
[xarrow release];
[window release];
[super dealloc];
}

@end

// Returns an image of the given size containing the given string
UIImage *createImageWithText(CGSize imageSize, NSString *text) {

// Create a bitmap graphics context of the given size
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, imageSize.width, imageSize.height, 8, imageSize.width*4, colorSpace, kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorSpace);
if (context== NULL) {
return nil;
}

// Custom CGContext coordinate system is flipped with respect to UIView, so transform, then push
CGContextTranslateCTM(context, 0, imageSize.height);
CGContextScaleCTM(context, 1.0, -1.0);
UIGraphicsPushContext(context);

// Inset the text rect then draw the text
CGRect textRect = CGRectMake(4, 2, imageSize.width - 8, imageSize.height - 8);
UIFont *font = [UIFont boldSystemFontOfSize:24];
[[UIColor blackColor] set];
[text drawInRect:textRect withFont:font lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentCenter];

// Create and return the UIImage object
CGImageRef cgImage = CGBitmapContextCreateImage(context);
UIImage *uiImage = [[UIImage alloc] initWithCGImage:cgImage];
UIGraphicsPopContext();
CGContextRelease(context);
CGImageRelease(cgImage);
return uiImage;
}



Open Tool Chain headers version



HelloSensor.app : Select all


/*
HelloSensor.app
main.m
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <UIKit/UIWindow.h>
#import <UIKit/UIHardware.h>
#import <UIKit/UIApplication.h>
#import <UIKit/UIImageView.h>
#import <UIKit/UIImage.h>
#import <UIKit/UITextView.h>
#include <stdio.h>
#include <time.h>
#include <math.h>

#ifdef ASPEN
#ifndef UIKIT_UIFont_UIColor_H
#define UIKIT_UIFont_UIColor_H
typedef float CGFloat;
#import
#import
#endif

#ifndef UIKIT_UIAccelerometer_H
#define UIKIT_UIAccelerometer_H
#import
#define kUpdateFrequency 10 // Hz
#endif

#endif


#ifdef ASPEN
@interface HelloSensor : UIApplication
#else
@interface HelloSensor : UIApplication
#endif
{
UIWindow *window;
UIView *mainView;
UITextView *textView;
UIImageView *xarrow;
}
#ifdef ASPEN
- (void)acceleratedInX:(float)xx Y:(float)yy Z:(float)zz;
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration;
#endif
@end

@implementation HelloSensor


#ifdef ASPEN
// UIAccelerometer delegate method in SDK
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
[self acceleratedInX:acceleration.x Y:acceleration.y Z:acceleration.z];
}
#endif

/*
The meaning of X, Y, Z by Erica Sadun
X = Roll X corresponds to roll, or rotation around the axis that runs from your home button to your earpiece.
Values vary from 0.5 (rolled all the way to the left) to -0.5 (rolled all the way to the right).

Y = Pitch. Place your iPhone on the table and mentally draw a horizontal line about half-way down the screen.
That's the axis around which the Y value rotates.
Values go from 0.5 (the headphone jack straight down) to -0.5 (the headphone jack straight up).

Z = Face up/face down. I expected the Z value to correspond to yaw. And it does not.
It refers to whether your iPhone is face up (-0.5) or face down (0.5).
When placed on it side, either the side with the volume controls and ringer switch, or the side directly opposite
, the Z value equates to 0.0.
*/

- (void)acceleratedInX:(float)xx Y:(float)yy Z:(float)zz
{
// Create Status feedback string
NSString *xstring = [NSString stringWithFormat:
@"X (roll, %4.1f%%): %f\nY (pitch %4.1f%%): %f\nZ (%4.1f%%) : %f",
100.0 - (xx + 0.5) * 100.0, xx,
100.0 - (yy + 0.5) * 100.0, yy,
100.0 - (zz + 0.5) * 100.0, zz];
[textView setText:xstring];

// Revert Arrow and then rotate to new coords
[xarrow setTransform:CGAffineTransformIdentity];
float angle = atan2(yy, xx);
angle *= 180.0/3.14159;
[xarrow setRotationBy:angle];
}


- (void) applicationDidFinishLaunching: (id) unused
{
#ifdef ASPEN
[UIHardware _setStatusBarHeight:0.0f];
[self setStatusBarMode:2 duration:0.0f];
[self setStatusBarHidden:YES animated:NO]; // hide status bar
#endif

struct CGRect rect = [UIHardware fullScreenApplicationContentRect];
rect.origin.x = rect.origin.y = 0.0f;
window = [[UIWindow alloc] initWithContentRect: rect];
mainView = [[UIView alloc] initWithFrame: rect];

textView = [[UITextView alloc] initWithFrame:
CGRectMake(0.0, 0.0, 320.0, 480.0)];
[textView setEditable:NO];
#ifdef ASPEN
[textView setFont:[UIFont systemFontOfSize:24]];
#else
[textView setTextSize:24];
#endif
[mainView addSubview: textView];

// I changed the arrow by getting it from Notes app
xarrow = [[UIImageView alloc] initWithFrame: CGRectMake(135.0, 320.0, 50.0, 46.0)];
UIImage *img = [[UIImage imageAtPath:@"/Applications/MobileNotes.app/arrow right.png"] retain];

// If you want the original arrow get it from http://www.tuaw.com/2007/09/10/iphone-coding-using-the-accelerometer/
// xarrow = [[UIImageView alloc] initWithFrame: CGRectMake(50.0, 320.0, 200.0, 50.0)];
// [[UIImage imageAtPath:[[NSBundle mainBundle] pathForResource:@"arrow" ofType:@"png" inDirectory:@"/"]] retain];


[xarrow setImage:img];
[textView addSubview:xarrow];

[window orderFront: self];
[window setContentView: mainView];

#ifdef ASPEN
[window makeKeyAndVisible];
[[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / kUpdateFrequency)];
[[UIAccelerometer sharedAccelerometer] setDelegate:self];
#else
[window makeKey: self];
[window _setHidden: NO];
#endif

}
@end

int main(int argc, char *argv[]) {
int returnCode;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
returnCode = UIApplicationMain(argc, argv, [HelloSensor class]);
[pool release];
return returnCode;
}

No comments: