Analiza las formas de onda de vibración

Los actuadores de vibración más comunes en los dispositivos Android son los actuadores resonantes lineales (LRAs). Los LRA simulan la sensación de hacer clic en un botón en una superficie de vidrio que, de otro modo, no respondería. Una señal de respuesta de clic clara y nítida suele durar entre 10 y 20 milisegundos. Esta sensación hace que las interacciones del usuario se sientan más naturales. En el caso de los teclados virtuales, estos comentarios de clic pueden aumentar la velocidad de escritura y reducir los errores.

Los LRA tienen algunas frecuencias resonantes comunes:

  • Algunos LRA tenían frecuencias resonantes en el rango de 200 a 300 Hz, que coincide con la frecuencia a la que la piel humana es más sensible a la vibración. La sensación de vibraciones en este rango de frecuencia suele describirse como suave, nítida y penetrante.
  • Otros modelos de LRA tienen frecuencias de resonancia más bajas, alrededor de 150 Hz. La sensación es cualitativamente más suave y completa (en dimensión).
Los componentes incluyen, de arriba abajo, una cubierta, una placa, un imán central, 2 imanes laterales, masa, 2 resortes, una bobina, un circuito flexible, una base y un adhesivo.
Componentes de un actuador resonante lineal (LRA).

Dado el mismo voltaje de entrada en dos frecuencias diferentes, las amplitudes de salida de vibración pueden ser diferentes. Cuanto más alejada esté la frecuencia de la frecuencia resonante del LRA, menor será su amplitud de vibración.

Los efectos táctiles de un dispositivo determinado usan el actuador de vibración y su controlador. Los controladores táctiles que incluyen funciones de sobremarcha y frenado activo pueden reducir el tiempo de aumento y el timbre de los LRA, lo que genera una vibración más responsiva y clara.

Aceleración de salida del vibrador

La asignación de frecuencia a aceleración de salida (FOAM) describe la aceleración de salida máxima alcanzable (en G pico) a una frecuencia de vibración determinada (en hercios). A partir de Android 16 (nivel de API 36), la plataforma proporciona compatibilidad integrada con esta asignación a través de VibratorFrequencyProfile. Puedes usar esta clase, junto con las APIs de sobres básicos y avanzados, para crear efectos táctiles.

La mayoría de los motores de LRA tienen un solo pico en su FOAM, por lo general, cerca de su frecuencia resonante. La aceleración generalmente disminuye de forma exponencial a medida que la frecuencia se desvía de este rango. Es posible que la curva no sea simétrica y tenga una meseta alrededor de la frecuencia resonante para proteger el motor del daño.

En el gráfico adyacente, se muestra un ejemplo de FOAM para un motor de LRA.

A medida que la frecuencia aumenta a alrededor de 120 Hz, la aceleración aumenta
       de forma exponencial. Luego, la aceleración se mantiene constante hasta alrededor de 180 Hz, después de lo cual disminuye.
Ejemplo de FOAM para un motor de LRA.

Umbral de detección de percepción humana

El umbral de detección de percepción humana hace referencia a la aceleración mínima de una vibración que una persona puede detectar de forma confiable. Este nivel varía según la frecuencia de vibración.

El gráfico adyacente muestra el umbral de detección de la percepción táctil humana, en aceleración, como una función de la frecuencia temporal. Los datos del umbral se convierten del umbral de desplazamiento en la Figura 1 de Bolanowski Jr., S. J., et al., 1988, “Four channels mediate the mechanical aspects of touch”.

Android controla automáticamente este umbral en BasicEnvelopeBuilder, que verifica que todos los efectos usen un rango de frecuencia que produzca amplitudes de vibración que superen el umbral de detección de percepción humana en al menos 10 dB.

A medida que la frecuencia aumenta a alrededor de 20 Hz, el umbral de detección humana aumenta de forma logarítmica a alrededor de -35 dB. El umbral permanece estable hasta alrededor de 200 Hz, después de lo cual aumenta de forma aproximadamente lineal hasta -20 dB.
Umbral de detección de la percepción táctil humana.

En un instructivo en línea, se explica con más detalle la conversión entre la amplitud de la aceleración y la amplitud del desplazamiento.

Niveles de aceleración de vibración

La percepción humana de la intensidad de la vibración, una medida de percepción, no crece de forma lineal con la amplitud de la vibración, un parámetro físico. La intensidad percibida se caracteriza por el nivel de sensación (SL), que se define como una cantidad de dB por encima del umbral de detección en la misma frecuencia.

La amplitud de aceleración de vibración correspondiente (en G pico) se puede calcular de la siguiente manera:

$$ Amplitude(G) = 10^{Amplitude(db)/20} $$

…en la que la amplitud en dB es la suma de la SL y el umbral de detección (el valor a lo largo del eje vertical en el gráfico adyacente) en una frecuencia en particular.

