最後我做到了,我用userAcceleration
數據這是設備的加速度由於設備不包括重力,我發現有很多人使用正常的加速度數據和做數學的很多,可以移除重力,現在它已經由iOS 6在userAcceleration
中完成。
而且我使用了1個識別器,它是一個2D識別器(即點(5,10),無Z)。
這是1$ recognizer的鏈接,在下載部分有一個C++版本。
這裏是我的代碼的步驟...
- 閱讀
userAcceleration
數據與frequancy 50 HZ。
- 對其應用低通濾波器。
- 僅當其x或y值大於0.05以降低噪音時才考慮這一點。
(注意:下一步取決於您的代碼和您使用的識別器)。
- 將x和y點保存到數組中。
- 從這個數組中創建一個2D路徑。
- 發送此路徑到識別器進行天氣訓練或識別它。
這裏是我的代碼...
@implementation MainViewController {
double previousLowPassFilteredAccelerationX;
double previousLowPassFilteredAccelerationY;
double previousLowPassFilteredAccelerationZ;
CGPoint position;
int numOfTrainedGestures;
GeometricRecognizer recognizer;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
previousLowPassFilteredAccelerationX = previousLowPassFilteredAccelerationY = previousLowPassFilteredAccelerationZ = 0.0;
recognizer = GeometricRecognizer();
//Note: I let the user train his own gestures, so i start up each time with 0 gestures
numOfTrainedGestures = 0;
}
#define kLowPassFilteringFactor 0.1
#define MOVEMENT_HZ 50
#define NOISE_REDUCTION 0.05
- (IBAction)StartAccelerometer
{
CMMotionManager *motionManager = [CMMotionManager SharedMotionManager];
if ([motionManager isDeviceMotionAvailable])
{
[motionManager setDeviceMotionUpdateInterval:1.0/MOVEMENT_HZ];
[motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue]
withHandler: ^(CMDeviceMotion *motion, NSError *error)
{
CMAcceleration lowpassFilterAcceleration, userAcceleration = motion.userAcceleration;
lowpassFilterAcceleration.x = (userAcceleration.x * kLowPassFilteringFactor) + (previousLowPassFilteredAccelerationX * (1.0 - kLowPassFilteringFactor));
lowpassFilterAcceleration.y = (userAcceleration.y * kLowPassFilteringFactor) + (previousLowPassFilteredAccelerationY * (1.0 - kLowPassFilteringFactor));
lowpassFilterAcceleration.z = (userAcceleration.z * kLowPassFilteringFactor) + (previousLowPassFilteredAccelerationZ * (1.0 - kLowPassFilteringFactor));
if (lowpassFilterAcceleration.x > NOISE_REDUCTION || lowpassFilterAcceleration.y > NOISE_REDUCTION)
[self.points addObject:[NSString stringWithFormat:@"%.2f,%.2f", lowpassFilterAcceleration.x, lowpassFilterAcceleration.y]];
previousLowPassFilteredAccelerationX = lowpassFilterAcceleration.x;
previousLowPassFilteredAccelerationY = lowpassFilterAcceleration.y;
previousLowPassFilteredAccelerationZ = lowpassFilterAcceleration.z;
// Just viewing the points to the user
self.XLabel.text = [NSString stringWithFormat:@"X : %.2f", lowpassFilterAcceleration.x];
self.YLabel.text = [NSString stringWithFormat:@"Y : %.2f", lowpassFilterAcceleration.y];
self.ZLabel.text = [NSString stringWithFormat:@"Z : %.2f", lowpassFilterAcceleration.z];
}];
}
else NSLog(@"DeviceMotion is not available");
}
- (IBAction)StopAccelerometer
{
[[CMMotionManager SharedMotionManager] stopDeviceMotionUpdates];
// View all the points to the user
self.pointsTextView.text = [NSString stringWithFormat:@"%d\n\n%@", self.points.count, [self.points componentsJoinedByString:@"\n"]];
// There must be more that 2 trained gestures because in recognizing, it gets the closest one in distance
if (numOfTrainedGestures > 1) {
Path2D path = [self createPathFromPoints]; // A method to create a 2D path from pointsArray
if (path.size()) {
RecognitionResult recongnitionResult = recognizer.recognize(path);
self.recognitionLabel.text = [NSString stringWithFormat:@"%s Detected with Prob %.2f !", recongnitionResult.name.c_str(),
recongnitionResult.score];
} else self.recognitionLabel.text = @"Not enough points for gesture !";
}
else self.recognitionLabel.text = @"Not enough templates !";
[self releaseAllVariables];
}
謝謝你的代碼示例。你使用了哪個cpp庫,你有一個完整的例子嗎?這會非常有幫助。 – 2014-01-31 12:41:43
@Zabady +1回覆。我只有幾個問題。你能否解釋一下我們如何得出lowPassFilter?另外,我得到了所有負面的滾動,偏航和俯仰加速度值。這是正常的嗎?如果是這樣,我們將如何根據這些負值計算加速率?提前致謝。 – Unheilig 2014-02-22 12:02:32
這太棒了!你開發這個產品的是什麼產品? – tadelv 2014-04-21 16:13:48