2012-05-14 1 views
3

J'ai besoin de calculer la vitesse de l'iphone dans l'espace, la vitesse de perforation par exemple.
Ma première question est: Les valeurs d'accélération accelerometer:didAccelerate avec ces actions de filtrage:
Comment calculer les valeurs de vélocité correctes à partir de l'accéromètre

gravity_x = acceleration.x * kFilteringFactor + gravity_x * (1.0 - kFilteringFactor); 
gravity_y = acceleration.y * kFilteringFactor + gravity_y * (1.0 - kFilteringFactor); 
gravity_z = acceleration.z * kFilteringFactor + gravity_z * (1.0 - kFilteringFactor); 
float gravityNorm = sqrt(gravity_x * gravity_x + gravity_y * gravity_y + gravity_z * gravity_z); 
accelX = acceleration.x - gravity_x/gravityNorm; 
accelY = acceleration.y - gravity_y/gravityNorm; 
accelZ = acceleration.z - gravity_z/gravityNorm; 

même que l'utilisation de
CoreMotion motionManager.deviceMotion.userAcceleration.x; motionManager.deviceMotion.userAcceleration.y; motionManager.deviceMotion.userAcceleration.z;?

Ensuite, selon les mêmes questions, je fais ce qui suit

const float accuracy=10; 
    float accx = (float) ((int) (accelX * accuracy))/ accuracy; 
    float accy= (float) ((int) (accelY * accuracy))/ accuracy; 
    float accz= (float) ((int) (accelZ * accuracy))/ accuracy; 

pour les valeurs d'arrondi, puis, comme je le pense, j'obtenir la vitesse actuelle

float dx = accx*9.81+prevX*9.81; 
float dy = accy*9.81+prevY*9.81; 
float dz = accz*9.81+prevZ*9.81; 

speed_after_x = dx/2*myAccelerometer.updateInterval+speed_before_x; 
speed_after_y = dy/2*myAccelerometer.updateInterval+speed_before_y; 
speed_after_z = dz/2*myAccelerometer.updateInterval+speed_before_z; 

selon iphone accelerometer speed and distance
puis

prevX=accx; 
    prevY=accy; 
    prevZ=accz; 

    speed_before_x=speed_after_x; 
    speed_before_y=speed_after_y; 
    speed_before_z=speed_after_z; 

et enfin de calculer spe ed comme vecteur de longueur

float speed = sqrt(speed_after_x*speed_after_x+speed_after_y*speed_after_y+speed_after_z*speed_after_z); 
    if (max_speed<speed) max_speed = speed; 

Mais la valeur de la vitesse, qui est dans l'étiquette dire contenant, augmente toujours. Je veux dire que si je déplaçais l'appareil et que je m'arrêtais, la valeur de vitesse ne passe pas à 0. L'accélération ne se compense-t-elle pas à 0?

+0

Est-ce que cela ne s'annule pas: '((int) (précision AccelX *))/précision;'. Comme ((10 * 100)/100 == 10. Si votre intention est d'arrondir le nombre et de le renvoyer à un flotteur, il y a de meilleures façons de le faire: – Diziet

+0

la précision est de 10, pour éviter les variations rapides des valeurs d'accélération – Aft3rmath

+0

Oui, mais multiplier un nombre puis diviser par le même nombre équivaut à ne rien faire (A * B)/B = A. – Diziet

Répondre

11

Voici l'exemple de code que j'ai réussi à masquer. Je vais le mettre ici pour l'instant:

// 
// ViewController.m 
// Acce 
// 
// Created by Diziet on 14/05/2012. 
// Copyright (c) 2012 __MyCompanyName__. All rights reserved. 
// 

#import "ViewController.h" 

@interface ViewController() { 
    UIAccelerationValue gravX; 
    UIAccelerationValue gravY; 
    UIAccelerationValue gravZ; 
    UIAccelerationValue prevVelocity; 
    UIAccelerationValue prevAcce; 
} 

@property (strong) UIAccelerometer *sharedAcc; 

@end 

@implementation ViewController 

@synthesize sharedAcc = _sharedAcc; 

