Search This Blog

7/23/16

如何使用 Android* 智慧型手機開發智慧型自動飛行器

如何使用 Android* 智慧型手機開發智慧型自動飛行器

簡介

小型的民用飛行器除了玩起來有趣,如果能實際動手做更令人興奮不已!如果您有興趣開發自己的「智慧型」飛行器,本文提供簡易的方向指引,協助您使用 Android* 智慧型手機、OpenCV*、C++ 和 Java 打造智慧型自動飛行器。* 這只是起點,一旦您熟悉了這些說明,還能用其他程式將飛行器改造得更為出色。請至 Intel® 軟體學院計畫 (Intel® Software Academic Program) [1] 取得自學 Intel® OpenCourseWare 的詳細資訊。

材料與方法

自動和智慧?
飛行器如果要自動飛行,所有必需的感測器、處理功能及通訊晶片都必須內建。雖然看起來配備不多,不過目前市面上一般大眾可以取得的商業民用飛行器,有許多都沒符合這樣的標準呢。
您看過 Lexus 和 KMEL Robotics [2] 的飛行器廣告嗎?廣告中有一大群超級精準的小型飛行器,這些飛行器在室內操作,空間中安置許多強大的感測器,因此可以編排飛行器的動作。由於飛行器近來很熱門,您或許也知道飛行器可以用 GPS 導航。GPS 方便且非常容易存取 (因為是數位訊號),所以飛機在高海拔的巡航階段會使用 GPS 導航。不過 GPS 的精確度在 ±2.5 公尺之間,還有影響很大的延遲問題,無法讓飛行器運用,將披薩送到家門口。飛行器近個 2.5 公尺可能會撞到房屋,左右差個 2.5 公尺可能也會墜毀。飛行器的確具有獨立導航能力,不過並不是十分「智慧」。
飛行器要能稱得上「智慧」,就必須內建足夠的處理功能,例如拍攝影片、即時分析 QR 條碼 (簡單)、形狀或動作 (困難) 等目標。甚至也可以即時測量體積和重新建置空間,就和使用 MIT UAV 的飛行器一樣 [3]. 不過以上種種「升級功能」都需要強大的處理器,並搭配使用加速器和 GPS 等感測器,有時可能還需要透過 3G/4G 網路進行通訊。以上這些裝備也必須輕巧、容易編程,能用理想的電池供電。歸結下來,我們只能用非常強大的手機,用來驅動飛行器的飛行功能。
我們最近使用 ZTE V975 Geek 這款搭載 Intel® Atom™ 處理器 Z2580 的 Android 智慧型手機,開發出飛行器遙控裝置。使用 Android 可輕鬆開發軟體,也能在個人電腦和智慧型手機之間共用程式碼,即使是 Intel® Integrated Performance Primitives (Intel® IPP) [4] 或 OpenCV [5] 這樣的原生程式庫,Intel Android 智慧型手機和個人電腦也都能使用,所以不需要從頭來過,智慧型手機已經具備所有必要元件:攝影機、GPS、加速器和 3G 網路。
馬達控制
選好內嵌的電腦之後,就可以連接馬達了。我們選擇了 Pololu Maestro* 伺服馬達控制器,價格約為 5 歐元,透過 USB 連接,甚至具有藍牙功能* (需搭配選購的藍牙序列介面)。這張控制卡可以控制標準伺服馬達。不論是引導四軸飛行器或其他類型飛行器,只要將無線電控制零件更換為 Android 智慧型手機,Pololu 卡就能讓它變成自動智慧型飛行器。這種搭配可以無限重複使用,很簡單,對吧?
用幾行程式碼加上 Android USB 標準套件,我們就能控制伺服馬達,進而操控飛行器的動作。再增加使用幾行程式碼,就能存取 GPS、拍照,並透過 3G 傳送。至於在軟體方面,使用 Android 可以迅速開發設計。
從 UsbDeviceConnection 呼叫 controlTransfer:
import android.hardware.usb.UsbDeviceConnection;
// …
private UsbDeviceConnection connection;
// …
connection.controlTransfer(0x40, command, value, channel, null, 0, 5000);

這張控制卡可以讓您移動伺服馬達,判定目標位置、速度及加速度,達成順暢的動作。「command」引數可為下列三個值之一:
 public static final int USB_SET_POSITION = 0x85;
 public static final int USB_SET_SPEED = 0x87;
 public static final int USB_SET_ACCELERATION = 0x89;
