振动执行器入门

设计 Android 设备上的触觉效果之前,了解振动执行器的工作原理会有所帮助。

Illustration of the components of a Haptic LRA

最常见的振动执行器是线性谐振执行器 (LRA)。每个 LRA 由一个线圈压在连接到弹簧的磁性运动质量上组成。施加到线圈的交流电压会产生电磁力,导致质量移动。弹簧提供恢复力,使质量返回到其起始位置。质量的来回运动导致 LRA 振动。它们在输出最大的谐振频率下具有谐振频率。

在两个不同频率下施加相同的输入电压时,振动输出幅度可能不同。频率越远离 LRA 的谐振频率,其振动幅度就越低。

LRA 在设备中的一个常见功能是在无响应的玻璃表面上模拟按钮点击的感觉。它有助于使用户交互感觉更自然。当应用于虚拟键盘上的打字时,点击反馈可以提高打字速度并减少错误。清晰而干脆的点击反馈信号通常持续时间小于 10 到 20 毫秒。实现良好的点击需要了解设备中使用的 LRA。这就是为什么依赖预制波形可以为点击提供最佳反馈的原因。无论何时需要点击反馈,您都可以将它们与平台提供的常量一起使用。

设备中可实现的触觉效果由振动执行器及其驱动程序共同决定。包括过压和主动制动功能的触觉驱动程序可以减少 LRA 的上升时间和振铃,从而实现更灵敏、更清晰的振动。为了说明,让我们看看自定义波形模式在通用设备上的行为。

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 // Do not 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 // Do not repeat.

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

下图显示了上面显示的代码片段对应的波形。

Plot of step function input waveform

相应的加速度如下所示

Plot of actual measured waveform, showing more organic transitions between levels

请注意,每当模式的幅度发生阶跃变化时(例如,在 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));

Plot of input waveform with additional steps

Plot of measured waveform, showing smoother transitions

因此,在 Android 设备上创建触觉效果需要做的不仅仅是提供频率和幅度值。在没有完全访问振动执行器和驱动程序的工程规范的情况下,从头设计触觉效果并非易事。Android API 提供了允许您执行以下操作的常量

  • 执行清晰的效果和基元

  • 将它们连接起来以组合新的触觉效果。

这些预定义的触觉常量和基元可以大大加快您的工作速度,同时确保高质量的触觉效果。