佟昭 張志利 梁豐 李向陽(yáng)
摘要:虛擬手仿真是虛擬現(xiàn)實(shí)和人機(jī)交互領(lǐng)域的一個(gè)重要研究?jī)?nèi)容。分析并建立了包含16個(gè)自由度的虛擬手運(yùn)動(dòng)學(xué)模型。對(duì)5DT數(shù)據(jù)手套的標(biāo)定和使用方法進(jìn)行了分析。推導(dǎo)了基于線性對(duì)應(yīng)關(guān)系的骨骼旋轉(zhuǎn)控制基本方程。闡述了每個(gè)手指骨骼對(duì)象的控制方法,采用一種新的方法以解決拇指掌骨的運(yùn)動(dòng)控制問題,并編寫了虛擬手控制腳本。在Unity中開發(fā)虛擬手控制場(chǎng)景,運(yùn)行場(chǎng)景進(jìn)行仿真驗(yàn)證,取得良好效果。
關(guān)鍵詞:虛擬手;Unity;數(shù)據(jù)手套;控制腳本
中圖分類號(hào):TP391 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1009-3044(2015)21-0186-04
Research of Virtual Hand Simulation Based on Unity and 5DT Data Glove
TONG Zhao, ZHANG Zhi-li, LIANG Feng, LI Xiang-yang
(The Second Artillery Engineering University, Xian 710025, China)
Abstract: Virtual hand simulation is an important research topic in the field of virtual reality and human-computer interaction. A kinematic model of the virtual hand that contains 16 freedom degrees was obtained. Calibration and use of the 5DT data glove were analyzed. The linear relationship based fundamental equation of skeleton rotation was derived. The control method of finger skeleton objects were expounded. A new method was adopted to solve the problem of thumb metacarpal bone motion control. The virtual hand control script was written. The scene was built in Unity, which got a good result.
Key words: virtual hand; Unity; data glove; control script
虛擬手作為用戶的手的替身,在眾多虛擬現(xiàn)實(shí)應(yīng)用中扮演了重要角色,它與虛擬世界進(jìn)行交互,使其發(fā)生符合用戶期望的變化,讓用戶沉浸在虛擬環(huán)境中完成預(yù)想的一系列操作,而虛擬手仿真技術(shù)的進(jìn)步能夠讓用戶可以在虛擬現(xiàn)實(shí)應(yīng)用中獲得更加優(yōu)質(zhì)的體驗(yàn)。
對(duì)于數(shù)據(jù)手套驅(qū)動(dòng)的虛擬手仿真研究,已有不少相關(guān)研究:有的使用了旋轉(zhuǎn)矩陣[1],有的每次都要通過代碼尋找父物體[2],有的使用C++在Creator平臺(tái)中進(jìn)行開發(fā),其編程的難度較大[3],有的還要二次開發(fā)程序集[4]。
Unity是一款跨平臺(tái)3D游戲引擎,它使用C#或JavaScript語(yǔ)言,代碼編寫相對(duì)簡(jiǎn)單,且無(wú)需過問圖形渲染過程,使得開發(fā)人員可以更專心于功能的設(shè)計(jì)。而且Unity編輯器提供了對(duì)場(chǎng)景的直接測(cè)試,場(chǎng)景正在運(yùn)行的過程中還可以對(duì)其進(jìn)行修改以查看更多的細(xì)節(jié)。
本文使用Unity開發(fā)了一個(gè)使用5DT數(shù)據(jù)手套對(duì)虛擬手進(jìn)行運(yùn)動(dòng)控制的仿真程序。首先分析了手部結(jié)構(gòu)和運(yùn)動(dòng)規(guī)律,建立了16自由度的手部運(yùn)動(dòng)學(xué)模型;推導(dǎo)了控制骨骼旋轉(zhuǎn)的基本方程,對(duì)不同的骨骼控制方法進(jìn)行分類討論,提出了拇指掌骨旋轉(zhuǎn)控制的新方法;在Visual Studio中編輯控制器腳本,在Unity中編輯項(xiàng)目并生成了可執(zhí)行程序,取得了良好的仿真效果。
1 虛擬手運(yùn)動(dòng)學(xué)建模
手部共包含27塊骨骼,其中,主要的骨骼和關(guān)節(jié)名稱如圖1所示(原始圖片來源于http://sucai.redocn. com/tupian/570815.html)。
正常情況下,骨骼靠近人體的一端一直和關(guān)節(jié)連接,其約束模型可簡(jiǎn)化為鉸鏈約束[6],骨骼繞靠近人體一端關(guān)節(jié)的旋轉(zhuǎn)運(yùn)動(dòng)可以描述其局部運(yùn)動(dòng),為此規(guī)定骨骼局部坐標(biāo)系如下:以骨骼靠近手掌一端(近掌端)作為原點(diǎn);從原點(diǎn)指向骨骼另一端的方向作為X軸正方向;在手進(jìn)行抓握時(shí),手指做屈伸運(yùn)動(dòng)的平面內(nèi),與X軸垂直指向外側(cè)的方向作為Y軸正方向;以“右手定則”確定Z軸正方向;如圖2所示。
為了建立虛擬手模型,考慮盡量簡(jiǎn)化骨骼運(yùn)動(dòng),又要保留其運(yùn)動(dòng)特征,應(yīng)合理限制各個(gè)手指骨骼旋轉(zhuǎn)的自由度和角度范圍。通過觀察手指運(yùn)動(dòng),骨骼繞關(guān)節(jié)做局部旋轉(zhuǎn)的自由度和角度大致范圍如表1所示。
2 使用5DT數(shù)據(jù)手套
2.1 5DT數(shù)據(jù)手套
本文采用的是5DT Data Glove Ultra 14數(shù)據(jù)手套,內(nèi)置14個(gè)傳感器,其外觀及官方定義的傳感器編號(hào)如圖3所示。
2.2 標(biāo)定方法
數(shù)據(jù)手套標(biāo)定的出發(fā)點(diǎn),是結(jié)合人手關(guān)節(jié)彎曲的角度范圍,使用歸一化的數(shù)據(jù)控制虛擬手骨骼旋轉(zhuǎn)。數(shù)據(jù)手套驅(qū)動(dòng)可將傳感器的彎曲角度線性地轉(zhuǎn)換為0到4095之間的整數(shù)(伸直為最小值,彎曲180度為最大值),這些原始數(shù)值可以通過SDK中FDTGloveUltraCSharpWrapper程序集的GetSensorRawAll方法記錄到數(shù)組中[7]。之前已經(jīng)討論過,手指運(yùn)動(dòng)具有一定范圍,而手指的極限位置會(huì)形成傳感器的最小彎曲和最大彎曲,從而得到傳感器的最小數(shù)值[rLow]和最大數(shù)值[rUp]。SDK中的標(biāo)定方法SetCalibration,通過式(1)將當(dāng)前的原始數(shù)值[rVal]線性映射為[0,1]區(qū)間內(nèi)的數(shù)值[scaled],從而實(shí)現(xiàn)歸一化。
[scaled=0,rVal 當(dāng)手動(dòng)標(biāo)定出現(xiàn)錯(cuò)誤,使[rUp≤rLow]時(shí),[scaled]的計(jì)算如式(2)。 [scaled=01,rVal≤rLow,rVal>rLow] (2) 3 Unity場(chǎng)景開發(fā) 3.1 Unity項(xiàng)目開發(fā)流程 1)導(dǎo)入資源:項(xiàng)目開發(fā)所需要的一切資源都要放在Assets文件夾中才能被Unity編輯器使用,比如三維模型、貼圖、SDK程序集和腳本文件等。為了更有效地管理資源,通常在Assets文件夾中創(chuàng)建幾個(gè)子文件夾,將各種資源分門別類存放進(jìn)去,例如Scripts(腳本)、Plugins(插件)、Models(模型)、Texture(貼圖)等。由于使用的是64位版本的Unity,因此需要將64位的數(shù)據(jù)手套驅(qū)動(dòng)文件fglove.dll也放入Assets文件夾。 2)編輯腳本:Unity支持用JavaScript和C#兩種語(yǔ)言編寫腳本。JavaScript語(yǔ)句比較精簡(jiǎn),易于上手,并且Unity對(duì)它的執(zhí)行效率進(jìn)行了優(yōu)化。而C#語(yǔ)言通用性比較強(qiáng),可以使用面向C#的SDK進(jìn)行開發(fā)。支持使用內(nèi)置的MonoDevelop和其他編輯器(比如Microsoft Visual Studio)進(jìn)行開發(fā)。本文基于C#語(yǔ)言編寫了虛擬手控制腳本,將在3.2節(jié)中詳細(xì)介紹。 3)編輯和測(cè)試場(chǎng)景:將導(dǎo)入的各種資源放置到場(chǎng)景中,在場(chǎng)景中添加聲光,設(shè)置模型材質(zhì),為游戲?qū)ο筇砑咏M件等,搭建虛擬現(xiàn)實(shí)環(huán)境。 將控制腳本拖拽至虛擬手對(duì)象的查看器空白處,即可為虛擬手添加腳本。點(diǎn)擊運(yùn)行按鈕測(cè)試場(chǎng)景運(yùn)行情況。 4)構(gòu)建和執(zhí)行:Unity支持多達(dá)20種軟硬件平臺(tái)的游戲開發(fā),在其“File->Build Settings”下可以設(shè)置其輸出平臺(tái)。本文選擇x86_x64構(gòu)架的Windows平臺(tái)。 3.2 虛擬手控制腳本 3.3.1 引用命名空間 在腳本開頭用using關(guān)鍵字聲明所引用的程序集FDTGloveUltraCSharpWrapper,之后便可以使用程序集內(nèi)的各種方法。在類的開頭,定義和初始化腳本需要的字段,設(shè)定骨骼編號(hào)分組(下面“虛擬手控制”中會(huì)提到)和骨骼旋轉(zhuǎn)角度范圍。 3.3.2 開始 在Start()方法中實(shí)現(xiàn)腳本的初始化,有以下內(nèi)容。 1)初始化手套實(shí)例: 用glove = new CfdGlove()和glove.Open ("USB0")兩個(gè)語(yǔ)句新建并初始化手套實(shí)例。 2)映射骨骼: 本文使用Transform類型的數(shù)組lHandBones[]引用虛擬手手指的15個(gè)骨骼。為了使數(shù)據(jù)手套傳感器控制所對(duì)應(yīng)的虛擬手骨骼旋轉(zhuǎn)的這種映射關(guān)系在代碼中更加直觀,使場(chǎng)景中的骨骼對(duì)象在lHandBones[]中的編號(hào)盡量與數(shù)據(jù)手套對(duì)應(yīng)位置上的傳感器編號(hào)一致,對(duì)照?qǐng)D1設(shè)定游戲場(chǎng)景骨骼到lHandBones[]元素的映射關(guān)系如表2所示。 3)標(biāo)定手套 用caliFileLoaded = glove.LoadCalibration (“文件完整路徑”)語(yǔ)句加載在GloveManager中保存的標(biāo)定文件,并用bool類型的caliFileLoaded字段記錄標(biāo)定文件是否成功加載。 3.3.3 虛擬手控制 通過Update()方法,實(shí)現(xiàn)了在每一個(gè)游戲幀里讀取數(shù)據(jù)手套傳感器數(shù)值、并映射為場(chǎng)景中骨骼旋轉(zhuǎn)的角度。本小節(jié)首先推導(dǎo)了控制虛擬手骨骼旋轉(zhuǎn)的基本方程,而后討論了各種類型骨骼的控制方案,最后介紹了如何通過代碼實(shí)現(xiàn)。 1)虛擬手骨骼旋轉(zhuǎn)控制基本方程 設(shè)傳感器的最小彎曲角度為[angleLow],最大彎曲角度為[angleUp],傳感器的當(dāng)前彎曲角度為[angle],若數(shù)據(jù)手套傳感器的數(shù)值和其彎曲角度成線性關(guān)系,則存在實(shí)數(shù)[k]使得 [angle-angleLow=k(rVal-rLow)] (3) 可以推出 [angle=(angleUp-angleLow)?scaled+angleLow] (4) 設(shè)骨骼旋轉(zhuǎn)的最小彎曲角度為[handLow],最大彎曲角度為[handUp],當(dāng)前骨骼旋轉(zhuǎn)角度為[hand],若骨骼旋轉(zhuǎn)角度與傳感器彎曲角度成線性關(guān)系,即存在實(shí)數(shù)[q]使得: [hand-handLow=q(angle-angleLow)] (5) 則同理可推出 [hand=(handUp-handLow)?scaled+handLow] (6) 由式(6)即得到了基于線性對(duì)應(yīng)關(guān)系的虛擬手骨骼旋轉(zhuǎn)控制基本方程。 2)虛擬手骨骼旋轉(zhuǎn)控制方案 控制虛擬手骨骼旋轉(zhuǎn)的總體方案是,將骨骼對(duì)象的編號(hào)進(jìn)行分組:0、1、4、6、7、10、13號(hào)為第一組,5、8、11、14號(hào)為第二組,3、9、12號(hào)為第三組,2號(hào)為第四組,每個(gè)組內(nèi)的骨骼控制方法是相近的。第一組和第二組骨骼情形簡(jiǎn)單,編號(hào)分別用一個(gè)數(shù)組存放,便于使用foreach語(yǔ)句遍歷組內(nèi)編號(hào)進(jìn)行控制,其他兩組逐個(gè)骨骼進(jìn)行控制,取表1中的角度范圍作為虛擬手骨骼的旋轉(zhuǎn)范圍,具體方法如下。 ① 0、1、4、6、7、10、13號(hào)骨骼只有Z一個(gè)自由度,且其靠近手掌一端的關(guān)節(jié)處有一個(gè)同樣編號(hào)的傳感器,則根據(jù)式(6),由此傳感器數(shù)據(jù)控制其Z軸旋轉(zhuǎn)。 ② 5、8、11、14號(hào)骨骼只有Z一個(gè)自由度,但沒有對(duì)應(yīng)的傳感器,根據(jù)手部運(yùn)動(dòng)規(guī)律[8],其旋轉(zhuǎn)角度分別規(guī)定為4、7、10、13號(hào)骨骼旋轉(zhuǎn)角的2/3。
③ 3、9、12號(hào)骨骼有Y、Z兩個(gè)自由度,且其靠近手掌一端的關(guān)節(jié)處有一個(gè)同樣編號(hào)的傳感器,由此傳感器數(shù)據(jù)按式(6)控制其Z軸旋轉(zhuǎn),此關(guān)節(jié)靠近中指一側(cè)、與相鄰關(guān)節(jié)之間有一個(gè)傳感器,由此傳感器數(shù)據(jù)控制骨骼的Y軸旋轉(zhuǎn)。由于規(guī)定6號(hào)骨骼無(wú)Y向旋轉(zhuǎn),可作為參考,因此3號(hào)和9號(hào)的Y軸旋轉(zhuǎn)由數(shù)據(jù)手套的5號(hào)和8號(hào)傳感器按式(6)控制,而12號(hào)的Y向旋轉(zhuǎn)是它相對(duì)于9號(hào)的Y向旋轉(zhuǎn)和9號(hào)自身Y向旋轉(zhuǎn)的疊加,12號(hào)相對(duì)于9號(hào)的Y向旋轉(zhuǎn)可由11號(hào)傳感器數(shù)值經(jīng)式(6)計(jì)算得到。
④ 2號(hào)骨骼有X、Y、Z三個(gè)自由度,而只有2號(hào)傳感器與其直接對(duì)應(yīng)。與2號(hào)傳感器相鄰的是0號(hào)傳感器,如果找到0號(hào)傳感器數(shù)值與2號(hào)骨骼的旋轉(zhuǎn)角度之間的關(guān)系,就可以用0號(hào)和2號(hào)傳感器共同控制2號(hào)骨骼的旋轉(zhuǎn)。基于此,借助GloveManager做如下分析。
首先使用將傳感器進(jìn)行適當(dāng)標(biāo)定,而后單獨(dú)觀測(cè)0、2號(hào)傳感器數(shù)值,通過兩種手部運(yùn)動(dòng)研究拇指指骨的控制方法:(a)保持拇指近節(jié)指骨和末節(jié)指骨不轉(zhuǎn)動(dòng),沿Y軸轉(zhuǎn)動(dòng)拇指掌骨,使拇指指甲近似在同一平面內(nèi)移動(dòng),得到圖4中a段曲線;(b)保持拇指末節(jié)指骨不轉(zhuǎn)動(dòng),沿Z軸轉(zhuǎn)動(dòng)拇指掌骨,使拇指在XOY平面內(nèi)進(jìn)行自然的屈伸運(yùn)動(dòng),得到圖4中b段曲線。
觀察a段曲線發(fā)現(xiàn),拇指掌骨的Y向旋轉(zhuǎn)對(duì)2號(hào)傳感器數(shù)值有明顯影響,而對(duì)0號(hào)的影響并不明顯,因此可以用2號(hào)傳感器的數(shù)值控制拇指掌骨的Y向旋轉(zhuǎn)。觀察b段曲線發(fā)現(xiàn),拇指掌骨單純沿Z軸旋轉(zhuǎn)時(shí),0、2號(hào)傳感器數(shù)值都有明顯變化。若單純用2號(hào)傳感器的數(shù)值控制拇指掌骨的Z向旋轉(zhuǎn),會(huì)導(dǎo)致拇指掌骨沿Y軸旋轉(zhuǎn)時(shí)傳感器數(shù)值會(huì)同時(shí)帶動(dòng)虛擬手拇指掌骨沿Z向旋轉(zhuǎn)。
解決辦法是,用2號(hào)傳感器的歸一化數(shù)值和比例因子[f2]的乘積,減去0號(hào)傳感器數(shù)值歸一化和比例因子[f0]的乘積,將差值限定在[0,1]區(qū)間內(nèi),若比0小則為0,比1大則取1。這個(gè)差值作為[scaled]值代入式(6)計(jì)算2號(hào)骨骼對(duì)象Z向旋轉(zhuǎn)角,本文設(shè)置[f2]取1.3,[f0]取0.3。另外,通過觀察發(fā)現(xiàn),2號(hào)骨骼的X向旋轉(zhuǎn)與Y向旋轉(zhuǎn)成線性關(guān)系,因此可以用1減去2號(hào)傳感器歸一化數(shù)值的差值控制其X向旋轉(zhuǎn)。
3)代碼實(shí)現(xiàn)
① 令字段獲取手套傳感器數(shù)值。用GetSensorScaledAll (ref values)語(yǔ)句得到的長(zhǎng)度為20的數(shù)組values中,前14個(gè)元素中的values[i]即為圖3中編號(hào)為i的傳感器的歸一化數(shù)據(jù)。
② 傳感器數(shù)值換算為角度。根據(jù)式(6),計(jì)算各傳感器所相應(yīng)自由度上的旋轉(zhuǎn)角度。
③ 根據(jù)計(jì)算結(jié)果旋轉(zhuǎn)骨骼對(duì)象。設(shè)游戲?qū)ο竺麨閛bj,則obj.transform.localRotation是一個(gè)四元數(shù)(Quaternion)類型變量,描述了obj的局部坐標(biāo)系相對(duì)于其父級(jí)對(duì)象的局部坐標(biāo)系的旋轉(zhuǎn)。Quaternion.Euler()方法將繞三個(gè)軸分別轉(zhuǎn)動(dòng)一定角度(單位為度)的一個(gè)旋轉(zhuǎn)轉(zhuǎn)換為一個(gè)四元數(shù)。通過lHandPalm.localRotation = Quaternion. Euler (x,y,z)語(yǔ)句,就實(shí)現(xiàn)了讓LeftHand對(duì)象繞父級(jí)對(duì)象局部坐標(biāo)的z軸旋轉(zhuǎn)z度、x軸旋轉(zhuǎn)x度、繞y軸旋轉(zhuǎn)y度(以這樣的順序[9])。根據(jù)控制方案,將②中計(jì)算的角度值作為上述語(yǔ)句中的相應(yīng)的y或z,則可實(shí)現(xiàn)骨骼對(duì)象在場(chǎng)景中的旋轉(zhuǎn)。
3.3.4 界面顯示
在OnGUI()方法中使用GUI.Label方法顯示標(biāo)定文件是否成功加載,若caliFileLoaded字段為真則顯示“Calibration File Loaded”,否則顯示“Calibration File Loading Failed”。
4 仿真驗(yàn)證
用GloveManager對(duì)數(shù)據(jù)手套進(jìn)行標(biāo)定后保存標(biāo)定文件,并在虛擬手控制腳本的檢視器中輸入其完整路徑,點(diǎn)擊運(yùn)行按鈕,各種手勢(shì)下的仿真效果如圖5所示??傮w上運(yùn)動(dòng)跟蹤的效果較好,但是對(duì)于大拇指掌骨在某些方位下旋轉(zhuǎn)的控制仍然令用戶困惑,說明在數(shù)據(jù)手套傳感器數(shù)量不足的情況下,大拇指掌骨的運(yùn)動(dòng)重定向仍需要進(jìn)一步優(yōu)化。
5 結(jié)論
本文在Unity中開發(fā)了一個(gè)用5DT數(shù)據(jù)手套控制虛擬手活動(dòng)的場(chǎng)景,并對(duì)其關(guān)鍵技術(shù)和實(shí)現(xiàn)進(jìn)行了闡述,對(duì)開發(fā)過程中遇到的一些問題提出了解決辦法,最后運(yùn)行場(chǎng)景取得了較好效果。今后將研究利用Unity實(shí)現(xiàn)虛擬手抓取物體,以提高對(duì)數(shù)據(jù)手套的利用效果。
參考文獻(xiàn):
[1] 安明, 陳善廣, 劉玉慶. 基于數(shù)據(jù)手套的虛擬手精確建模的研究與實(shí)現(xiàn)[J]. 計(jì)算機(jī)仿真, 2010(1): 241-244.
[2] 張志純, 楊曉文, 況立群, 等. 基于Virtools和5DT數(shù)據(jù)手套的手勢(shì)仿真研究[J]. 科學(xué)技術(shù)與工程, 2015(4): 140-144.
[3] 陳冠宇, 李雯文, 佘建國(guó). 船舶機(jī)艙虛擬環(huán)境中虛擬手的介入操控[J]. 上海海事大學(xué)學(xué)報(bào), 2014(04): 50-54, 84.
[4] 羅迎. Quest3D虛擬人機(jī)交互系統(tǒng)中5DT數(shù)據(jù)手套的應(yīng)用[J]. 科學(xué)技術(shù)與工程, 2011(4): 855-859.
[5] 宣雨松. Unity3D游戲開發(fā)[M]. 北京: 人民郵電出版社, 2012.
[6] 李澍, 劉毅,王念東. 虛擬環(huán)境中的多手指抓取操作技術(shù)[J]. 計(jì)算機(jī)輔助設(shè)計(jì)與圖形學(xué)學(xué)報(bào), 2010,22(10): 1728-1733.
[7] 5DT. 5DT Data Glove Ultra Manual [EB/OL]. 2011/2015-04-19. http://www.5dt.com/?page_id=34.
[8] 殷磊, 韓靜, 王燁, 等. 虛擬現(xiàn)實(shí)環(huán)境下虛擬手控制技術(shù)研究[J]. 系統(tǒng)仿真學(xué)報(bào),2009(2): 488-451.
[9] 游戲蠻牛. Unity腳本手冊(cè)[EB/OL]. 2014/2015-04-28. http://www.unitymanual.com/m/Script/index.htm