振動の波形を分析する

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 とともに使用して、ハプティクス エフェクトを作成できます。

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

隣接するグラフは、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 までほぼ直線的に増加します。
人間の触覚認識検出のしきい値。

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

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

振動強度の人間の知覚(知覚測定値)は、振動振幅(物理パラメータ)と比例して増加しません。知覚される強度は、感覚レベル(SL)で表されます。これは、同じ周波数で検出しきい値を超える dB 量として定義されます。

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

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

ここで、振幅 dB は、特定の周波数における SL と検出しきい値(隣接するグラフの垂直軸の値)の合計です。

隣接するグラフは、10、20、30、40、50 dB SL の振動加速度レベルと、人間の触覚認識検出しきい値(0 dB SL)を時間周波数の関数として示しています。データは、Verrillo, R. の図 8 から推定されています。T. らによる 1969 年の論文「バイブレーション タッチ 刺激の感覚の強さ」

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

Android は、BasicEnvelopeBuilder でこの変換を自動的に処理します。この変換では、値を感覚レベル空間(dB SL)の正規化された強度として取得し、出力加速度に変換します。一方、WaveformEnvelopeBuilder は、この変換を適用せず、代わりに加速度空間(G)で正規化された出力加速度振幅として値を取得します。Envelope 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));

次のグラフは、上記のコード スニペットに相当する入力波形と出力加速度を示しています。パターンの振幅が急激に変化すると(0ms、150ms、200ms、250ms、700ms で変化)、加速度は急激にではなく、徐々に増加します。また、振幅のステップ変化ごとにオーバーシュートが発生し、入力振幅が突然 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 に関する知識が必要です。最良の結果を得るには、デバイスの事前作成された波形とプラットフォーム提供の定数を使用します。これにより、次のことができます。

  • クリア エフェクトとプリミティブを実行します。
  • 連結して新しいハプティクス エフェクトを作成します。

これらの事前定義されたハプティクス定数とプリミティブを使用すると、高品質のハプティクス エフェクトを作成しながら、作業を大幅に高速化できます。