Самые распространенные вибромоторы на устройствах Android – линейные резонансные приводы (LRA). Линейные резонансные приводы имитируют нажатие кнопки на стеклянной поверхности, которая в противном случае не реагировала бы на прикосновения. Четкий и ясный сигнал обратной связи при нажатии обычно длится от 10 до 20 миллисекунд. Это делает взаимодействие с устройством более естественным. При использовании виртуальной клавиатуры обратная связь при нажатии клавиш может повысить скорость набора текста и снизить количество ошибок.
У линейных резонансных приводов есть несколько распространенных резонансных частот:
- У некоторых линейных резонансных приводов резонансная частота находилась в диапазоне 200–300 Гц, который совпадает с частотой, при которой кожа человека наиболее чувствительна к вибрации. Вибрации в этом диапазоне частот обычно описываются как плавные, резкие и проникающие.
- У других моделей линейных резонансных приводов резонансная частота ниже – около 150 Гц. Ощущения от вибрации более мягкие и объемные.
При одинаковом входном напряжении на двух разных частотах амплитуда вибрации может быть разной. Чем дальше частота от резонансной частоты LRA, тем ниже амплитуда вибрации.
В тактильных эффектах устройства используются как вибрационный привод, так и его драйвер. Вибромоторы с функцией форсажа и активного торможения могут сократить время нарастания и звонкость линейных резонансных приводов, что приводит к более быстрому и четкому виброотклику.
Ускорение вибратора
Сопоставление частоты и выходного ускорения (FOAM) описывает максимальное достижимое выходное ускорение (в пиковых значениях G) при заданной частоте вибрации (в герцах). В Android 16 (уровень API 36) и более поздних версиях платформа предоставляет встроенную поддержку этого сопоставления с помощью VibratorFrequencyProfile. Этот класс можно использовать вместе с API basic и advanced для создания тактильных эффектов.
У большинства вибромоторов с линейным резонансным приводом в функции FOAM есть один пик, обычно вблизи резонансной частоты. Ускорение обычно уменьшается по экспоненте при отклонении частоты от этого диапазона. Кривая может быть несимметричной и иметь плато в области резонансной частоты, чтобы защитить двигатель от повреждений.
На соседнем графике показан пример FOAM для двигателя LRA.
Порог обнаружения восприятия человека
Порог восприятия вибрации – это минимальное ускорение вибрации, которое человек может надежно обнаружить. Уровень вибрации зависит от ее частоты.
На соседнем графике показан порог обнаружения тактильного восприятия человеком в зависимости от временной частоты. Пороговые значения данных были преобразованы из пороговых значений смещения, указанных на рисунке 1 в работе Болановского-младшего. S. Статья 1988 года J. et al. "Four channels mediate the mechanical aspects of touch".
Android автоматически обрабатывает этот порог в BasicEnvelopeBuilder, проверяя, чтобы все эффекты использовали диапазон частот, который создает амплитуду вибрации, превышающую порог восприятия человеком не менее чем на 10 дБ.
В онлайн-руководстве также объясняется, как перевести амплитуду ускорения в амплитуду смещения.
Уровни ускорения вибрации
Человеческое восприятие интенсивности вибрации (перцептивный параметр) не растет линейно с амплитудой вибрации (физический параметр). Воспринимаемая интенсивность характеризуется уровнем ощущения (SL), который определяется как количество децибел выше порога обнаружения на той же частоте.
Соответствующая амплитуда ускорения вибрации (в G peak) может быть рассчитана следующим образом:
…где амплитуда в дБ – это сумма уровня звукового давления и порога обнаружения (значение на вертикальной оси на соседнем графике) на определенной частоте.
На соседнем графике показаны уровни ускорения вибрации при 10, 20, 30, 40 и 50 дБ SL, а также порог обнаружения тактильного восприятия человека (0 дБ SL) в зависимости от временной частоты. Данные получены на основе рисунка 8 в работе Verrillo, R. Статья Т. и других авторов 1969 года "Sensation magnitude of vibrotactile stimuli".
Android автоматически выполняет преобразование в BasicEnvelopeBuilder, которое принимает значения в виде нормализованной интенсивности в пространстве уровня ощущений (дБ УО) и преобразует их в выходное ускорение. WaveformEnvelopeBuilder, напротив, не применяет эту конверсию и принимает значения в качестве нормализованных выходных амплитуд ускорения в пространстве ускорения (Gs). API Envelope предполагает, что при изменении силы вибрации дизайнер или разработчик ожидает, что воспринимаемая интенсивность будет следовать кусочно-линейной огибающей.
Сглаживание формы волны по умолчанию на устройствах
Например, рассмотрим, как пользовательский шаблон звуковой волны будет работать на обычном устройстве:
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 мс. Кроме того, на каждом этапе изменения амплитуды наблюдается перерегулирование, а при резком падении амплитуды до нуля заметен звон, который длится не менее 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 // Don't 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; // Don't repeat.
vibrator.vibrate(VibrationEffect.createWaveform(timings, amplitudes, repeatIndex));
Создание более сложных тактильных эффектов
Другие элементы ответа на клик более сложны и требуют знания LRA, используемого в устройстве. Для наилучших результатов используйте встроенные в устройство формы волны и константы, предоставленные платформой. Это позволит вам:
- Выполнять четкие эффекты и примитивы.
- Объединяйте их, чтобы создавать новые тактильные эффекты.
Эти константы и примитивы помогут вам создавать высококачественные тактильные эффекты гораздо быстрее.