Detección de la fuerza de presión del grifo usando acelerómetro

Ayer, en la presentación sobre el nuevo Garageband para iPad 2, Apple hizo una demostración de una característica interesante: la detección de la presión del grifo mediante el uso del acelerómetro. (Consulte la sección de tambores en la página de Garageband ).

Me pregunto cómo se supone que debería funcionar si el iPad queda plano sobre la mesa. Sin movimiento, sin aceleración mensurable, ¿no?

Algunas buenas respuestas. Aquí hay un código de trabajo. Implementé esto como una subclase de UIGestureRecognizer para que pueda simplemente colocarlo y adjuntarlo a UIView o UIButton. Una vez activado, tendrá la “presión” configurada en un flotante entre 0.0f y 2.0f. Opcionalmente puede establecer las presiones mínimas y máximas necesarias para reconocer. Disfrutar.

// // CPBPressureTouchGestureRecognizer.h // PressureSensitiveButton // // Created by Anthony Picciano on 3/21/11. // Copyright 2011 Anthony Picciano. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // #import  #define CPBPressureNone 0.0f #define CPBPressureLight 0.1f #define CPBPressureMedium 0.3f #define CPBPressureHard 0.8f #define CPBPressureInfinite 2.0f @interface CPBPressureTouchGestureRecognizer : UIGestureRecognizer  { @public float pressure; float minimumPressureRequired; float maximumPressureRequired; @private float pressureValues[30]; uint currentPressureValueIndex; uint setNextPressureValue; } @property (readonly, assign) float pressure; @property (readwrite, assign) float minimumPressureRequired; @property (readwrite, assign) float maximumPressureRequired; @end // // CPBPressureTouchGestureRecognizer.h // PressureSensitiveButton // // Created by Anthony Picciano on 3/21/11. // Copyright 2011 Anthony Picciano. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // #import  #import "CPBPressureTouchGestureRecognizer.h" #define kUpdateFrequency 60.0f #define KNumberOfPressureSamples 3 @interface CPBPressureTouchGestureRecognizer (private) - (void)setup; @end @implementation CPBPressureTouchGestureRecognizer @synthesize pressure, minimumPressureRequired, maximumPressureRequired; - (id)initWithTarget:(id)target action:(SEL)action { self = [super initWithTarget:target action:action]; if (self != nil) { [self setup]; } return self; } - (id)init { self = [super init]; if (self != nil) { [self setup]; } return self; } - (void)setup { minimumPressureRequired = CPBPressureNone; maximumPressureRequired = CPBPressureInfinite; pressure = CPBPressureNone; [[UIAccelerometer sharedAccelerometer] setUpdateInterval:1.0f / kUpdateFrequency]; [[UIAccelerometer sharedAccelerometer] setDelegate:self]; } #pragma - #pragma UIAccelerometerDelegate methods -(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration { int sz = (sizeof pressureValues) / (sizeof pressureValues[0]); // set current pressure value pressureValues[currentPressureValueIndex%sz] = acceleration.z; if (setNextPressureValue > 0) { // calculate average pressure float total = 0.0f; for (int loop=0; loop= minimumPressureRequired && pressure < = maximumPressureRequired) self.state = UIGestureRecognizerStateRecognized; else self.state = UIGestureRecognizerStateFailed; } } currentPressureValueIndex++; } #pragma - #pragma UIGestureRecognizer subclass methods - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { setNextPressureValue = KNumberOfPressureSamples; self.state = UIGestureRecognizerStatePossible; } - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { self.state = UIGestureRecognizerStateFailed; } - (void)reset { pressure = CPBPressureNone; setNextPressureValue = 0; currentPressureValueIndex = 0; } @end 

Imagino que la carcasa de aluminio y la mesa no impiden movimientos muy pequeños y que el sensor es muy sensible.

O bien, la experiencia de usuario de Garage Band es mejor con iPad parado en Smart Cover.

Bueno, simplemente haz este experimento:

abra con XCode la aplicación tutorial AccelerometerGraph incluida en el paquete XCode. Luego, inicie la aplicación (filtro de paso alto, mejor usando el filtro adaptable): verá que la línea azul cambia según la intensidad de la aplicación. Por supuesto, esto se ve afectado por el temblor en la tabla, que agrega ruido a la medida, pero aún puede filtrarlo al verificar los datos del acelerómetro con el evento táctil.

Entonces este tipo de detección de presión es posible usando el acelerómetro.

¿Detección de tamaño de área de toque? (Grifo más fuerte, huella digital más grande) ¿Dinámica del toque?

Sólo de pensar.

viggio24 tiene razón. la detección del área de los dedos funciona bien. (Tengo algunos mensajes aquí con la línea trivial de código para obtenerlo). el único problema es que no está claro cuáles son las consecuencias si lo habilita; suponemos que simplemente no será aprobado en el mejor de los casos.

Tal vez se deba al giroscopio más sensible? Combinado con los datos del Acelerómetro, es razonablemente fácil determinar incluso pequeños cambios en el movimiento. Sólo una corazonada. A menos que haya algo que no nos estén diciendo, que no sería el primero.

Incluso si el SDK nos expone el área táctil solamente, creo que el hardware de la pantalla proporciona al sistema operativo mucha más información: píxeles tocados (utilizados para la detección de área) y duración del toque. Juntos (y experimentando) pueden darte una buena estimación de la presión aplicada. Sería bueno si Apple publicara esta estimación de presión empírica para los desarrolladores.

Pruébelo usted mismo con la aplicación de muestra AccelerometerGraph. El dispositivo y la superficie de la mesa tienen una rigidez finita, por lo que es posible que vea pequeños puntos en el gráfico.

ADICIONAL:

Si comstack la muestra del gráfico AccelerometerGraph de Apple desde el código fuente usted mismo, puede boost la ganancia en el eje vertical y ver los blips para aceleraciones más pequeñas.