vibraciones para medir giroscopio celulares casero aplicaciones acelerometro ios iphone objective-c tap

ios - para - acelerometro y giroscopio



Detecta golpes duros en cualquier lugar del iPhone a través del acelerómetro (4)

Así es como lo logré.

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration { if (pause) { return; } if (handModeOn == NO) { if(pocketFlag == NO) return; } // float accelZ = 0.0; // float accelX = 0.0; // float accelY = 0.0; rollingX = (acceleration.x * kFilteringFactor) + (rollingX * (1.0 - kFilteringFactor)); rollingY = (acceleration.y * kFilteringFactor) + (rollingY * (1.0 - kFilteringFactor)); rollingZ = (acceleration.z * kFilteringFactor) + (rollingZ * (1.0 - kFilteringFactor)); float accelX = acceleration.x - rollingX; float accelY = acceleration.y - rollingY; float accelZ = acceleration.z - rollingZ; if((-accelZ >= [senstivity floatValue] && timerFlag) || (-accelZ <= -[senstivity floatValue] && timerFlag)|| (-accelX >= [senstivity floatValue] && timerFlag) || (-accelX <= -[senstivity floatValue] && timerFlag) || (-accelY >= [senstivity floatValue] && timerFlag) || (-accelY <= -[senstivity floatValue] && timerFlag)) { timerFlag = false; addValueFlag = true; timer = [NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector:@selector(timerTick:) userInfo:nil repeats:YES]; } if(addValueFlag) { [self.accArray addObject:[NSNumber numberWithFloat:-accelX]]; [self.accArray addObject:[NSNumber numberWithFloat:-accelY]]; [self.accArray addObject:[NSNumber numberWithFloat:-accelZ]]; } }

Estoy tratando de detectar los toques que podrían estar en cualquier parte del iPhone, no solo en la pantalla del iPhone. Aquí hay un link que muestra que es posible.

Básicamente, lo que quiero hacer es enviar una alerta si el usuario toca 3 veces en el iPhone mientras el teléfono está en su bolsillo. Lo que he logrado es que puedo detectar los 3 toques pero también recibo las falsas alertas en estos casos. 1) si el usuario camina, 2) agita su teléfono 3) corriendo. Necesito solo comprobar si el usuario ha golpeado su iPhone 3 veces.

