Najczęściej spotykane na urządzeniach z Androidem siłowniki wibracyjne to siłowniki rezonansowe liniowe (LRA). LRAs symulują wrażenie kliknięcia przycisku na powierzchni szklanej, która normalnie nie reaguje na dotyk. Jasny i czysty sygnał kliknięcia trwa zwykle od 10 do 20 milisekund. Dzięki temu interakcje z użytkownikiem wydają się bardziej naturalne. W przypadku klawiatur wirtualnych ta funkcja może zwiększyć szybkość pisania i zmniejszyć liczbę błędów.
LRAs mają kilka wspólnych częstotliwości rezonansowych:
- Niektóre LRAs miały częstotliwości rezonansowe w zakresie 200–300 Hz, co zbiega się z częstotliwością, przy której ludzka skóra jest najbardziej wrażliwa na wibracje. Wrażenia z wibracji w tym zakresie częstotliwości są zwykle opisywane jako płynne, ostre i przenikliwe.
- Inne modele LRAs mają niższe częstotliwości rezonansowe, około 150 Hz. Wrażenie jest jakościowo bardziej miękkie i pełniejsze (w wymiarach).
Przy tym samym napięciu wejściowym o 2 różnych częstotliwościach amplitudy drgań wyjściowych mogą być różne. Im większa odległość częstotliwości od częstotliwości rezonansowej LRA, tym mniejsza amplituda drgań.
Efekty haptyczne danego urządzenia korzystają zarówno z silnika wibracyjnego, jak i z sterownika. Sterowniki haptyczne, które obejmują funkcje overdrive i aktywnego hamowania, mogą skrócić czas narastania i dzwonienia w przypadku LRAs, co prowadzi do bardziej responsywnej i jasnej wibracji.
Przyspieszenie wyjścia wibratora
Mapowanie częstotliwości na przyspieszenie wyjściowe (FOAM) opisuje maksymalne możliwe przyspieszenie wyjściowe (w G szczyt) przy danej częstotliwości wibracji (w hercach). Od Androida 16 (poziom interfejsu API 36) platforma zapewnia wbudowane wsparcie dla tego mapowania za pomocą VibratorFrequencyProfile
. Za pomocą tej klasy oraz interfejsów API kopert podstawowych i zaawansowanych możesz tworzyć efekty haptyczne.
Większość silników LRA ma jeden szczyt w krzywej 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 zawierać plateau wokół częstotliwości rezonansowej, aby chronić silnik przed uszkodzeniem.
Na sąsiednim wykresie pokazano przykładową piankę dla silnika LRA.
Próg wykrywania ludzkiego postrzegania
Próg wykrywania przez człowieka odnosi się do minimalnego przyspieszenia wibracji, które człowiek może niezawodnie wykryć. Ten poziom zależy od częstotliwości wibracji.
Na sąsiednim wykresie widać próg wykrywania haptycznego odbioru przez człowieka w przyspieszeniu jako funkcję częstotliwości czasowej. Dane progowe są przekształcane z progu przemieszczenia w Rysunku 1 w artykule Bolanowski Jr., S. J., et al., 1988, „Cztery kanały pośredniczą w mechanicznych aspektach dotyku”.
Android automatycznie obsługuje ten próg w BasicEnvelopeBuilder
, który sprawdza, czy wszystkie efekty używają zakresu częstotliwości, który generuje amplitudy wibracji, których amplitudy wykrywania przez człowieka przekraczają próg wykrywania o co najmniej 10 dB.
W samouczku online znajdziesz więcej informacji o konwersji między amplitudą przyspieszenia a amplitudą przemieszczenia.
Poziomy przyspieszenia wibracji
Odbieranie przez człowieka intensywności wibracji, czyli odczucia, nie wzrasta w prosto proporcjonalnie do amplitudy wibracji, czyli parametru fizycznego. Odbierana intensywność jest charakteryzowana przez poziom wrażenia (SL), który jest zdefiniowany jako wartość w dB powyżej progu wykrywania na tej samej częstotliwości.
Odpowiednią amplitudę przyspieszenia drgań (w G szczytowych) można obliczyć w ten sposób:
...gdzie dB amplitudy jest sumą SL i progresu wykrywania – wartości na osi pionowej na sąsiednim wykresie – przy danej częstotliwości.
Na sąsiednim wykresie pokazano poziomy przyspieszenia wibracji na poziomie 10, 20, 30, 40 i 50 dB SL oraz próg wykrywania wibracji przez człowieka (0 dB SL) jako funkcję częstotliwości czasowej. Dane są oszacowane na podstawie rysunku 8 w Verrillo, R. T., et al., 1969, „Sensation magnitude of vibrotactile stimuli."
Android automatycznie obsługuje tę konwersję w funkcji BasicEnvelopeBuilder
, która przyjmuje wartości jako skończone natężenia w przestrzeni sensation level (dBSL) i przekształca je w przyspieszenie wyjściowe. Z drugiej strony WaveformEnvelopeBuilder
nie stosuje tej konwersji i zamiast tego przyjmuje wartości jako skończone wartości wyjściowe przyspieszenia w przestrzeni przyspieszenia (Gs). Interfejs API envelope zakłada, że gdy projektant lub deweloper myśli o zmianach siły wibracji, oczekuje, że wyczuwalna intensywność będzie się zmieniać w sposób schodkowy.
Domyślne wygładzanie krzywej na urządzeniach
Dla przykładu zobacz, jak niestandardowy wzór fali zachowuje się na urządzeniu ogólnym:
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 widać sygnał wejściowy i przyspieszenie wyjściowe odpowiadające poprzedzającym fragmentom kodu. Pamiętaj, że przyspieszenie wzrasta stopniowo, a nie gwałtownie, gdy w wzorze występuje zmiana amplitudy o krok – czyli w 0 ms, 150 ms, 200 ms, 250 ms i 700 ms. Występuje też przeregulowanie przy każdej zmianie amplitudy, a także widoczne zjawisko zniekształceń, które trwa co najmniej 50 ms, gdy amplituda wejścia nagle spada do 0.
Ulepszona reakcja haptyczna
Aby uniknąć przesterowania i zredukować czas dzwonienia, zmień amplitudy w bardziej stopniowy sposób. Poniżej pokazano wykresy fali i przyspieszenia w zmienionej 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 haptycznych.
Inne elementy wystarczającej odpowiedzi na kliknięcie są bardziej złożone i wymagają pewnej wiedzy o używanych na urządzeniu funkcjach LRA. Aby uzyskać najlepsze wyniki, użyj gotowych przebiegów sygnału na urządzeniu i konstant udostępnionych przez platformę, które umożliwiają wykonywanie tych czynności:
- Wykonuj czyste efekty i proste elementy.
- Łącz je, aby tworzyć nowe efekty haptyczne.
Te wstępnie zdefiniowane statyczne i proste elementy haptyczne mogą znacznie przyspieszyć pracę przy tworzeniu wysokiej jakości efektów haptycznych.