振動の波形を分析する

Android デバイスで最も一般的なバイブレーション アクチュエータは、リニア共振アクチュエータ(LRA)です。LRA は、反応しないガラス面でボタンをクリックしたときの感触をシミュレートします。クリアで鮮明なクリック フィードバック信号は、通常 10 ~ 20 ミリ秒の長さです。この感覚により、ユーザーの操作がより自然に感じられます。仮想キーボードの場合、このクリック フィードバックにより、入力速度が向上し、エラーが減少します。

LRA には、一般的な共振周波数がいくつかあります。

  • 一部の LRA の共振周波数は 200 ~ 300 Hz の範囲にあり、これは人間の皮膚が振動に最も敏感な周波数と一致します。この周波数帯域の振動は、通常、滑らか、鋭い、貫通する、と表現されます。
  • 他のモデルの LRA の共振周波数は 150 Hz 程度と低く、感覚は質的に柔らかく、より充実したものになります。
コンポーネントは、上から順に、カバー、プレート、中央の磁石、2 つの側面の磁石、質量、2 つのバネ、コイル、フレキシブル回路、ベース、接着剤で構成されています。
リニア共振アクチュエータ(LRA)のコンポーネント。

2 つの異なる周波数で同じ入力電圧が与えられた場合、振動出力の振幅は異なる可能性があります。周波数が LRA の共振周波数から離れるほど、振動振幅は小さくなります。

特定のデバイスの触覚効果では、バイブレーション アクチュエータとそのドライバの両方が使用されます。オーバードライブ機能とアクティブ ブレーキング機能を含むハプティクス ドライバは、LRA の立ち上がり時間とリンギングを短縮し、よりレスポンスがよくクリアなバイブレーションを実現します。

バイブレーターの出力加速度

周波数と出力加速度のマッピング(FOAM)は、特定の振動周波数(ヘルツ単位)で達成可能な最大出力加速度(G ピーク単位)を表します。Android 16(API レベル 36)以降では、プラットフォームが VibratorFrequencyProfile を通じてこのマッピングの組み込みサポートを提供します。このクラスは、基本エンベロープ API と高度なエンベロープ API とともに、触覚効果の作成に使用できます。

ほとんどの LRA モーターの FOAM には、通常は共振周波数付近に 1 つのピークがあります。一般に、周波数がこの範囲から外れると、加速度は指数関数的に減少します。この曲線は対称ではなく、モーターの損傷を防ぐために共振周波数の付近で平坦になることがあります。

隣のプロットは、LRA モーターの FOAM の例を示しています。

周波数が約 120 Hz に増加すると、加速度は指数関数的に増加します。その後、加速度は 180 Hz 程度まで安定し、その後は減少します。
LRA モーターの FOAM の例。

人間の知覚検出のしきい値

人間の知覚検出のしきい値とは、人が確実に検出できる振動の最小加速度を指します。このレベルは、振動の周波数によって異なります。

隣のプロットは、人間の触覚認識検出のしきい値を加速度で表したもので、時間周波数の関数として示されています。しきい値データは、Bolanowski Jr. の図 1 の変位しきい値から変換されます。S. J. らの 1988 年の記事「Four channels mediate the mechanical aspects of touch.」

Android は BasicEnvelopeBuilder でこのしきい値を自動的に処理します。これにより、すべてのエフェクトが、人間の知覚検出のしきい値を少なくとも 10 dB 超える振動振幅を生成する周波数範囲を使用していることが確認されます。

周波数が約 20 Hz まで増加すると、人間による検出の閾値は対数的に上昇し、約 -35 dB になります。しきい値は 200 Hz 程度まで一定で、その後 -20 dB までほぼ直線的に増加します。
人間の触覚認識検出のしきい値。

オンライン チュートリアルでは、加速度振幅と変位振幅の間の変換について詳しく説明しています。

バイブレーションの加速度レベル

振動の強度に対する人間の知覚(知覚の尺度)は、振動の振幅(物理パラメータ)に比例して増加しません。知覚される強度は、同じ周波数での検出閾値を超える dB 量として定義される感覚レベル(SL)によって特徴付けられます。

対応する振動加速度振幅(G ピーク)は次のように計算できます。

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

ここで、振幅 dB は、特定の周波数における SL と検出閾値(隣接するプロットの縦軸の値)の合計です。

隣のプロットは、10、20、30、40、50 dB SL の振動加速度レベルと、人間の触覚認識検出のしきい値(0 dB SL)を時間周波数の関数として示しています。このデータは、Verrillo, R. の図 8 から推定されています。T. らの 1969 年の記事「Sensation magnitude of vibrotactile stimuli.」を参照してください。

希望する体感レベルが上がると、必要な加速度(dB)もほぼ同じ量だけ上がります。たとえば、100 Hz の振動の 10 dB 感覚レベルは、-30 dB ではなく -20 dB 程度です。
バイブレーションの加速度レベル。

Android は、BasicEnvelopeBuilder でこの変換を自動的に処理します。この BasicEnvelopeBuilder は、感覚レベル空間(dB SL)で正規化された強度として値を取得し、それらを出力加速度に変換します。一方、WaveformEnvelopeBuilder はこの変換を適用せず、代わりに加速度空間(Gs)で正規化された出力加速度振幅として値を取得します。エンベロープ API は、デザイナーやデベロッパーがバイブレーションの強さの変化を考えるとき、知覚される強度が区分的線形エンベロープに従うことを想定しています。

デバイスのデフォルトの波形平滑化

例として、汎用デバイスでのカスタム波形パターンの動作を考えてみましょう。

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

次のプロットは、上記のコード スニペットに対応する入力波形と出力加速度を示しています。パターンに振幅のステップ変化があるたびに(0 ミリ秒、150 ミリ秒、200 ミリ秒、250 ミリ秒、700 ミリ秒)、加速度は急激ではなく徐々に増加します。また、振幅の各ステップ変化でオーバーシュートが発生し、入力振幅が突然 0 に低下すると、少なくとも 50 ミリ秒続くリンギングが目に見える形で発生します。

ステップ関数の入力波形のプロット。
レベル間のより自然なトランジションを示す、実際の測定波形のプロット。

ハプティクス パターンの改善

オーバーシュートを回避し、リンギング時間を短縮するには、振幅をより緩やかに変更します。以下に、改訂版の波形と加速度プロットを示します。

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

追加のステップを含む入力波形のプロット。
測定された波形のプロット。よりスムーズなトランジションを示しています。

より複雑な触覚効果を作成する

満足のいくクリック レスポンスの他の要素はより複雑で、デバイスで使用される LRA に関する知識が必要です。最適な結果を得るには、デバイスの事前作成された波形とプラットフォーム提供の定数を使用します。これにより、次のことが可能になります。

  • クリア効果とプリミティブを実行します。
  • それらを連結して、新しい触覚効果を作成します。

これらの事前定義されたハプティクス定数とプリミティブを使用すると、高品質のハプティクス効果を作成しながら、作業を大幅にスピードアップできます。