Analyser les formes d'ondes de vibration

Les actionneurs de vibration les plus courants sur les appareils Android sont les actionneurs résonnants linéaires (LRA). Les LRA simulent la sensation d'un clic sur un bouton sur une surface en verre qui ne répond pas. Un signal de retour clair et net dure généralement entre 10 et 20 millisecondes. Cette sensation rend les interactions des utilisateurs plus naturelles. Pour les claviers virtuels, ce retour de clic peut augmenter la vitesse de frappe et réduire les erreurs.

Les LRA ont quelques fréquences de résonance courantes :

  • Certains LRA avaient des fréquences de résonance comprises entre 200 et 300 Hz, ce qui correspond à la fréquence à laquelle la peau humaine est la plus sensible aux vibrations. Les vibrations de cette gamme de fréquences sont généralement décrites comme douces, fortes et pénétrantes.
  • D'autres modèles d'actionneurs de résonance linéaire ont des fréquences de résonance plus basses, autour de 150 Hz. La sensation est qualitativement plus douce et plus pleine (en dimension).
Les composants comprennent, de haut en bas, un couvercle, une plaque, un aimant central, deux aimants latéraux, une masse, deux ressorts, une bobine, un circuit flexible, une base et un adhésif.
Composants d'un actionneur résonant linéaire (LRA).

Pour une même tension d'entrée à deux fréquences différentes, les amplitudes de vibration peuvent être différentes. Plus la fréquence est éloignée de la fréquence de résonance du LRA, plus l'amplitude de ses vibrations est faible.

Les effets haptiques d'un appareil donné utilisent à la fois l'actionneur de vibration et son pilote. Les pilotes haptiques qui incluent des fonctionnalités d'overdrive et de freinage actif peuvent réduire le temps de montée et la résonance des LRA, ce qui permet d'obtenir une vibration plus réactive et plus claire.

Accélération de la sortie du vibreur

Le mappage de la fréquence à l'accélération de sortie (FOAM) décrit l'accélération de sortie maximale pouvant être atteinte (en G crête) à une fréquence de vibration donnée (en Hertz). À partir d'Android 16 (niveau d'API 36), la plate-forme fournit une prise en charge intégrée de ce mappage via VibratorFrequencyProfile. Vous pouvez utiliser cette classe, ainsi que les API d'enveloppe de base et avancées, pour créer des effets haptiques.

La plupart des moteurs LRA ont un seul pic dans leur FOAM, généralement près de leur fréquence de résonance. L'accélération diminue généralement de manière exponentielle à mesure que la fréquence s'écarte de cette plage. La courbe peut ne pas être symétrique et peut présenter un plateau autour de la fréquence de résonance pour protéger le moteur contre les dommages.

Le graphique adjacent montre un exemple de FOAM pour un moteur LRA.

À mesure que la fréquence augmente jusqu'à environ 120 Hz, l'accélération augmente de manière exponentielle. L'accélération reste ensuite stable jusqu'à environ 180 Hz, après quoi elle diminue.
Exemple de FOAM pour un moteur LRA.

Seuil de détection de la perception humaine

Le seuil de détection de la perception humaine fait référence à l'accélération minimale d'une vibration qu'une personne peut détecter de manière fiable. Ce niveau varie en fonction de la fréquence de vibration.

Le graphique adjacent montre le seuil de détection de la perception haptique humaine, en accélération, en fonction de la fréquence temporelle. Les données de seuil sont converties à partir du seuil de déplacement de la figure 1 de Bolanowski Jr., S. Article de J. et al. publié en 1988, "Four channels mediate the mechanical aspects of touch.".

Android gère automatiquement ce seuil dans BasicEnvelopeBuilder, qui vérifie que tous les effets utilisent une gamme de fréquences produisant des amplitudes de vibration qui dépassent le seuil de détection de la perception humaine d'au moins 10 dB.

À mesure que la fréquence augmente jusqu'à environ 20 Hz, le seuil de détection humaine augmente de manière logarithmique jusqu'à environ -35 dB. Le seuil reste stable jusqu'à environ 200 Hz, après quoi il augmente de manière à peu près linéaire jusqu'à -20 dB.
Seuil de détection de la perception haptique humaine.