En el gráfico adyacente, se muestran los niveles de aceleración de vibración a 10, 20, 30, 40 y 50 dB SL, junto con el umbral de detección de percepción táctil humana (0 dB SL), como función de la frecuencia temporal. Los datos se estiman a partir de la figura 8 en Verrillo, R. T., et al., "Sensation magnitude of vibrotactile stimuli", artículo de 1969.

A medida que aumenta el nivel de sensación deseado, la aceleración requerida, en dB, aumenta aproximadamente en la misma cantidad. Por ejemplo, el nivel de sensación de 10 dB para una vibración de 100 Hz es de alrededor de -20 dB, en lugar de -30 dB.
Niveles de aceleración de la vibración.

Android controla automáticamente esta conversión en BasicEnvelopeBuilder, que toma valores como intensidades normalizadas en el espacio de nivel de sensación (dB SL) y los convierte en aceleración de salida. Por otro lado, WaveformEnvelopeBuilder no aplica esta conversión y, en su lugar, toma valores como amplitudes de aceleración de salida normalizadas en el espacio de aceleración (G). La API de envelope supone que, cuando un diseñador o desarrollador piensa en cambios en la intensidad de la vibración, espera que la intensidad percibida siga una envolvente lineal por partes.

Suavización predeterminada de la forma de onda en los dispositivos

A modo de ejemplo, considera cómo se comporta un patrón de forma de onda personalizado en un dispositivo genérico:

Kotlin

val timings: LongArray = longArrayOf(50, 50, 50, 50, 50, 100, 350, 250)
val amplitudes: IntArray = intArrayOf(77, 79, 84, 99, 143, 255, 0, 255)
val repeatIndex = -1 // Don't repeat.

vibrator.vibrate(VibrationEffect.createWaveform(timings, amplitudes, repeatIndex))

Java

long[] timings = new long[] { 50, 50, 50, 50, 50, 100, 350, 250 };
int[] amplitudes = new int[] { 77, 79, 84, 99, 143, 255, 0, 255 };
int repeatIndex = -1 // Don't repeat.

vibrator.vibrate(VibrationEffect.createWaveform(timings, amplitudes, repeatIndex));

En los siguientes gráficos, se muestran la forma de onda de entrada y la aceleración de salida que corresponden a los fragmentos de código anteriores. Ten en cuenta que la aceleración aumenta gradualmente, no de forma repentina, cada vez que hay un cambio brusco de amplitud en el patrón, es decir, a los 0 ms, 150 ms, 200 ms, 250 ms y 700 ms. También hay un exceso en cada cambio de paso de amplitud, y hay un timbre visible que dura al menos 50 ms cuando la amplitud de entrada cae repentinamente a 0.

Gráfico de la forma de onda de entrada de la función de paso.
Gráfico de la forma de onda medida real, que muestra transiciones más orgánicas entre los niveles.

Patrón táctil mejorado

Para evitar el sobreimpulso y reducir el tiempo de timbre, cambia las amplitudes de forma más gradual. A continuación, se muestran las formas de onda y los gráficos de aceleración de la versión revisada:

Kotlin

val timings: LongArray = longArrayOf(
    25, 25, 50, 25, 25, 25, 25, 25, 25, 25, 75, 25, 25,
    300, 25, 25, 150, 25, 25, 25
)
val amplitudes: IntArray = intArrayOf(
    38, 77, 79, 84, 92, 99, 121, 143, 180, 217, 255, 170, 85,
    0, 85, 170, 255, 170, 85, 0
)
val repeatIndex = -1 // Do not repeat.

vibrator.vibrate(VibrationEffect.createWaveform(timings, amplitudes, repeatIndex))

Java

long[] timings = new long[] {
        25, 25, 50, 25, 25, 25, 25, 25, 25, 25, 75, 25, 25,
        300, 25, 25, 150, 25, 25, 25
    };
int[] amplitudes = new int[] {
        38, 77, 79, 84, 92, 99, 121, 143, 180, 217, 255, 170, 85,
        0, 85, 170, 255, 170, 85, 0
    };
int repeatIndex = -1; // Do not repeat.

vibrator.vibrate(VibrationEffect.createWaveform(timings, amplitudes, repeatIndex));

Gráfico de la forma de onda de entrada con pasos adicionales.
Gráfico de la forma de onda medida, que muestra transiciones más suaves.

Crea efectos táctiles más complejos

Otros elementos de una respuesta satisfactoria al clic son más complejos y requieren cierto conocimiento de la LRA que se usa en un dispositivo. Para obtener los mejores resultados, usa las formas de onda prefabricadas del dispositivo y las constantes proporcionadas por la plataforma, que te permiten hacer lo siguiente:

  • Realiza efectos y elementos primitivos claros.
  • Concatenalos para componer nuevos efectos táctiles.

Estas constantes y primitivas táctiles predefinidas pueden acelerar mucho tu trabajo mientras creas efectos táctiles de alta calidad.