Gyroscope : A gyroscope measures the rate at which a device rotates around each of the three spatial axes
Accelerometer : measures the acceleration of the device along each of the three spatial axes.
Access Accelerometer using UIAccelerometer
Configuring the accelerometer
#define kAccelerometerFrequency 50.0 //Hz
-(void)configureAccelerometer
{
UIAccelerometer* theAccelerometer = [UIAccelerometer sharedAccelerometer];
theAccelerometer.updateInterval = 1 / kAccelerometerFrequency;
theAccelerometer.delegate = self;
// Delegate events begin immediately.
}
Receiving an accelerometer event
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
UIAccelerationValue x, y, z;
x = acceleration.x;
y = acceleration.y;
z = acceleration.z;
// Do something with the values.
}
It shows a simplified version of a low-pass filter.
This example uses a low-value filtering factor to generate a value that uses 10 percent of the
unfiltered acceleration data and 90 percent of the previously filtered value
Isolating the effects of gravity from accelerometer data
#define kFilteringFactor 0.1
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
// Use a basic low-pass filter to keep only the gravity component of each axis.
accelX = (acceleration.x * kFilteringFactor) + (accelX * (1.0 - kFilteringFactor));
accelY = (acceleration.y * kFilteringFactor) + (accelY * (1.0 - kFilteringFactor));
accelZ = (acceleration.z * kFilteringFactor) + (accelZ * (1.0 - kFilteringFactor));
// Use the acceleration data.
}
shows a simplified high-pass filter computation with constant effect of gravity.
Getting the instantaneous portion of movement from accelerometer data
#define kFilteringFactor 0.1
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
// Subtract the low-pass value from the current value to get a simplified high-pass filter
accelX = acceleration.x - ( (acceleration.x * kFilteringFactor) + (accelX * (1.0 - kFilteringFactor)) );
accelY = acceleration.y - ( (acceleration.y * kFilteringFactor) + (accelY * (1.0 - kFilteringFactor)) );
accelZ = acceleration.z - ( (acceleration.z * kFilteringFactor) + (accelZ * (1.0 - kFilteringFactor)) );
// Use the acceleration data.
}
Handling Accelerometer and Gycometer using COREMOTION
Core Motion is a system framework that obtains motion data from sensors on a device and presents that data to applications for processing.
Core Motion defines a manager class, CMMotionManager, and three classes whose instances encapsulate measurements of motion data of various types:
A CMAccelerometerData object encapsulates a data structure that records a measurement of device acceleration along the three spatial axes. This data derives from the accelerometer.
A CMGyroData object encapsulates a data structure that records a biased estimate of a device’s rate of rotation along the three spatial axes.
A CMDeviceMotion
object encapsulates processed device-motion data that derives from both the accelerometer and the gyroscope.
************Handling Accelerometer using CoreMotion************
To start receiving and handling accelerometer data, create an instance of the CMMotionManager class and call one of the following two methods on it:
startAccelerometerUpdates
After this method is called, Core Motion continuously updates the accelerometerData property of CMMotionManager with the latest measurement of accelerometer activity.
startAccelerometerUpdatesToQueue:withHandler:
Before calling this method, the application assigns an update interval to the accelerometerUpdateInterval property. It also creates an instance of NSOperationQueue and implements a block of the CMAccelerometerHandler type that handles the accelerometer updates.
Configuring the motion manager and starting updates
- (void)startAnimation {
if (!animating) {
// code that configures and schedules CADisplayLink or timer here ...
}
motionManager = [[CMMotionManager alloc] init]; // motionManager is an instance variable
motionManager.accelerometerUpdateInterval = 0.01; // 100Hz
memset(filteredAcceleration, 0, sizeof(filteredAcceleration));
[motionManager startAccelerometerUpdates];
}
- (void)stopAnimation {
if (animating) {
// code that invalidates CADisplayLink or timer here...
}
[motionManager stopAccelerometerUpdates];
}
Below code shows how the application, in this same method, gets the latest accelerometer data and runs it through a low-pass filter. It then updates the drawing model with the filtered acceleration values and renders its view.
Listing 4-8 Sampling and filtering accelerometer data
- (void)drawView {
// alpha is the filter value (instance variable)
CMAccelerometerData *newestAccel = motionManager.accelerometerData;
filteredAcceleration[0] = filteredAcceleration[0] * (1.0-alpha) + newestAccel.acceleration.x * alpha;
filteredAcceleration[1] = filteredAcceleration[1] * (1.0-alpha) + newestAccel.acceleration.y * alpha;
filteredAcceleration[2] = filteredAcceleration[2] * (1.0-alpha) + newestAccel.acceleration.z * alpha;
[self updateModelsWithAcceleration:filteredAcceleration];
[renderer render];
}
Note: You can apply a low-pass or high-pass filter to acceleration values and thereby isolate the gravity and user-acceleration components:
To apply a low-pass filter, thereby isolating the gravity component,
To apply a high-pass filter, thereby isolating the user-acceleration component
*******Handling Gyroscope Using CORE MOTION*******
To start receiving and handling rotation-rate data, create an instance of the CMMotionManager class and call one of the following two methods on it:
startGyroUpdates
After this method is called, Core Motion continuously updates the gyroData property of CMMotionManager with the latest measurement of gyroscope activity.
startGyroUpdatesToQueue:withHandler:
Before calling this method, the application assigns an update interval to the gyroUpdateInterval property.
It also creates an instance of NSOperationQueue and implements a block of the CMGyroHandler type that handles the gyroscope updates.
Creating the CMMotionManager object and setting up for gyroscope updates
- (void)viewDidLoad {
[super viewDidLoad];
motionManager = [[CMMotionManager alloc] init];
motionManager.gyroUpdateInterval = 1.0/60.0;
if (motionManager.gyroAvailable) {
opQ = [[NSOperationQueue currentQueue] retain];
gyroHandler = ^ (CMGyroData *gyroData, NSError *error) {
CMRotationRate rotate = gyroData.rotationRate;
// handle rotation-rate data here......
};
} else {
NSLog(@"No gyroscope on device.");
toggleButton.enabled = NO;
[motionManager release];
}
}
Starting and stopping gyroscope updates
- (IBAction)toggleGyroUpdates:(id)sender {
if ([[(UIButton *)sender currentTitle] isEqualToString:@"Start"]) {
[motionManager startGyroUpdatesToQueue:opQ withHandler:gyroHandler];
} else {
[motionManager stopGyroUpdates];
}
}
No comments:
Post a Comment