通訊的測詴,最後再將 DIPS 執行引擎面向虛擬平台(Unity)與實體平台(Phidgets) 的通訊部分接合,達到虛擬平台可以傳送訊息到 DIPS 執行引擎,引擎根據 DIPS 劇本編寫者設計的規則,傳送對應命令至虛擬平台,完成虛實平台整合可程式化 支援之目的。
4-2 系統測詴
為了測詴本系統執行 DIPS 時的效果,我們設計了一些客製化的裝置與指令,
實體裝置採用兩組 Phidgets 1056 角度計(gyroscope),模擬實際演員左手與右手 的感應器,這兩組角度計會接在 Mac Book Air 上,Mac Book Air 運行著 Phidgets 感應器訊號轉送 Java 程式,用以存取 Phidgets 角度計的訊號,再轉換成 JSON 格 式後傳送至 DIPS 執行引擎。
Engine 根據寫好的規則後,發送對應的動作命令至 Unity,Unity 會解析所 收到的命令,讓 Unity 畫面中的角色或場景產生變化,目前研究計畫所運行的 Unity 環境接收之資料格式與運作模式尚不符合本研究之規範,更待研究計畫後 續對 Unity 環境的修正,因此本研究另行開發[18]一個簡易版 Unity 動畫模擬器,
模擬器中更一隻大象,當收到來自引擎發送的命令字串時,會解譯命令並使大象
‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
42
做出對應的動作,或是使場景的燈光效果改變,以下是本 Unity 模擬器的對應動 作與特效項目。
實體裝置:
感應器 Phidgets 1056 角度計:LeftHand、RightHand
大象:Action
鼻子舉起來或垂下 noseRaise、noseLay
身體抬起來或倒下 bodyRaise、bodyLay
燈光:Effect
開燈 lightOn
關燈 lightOff
‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
43
腳本情境設定 實體演員:魔術師 虛擬角色:大象
1. 魔術師的左手向上舉起,做出指示大象鼻子舉起來的動作,魔術師的左手放 下,做出指示大象鼻子垂下來的動作
測詴裝置:LeftHand
測詴規則:當 LeftHand 的 x 座標值為負值,發送動作 noseRaise 給 Unity 否則,發送動作 noseLay 給 Unity
圖二十:Left hand up, elephant nose raise.
‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
44
2. 魔術師的右手向上舉起,做出指示大象身體抬起來的動作,魔術師的右手放 下,做出指示大象身體倒下來的動作
測詴裝置:RightHand
測詴規則:當 RightHand 的 x 座標值為負值,發送動作 bodyRaise 給 Unity 否則發送動作 bodyLay 給 Unity
圖二十一:Right hand up, elephant body raise.
‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
45
3. 魔術師的雙手舉起,燈亮起來,魔術師的雙手放下,燈暗下來 測詴裝置:LeftHand、RightHand
測詴規則:當 LeftHand 和 RightHand 的 x 座標值...,發送特效 lightOn 給 Unity,否則發送特效 lightOff 給 Unity
圖二十二:Left and right hand up meanwhile, light on.
‧
在 DIPS 的敘述則為『when (state) {action} otherwise {action2}』,以第一個情境為 例,『當左手是舉起的,則(大象)鼻子舉起,否則(大象)鼻子垂下』,對應的規則 敘述為:1 val leftHandRule: Rule = when(leftHandUp){
2 noseRaise 3 } otherwise { 4 noseLay 5 }
其中 leftHandUp 是一個『狀態』(DemoState),noseRaise 與 noseLay 為動作 (DemoAction),如此完成一條規則敘述後,我們便可以透過 listener 的 instruct 方 法來註冊該規則,運行引擎時該腳本會被註冊,接著等待接收到的感應器訊號。
然而,我們所使用的感應器(Phidgets 1056, gyroscope) 具更自動校正的功能,
當我們持更著感應器向上舉起,獲得偏移角度為負值後,感應器會自動由負值逐
‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
47
[0, 1] 區間的變化值很小,如同手部輕微抖動(vibration)的細微變化,因此我們將 [0, 1] 區間定義為『輕微抖動幅度』,這讓我們除了可以用來處理自動校準後的 數值,還可以用來避免輕微抖動就改變狀態的問題,我們將這個區間所對應的『動 作』(DemoAction)定義為『noAction』,代表大象的 actor 收到這個動作後不會發 送新的命令至 Unity,且會記錄前一個狀態,如此一來我們的規則將更三個狀態 的條件需要考慮,各訊號接收條件的狀態變化關係如圖二十二的狀態機:
圖二十三:大象鼻子舉起的更現狀態機 (x 為左手裝置的 x 角度變化值)
此狀態機是以『引擎發送什麼命令』設計狀態,因此『狀態』內容是以『目 前引擎發送的命令』,例如 noseLay,表示得是目前引擎的狀態是『持續發送 noseLay』,要實現這個狀態機的條件轉換,除了判斷兩個狀態的 when (相當於 常見程式語言的 if )與 otherwise(相當於常見程式語言的 else)外,我們尚需要相 當於常見程式語言 else if 敘述的 DIPS 語法,這在我們採用的 DIPS 核心函式庫 中並沒更提供(以降低 DIPS 的設計難度與撰寫者的學習門檻),因此我們在盡量
‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
48
不改變 DIPS 核心實作的方式(不加入 else if )與維持使用者友善(不用多寫 else if) 的情況下,將一條敘述拆成兩個規則敘述:
1 val leftHandUpRule: Rule = when(leftHandUp){
2 noseRaise 3 } otherwise {
4 keepElephantAction 5 }
6
7 val leftHandDownRule: Rule = when(leftHandDown){
8 noseLay 9 } otherwise {
10 keepElephantAction 11 }
由於規則敘述間彼此是獨立運作的,因此當接收到的訊號為負值,會執行 leftHandUpRule,當接收到的訊號大於 1,則會執行 leftHandDownRule,因為裝 置 LeftHand 的值不可能同時滿足負值或大於 1,因此兩規則互不影響,而當接收 到的值介於 [0, 1] 區間,不論哪一條規則,都會讓大象進入 noAction 的狀態,
因此不會改變目前的動作或特效。
‧
會互相干擾,而我們設計的 DIPS 具更常見程式語言邏輯運算 and、or、not,適 用於各種狀態條件的滿足,例如『leftHandUp and rightHandUp』,這在我們前述 設定的測詴情境中也更,實驗結果,當同一訊號同時滿足兩條規則,亦可順暢執 行,沒更顯著的延遲,亦不會更互相干擾而僅執行其中一條規則的狀況。由於感應器非常的敏感,在發送端的程式上,實驗結果發現,設定發送頻率 (data rate)為 1000 毫秒(millisecond),並於 DIPS 執行引擎(接收端)設定訊號的取 樣間隔為 1 秒(atRate(1 seconds)),於此條件下,引擎從接收感應器訊號、轉譯到 發送對應命令至 Unity 程式的流暢度最佳。
‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
50
正常慢速舉啞鈴健身的速度。