#define kAccelerometerFrequency  50.0 //Hz 
#define kFilteringFactor 0.1 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 
    self.sharedAcc = [UIAccelerometer sharedAccelerometer]; 
    self.sharedAcc.delegate = self; 
    self.sharedAcc.updateInterval = 1/kAccelerometerFrequency; 

    gravX = gravY = gravZ = prevVelocity = prevAcce = 0.f; 
} 

- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 
    // Release any retained subviews of the main view. 
} 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 
} 

- (UIAccelerationValue)tendToZero:(UIAccelerationValue)value { 
    if (value < 0) { 
     return ceil(value); 
    } else { 
     return floor(value); 
    } 
} 

#define kAccelerometerFrequency  50.0 //Hz 
#define kFilteringFactor 0.1 
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration { 
    gravX = (acceleration.x * kFilteringFactor) + (gravX * (1.0 - kFilteringFactor)); 
    gravY = (acceleration.y * kFilteringFactor) + (gravY * (1.0 - kFilteringFactor)); 
    gravZ = (acceleration.z * kFilteringFactor) + (gravZ * (1.0 - kFilteringFactor)); 

    UIAccelerationValue accelX = acceleration.x - ((acceleration.x * kFilteringFactor) + (gravX * (1.0 - kFilteringFactor))); 

    UIAccelerationValue accelY = acceleration.y - ((acceleration.y * kFilteringFactor) + (gravY * (1.0 - kFilteringFactor))); 
    UIAccelerationValue accelZ = acceleration.z - ((acceleration.z * kFilteringFactor) + (gravZ * (1.0 - kFilteringFactor))); 
    accelX *= 9.81f; 
    accelY *= 9.81f; 
    accelZ *= 9.81f; 
    accelX = [self tendToZero:accelX]; 
    accelY = [self tendToZero:accelY]; 
    accelZ = [self tendToZero:accelZ]; 

    UIAccelerationValue vector = sqrt(pow(accelX,2)+pow(accelY,2)+pow(accelZ, 2)); 
    UIAccelerationValue acce = vector - prevVelocity; 
    UIAccelerationValue velocity = (((acce - prevAcce)/2) * (1/kAccelerometerFrequency)) + prevVelocity; 

    NSLog(@"X %g Y %g Z %g, Vector %g, Velocity %g",accelX,accelY,accelZ,vector,velocity); 

    prevAcce = acce; 
    prevVelocity = velocity; 
} 

@end 

Il faudra modifier pour vos besoins, d'autant plus que je suis juste jeter les valeurs loin par la suite. La valeur résultante 'vélocité' enregistrée en tant que 'Vitesse' tend vers des valeurs négatives extrêmement faibles après que les événements d'accélération ont cessé, par ex. * 10^-17. Donc oui, c'est pratiquement nul dans mon livre. Vous voudrez faire quelques arrondis là-bas et probablement même augmenter les valeurs. Je ne pense pas que je pourrais l'obtenir plus haut que 0,2 ou 0,3 mais encore une fois je ne veux pas jeter mon téléphone à travers la pièce (pour l'instant).

+0

Je ne pense pas, parce que j'ai ajouté ce multiplicateur après avoir découvert le problème, et il est utilisé pour convertir G-mesures en m par seconde – Aft3rmath

+0

Ce n'est pas le * 9,81 Je me demande à propos de , c'était un 'aussi'/de côté. C'est le fait que vous ajoutez accx à prevX. Si prevX ne peut pas être négatif, ce que je ne pense pas que ce soit selon vos calculs, vous obtiendrez une valeur d'accélération en constante augmentation. Vous devez avoir une certaine multiplication de la valeur existante, de sorte que si l'accélération du moment actuel dans un axe particulier est zéro, l'accélération que vous enregistrez sera nulle. Je vais mettre cela dans la réponse. – Diziet

+0

pourquoi prevX ne peut pas être négatif? 'PrevX = accx; prevY = accy; prevZ = accz; 'accx peut être négatif.J'ajoute accx à prevX en fonction de 'velocity [i] = (accélération [i] + accélération [i-1])/2 * intervalle + vitesse [i-1]' – Aft3rmath

Questions connexes