Un tutoriel en ligne explique plus en détail la conversion entre l'amplitude d'accélération et l'amplitude de déplacement.

Niveaux d'accélération des vibrations

La perception humaine de l'intensité des vibrations, une mesure de perception, ne croît pas de manière linéaire avec l'amplitude des vibrations, un paramètre physique. L'intensité perçue est caractérisée par le niveau de sensation (SL), qui est défini comme une quantité de dB au-dessus du seuil de détection à la même fréquence.

L'amplitude d'accélération des vibrations correspondante (en G crête) peut être calculée comme suit :

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

…où l'amplitude en dB est la somme du niveau de source et du seuil de détection (la valeur le long de l'axe vertical dans le graphique adjacent) à une fréquence donnée.

Le graphique ci-contre montre les niveaux d'accélération des vibrations à 10, 20, 30, 40 et 50 dB SL, ainsi que le seuil de détection de la perception haptique humaine (0 dB SL), en fonction de la fréquence temporelle. Les données sont estimées à partir de la figure 8 de Verrillo, R. T., et al.'s 1969 article, "Sensation magnitude of vibrotactile stimuli.".

À mesure que le niveau de sensation souhaité augmente, l'accélération requise, en dB, augmente à peu près dans les mêmes proportions. Par exemple, le seuil de sensation de 10 dB pour une vibration de 100 Hz est d'environ -20 dB, au lieu de -30 dB.
Niveaux d'accélération du vibreur.

Android gère automatiquement cette conversion dans BasicEnvelopeBuilder, qui prend des valeurs sous forme d'intensités normalisées dans l'espace de niveau de sensation (dB SL) et les convertit en accélération de sortie. WaveformEnvelopeBuilder, en revanche, n'applique pas cette conversion et prend plutôt les valeurs comme amplitudes d'accélération de sortie normalisées dans l'espace d'accélération (Gs). L'API d'enveloppe suppose que, lorsqu'un concepteur ou un développeur pense aux changements d'intensité des vibrations, il s'attend à ce que l'intensité perçue suive une enveloppe linéaire par morceaux.

Lissage par défaut de la forme d'onde sur les appareils

Pour illustrer cela, examinons le comportement d'un modèle de forme d'onde personnalisé sur un appareil générique :

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));

Les graphiques suivants montrent la forme d'onde d'entrée et l'accélération de sortie correspondant aux extraits de code précédents. Notez que l'accélération augmente progressivement, et non soudainement, chaque fois qu'il y a un changement d'amplitude dans le modèle, c'est-à-dire à 0 ms, 150 ms, 200 ms, 250 ms et 700 ms. Il existe également un dépassement à chaque changement d'amplitude, ainsi qu'une oscillation visible qui dure au moins 50 ms lorsque l'amplitude d'entrée chute soudainement à 0.

Graphique de la forme d'onde d'entrée de la fonction échelon.
Graphique de la forme d'onde mesurée, montrant des transitions plus naturelles entre les niveaux.

Amélioration du schéma haptique

Pour éviter le dépassement et réduire le temps de résonance, modifiez les amplitudes plus progressivement. Vous trouverez ci-dessous les graphiques de forme d'onde et d'accélération de la version révisée :

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));

Graphique de la forme d'onde d'entrée avec des étapes supplémentaires.
Graphique de la forme d'onde mesurée, montrant des transitions plus fluides.

Créer des effets haptiques plus complexes

D'autres éléments d'une réponse de clic satisfaisante sont plus complexes et nécessitent une certaine connaissance du moteur linéaire résonant utilisé dans un appareil. Pour de meilleurs résultats, utilisez les formes d'onde préfabriquées de l'appareil et les constantes fournies par la plate-forme, qui vous permettent de faire ce qui suit :

  • Effectuez des effets clairs et des primitives.
  • Concaténez-les pour composer de nouveaux effets haptiques.

Ces constantes et primitives haptiques prédéfinies peuvent accélérer considérablement votre travail lors de la création d'effets haptiques de haute qualité.