分段線性包絡 (PWLE) 效果是一連串的點,可定義一段時間內的震動頻率和加速度。PWLE 可提供更豐富且動態的觸覺回饋。
Android 16 以上版本提供兩項應用程式開發人員 API,協助建立 PWLE 效果:
- 基本 PWLE API:簡單易用,但有許多限制。適合快速入門。請前往
BasicEnvelopeBuilder
瞭解詳情。 - 進階 PWLE API:提供更多控制權和彈性,但需要觸覺回饋知識,並對硬體有一定程度的瞭解。如要瞭解詳情,請參閱
WaveformEnvelopeBuilder
。
如要支援這些 API,裝置必須實作下列 HAL API:
- 輸出加速對應頻率 (FOAM):提供裝置的震動頻率與可達到的最大輸出加速度對應。
- Compose PWLE:播放由震動波形的 PWLE 定義的震動。
基本 PWLE API
如要快速建立 PWLE 效果,不必深入瞭解硬體或人類感知的細微差異,開發人員可以使用基本 PWLE API,並透過下列參數定義:
- 強度值介於 [0, 1] 之間,代表震動的感知強度。舉例來說,0.5 的值代表裝置可達到的全域最大強度的一半。
- 銳利度值介於 [0, 1] 之間,代表震動的清脆程度。值越小,震動越平緩;值越大,震動越強烈。
- 「時間長度」是指從上一個 PWLE 點 (即強度和銳利度配對) 轉換至新點所需的時間,以毫秒為單位。
以下是波形範例,在 500 毫秒內將強度從低音調提升至高音調的最大強度震動,然後在 100 毫秒內降至 0 (關閉):
VibrationEffect effect = new VibrationEffect.BasicEnvelopeBuilder()
.setInitialSharpness(0.0f)
.addControlPoint(1.0f, 1.0f, 500)
.addControlPoint(0.0f, 1.0f, 100)
.build();
限制
如要建立流暢無縫的觸覺體驗,PWLE 效果必須以強度 0.0 開始和結束。API 會強制執行這項規定,將開始強度固定為 0,如果結束強度不是 0,就會擲回例外狀況。這項限制可避免因振幅不連續而產生不良的動態效果,進而對使用者的觸覺感知造成負面影響。
為確保 Android 生態系統的 PWLE 效果呈現一致,架構要求支援這項功能的裝置,必須能處理 PWLE 點之間至少 10 毫秒的間隔,以及 PWLE 效果至少 16 個點。VTS 測試會強制執行這些要求,確保 Android 裝置的 PWLE 效果穩定可靠。
進階 PWLE API
具備觸覺回饋進階知識的開發人員,可使用下列條件定義 PWLE 效果:
- [0, 1] 範圍內的「振幅」值代表特定頻率可達到的強度,由裝置 FOAM 決定。舉例來說,0.5 的值會產生最大輸出加速度的一半,而這是在指定頻率下可達成的。
- 頻率直接以赫茲指定。
- Duration 是指從上一個 PWLE 點到新點的轉換時間,以毫秒為單位。
以下是波形範例,說明如何以 120 Hz 的頻率,在 100 毫秒內將震動器從關閉狀態調至全振幅,並維持該狀態 200 毫秒,然後在 100 毫秒內調回關閉狀態:
VibrationEffect effect = new VibrationEffect.WaveformEnvelopeBuilder()
.addControlPoint(1.0f, 120f, 100)
.addControlPoint(1.0f, 120f, 200)
.addControlPoint(0.0f, 120f, 100)
.build();
限制
架構不會修改開發人員提供的要求頻率和振幅值,但會新增 0 振幅的起點,確保轉換過程順暢。
開發人員有責任確保 PWLE 效果中指定的頻率落在裝置支援的範圍內,也就是裝置 FOAM 定義的範圍。如果值超出這些限制,裝置不會播放任何震動。
頻率至輸出加速對應 (FOAM)
如要支援 PWLE API,就必須準確呈現裝置的頻率,以輸出加速度功能。本節將詳細說明這項資料的重要性、PWLE API 的使用方式,以及產生這項資料的程序。
瞭解對應關係
支援 PWLE 效果的裝置必須提供頻率,才能輸出頻率加速對應 (FOAM)。FOAM 是由 HAL 產生的資料結構,可將振動頻率 (以赫茲為單位) 對應至該頻率下致動器可達到的最大輸出加速度 (以 G 峰值為單位)。這張地圖有助於瞭解支援的頻率範圍內震動輸出量的變化,以及定義基本 PWLE API。
下圖顯示典型共振致動器的 FOAM 範例,輸入電壓限制在共振頻率附近,以保護馬達:
圖 1. 一般共振致動器的 FOAM 範例。
FOAM 主要有三項用途:
- 定義完整頻率範圍:FOAM 會指定支援的最小和最大震動頻率,定義裝置的完整頻率範圍。
- 定義強度和銳利度值:基本 PWLE API 會根據人類對強度和銳利度的感知程度運作,然後使用 FOAM 中的輸出加速度值,將這些值對應至硬體頻率和振幅參數。這項對應作業可確保觸覺效果是根據硬體功能呈現。銳利度範圍由可感知最低門檻定義,對應裝置可產生使用者可感受觸覺效果的頻率。架構會根據所選頻率的目標輸出加速度,將「強度」值對應至振幅。這有助於確保裝置在達到所選強度等級的同時,不會超出裝置功能範圍。
- 公開硬體功能:FOAM 會在
VibratorFrequencyProfile
中公開給開發人員,提供完整頻率來輸出加速度資料集,詳細說明裝置的部分觸覺功能。開發人員可運用進階 PWLE API 取得這項資料,建立超出架構定義基本強度和銳利度範圍的自訂震動效果。
FOAM 和基本 PWLE API
FOAM 在塑造震動效果方面扮演重要角色。這項屬性用於計算基本包絡線 API 的銳利度範圍,確保使用者能感受到震動。這個範圍對應的頻率,輸出加速值至少要比人類感知偵測閾值 (即最低可感知程度) 高出 10 dB。確保震動強度足以讓使用者感受到。
此外,架構會使用 FOAM 資料,將基本 PWLE API 中使用的強度和銳利度值,對應至相應的振幅和頻率值。這項對應有助於在不同裝置上產生可感知的觸覺回饋。
VTS 測試可確保支援包絡線效果的裝置具有非空白的頻率範圍,可產生可感知的震動。這有助於確保裝置能產生足夠強度的震動,讓使用者清楚感受到。
FOAM 和進階 PWLE API
開發人員可透過 VibratorFrequencyProfile
存取 FOAM,並取得下列資訊:
- 頻率範圍:開發人員可以分別使用
getMinFrequencyHz
和getMaxFrequencyHz
,以赫茲為單位擷取裝置支援的最低和最高頻率。 - 最大輸出加速度:裝置可達到的最大輸出加速度 (以 G 為單位),可透過
getMaxOutputAccelerationGs
取得。 - 輸出加速度對應的頻率:
getFrequenciesOutputAcceleration
提供 HAL 中實作的輸出加速度對應頻率。
開發人員可使用這項資訊,透過進階 PWLE API 建立封套效果。舉例來說,指定輸出加速度 (以 G 為單位) 時,必須將其正規化為 [0.0, 1.0] 範圍內的值,相對於裝置的最大輸出加速度。
開發人員可透過進階 PWLE API 使用整個頻率範圍,因此提供的 FOAM 資料必須確保震動器安全無虞,且不會超出其功能範圍。
人類感知偵測門檻
人類感知偵測門檻是指人體可穩定偵測到的最低震動加速度。震動強度會因震動頻率而異。
下圖顯示人類觸覺感知偵測閾值 (以加速度表示)1,是時間頻率的函式:
圖 2. 人類觸覺感知偵測門檻。
為確保使用者能持續感受到觸覺效果,VTS 測試會驗證具備包絡線功能的裝置是否具有頻率範圍,可產生超過人類感知偵測閾值 10 dB 的震動幅度。
體感震動強度與震動加速度振幅
人類對震動強度的感知 (一種感知測量) 並不會隨著震動幅度 (一種物理參數) 呈線性成長。PWLE API 假設設計師或開發人員考慮變更震動強度時,會預期感知強度遵循 PWLE。感知強度的特徵是感覺強度 (SL),定義為相同頻率下高於偵測閾值的 dB 值。因此,振動加速度幅度 (以 G 峰值為單位) 的計算方式如下:
\(Amplitude(G) =10^\frac{Amplitude(db)}{20}\)
其中,振幅 dB 是特定頻率下 SL 和偵測閾值的總和 (下圖中縱座標上的值)。
這樣一來,PWLE API 就能確保連續控制點對之間的感知強度變化呈線性。
下圖顯示 10、20、30、40 和 50 dB SL 的振動加速度位準2,以及人類觸覺感知偵測閾值 (0 dB SL),以時間頻率為函式。
圖 3. 震動加速程度。
判斷最大輸出加速曲線的頻率
本節提供一般指南,說明如何從裝置取得頻率至最大輸出加速度曲線,並用來產生 FOAM 資料。
取得最大電壓曲線 (V)
V
是指在震動器工作頻率範圍內,可安全施加的最大電壓。這可確保震動器在安全範圍內運作,避免損壞並盡可能提高震動強度。
如果硬體包含電壓限制功能,請使用這項功能直接測量支援頻率範圍內可達到的最大電壓。
計算最大加速度 (M)
M
是最大加速度,可透過各種方法計算。本節說明適用於使用線性共振致動器 (LRA) 的裝置的方法。
這個方法會將特定頻率下的最大施加電壓,轉換為以 G 峰值表示的相應最大加速度值。
這項轉換使用的核心方程式如下:
\(\text{Accel}(w)= (\text{Vsys}\times\text{BLsys}\times\text{Loc_coeff}/\text{Rsys}/\text{MPhone})\times{w^2}/\text{Psys_abs}/{9.81}\)
其中:
Vsys
:套用至觸覺致動器的實際電壓位準
BLsys
:振動馬達的磁場強度 (B
) 和導體長度 (L
) 的乘積
Loc_coeff
:位置係數,可將模組層級的加速度轉換為手機層級的加速度
Rsys
:震動馬達線圈的電阻
MPhone
:裝置 (例如手機) 的質量
w
:驅動訊號的角頻率 (每秒弧度),計算方式如下:
\(w = 2 \pi f\)
Psys_abs
:二階質量、阻尼器和彈簧系統的振幅回應,計算方式如下:
\(\text{Psys_abs} = (\text{Wnsys}^2-w^2)^2+({w}\times(\text{Wnsys}/\text{Qsys}))^2\)
Wnsys
:振動系統的自然頻率
Qsys
:震動系統的品質因數
Loc_coeff
是指在手機層級測得的加速度與在模組層級測得的加速度比率。這個比率用於將模組層級的加速度讀數轉換為等值的電話層級加速度讀數。在手機層級,由於模組運動的角加速度,加速度會放大,而這個係數會考量這類效應。計算方式如下:
\(\text{Loc_coeff} = \text{phone_acceleration} / \text{module_acceleration}\)
舉例來說,如果模組加速度為 1 g,手機加速度為 2.5 g,則 Loc_coeff
= 2.5。這表示放大 2.5 倍。
Android 架構會以赫茲為單位計算頻率,因此 HAL 在產生 FOAM 資料時,需要將頻率單位從每秒弧度轉換為赫茲。
生成 FOAM 曲線
結合最大電壓曲線 (V
) 和加速度計算 (M
),即可判斷 FOAM 曲線:
- 針對所需範圍內的每個頻率 (
f
),從最大電壓曲線找出對應的最大電壓V(f)
。 - 使用上述方程式計算該頻率下的最大加速度,並將
V(f)
代入Vsys
,以及將對應的f
代入w
。這樣您就能獲得M(V(f), f)
。 - 這項計算出的加速度就是
FOAM(f)
值。
公開 FOAM 資料
生成 FOAM 曲線後,HAL 會將曲線表示為 FrequencyAccelerationMapEntry
物件清單。每個項目都會定義對應中的一個點,指定頻率 (以赫茲為單位) 和對應的最大輸出加速度 (以 G 峰值為單位)。
雖然 FOAM 的解析度沒有嚴格規定,但我們建議定義曲線時,只設定一個最高峰。在基本封包 API 中,系統只會使用第一個峰值來對應震動效果。為盡量提高線性內插法的準確度,建議您在峰值附近定義高頻率解析度,以判斷中間加速度值。舉例來說,在峰值頻率的 +/- 10 Hz 範圍內,使用 1 Hz 的步階。
裝置功能和限制
對於 Android 16 以上版本,為協助開發人員最佳化 PWLE 效果並確保裝置間的相容性,Android 包含 HAL API,可查詢裝置的 PWLE 功能。這些方法會提供裝置限制的相關資訊,例如最低或最高 PWLE 原始時間長度,以及 PWLE 組合中允許的原始時間長度數量。
HAL API 包括:
CAP_COMPOSE_PWLE_EFFECTS_V2
:裝置支援這項功能時,IVibrator.getCapabilities
會傳回這個值。getFrequencyToOutputAccelerationMap
:擷取 FOAM 資料。getPwleV2PrimitiveDurationMinMillis
:以毫秒為單位,擷取任何原始 PWLE 允許的最短時間長度。getPwleV2PrimitiveDurationMaxMillis
:以毫秒為單位,擷取任何原始 PWLE 允許的最大時間長度。getPwleV2CompositionSizeMax
:擷取IVibrator.composePwleV2
支援的 PWLE 原始型別數量上限。
開發人員可以取得這項資訊,根據目標裝置的特定功能調整效果,特別是使用進階 PWLE API 時。
架構在處理使用基本 API 建立的效果時,也會使用這些 API。如果效果超出裝置限制 (例如 PWLE 點數過多或時間長度超過上限),架構會自動調整效果,使其符合允許的範圍。這項調整程序會盡量保留設計的原始意圖和風格。
-
門檻資料是根據 Bolanowski Jr. 於 2004 年發表的論文 (圖 1) 中的位移門檻轉換而來,S. J. 等人。「四個管道可調解觸控的機械層面。」Journal of the Acoustical Society of America 84(5): 1680-1694 (1988)。這份線上教學課程說明瞭加速度振幅和位移振幅之間的轉換。 ↩
-
這項資料是根據 Verrillo, R. 著作中的圖 8 估算而得。T.、 et al.. 「觸覺刺激的感覺強度。」 Perception & Psychophysics 6: 366-372 (1969)。 ↩