黃弢,汪迪,萬(wàn)晨暉,馬瑞啟,許 洋
(華中科技大學(xué)機(jī)械科學(xué)與工程學(xué)院,武漢 430074)
實(shí)驗(yàn)教學(xué)是高校創(chuàng)新實(shí)踐人才培養(yǎng)的重要手段[1],機(jī)器人教學(xué)是工程類(lèi)實(shí)驗(yàn)教學(xué)中重要的組成部分[2],在實(shí)驗(yàn)教學(xué)中,受限于現(xiàn)場(chǎng)條件和傳統(tǒng)工業(yè)機(jī)器人的價(jià)格,可用的實(shí)驗(yàn)資源往往有限,學(xué)習(xí)成本較高。借助計(jì)算機(jī)仿真技術(shù),可在軟件中集成虛擬仿真模塊,自定義仿真場(chǎng)景[3]。
目前,國(guó)內(nèi)外比較通用的機(jī)器人仿真軟件有VREP、Gazebo和Webots 等[4]。V-REP是一款靈活的通用機(jī)器人仿真器,支持嵌入式腳本,插件和ROS 節(jié)點(diǎn)[6],自2019 年后改名為CoppeliaSim,V-REP已經(jīng)停止更新。Gazebo可構(gòu)建機(jī)器人運(yùn)動(dòng)仿真模型,支持傳感器數(shù)據(jù)的仿真[7],主要配合ROS 仿真在Linux 平臺(tái)使用。Webots自帶眾多不同種類(lèi)傳感器和驅(qū)動(dòng)器[8],近年來(lái)在四足類(lèi)機(jī)器人仿真上應(yīng)用廣泛[9]?,F(xiàn)有平臺(tái)的不足之處在于,它們只是一個(gè)仿真工具,而非一個(gè)實(shí)驗(yàn)工具,為完成實(shí)驗(yàn)往往需要多個(gè)軟件相互配合,學(xué)習(xí)成本高,開(kāi)發(fā)一款具備機(jī)器人仿真功能與實(shí)驗(yàn)設(shè)計(jì)的平臺(tái)則具有較大意義。
工業(yè)機(jī)器人中應(yīng)用較為廣泛的是示教編程,即通過(guò)示教器控制機(jī)器人移動(dòng),在運(yùn)動(dòng)過(guò)程中記錄相應(yīng)的關(guān)節(jié)位置,完成示教操作。這種示教方式過(guò)于簡(jiǎn)單和低效,并不適用于機(jī)器人學(xué)科教學(xué)。一種較好的方式是類(lèi)似于Matlab 腳本化、交互式編程,既可通過(guò)類(lèi)的方式封裝簡(jiǎn)易調(diào)用函數(shù),也可以賦予用戶自己實(shí)現(xiàn)算法的能力。
為使機(jī)器人仿真實(shí)驗(yàn)平臺(tái)更具靈活性和可擴(kuò)展性,采用以Bullet為仿真引擎,以Lua 為交互式操作語(yǔ)言、Qt為圖形框架和節(jié)點(diǎn)圖和數(shù)據(jù)流驅(qū)動(dòng)為實(shí)驗(yàn)系統(tǒng)的技術(shù)方案。體架構(gòu)設(shè)計(jì)如圖1 所示。
圖1 基于Bullet引擎的機(jī)器人仿真實(shí)驗(yàn)平臺(tái)整體架構(gòu)
其中,仿真層為機(jī)器人仿真的核心實(shí)現(xiàn),由OpenGL提供場(chǎng)景管理與視圖管理,Bullet 提供物理運(yùn)算,如碰撞檢測(cè)、運(yùn)動(dòng)學(xué)運(yùn)算和動(dòng)力學(xué)運(yùn)算等。操縱層面向用戶,以函數(shù)和功能節(jié)點(diǎn)的方式向用戶提供對(duì)仿真層的功能訪問(wèn)。
Bullet是一種應(yīng)用廣泛的物理引擎,支持多個(gè)平臺(tái)[10]。作為一款物理引擎,它并沒(méi)有提供可視化對(duì)象的方法,為可視化Bullet對(duì)象,還需要使用OpenGL,它的接口與圖形卡硬件非常接近,處理底層命令,尤其是圖形應(yīng)用程序,是一項(xiàng)煩瑣的任務(wù),例如Glut、FreeGlut、Glfw庫(kù)可以用來(lái)簡(jiǎn)化工作,這類(lèi)庫(kù)通??煞Q(chēng)為包裝器,另外它還負(fù)責(zé)應(yīng)用程序的啟動(dòng)、控制和輸入處理[13]。
物理計(jì)算方面由Bullet 提供的相關(guān)接口實(shí)現(xiàn),主要涉及的核心對(duì)象有世界對(duì)象、碰撞配置、碰撞檢測(cè)、約束解算器和碰撞調(diào)度器等多種。物理和圖形部分需要進(jìn)行運(yùn)動(dòng)狀態(tài)綁定和幾何更新,以便根據(jù)物理引擎計(jì)算的位姿變換矩陣更新幾何顯示。采用物理和圖形分離的架構(gòu)能降低程序耦合,便于功能擴(kuò)展[14]。
圖2 渲染場(chǎng)景的一般流程
在創(chuàng)建OpenGL上下文之后,將解析OpenGL函數(shù)指針,即調(diào)用硬件平臺(tái)的函數(shù)實(shí)現(xiàn),所有OpenGL命令都會(huì)用來(lái)改變當(dāng)前上下文的狀態(tài)信息,OpenGL 根據(jù)上下文的狀態(tài)信息進(jìn)行渲染工作。
Bullet保持其核心組件的相同模塊化設(shè)計(jì),甚至包括單個(gè)物理對(duì)象。這使得可通過(guò)隨意互換或替換物理對(duì)象的組件來(lái)定制它們。在Bullet中構(gòu)建物理對(duì)象需要3 個(gè)組件:
(1)碰撞形狀(Collision Shape)。定義物體的體積和形狀,可以是長(zhǎng)方體、球體、圓柱體或其他更為復(fù)雜的形狀,決定了物體與其他物體在碰撞時(shí)的響應(yīng)方式。
(2)運(yùn)動(dòng)狀態(tài)(Motion State)。跟蹤物體的運(yùn)動(dòng)狀態(tài),運(yùn)動(dòng)狀態(tài)的工作是記錄對(duì)象的當(dāng)前位置和方向。
(3)碰撞對(duì)象(Collision Object)。作為對(duì)象的主控制器,管理前面提到的組件和對(duì)象的物理屬性。碰撞物體是物理物體的基本組成部分,因?yàn)樗鼈儽3至宋矬w的物理屬性。
文獻(xiàn)[19]顯示,當(dāng)模型的水平范圍為8~10倍隧道直徑時(shí),即可獲得較高的計(jì)算精度。本文建立了二維彈塑性動(dòng)力有限元模型,模型水平方向?yàn)?0 m,豎直方向?yàn)?0 m,盾構(gòu)隧道直徑為6 m。
從創(chuàng)建Bullet對(duì)象,配置相應(yīng)的物理參數(shù),到步進(jìn)模擬,場(chǎng)景渲染基本流程如圖3 所示。
圖3 場(chǎng)景渲染、基本流程
在創(chuàng)建Bullet對(duì)象之后,在OpenGL中同步創(chuàng)建幾何形狀,其關(guān)鍵在于運(yùn)動(dòng)狀態(tài)的綁定,這一步驟是通過(guò)指針?lè)绞皆O(shè)定運(yùn)動(dòng)狀態(tài)。既當(dāng)物理模型中的運(yùn)動(dòng)狀態(tài)更新時(shí),用于描述運(yùn)動(dòng)狀態(tài)的變量值會(huì)同步更新,當(dāng)渲染場(chǎng)景時(shí),通過(guò)指針來(lái)訪問(wèn)描述運(yùn)動(dòng)狀態(tài)的變量,此時(shí)即可實(shí)現(xiàn)狀態(tài)的同步更新。
Lua 是一種嵌入式腳本語(yǔ)言,擴(kuò)展性好,容易與C/C++語(yǔ)言結(jié)合。Lua的目標(biāo)是僅提供一些很有限但卻很強(qiáng)大的語(yǔ)言機(jī)制[11]。Lua 是基于關(guān)聯(lián)數(shù)組和擴(kuò)展性語(yǔ)法結(jié)構(gòu)設(shè)計(jì)的語(yǔ)言,支持動(dòng)態(tài)定義類(lèi)型,內(nèi)存自動(dòng)回收機(jī)制,常被用于嵌入其他宿主語(yǔ)言[12]。
將Bullet相關(guān)功能封裝為C ++接口,即可實(shí)現(xiàn)基于C++語(yǔ)言的機(jī)器人仿真,但C ++程序需要編譯,無(wú)法脫離開(kāi)發(fā)環(huán)境存在,不便于用在實(shí)際的教學(xué)環(huán)境。Lua語(yǔ)言提供了一種在Lua中調(diào)用C++函數(shù)的機(jī)制。
Lua與C/C++語(yǔ)言之間的通信,主要是通過(guò)一個(gè)虛擬堆棧進(jìn)行。Lua 給C ++語(yǔ)言提供了API 來(lái)對(duì)堆棧進(jìn)行操作,這些API 就好比兩者之間通信的協(xié)議。C++與Lua的常規(guī)綁定方法如下:
(1)在C++中提供具體的函數(shù)
(2)在C++中按照指定格式提供回調(diào)函數(shù),調(diào)用具體的函數(shù)
(3)在C++中注冊(cè)回調(diào)函數(shù)
可見(jiàn),對(duì)于每一個(gè)需要在Lua 中調(diào)用的C ++函數(shù),都需要一系列較為繁瑣的綁定過(guò)程。對(duì)于Qt環(huán)境而言,使用QtLua 庫(kù)可以大大簡(jiǎn)化這一過(guò)程。它提供了有用的C++包裝器類(lèi),以使Lua 和C ++都可訪問(wèn)C++和Lua 對(duì)象。利用Qt 元對(duì)象系統(tǒng)的優(yōu)勢(shì)將QObject成員公開(kāi)給Lua腳本。其特點(diǎn)如下:
(1)不公開(kāi)基于Lua 堆棧的CAPI,僅從C ++代碼操縱QtLua::State和QtLua::Value 之類(lèi)的C ++對(duì)象。
(2)通過(guò)繼承QtLua::UserData類(lèi),可將C++對(duì)象作為用戶數(shù)據(jù)值提供給Lua??赏ㄟ^(guò)覆蓋虛擬函數(shù)來(lái)重新定義所有Lua 元操作,包括對(duì)來(lái)自Lua 的userdata對(duì)象的迭代。
(3)可以將QtLua::Function 類(lèi)子類(lèi)化,以輕松定義可從Lua 調(diào)用的C ++函數(shù)對(duì)象。使用QtLua 綁定Lua與C++的基本流程如圖4 所示。
圖4 在C++中綁定Lua的基本流程
創(chuàng)造LuaState,用于儲(chǔ)存Lua 變量值的虛擬堆棧,啟用Lua的標(biāo)準(zhǔn)庫(kù),注冊(cè)自定義對(duì)象。如自定義變量(屬性)、自定義函數(shù)對(duì)象和自定義類(lèi)對(duì)象。然后就可以通過(guò)state執(zhí)行Lua語(yǔ)句,Lua中注冊(cè)的C ++對(duì)象均可通過(guò)Lua語(yǔ)句來(lái)調(diào)用或賦值。
基于節(jié)點(diǎn)圖的控制方式是對(duì)基于Lua控制方式的一層封裝,實(shí)現(xiàn)了以事件驅(qū)動(dòng)的方式來(lái)調(diào)用Lua,并將設(shè)備和功能塊抽象為節(jié)點(diǎn),節(jié)點(diǎn)之間的數(shù)據(jù)傳遞方式通過(guò)連線來(lái)定義。
在現(xiàn)有基于Lua 腳本的控制模式下,已可進(jìn)行構(gòu)建機(jī)器人仿真場(chǎng)景,分析仿真結(jié)果等操作。在復(fù)雜的機(jī)器人場(chǎng)景中,往往需要多臺(tái)機(jī)器人相互協(xié)作共同完成實(shí)驗(yàn)任務(wù),為實(shí)現(xiàn)靈活的機(jī)器人運(yùn)動(dòng)控制,可根據(jù)不同實(shí)驗(yàn)場(chǎng)景進(jìn)行機(jī)器人組態(tài)[16]。本平臺(tái)設(shè)計(jì)了一種基于事件驅(qū)動(dòng)的圖形節(jié)點(diǎn)編程工具。
節(jié)點(diǎn)編輯工具在建模類(lèi)工具中應(yīng)用廣泛,如Blender的材質(zhì)編輯和模型渲染節(jié)點(diǎn)圖。其基本流程為事先定義數(shù)據(jù)模型并將其注冊(cè)到數(shù)據(jù)模型注冊(cè)表,構(gòu)造節(jié)點(diǎn)并與對(duì)應(yīng)的數(shù)據(jù)模型進(jìn)行綁定,用戶操作信號(hào)或者定時(shí)器信號(hào)、通信信號(hào)等將觸發(fā)模型計(jì)算,計(jì)算結(jié)果將傳播到輸出連接,每個(gè)新連接都會(huì)獲取可用的數(shù)據(jù)并進(jìn)一步傳播,數(shù)據(jù)節(jié)點(diǎn)的組成如圖5 所示。
圖5 數(shù)據(jù)節(jié)點(diǎn)的組成
數(shù)據(jù)節(jié)點(diǎn)采用數(shù)據(jù)模型和圖形節(jié)點(diǎn)分離的設(shè)計(jì)模式,數(shù)據(jù)模型負(fù)責(zé)定義端口、數(shù)據(jù)輸入、輸出和數(shù)據(jù)運(yùn)算等,而圖形節(jié)點(diǎn)則定義了圖形的外觀樣式、幾何形狀和連接狀態(tài)等。
本平臺(tái)將圖形節(jié)點(diǎn)和Lua 腳本融合,實(shí)現(xiàn)一種形如Simulink中Matlab Function的效果。在節(jié)點(diǎn)從構(gòu)造到數(shù)據(jù)輸入、輸出的不同階段,將執(zhí)行不同的函數(shù)。Lua腳本節(jié)點(diǎn)生命周期中所執(zhí)行的函數(shù)如圖6 所示。
圖6 Lua腳本節(jié)點(diǎn)生命周期中所執(zhí)行的函數(shù)
其中構(gòu)造函數(shù)和初始化函數(shù)只執(zhí)行一遍,而數(shù)據(jù)輸入觸發(fā)的運(yùn)算類(lèi)函數(shù)將在每次輸入數(shù)據(jù)時(shí)執(zhí)行。在Lua函數(shù)中通過(guò)調(diào)用獲取節(jié)點(diǎn)數(shù)據(jù)函數(shù),將數(shù)據(jù)從C++環(huán)境中拷貝到Lua 環(huán)境,編寫(xiě)相應(yīng)的處理邏輯,調(diào)用輸出節(jié)點(diǎn)數(shù)據(jù)函數(shù),將數(shù)據(jù)節(jié)點(diǎn)數(shù)據(jù)傳播到下個(gè)節(jié)點(diǎn)。
節(jié)點(diǎn)圖的典型優(yōu)勢(shì)在于基于數(shù)據(jù)流驅(qū)動(dòng)的控制邏輯,避免了循環(huán)掃描指令的CPU 負(fù)荷,同時(shí)圖形化交互和事件驅(qū)動(dòng)方式符合人的控制直覺(jué)??蓪⒌湫偷墓δ軌K封裝為圖形節(jié)點(diǎn),用戶只需要考慮輸入和輸出,而不用關(guān)注內(nèi)部的實(shí)現(xiàn)細(xì)節(jié)。節(jié)點(diǎn)之間具有低耦合的特性,可根據(jù)實(shí)際的邏輯將不同的節(jié)點(diǎn)進(jìn)行連接和組合。
圖7 是一個(gè)G代碼解析并控制Scara機(jī)器人繪圖的一個(gè)案例,Gcoder 模塊負(fù)責(zé)G 代碼的解析,將解析得到的點(diǎn)位通過(guò)輸出端口輸出,連接到一個(gè)散點(diǎn)圖模塊和機(jī)器人“反解驅(qū)動(dòng)”模塊,“反解驅(qū)動(dòng)”模塊的輸出端口輸出機(jī)器人實(shí)際末端軌跡。
圖7 Scara機(jī)器人繪圖案例
Scara機(jī)器人繪圖實(shí)驗(yàn)流程如圖8 所示。
圖8 Scara機(jī)器人繪圖流程
通過(guò)Gcoder模塊導(dǎo)入G代碼文件并解析,將開(kāi)啟一段定時(shí)循環(huán),不斷輸出點(diǎn)位數(shù)據(jù),虛線框中的內(nèi)容在“反解驅(qū)動(dòng)”節(jié)點(diǎn)中實(shí)現(xiàn)。G代碼解析并執(zhí)行完畢后,運(yùn)行效果如圖9 所示。
圖9 Scara機(jī)器人繪圖效果
發(fā)現(xiàn)最終運(yùn)動(dòng)得到的路徑與期望路徑基本一致,達(dá)到預(yù)期的實(shí)驗(yàn)?zāi)康?,如圖10 所示。
圖10 機(jī)器人末端理論軌跡與實(shí)際軌跡
本實(shí)驗(yàn)平臺(tái)支持多種實(shí)驗(yàn)場(chǎng)景,通過(guò)導(dǎo)入不同機(jī)器人模型可進(jìn)行不同的實(shí)驗(yàn)。得益于Bullet的碰撞檢測(cè)功能,能在機(jī)器人場(chǎng)景中模擬抓取實(shí)驗(yàn)。Scara機(jī)器人抓取案例腳本實(shí)驗(yàn)界面如圖11 所示。
圖11 Scara機(jī)器人抓取案例腳本
游戲手柄是一種典型的輸入設(shè)備,通過(guò)操縱按鈕和搖桿可以向計(jì)算機(jī)發(fā)送相應(yīng)的觸發(fā)信號(hào)和鍵值,是一種典型的事件發(fā)生裝置。在實(shí)驗(yàn)平臺(tái)中,游戲手柄作為輸入設(shè)備被定義為功能節(jié)點(diǎn),它的按鍵信號(hào)被映射到節(jié)點(diǎn)的輸出端口,并與后續(xù)的邏輯處理節(jié)點(diǎn)相連接。當(dāng)按下或松開(kāi)手柄的某一個(gè)鍵時(shí),對(duì)應(yīng)的端口將發(fā)射一個(gè)數(shù)據(jù)更新信號(hào),并將數(shù)據(jù)傳遞到下一個(gè)節(jié)點(diǎn)。
手柄的前后左右搖桿來(lái)控制Scara 機(jī)器人末端的平面移動(dòng)方向,上下鍵來(lái)控制機(jī)器人升降。而B(niǎo)、A功能鍵用于控制末端執(zhí)行器——卡爪的開(kāi)合,Scara機(jī)器人抓取效果如圖12 所示。
圖12 Scara機(jī)器人抓取效果
由Scara機(jī)器人解析G代碼繪圖和抓取物體實(shí)驗(yàn)中可見(jiàn),本平臺(tái)能夠快速搭建仿真實(shí)驗(yàn),并對(duì)結(jié)果進(jìn)行實(shí)時(shí)可視化分析。機(jī)器人功能的節(jié)點(diǎn)化使得實(shí)驗(yàn)平臺(tái)具有較高的可重構(gòu)性和可擴(kuò)展性,能適應(yīng)機(jī)器人實(shí)驗(yàn)的多樣化。
基于Bullet 設(shè)計(jì)了一種機(jī)器人仿真實(shí)驗(yàn)平臺(tái),具備運(yùn)動(dòng)學(xué)解算、碰撞檢測(cè)與軌跡可視化功能。通過(guò)使用數(shù)據(jù)流節(jié)點(diǎn)圖作為邏輯手段,將計(jì)算模塊和通信模塊封裝為功能節(jié)點(diǎn),大大降低了實(shí)驗(yàn)搭建的難度。通過(guò)圖形連接定義運(yùn)算邏輯的方式,便于用戶快速理解實(shí)驗(yàn)架構(gòu)。應(yīng)用實(shí)例表明,該平臺(tái)功能完善,可擴(kuò)展性強(qiáng),兼具腳本語(yǔ)言的靈活性與圖形化語(yǔ)言的便捷性,適用機(jī)器人的多種實(shí)驗(yàn)場(chǎng)景。