Aquí está mi código.

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration { if (handModeOn == NO) { if(pocketFlag == NO) return; } float accelZ = 0.0; float accelX = 0.0; float accelY = 0.0; accelX = (acceleration.x * kFilteringFactor) + (accelX * (1.0 - kFilteringFactor)); accelY = (acceleration.y * kFilteringFactor) + (accelY * (1.0 - kFilteringFactor)); accelZ = (acceleration.z * kFilteringFactor) + (accelZ * (1.0 - kFilteringFactor)); self.z.text = [NSString stringWithFormat:@"%0.1f", -accelZ]; if((-accelZ >= [senstivity floatValue] && timerFlag) || (-accelZ <= -[senstivity floatValue] && timerFlag)|| (-accelX >= [senstivity floatValue] && timerFlag) || (-accelX <= -[senstivity floatValue] && timerFlag) || (-accelY >= [senstivity floatValue] && timerFlag) || (-accelY <= -[senstivity floatValue] && timerFlag)) { timerFlag = false; addValueFlag = true; timer = [NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector:@selector(timerTick:) userInfo:nil repeats:YES]; } if(addValueFlag) { if (self.xSwitch.on) { NSLog(@"X sWitch is on"); [self.accArray addObject:[NSNumber numberWithFloat:-accelX]]; } if (self.ySwitch.on) { NSLog(@"Y Switch is on"); [self.accArray addObject:[NSNumber numberWithFloat:-accelY]]; } if (self.zSwitch.on) { NSLog(@"Z Switch is on"); [self.accArray addObject:[NSNumber numberWithFloat:-accelZ]]; } } //} } - (void)timerTick:(NSTimer *)timer1 { [timer1 invalidate]; addValueFlag = false; int count = 0; for(int i = 0; i < self.accArray.count; i++) { if(([[self.accArray objectAtIndex:i] floatValue] >= [senstivity floatValue]) || ([[self.accArray objectAtIndex:i] floatValue] <= -[senstivity floatValue])) { count++; [self playAlarm:@"beep-1" FileType:@"mp3"]; } if(count >= 3) { [self playAlarm:@"06_Alarm___Auto___Rapid_Beeping_1" FileType:@"caf"]; [self showAlert]; timerFlag = true; [self.accArray removeAllObjects]; return; } } [self.accArray removeAllObjects]; timerFlag = true; }

Cualquier ayuda sería realmente apreciada.

Gracias


Debe aplicar un filtro de paso alto a los datos del acelerómetro. Eso le dará solo los picos en la señal: toques agudos.

Hice una búsqueda rápida en "filtro de paso alto de UIAccelerometer" y encontré varios resultados. El código más simple toma un promedio móvil de la entrada del acelerómetro, luego resta ese promedio de la lectura instantánea para encontrar cambios repentinos. Sin duda, también hay métodos más sofisticados.

Una vez que tenga un código que reconozca los toques agudos, deberá elaborar un código que detecte 3 toques agudos seguidos.


Esto, como lo sugiere otra respuesta, tiene que ver con el filtrado de los toques de la corriente de datos del acelerómetro. Las tomas similares a impulsos tendrán un espectrograma característico (combinación de frecuencias) que se puede detectar cuando la respuesta de un filtro adecuado es superior a un umbral.

Esta es una operación muy común en iPhone, le sugiero que consulte la documentación oficial, como here

El código de muestra al que me he vinculado le brinda dos cosas importantes: código de ejemplo oficial para el filtro de paso alto Y una aplicación de muestra que graficará los datos del acelerómetro. Puede usar esto para visualizar sus toques, pasos y saltos, para comprender mejor por qué su filtro responde falsamente.

Además, Internet es una gran fuente de literatura sobre el diseño de filtros: si necesita hacer un filtro de muy alta calidad, es posible que deba consultar la literatura. Sin embargo, creo que un filtro de segundo orden adecuado probablemente sería suficiente.

@implementation HighpassFilter - (id)initWithSampleRate:(double)rate cutoffFrequency:(double)freq { self = [super init]; if (self != nil) { double dt = 1.0 / rate; double RC = 1.0 / freq; filterConstant = RC / (dt + RC); } return self; } - (void)addAcceleration:(UIAcceleration *)accel { double alpha = filterConstant; if (adaptive) { double d = Clamp(fabs(Norm(x, y, z) - Norm(accel.x, accel.y, accel.z)) / kAccelerometerMinStep - 1.0, 0.0, 1.0); alpha = d * filterConstant / kAccelerometerNoiseAttenuation + (1.0 - d) * filterConstant; } x = alpha * (x + accel.x - lastX); y = alpha * (y + accel.y - lastY); z = alpha * (z + accel.z - lastZ); lastX = accel.x; lastY = accel.y; lastZ = accel.z; } - (NSString *)name { return adaptive ? @"Adaptive Highpass Filter" : @"Highpass Filter"; } @end

Es importante destacar que este filtro es independiente de la dirección, ya que solo se filtra la magnitud de la aceleración. Esto es crucial para hacer que la respuesta parezca normal. De lo contrario, los usuarios pueden sentir que tienen que tocar desde diferentes ángulos para encontrar un sweetspot.

En otra nota, si esta tarea es demasiado difícil y complicada, sugiero encarecidamente que capture sus datos (en un archivo WAV, por ejemplo) y utilice uno de los programas de análisis de señales comunes para tener una mejor idea de dónde está yendo mal. Ver Baudline


Prueba este código:

UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)]; longPress.minimumPressDuration = 2; //seconds //longPress.delegate = self; [myButton addGestureRecognizer:longPress];