Android 기기에서 가장 일반적인 진동 액추에이터는 선형 공진 액추에이터 (LRA)입니다. LRA는 반응이 없는 유리 표면에서 버튼을 클릭하는 느낌을 시뮬레이션합니다. 선명하고 깔끔한 클릭 피드백 신호는 일반적으로 10~20밀리초 동안 지속됩니다. 이러한 느낌을 통해 사용자 상호작용이 더 자연스럽게 느껴집니다. 가상 키보드의 경우 이 클릭 피드백을 통해 입력 속도를 높이고 오류를 줄일 수 있습니다.
LRA에는 몇 가지 일반적인 공진 주파수가 있습니다.
- 일부 LRA의 공진 주파수는 200~300Hz 범위였으며, 이는 인간 피부가 진동에 가장 민감한 주파수와 일치합니다. 이 주파수 범위에서 진동의 느낌은 일반적으로 부드럽고 날카롭고 꿰뚫는 느낌으로 표현됩니다.
- 다른 LRA 모델은 공진 주파수가 약 150Hz로 더 낮습니다. 느낌은 질적으로 더 부드럽고 꽉 차 있습니다.
두 가지 다른 주파수에서 동일한 입력 전압을 가정할 때 진동 출력 진폭은 다를 수 있습니다. 주파수가 LRA의 공진 주파수에서 멀수록 진동 진폭이 낮아집니다.
특정 기기의 햅틱 효과는 진동 액추에이터와 해당 드라이버를 모두 사용합니다. 오버드라이브 및 능동 제동 기능이 포함된 햅틱 드라이버는 LRA의 상승 시간과 울림을 줄여 더 민감하고 선명한 진동을 제공할 수 있습니다.
진동기 출력 가속
주파수-출력 가속도 매핑 (FOAM)은 주어진 진동 주파수 (헤르츠)에서 달성할 수 있는 최대 출력 가속도 (피크 G)를 나타냅니다. Android 16 (API 수준 36)부터 플랫폼은 VibratorFrequencyProfile
를 통해 이 매핑을 위한 기본 제공 지원을 제공합니다. 이 클래스를 기본 및 고급 엔벨롭 API와 함께 사용하여 햅틱 효과를 만들 수 있습니다.
대부분의 LRA 모터는 FOAM에 단일 피크를 갖고 있으며, 일반적으로 공진 주파수 근처에 있습니다. 가속은 일반적으로 주파수가 이 범위를 벗어나면 지수적으로 감소합니다. 곡선이 대칭적이지 않을 수 있으며 모터가 손상되지 않도록 공진 주파수 주변에 고원이 있을 수 있습니다.
인접한 그래프는 LRA 모터의 FOAM 예시를 보여줍니다.
인간 인식 감지 기준
인간 지각 감지 기준점은 사람이 안정적으로 감지할 수 있는 최소 진동 가속도를 나타냅니다. 이 수준은 진동 빈도에 따라 다릅니다.
인접한 그래프는 시간 주파수의 함수로 인간의 햅틱 감지 감지 기준점(가속도)을 보여줍니다. 임곗값 데이터는 Bolanowski Jr.의 그림 1의 변위 임곗값에서 변환됩니다. S. J., et al.'s 1988 article, "Four channels mediate the mechanical aspects of touch.".
Android는 BasicEnvelopeBuilder
에서 이 임곗값을 자동으로 처리하여 모든 효과가 인간의 지각 감지 임곗값을 10dB 이상 초과하는 진동 진폭을 생성하는 주파수 범위를 사용하는지 확인합니다.
온라인 튜토리얼에서는 가속도 진폭과 변위 진폭 간의 변환을 자세히 설명합니다.
진동 가속도 수준
지각 측정값인 인간의 진동 강도 지각은 물리적 매개변수인 진동 진폭과 선형적으로 증가하지 않습니다. 지각된 강도는 동일한 주파수에서 감지 임계값을 초과하는 dB 값으로 정의되는 감각 수준 (SL)으로 특성화됩니다.
이에 상응하는 진동 가속도 진폭 (G 피크 단위)은 다음과 같이 계산할 수 있습니다.
여기서 진폭 dB는 특정 주파수에서 SL과 감지 기준점(인접한 그래프의 세로축 값)의 합입니다.
인접한 그래프는 시간 주파수 함수로서 10, 20, 30, 40, 50 dB SL의 진동 가속도 수준과 인간의 햅틱 감지 감지 기준점 (0 dB SL)을 보여줍니다. 데이터는 Verrillo, R.의 그림 8에서 추정되었습니다. T., et al.'s 1969 article, "Sensation magnitude of vibrotactile stimulus."
Android는 BasicEnvelopeBuilder
에서 이 변환을 자동으로 처리합니다. BasicEnvelopeBuilder
는 값을 감각 수준 공간 (dB SL)의 정규화된 강도로 취하고 이를 출력 가속도로 변환합니다. 반면 WaveformEnvelopeBuilder
는 이 변환을 적용하지 않으며 대신 가속 공간 (Gs)에서 정규화된 출력 가속도 진폭으로 값을 취합니다. 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))
자바
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으로 떨어질 때 50ms 이상 지속되는 링잉이 눈에 띄게 보입니다.
개선된 햅틱 패턴
오버슈트를 방지하고 울림 시간을 줄이려면 진폭을 더 점진적으로 변경하세요. 다음은 수정된 버전의 파형 및 가속도 그래프를 보여줍니다.
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))
자바
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에 관한 지식이 필요합니다. 최상의 결과를 얻으려면 기기의 사전 제작된 웨이브폼과 플랫폼에서 제공하는 상수를 사용하세요. 이를 통해 다음 작업을 할 수 있습니다.
- 선명한 효과와 원시 값을 실행합니다.
- 이를 연결하여 새로운 햅틱 효과를 구성합니다.
이러한 사전 정의된 햅틱 상수와 프리미티브를 사용하면 고품질 햅틱 효과를 만들면서 작업 속도를 크게 높일 수 있습니다.