Rilevamento della forza di pressione tramite l’accelerometro

Ieri, nella presentazione del nuovo Garageband per iPad 2, Apple ha dimostrato una caratteristica interessante: il rilevamento della pressione del rubinetto utilizzando l’accelerometro. (Vedi la sezione batteria nella pagina Garageband .)

Mi chiedo come dovrebbe funzionare se l’iPad si stende sul tavolo. Nessun movimento, nessuna accelerazione misurabile, no?

Alcune buone risposte Ecco un codice funzionante. L’ho implementato come sottoclass di UIGestureRecognizer in modo che tu possa semplicemente rilasciarlo e collegarlo a un UIView o UIButton. Una volta triggersto, avrà la “pressione” impostata su un valore tra 0,0f e 2,0f. È ansible impostare opzionalmente le pressioni minima e massima necessarie per il riconoscimento. Godere.

// // 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 

Immagino che il case in alluminio e il tavolo non impediscano movimenti molto piccoli e che il sensore sia molto sensibile.

Oppure, l’esperienza utente di Garage Band è migliore con iPad in piedi sulla Smart Cover.

Beh, semplicemente fai questo esperimento:

apri con XCode l’app per l’esercitazione AccelerometerGraph inclusa nel pacchetto XCode. Quindi avvia l’app (filtro passa-alto, meglio utilizzando il filtro adattivo): vedrai la linea blu cambiare in base alla forza dell’app. Ovviamente questo è influenzato dal tremore nella tabella, che aggiunge rumore alla misura, ma è comunque ansible filtrarlo controllando i dati dell’accelerometro con l’evento touch.

Quindi questo tipo di rilevamento della pressione è ansible usando l’accelerometro.

Tocca il rilevamento della dimensione dell’area? (Tocco più forte, impronta digitale più grande) Tocca la dynamic?

Solo pensando.

viggio24 ha ragione. il rilevamento delle dita funziona bene. (Ho alcuni post qui con la linea banale del codice per ottenerlo). l’unico problema è che non è chiaro quali siano le conseguenze se la spedizione viene abilitata; supponiamo che semplicemente non sarà approvato nel migliore dei casi.

Forse è dovuto al giroscopio più sensibile? In combinazione con i dati dell’accelerometro, è probabilmente ragionevolmente facile determinare anche piccoli cambiamenti nei movimenti. Solo un sospetto. A meno che non ci stia dicendo qualcosa che non sarebbe il primo.

Anche se l’SDK ci espone solo l’area sensibile, credo che l’hardware dello schermo fornisca al sistema operativo molte più informazioni: pixel toccati (utilizzati per il rilevamento dell’area) e durata del touch. Insieme (e sperimentando) possono darti una buona stima della pressione applicata. Sarebbe bello se Apple stesse rilasciando questa stima empirica della pressione agli sviluppatori.

Provalo tu stesso con l’app di esempio AccelerometerGraph. Il dispositivo e il piano del tavolo hanno una rigidità finita, quindi potresti vedere piccoli punti nel grafico.

AGGIUNTO:

Se compili l’esempio di grafico AccelerometerGraph di Apple direttamente dal codice sorgente, puoi aumentare il guadagno sull’asse verticale e vedere i blip per accelerazioni minori.