המפעילים הנפוצים ביותר של רטט במכשירי Android הם מפעילים ליניאריים רזוננטיים (LRA). ה-LRA מדמה את התחושה של לחיצה על לחצן על משטח זכוכית שלא מגיב. אות ברור וחד של משוב על קליק נמשך בדרך כלל בין 10 ל-20 אלפיות השנייה. התחושה הזו גורמת לאינטראקציות של המשתמשים להרגיש טבעיות יותר. במקלדות וירטואליות, משוב ללחיצה יכול להגדיל את מהירות ההקלדה ולצמצם את השגיאות.
ל-LRA יש כמה תדרים רזוננטיים נפוצים:
- לחלק מהמנועים הרטט ליניאריים היו תדרי תהודה בטווח של 200 עד 300 הרץ, שמתאים לתדר שבו העור האנושי הכי רגיש לרטט. התחושה של רעידות בטווח התדרים הזה מתוארת בדרך כלל כחלקה, חדה וחודרת.
- לדגמים אחרים של מנועי תהודה ליניאריים יש תדרי תהודה נמוכים יותר, בסביבות 150 הרץ. התחושה רכה ומלאה יותר (במימד).
אם מתח הכניסה זהה בשני תדרים שונים, משרעת פלט הרטט יכולה להיות שונה. ככל שהתדירות רחוקה יותר מהתדירות התהודה של ה-LRA, משרעת הרטט שלה נמוכה יותר.
אפקטים של משוב הפטי במכשיר מסוים משתמשים גם במפעיל הרטט וגם במנהל ההתקן שלו. מנהלי התקנים של משוב הפטי שכוללים תכונות של אוברדרייב ובלימה אקטיבית יכולים לקצר את זמן העלייה ואת הצלצול של מנועי ה-LRA, וכך ליצור רטט ברור ומגיב יותר.
האצת הפלט של הרטט
מיפוי התדירות להאצת הפלט (FOAM) מתאר את האצת הפלט המקסימלית שאפשר להשיג (בשיא G) בתדירות רטט נתונה (בהרץ). החל מ-Android 16 (רמת API 36), הפלטפורמה מספקת תמיכה מובנית במיפוי הזה באמצעות VibratorFrequencyProfile. אפשר להשתמש במחלקה הזו, יחד עם ממשקי ה-API של מעטפות בסיסיות ומתקדמות, כדי ליצור אפקטים של משוב מישושי.
לרוב המנועים מסוג LRA יש שיא אחד ב-FOAM שלהם, בדרך כלל ליד תדר התהודה שלהם. ההאצה בדרך כלל יורדת באופן אקספוננציאלי ככל שהתדר חורג מהטווח הזה. יכול להיות שהעקומה לא תהיה סימטרית, ושתכלול מישור סביב תדר התהודה כדי להגן על המנוע מפני נזק.
בתרשים הסמוך מוצגת דוגמה של FOAM למנוע LRA.
הסף לזיהוי תפיסה אנושית
סף הגילוי של תפיסה אנושית מתייחס לתאוצה המינימלית של רטט שאדם יכול לזהות באופן מהימן. הרמה הזו משתנה בהתאם לתדירות הרטט.
בתרשים הסמוך מוצג סף הזיהוי של תפיסה מישושית אצל בני אדם, בתאוצה, כפונקציה של תדירות זמנית. נתוני הסף מומרים מסף ההעתקה באיור 1 של Bolanowski Jr., S. J., et al.'s 1988 article, "Four channels mediate the mechanical aspects of touch.".
מערכת Android מטפלת אוטומטית בסף הזה ב-BasicEnvelopeBuilder, שמאמת שכל האפקטים משתמשים בטווח תדרים שמפיק אמפליטודות של רטט שחורגות מסף הזיהוי של התפיסה האנושית לפחות ב-10 dB.
במדריך אונליין מוסבר המעבר בין משרעת התאוצה למשרעת ההעתקה.
רמות התאוצה של הרטט
התפיסה האנושית של עוצמת הרטט, שהיא מדד תפיסתי, לא גדלה באופן לינארי עם אמפליטודת הרטט, שהיא פרמטר פיזי. עוצמה נתפסת מאופיינת ברמת תחושה (SL), שמוגדרת כסכום בדציבלים מעל סף הזיהוי באותה תדירות.
אפשר לחשב את משרעת תאוצת הרטט המתאימה (ב-G שיא) באופן הבא:
…כאשר אמפליטודת הדציבלים היא סכום של SL ושל סף הזיהוי – הערך לאורך הציר האנכי בתרשים הסמוך – בתדר מסוים.
בתרשים הסמוך מוצגים רמות התאוצה של הרטט ב-10, 20, 30, 40 ו-50 dB SL, יחד עם סף הזיהוי של תפיסת המישוש האנושית (0 dB SL), כפונקציה של תדירות זמנית. הנתונים הם הערכה מתוך איור 8 במאמר של Verrillo, R. T., et al.'s 1969 article, "Sensation magnitude of vibrotactile stimuli.".
מערכת Android מטפלת בהמרה הזו באופן אוטומטי ב-BasicEnvelopeBuilder, שבו הערכים הם עוצמות מנורמלות במרחב של רמת התחושה (dB SL) והם מומרים לתאוצה של הפלט. לעומת זאת, WaveformEnvelopeBuilder לא מחיל את ההמרה הזו, והערכים שמתקבלים הם אמפליטודות מנורמלות של תאוצת הפלט במרחב התאוצה (Gs). ממשק ה-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))
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));
התרשימים הבאים מציגים את צורת הגל של הקלט ואת התאוצה של הפלט בהתאם לקטעי הקוד שלמעלה. שימו לב שההאצה גדלה בהדרגה ולא בפתאומיות, בכל פעם שיש שינוי שלב במשרעת התבנית – כלומר, ב-0ms, ב-150ms, ב-200ms, ב-250ms וב-700ms. בנוסף, יש חריגה בכל שינוי של האמפליטודה, וניתן לראות תנודות שנמשכות לפחות 50 אלפיות השנייה כשהאמפליטודה של הקלט יורדת פתאום ל-0.
שיפור של דפוס המשוב המישוש
כדי להימנע מחריגה ולצמצם את זמן הצלצול, כדאי לשנות את האמפליטודות בצורה הדרגתית יותר. בתרשים הבא מוצגים צורת הגל והתאוצה של הגרסה המתוקנת:
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));
יצירת אפקטים הפטיים מורכבים יותר
אלמנטים אחרים בתגובה משביעת רצון ללחיצה הם מורכבים יותר, ונדרש ידע מסוים לגבי ה-LRA שמשמש במכשיר. כדי לקבל את התוצאות הכי טובות, מומלץ להשתמש בצורות הגל המוכנות מראש של המכשיר ובקבועים שסופקו על ידי הפלטפורמה, שמאפשרים לכם לבצע את הפעולות הבאות:
- הוספת אפקטים ברורים ופרימיטיבים.
- אפשר לשרשר אותם כדי ליצור אפקטים חדשים של משוב הפטי.
הקבועים והפרימיטיבים המוגדרים מראש האלה יכולים להאיץ מאוד את העבודה שלכם בזמן שאתם יוצרים אפקטים מישושיים באיכות גבוהה.