您必須選擇對應值,並以「channel」鎖定正確的伺服馬達。完整的原始程式碼,以及應用程式資訊清單的 USB 存取設定包含在 ZIP 檔案之中 [1]。
四軸飛行器特例
目前為止一切順利。硬體隨插即用,程式碼簡單明瞭,一切都在 Android 下完成。不過開發嵌入式系統有些特性,以下以四軸飛行器為例進行探討。多軸飛行器和比較簡單的機型 (如遙控車或飛機) 之間,有很大的差異。要驅動 RC 電動車,只要一個電子速度控制伺服馬達 (Electronic Speed Control,ESC) 控制加速,以及另一個伺服馬達控制方向即可,但多軸飛行器需要能持續平衡的引擎,以保持在適當位置。還好四軸飛行器原本就有穩定卡,與其直接連接 Pololu 控制卡及四軸飛行器的四個電子速度控制伺服馬達,還要在 Android 以 C/C++ 或 Java 編寫複雜的穩定軟體,不如將穩定卡直接連接 Pololu 卡,讓穩定卡管理四個引擎,輕鬆方便。其他要控制的部份則可使用簡單的 Java 指令完成,例如 +/- altitude+/- speed/+/- inclination, and +/- direction。我們選擇在 Android 智慧型手機作業,因為它有強大的處理器,而引擎平衡部分則交由只要數歐元的小型專用卡處理。開發人員,您可以瞭解一下這張卡的用途以及我們採用的原因,不過這張卡只需要在一開始校正,完成後就可以拋諸腦後了。
第一階段結論
在開發自動飛行器的初始階段,總結一下,硬體鏈為:
手機 <> micro USB-USB 主機介面卡 <> USB-mini USB 線 <> Pololu Maestro 卡 <>
4 條 JR 線 <> 穩定卡 <> JR 線 <> ESC <> UAV 引擎
手機 <> micro USB-USB 主機介面卡 <> USB-mini USB 線 <> Pololu Maestro 卡 <>
 4 條 JR 線 <> 穩定卡 <> JR 線 <> ESC <> UAV 引擎
此外,您還可以控制其他伺服馬達,例如裝設在四軸飛行器的雙通道 Direct 3D 攝影機,有需要也可以控制襟翼及起落架等等。Pololu Maestro 卡可控制 6 至 24 個馬達,遠超過本專案的實際需求,不過也帶來充分的彈性。
到目前為止,我們已經討論偏好使用的軟硬體,組成這項嵌入式專案的各項元件。下段將探討如何開發影像分析軟體,打造智慧型飛行器。

電腦視覺

我們已經確定飛行器需要良好的內嵌處理功能,才能達到智慧和自動的目標,但仍然缺乏程式碼來讓飛行器發揮潛能。所以現在就開始讓飛行器長出「眼睛」!
為什麼需要程式碼?
部分飛行器可利用 GPS 導航,不過 GPS 的精確度和延遲時間,無法讓飛行器精準穿梭在建築、人或樹木之間。其他飛行器可在實驗室精準靈巧地飛行,不過這是透過室內精密的攝影機和感測器獲得定位資訊,無法在室外應用相同技術。
在真實狀況中,飛行器必須能夠「看見」,以識別及追蹤標記或以視覺功能辨識人類。所以剩下問題就是由 Android 拍攝影像,並使用 OpenCV 進行分析。
如何進行?
OpenCV 是包含影像分析編程函式的開放原始碼程式庫,是眾多電腦視覺和虛擬實境專案的基礎。OpenCV 最初由 Intel 開發,目前提供給許多硬體和作業系統平台使用。您可在個人電腦開發程式碼,並部署於伺服器、智慧型手機或物聯網 (IoT) 平台。
我們先練習一下,嘗試辨識圓圈之類的簡單標示,並使用智慧型手機導航,讓我們能夠在圓圈前方一個固定距離停下。飛行器能夠由 GPS 導航到全球範圍的某個跑道位置 (約 3 公尺),但還必須能辨識地面或路面的標示,以便精準地將自己定位到降落位置上方,並保持固定高度,然後在標示地點降落,誤差只有幾公分。為了簡化測試,我們將把飛行控制放到螢幕上,您可以用手移動手機,模擬飛行器的動作。
使用智慧型手機導航圓圈
原生 Java 專案+
OpenCV 並不是 Android 上可以直接獲取的 Java 程式庫,而是一般 C++ 的原生程式庫,因此您需要使用 Android NDK。影像擷取和顯示部分將使用 Java,Java 和 C++ 之間的通訊則使用 JNI。我們需要安裝 Android NDK 和 Android SDK,建立上述參考的「圓圈」專案,新增 C/ C++ 元件,並變更專案設定以使用 OpenCV 程式庫,以下是這些作業的 Eclipse 螢幕擷取畫面:

