Analisar formas de onda de vibração

Os atuadores de vibração mais comuns em dispositivos Android são atuadores lineares ressonantes (LRAs, na sigla em inglês). Os LRAs simulam a sensação de um clique de botão em uma superfície de vidro que não responde. Um sinal de feedback de clique claro e nítido geralmente dura entre 10 e 20 milissegundos. Essa sensação deixa as interações do usuário mais naturais. Para teclados virtuais, esse feedback de clique pode aumentar a velocidade de digitação e reduzir erros.

Os LRAs têm algumas frequências de ressonância comuns:

  • Alguns LRAs tinham frequências de ressonância na faixa de 200 a 300 Hz, que coincide com a frequência em que a pele humana é mais sensível à vibração. A sensação de vibrações nessa faixa de frequência geralmente é descrita como suave, nítida e penetrante.
  • Outros modelos de LRAs têm frequências de ressonância mais baixas, em torno de 150 Hz. A sensação é qualitativamente mais suave e completa (em dimensão).
Os componentes incluem, de cima para baixo, uma tampa, uma placa, um ímã
       central, dois ímãs laterais, massa, duas molas, bobina, circuito flexível, base
       e adesivo.
Componentes de um atuador de ressonância linear (LRA, na sigla em inglês).

Dada a mesma tensão de entrada em duas frequências diferentes, as amplitudes de saída da vibração podem ser diferentes. Quanto mais distante a frequência estiver da frequência ressonante do LRA, menor será a amplitude da vibração.

Os efeitos hápticos de um determinado dispositivo usam o atuador de vibração e o driver dele. Drivers hápticos que incluem recursos de overdrive e frenagem ativa podem reduzir o tempo de subida e o toque de LRAs, resultando em uma vibração mais responsiva e clara.

Aceleração da saída do vibrador

O mapeamento de frequência-aceleração-de-saída (FOAM, na sigla em inglês) descreve a aceleração de saída máxima (em G pico) em uma determinada frequência de vibração (em hertz). A partir do Android 16 (nível 36 da API), a plataforma oferece suporte integrado a esse mapeamento pelo VibratorFrequencyProfile. É possível usar essa classe, junto com as APIs de envelope básico e avançado, para criar efeitos hápticos.

A maioria dos motores de LRA tem um único pico na FOAM, normalmente próximo à frequência ressonante. A aceleração geralmente diminui exponencialmente à medida que a frequência se desvia deste intervalo. A curva pode não ser simétrica e pode apresentar um platô em torno da frequência de ressonância para proteger o motor contra danos.

O gráfico adjacente mostra um exemplo de FOAM para um motor de LRA.

À medida que a frequência aumenta para cerca de 120 Hz, a aceleração aumenta
       exponencialmente. A aceleração permanece constante até cerca de 180 Hz,
       depois diminui.
Exemplo de FOAM para um motor de LRA.

Limite de detecção de percepção humana

O limite de detecção da percepção humana se refere à aceleração mínima de uma vibração que uma pessoa pode detectar com confiabilidade. Esse nível varia de acordo com a frequência da vibração.

O gráfico adjacente mostra o limiar de detecção de percepção tátil humana, em aceleração, como uma função da frequência temporal. Os dados de limite são convertidos do limite de deslocamento na Figura 1 de Bolanowski Jr., S. J., et al.'s 1988 article, "Four channels mediate the mechanical aspects of touch.".

O Android processa automaticamente esse limite no BasicEnvelopeBuilder, que verifica se todos os efeitos usam um intervalo de frequência que produz amplitudes de vibração que excedam o limite de detecção de percepção humana em pelo menos 10 dB.

À medida que a frequência aumenta para cerca de 20 Hz, o limiar de detecção humana
       aumenta de forma logarítmica para cerca de -35 dB. O limite permanece estável
       até cerca de 200 Hz, depois aumenta de forma aproximadamente linear até
       -20 dB.
Limite de detecção da percepção tátil humana.

Um tutorial on-line explica melhor a conversão entre a amplitude de aceleração e a amplitude de deslocamento.

Níveis de aceleração da vibração

A percepção humana da intensidade da vibração, uma medida de percepção, não aumenta linearmente com a amplitude da vibração, um parâmetro físico. A intensidade percebida é caracterizada pelo nível de sensação (SL, na sigla em inglês), que é definido como uma quantidade de dB acima do limite de detecção na mesma frequência.

A amplitude de aceleração de vibração correspondente (em G de pico) pode ser calculada da seguinte maneira:

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

...em que o dB de amplitude é a soma do SL e do limite de detecção, ou seja, o valor ao longo do eixo vertical no gráfico adjacente, em uma frequência específica.

O gráfico adjacente mostra os níveis de aceleração da vibração em 10, 20, 30, 40 e 50 dB SL, junto com o limiar de detecção de percepção tátil humana (0 dB SL), como uma função da frequência temporal. Os dados são estimados com base na Figura 8 em Verrillo, R. T., et al.'s 1969 article, "Sensation magnitude of vibrotactile stimuli.".

À medida que o nível de sensação desejado aumenta, a aceleração necessária,
       em dB, aumenta aproximadamente o mesmo valor. Por exemplo, o nível de sensação de 10 dB
       para uma vibração de 100 Hz é de aproximadamente -20 dB, em vez de
       -30 dB.
Níveis de aceleração da vibração.

O Android processa essa conversão automaticamente no BasicEnvelopeBuilder, que recebe valores como intensidades normalizadas no espaço do nível de sensação (dB SL) e os converte em aceleração de saída. O WaveformEnvelopeBuilder, por outro lado, não aplica essa conversão e recebe valores como amplitudes de aceleração de saída normalizadas no espaço de aceleração (Gs). A API de envelope pressupõe que, quando um designer ou desenvolvedor pensa em mudanças na intensidade da vibração, ele espera que a intensidade percebida siga um envelope linear por partes.

Suavização de forma de onda padrão em dispositivos

Para ilustrar, considere como um padrão de forma de onda personalizada se comporta em um 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));

Os gráficos a seguir mostram a forma de onda de entrada e a aceleração de saída correspondentes aos snippets de código anteriores. A aceleração aumenta gradualmente, não de repente, sempre que há uma mudança de amplitude no padrão, ou seja, em 0 ms, 150 ms, 200 ms, 250 ms e 700 ms. Há também um overshoot em cada mudança de etapa de amplitude, e há um som de campainha visível que dura pelo menos 50 ms quando a amplitude de entrada cai repentinamente para 0.

Gráfico da forma de onda de entrada da função escalonada.
Gráfico da forma de onda medida real, mostrando transições mais orgânicas entre os níveis.

Padrão tátil aprimorado

Para evitar o excesso e reduzir o tempo de toque, mude as amplitudes de forma mais gradual. A seguir, são mostrados os gráficos de forma de onda e aceleração da versão 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 da forma de onda de entrada com etapas adicionais.
Gráfico da forma de onda medida, mostrando transições mais suaves.

Criar efeitos táteis mais complexos

Outros elementos em uma resposta satisfatória de clique são mais complicados, exigindo algum conhecimento do LRA usado em um dispositivo. Para melhores resultados, use as formas de onda pré-fabricadas do dispositivo e as constantes fornecidas pela plataforma, que permitem fazer o seguinte:

  • Use efeitos claros e primitivos.
  • Faça a concatenação para criar novos efeitos hápticos.

Essas constantes e primitivas pré-definidas podem acelerar muito seu trabalho ao criar efeitos hápticos de alta qualidade.