Najpopularniejsze siłowniki wibracyjne w urządzeniach z Androidem to liniowe siłowniki rezonansowe (LRA). LRA symulują kliknięcie przycisku na szklanej powierzchni, która w innym przypadku nie reaguje na dotyk. Wyraźny i krótki sygnał wibracji trwa zwykle od 10 do 20 milisekund. Dzięki temu interakcje użytkownika są bardziej naturalne. W przypadku klawiatur wirtualnych ta wibracja może zwiększyć szybkość pisania i zmniejszyć liczbę błędów.
LRA mają kilka typowych częstotliwości rezonansowych:
- Niektóre LRA mają częstotliwości rezonansowe w zakresie od 200 do 300 Hz, co pokrywa się z częstotliwością, przy której skóra ludzka jest najbardziej wrażliwa na wibracje. Wibracje w tym zakresie częstotliwości są zwykle opisywane jako płynne, ostre i przenikliwe.
- Inne modele LRA mają niższe częstotliwości rezonansowe, około 150 Hz. Wibracje są jakościowo łagodniejsze i pełniejsze (w wymiarze).
Przy tym samym napięciu wejściowym przy 2 różnych częstotliwościach amplitudy wibracji mogą się różnić. Im większa różnica między częstotliwością a częstotliwością rezonansową LRA, tym mniejsza amplituda wibracji.
Efekty dotykowe danego urządzenia wykorzystują zarówno siłownik wibracyjny, jak i jego sterownik. Sterowniki dotykowe, które obejmują funkcje overdrive i aktywnego hamowania, mogą skrócić czas narastania i czas tłumienia LRA, co przekłada się na bardziej responsywne i wyraźne wibracje.
Przyspieszenie wyjściowe wibratora
Mapowanie częstotliwości na przyspieszenie wyjściowe (FOAM) opisuje maksymalne osiągalne przyspieszenie wyjściowe (w G peak) przy danej częstotliwości wibracji (w hercach). Od Androida 16 (API na poziomie 36) platforma zapewnia wbudowaną obsługę tego mapowania za pomocą klasy VibratorFrequencyProfile. Za pomocą tej klasy oraz podstawowych i zaawansowanych interfejsów API obwiedni możesz tworzyć efekty dotykowe.
Większość silników LRA ma pojedynczy pik w FOAM, zwykle w pobliżu częstotliwości rezonansowej. Przyspieszenie zwykle maleje wykładniczo, gdy częstotliwość odbiega od tego zakresu. Krzywa może nie być symetryczna i może mieć płaskowyż wokół częstotliwości rezonansowej, aby chronić silnik przed uszkodzeniem.
Na sąsiednim wykresie przedstawiono przykładowy FOAM dla silnika LRA.
Próg wykrywania percepcji ludzkiej
Próg wykrywania percepcji ludzkiej to minimalne przyspieszenie wibracji, które człowiek może niezawodnie wykryć. Ten poziom różni się w zależności od częstotliwości wibracji.
Na sąsiednim wykresie przedstawiono próg wykrywania percepcji dotykowej przez człowieka w zależności od częstotliwości czasowej. Dane progowe są przekształcane z progu przemieszczenia na rysunku 1 artykułu Bolanowskiego Jr., S. J. i in. z 1988 r. pt. „Four channels mediate the mechanical aspects of touch” (Cztery kanały pośredniczą w mechanicznych aspektach dotyku).
Android automatycznie obsługuje ten próg w klasie BasicEnvelopeBuilder, która sprawdza, czy wszystkie efekty używają zakresu częstotliwości, który generuje amplitudy wibracji przekraczające próg wykrywania percepcji ludzkiej o co najmniej 10 dB.
Samouczek online zawiera dodatkowe informacje o konwersji między amplitudą przyspieszenia a amplitudą przemieszczenia.
Poziomy przyspieszenia wibracji
Percepcja intensywności wibracji przez człowieka, czyli miara percepcji, nie rośnie liniowo z amplitudą wibracji, czyli parametrem fizycznym. Postrzegana intensywność jest charakteryzowana przez poziom odczuwania (SL), który jest definiowany jako wartość w dB powyżej progu wykrywania przy tej samej częstotliwości.
Odpowiednią amplitudę przyspieszenia wibracji (w G peak) można obliczyć w ten sposób:
...gdzie amplituda w dB to suma SL i progu wykrywania – wartość wzdłuż osi pionowej na sąsiednim wykresie – przy określonej częstotliwości.
Na sąsiednim wykresie przedstawiono poziomy przyspieszenia wibracji przy 10, 20, 30, 40 i 50 dB SL oraz próg wykrywania percepcji dotykowej przez człowieka (0 dB SL) w zależności od częstotliwości czasowej. Dane są szacowane na podstawie rysunku 8 w artykule Verrillo, R. T. i in. z 1969 r. pt. „Sensation magnitude of vibrotactile stimuli” (Wielkość odczuwania bodźców wibrotaktylnych).
Android automatycznie obsługuje tę konwersję w klasie BasicEnvelopeBuilder, która przyjmuje wartości jako znormalizowane intensywności w przestrzeni poziomu odczuwania (dB SL) i przekształca je na przyspieszenie wyjściowe. Z kolei klasa WaveformEnvelopeBuilder nie stosuje tej konwersji i przyjmuje wartości jako znormalizowane amplitudy przyspieszenia wyjściowego w przestrzeni przyspieszenia (Gs). Interfejs API obwiedni zakłada, że gdy projektant lub programista myśli o zmianach siły wibracji, oczekuje, że postrzegana intensywność będzie zgodna z obwiednią liniową.
Domyślne wygładzanie przebiegu na urządzeniach
Aby to zilustrować, rozważ, jak niestandardowy wzorzec przebiegu zachowuje się na ogólnym urządzeniu:
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));
Na wykresach poniżej przedstawiono przebieg wejściowy i przyspieszenie wyjściowe odpowiadające poprzednim fragmentom kodu. Pamiętaj, że przyspieszenie rośnie stopniowo, a nie nagle, gdy w wzorcu występuje skokowa zmiana amplitudy – czyli przy 0 ms, 150 ms, 200 ms, 250 ms i 700 ms. Przy każdej skokowej zmianie amplitudy występuje też przekroczenie, a gdy amplituda wejściowa nagle spada do 0, widoczne jest tłumienie trwające co najmniej 50 ms.
Ulepszony wzorzec dotykowy
Aby uniknąć przekroczenia i skrócić czas tłumienia, zmieniaj amplitudy bardziej stopniowo. Poniżej przedstawiamy wykresy przebiegu i przyspieszenia poprawionej wersji:
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));
Tworzenie bardziej złożonych efektów dotykowych
Inne elementy satysfakcjonującej reakcji na kliknięcie są bardziej złożone i wymagają pewnej wiedzy o LRA używanym w urządzeniu. Aby uzyskać najlepsze wyniki, używaj gotowych przebiegów urządzenia i stałych dostarczanych przez platformę, które umożliwiają:
- wykonywanie wyraźnych efektów i elementów pierwotnych;
- łączenie ich w celu tworzenia nowych efektów dotykowych.
Te predefiniowane stałe i elementy pierwotne mogą znacznie przyspieszyć pracę podczas tworzenia wysokiej jakości efektów dotykowych.