Java* 專案設定


C/C++ 專案設定


C/C++ 專案剖析器設定


包括 STL、OpenCV* 及 NDK 設定

最後專案將包括:
Java 主要檔案 « Src/MainActivity.java »
XML 配置檔案 « Res/layout/activity_main.xml » 及資訊清單
兩個 « Jni/Android.mk » 及 « Jni/Application.mk »
cpp 程式碼 « Jni/ComputerVision_jni.cpp » 及標頭 « Jni/ComputerVision_jni.h »
硬體架構
C++ 和 Java 不同,必須針對特定處理器進行編譯。只要在 Application.mk 檔案中編輯 APP_ABI 變數,即可進行這項調整。就我們使用的 Intel Atom 處理器智慧型手機而言,正確的值是「x86」,NDK 將會處理剩餘作業。
部署
無數的 Android 應用程式都使用OpenCV 程式庫,每個應用程式都可能使用不同版本的程式庫。開發應用程式時,您可以將所需版本的 OpenCV 綁定應用程式,不過還有更理想的作法:使用名為「OpenCV Manager」的依存關係管理程式。這是一款 Android 應用程式,可偵測何時需要 OpenCV、需要的版本、協助安裝,然後載入 OpenCV。您的應用程式必須與 OpenCV Manager 建立連線,剩下的一切都將「自動」執行。

C++/Java 與演算法的互動

我們希望在 OpenCV 偵測圓圈,判定中心和半徑,然後向智慧型手機操作者顯示指示,以實現完美置中且大小理想的圓圈。下列 Java 程式碼使用適合 Android 的 Java API,由攝影機擷取影像。它用 JNI 呼叫 C++,並將指標附加到記憶體中的影像,之後 C++ 程式碼將執行影像處理以偵測圓圈,並回呼 Java 顯示偵測到的圓圈,於圖片進行註解。
遙控操作
我在測試期間把手機移到一張紙前面,為了模擬飛行器的最終位置,我根據手機攝影機鏡頭選定距離,觀察圓圈在手機中的寬度。例如:我在紙上畫一個 10 公分的圓圈,將手機放在距離紙張 20 公分的位置,然後圓圈看起來有 300 像素寬。在正確距離時,這就是圓圈所需呈現的寬度。如果圓圈太大,我就往後移,太小則往前進,最後,飛行器將以精準距離位在圓圈之中。
我們的第一個測試案例非常簡單:1 個圓圈 = 1 個距離。不過您也可以進一步使用多個同心圓測試,大圓圈可從遠距離輕鬆偵測,如果飛行器太近看不清楚最大圓圈時則用中圓圈,然後飛行器最後會降落在最小的內圈。如果圓圈不夠精準,您也可以使用箭頭等更複雜的形狀。
將圓圈定位在智慧型手機的影像中央,模擬飛行器降落在著陸標示上方的中央定位。這類控制其實很簡單,若結合顏色、GPS 定位及深度等其他資訊,可以非常輕鬆地實作。

Java 程式碼

…
// 由攝影機擷取影像
import org.opencv.Android.CameraBridgeViewBase;
// 載入 OpenCV 原生相依性 
import org.opencv.Android.OpenCVLoader;
…
public void onResume()
{
super.onResume();
// 以回呼載入
// 專屬 OpenCV 的非一般性程式碼
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_6, this, mLoaderCallback);
}
…
// 一旦建立 OpenCV manager 連結,
// 就可以載入動態程式庫 
System.loadLibrary("jni_part");
…
C++ 程式碼
// JNI 的典型代表:Java 類別方法名稱
// 指標指向 RGB 影像作為引數
JNIEXPORT int JNICALL Java_com_example_circles_MainActivity_process
(JNIEnv *jenv, jobject obj, jlong addrGray, jlong addrRgba)
…
// 由指標取得點陣圖
Mat& mRgb = *(Mat*)addrRgba;
// 柔邊,需要在偵測圓圈之前進行
medianBlur(mGr,mGr,5);
// OpenCV 偵測 - 霍夫變換 
HoughCircles(mGr, //灰階輸入影像
*circles, //輸出向量
CV_HOUGH_GRADIENT, //要使用的偵測方法
4, //累加器解析度與影像的反轉率
mGr.rows/8, //偵測到的不同圓圈中心之間的最小距離
220, //兩者之中的較高閾值通過內部 canny 邊緣偵測器
200, //累加器閾值 100
20, //最小半徑
mGr.cols/8 //最大半徑
);

執行及後續步驟

由 Google Play 安裝 OpenCV Manager* [6] 並由 Eclipse 安裝應用程式 APK。* [7]. 啟動應用程式,遵照說明進行設定;應用程式將在視野中偵測圓圈,引導您使用預先定義直徑將圓圈置於畫面中央。
偵測圓圈是非常基本的作業,開始時最好使用單純背景和高對比,使圓圈輕鬆可見。簡單的電腦視覺函式可以處理簡單形狀,就像幼兒在玩簡單形狀一樣,圓形、正方形、星型 - 所有定義為向量的幾何基元。不過進階電腦視覺函式可以處理任何攝影輸入,不僅是簡單的幾何基元。這類程式庫用在擴增實境應用程式,可以偵測到相片中的其他相片,即使相片失真也沒問題。例如:提供食品包裝相片,應用程式可以偵測大張相片之中包裝的位置與 3D 方向。大部分電腦視覺應用程式的運作方式,都是將物件移動到固定的手機前方,偵測到物件後,就可由 3D 物件擴增,如以下影片的介紹:http://www.dailymotion.com/video/xco8xm_la-realite-augmentee-par-total-imme_tech [8].
我們的飛行器當然不用處理食品包裝,不過同樣的程式庫可以用不同方式使用,同樣是偵測固定的影像圖樣,只不過是用飛行器上移動的手機來偵測。例如:提供飛行器降落地點的相片之後,飛行器就能偵測降落地點,非常精確地計算本身相對於圖樣的位置,然後準備展現視覺功能。相同的程式庫,不同的使用方式。
要控制飛行器,只要替換顯示的指令,將「動力」、「翻滾」、「傾斜」及「偏離」等指令傳送到裝了攝影機的飛行器即可。還好引導飛行器的命令和書面指令完全相符,因此可以輕鬆地由室內手動測試改為用在室外飛行。
我們測試的智慧型手機上,每 1/800 秒就可以擷取及處理一個影像,每秒可處理 12.5 個畫面,這證明我們能夠以有限的開發時間 / 處理器 / 能源預算,為飛行器新增電腦「視覺」功能,這樣的預算對小型飛行器而言是合理且可以實現的。一切都是獨立運算,沒有遺漏任一個計算。
這項專案還可以進一步擴展,OpenCV 是開放原始碼程式庫,可以廣泛移植。此外,Intel IPP [5] 取代了部分低階的 OpenCV 呼叫,並插入針對 Intel 處理器高度最佳化的常式,加快程式碼速度。您可讓程式碼維持可移植,並仰賴開放原始碼程式庫,同時享有 Intel IPP 效能的各項選用優點。
最後,使用以 Intel 處理器為基礎的 Android 智慧型手機控制飛行器,是結合效能、耐用及易於部署等特色的解決方案。若您的智慧型手機功能不足,或希望打造更大的飛行器,借助第一個專案,可以遷移到其他作業系統或更強大的硬體平台。請再次查看其他軟體程式 [1],尋找其他飛行器和機器人領域的軟體開發說明。

關於作者

作者: Paul Guermonprez, Nicolas Vailliet, Cedric Andreolli
連結: http://intel-software-academic-program.com/pages/courses#drones
聯絡人: paul.guermonprez@intel.com
Team: 團隊:歐洲、中東及亞洲 Intel 軟體學院計畫 - 俄羅斯、法國巴黎

參考資料和資源

[1] Intel 軟體學院計畫:http://intel-software-academic-program.com/pages/courses#drones
[2] The Mill: Lexus “Swarm” 幕後花絮:http://vimeo.com/78549177
[3] MIT 自動機器人飛機於室內飛行::  http://www.youtube.com/watch?v=kYs215TgI7c
[4] Intel® Integrated Performance Primitives (Intel® IPP): http://software.intel.com/en-us/intel-ipp
[5] OpenCV: http://opencv.org
[6] Google Play: https://play.google.com/store
[7] Eclipse: https://www.eclipse.org
[8] www.dailymotion.com: La réalité augmentée, par Total Immersion.http://www.dailymotion.com/video/xco8xm_la-realite-augmentee-par-total-imme_tech
如需更全面的了解編譯器優化,請參閱優化注意

No comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...