• 沒有找到結果。

分析其實驗結果與未來可以改良之方向。

13

第二章 輪型移動機器人之路徑規劃

對於移動式機器人來說,在任一環境中移動時,要能夠確保機器人不會 與環境中的邊緣或障礙物產生碰撞將是需考慮的首要課題。對於處理機器人 的避障問題並非難事,可藉由機器人本身具備的感測器將偵測值回傳至對應 的動作(停止、轉彎或是倒退)即可達到避障目的。然而,此一設計步驟將會 使得機器人僅能安全的在環境中漫無目的的航行,因此標示目的地並規劃最 佳路徑讓機器人能夠依循指示前進將是進一步設計的課題。

2.1 路徑規劃

路徑規劃是在有限的工作環境中尋找一條合理的路徑, 用來連接初始 位置(包括位置點與方位角)與目標位置,並可成功地避開障礙物,此為機器 人研究領域中的核心技術之一。現有的路徑規劃演算法,多數以設計最短路 徑為目標,而實際上最短路徑並非確保適用於真實機器人,其中包含行走時 間與安全性等因素,本論文內容則不考慮行走時間之因素,僅針對路徑安全 性來做分析,下一節將提出最短路徑規劃之方法。

2.2 最短路經搜尋法

目前現有路徑規劃演算法中,以 Dijkstra 演算法[21]與 A*演算法[22]

最具代表性,此二演算法比較如表 2-1 所示[23][24]。Dijkstra 演算法主要用 於解決尋找最短路徑問題,但 Dijkstra 演算法屬於廣度搜尋法,當用於地 圖深度較大時演算法的搜尋深度會隨著地圖及節點擴大,使運算效率偏低。

反觀 A*演算法是採用啟發式評估(Heuristic Estimate)公式,將許多明顯為錯 誤的路徑排除,進而快速規劃出較佳路徑,Dijkstra 與 A*演算法搜尋範圍比 較如表 2-2 所示。以 Dijkstra 演算法規劃最短路徑將使得執行時間過長;

A*演算法執行時間較短,但所規劃出路徑並非最短路徑,而是近似最短路 徑,不過考慮演算效率問題,以及兩者結果差異不大的考量,本論文採取

14

A*演算法進行輪型移動機器人之路徑規劃。

表 2-1 最短路徑演算法之比較

Dijkstra 演算法 A*演算法

搜尋特性 廣度搜尋法 啟發式搜尋法

搜尋節點數 多 少

搜尋速度 慢 快

花費時間 長 短

搜尋路徑 最短路徑 近似最短路徑

花費函數 f(n)g(n) f(n)g(n)h(n) 表 2-2 搜尋範圍比較表[25]

Dijkstra’s 演算法 A*演算法 無障礙

有障礙

A*演算法是在 1968 年由 Hart 等三人[26]所提出,以最佳解優先搜尋方 式搜尋下一步的位置,屬於貪婪演算法(Greedy Algorithm)[27]之一,只要起 點與終點之間有路徑存在,則保證搜尋出最少花費成本之路徑,並有搜尋範 圍較小及執行時間短之優點,因此 A*演算法通常用在人工智慧遊戲中解決

比較項目 演算法

15

路徑搜尋問題[23,28]。

A*演算法規劃路徑之概念為產生出從定義起點n0到終點ng之路徑,將起 點之鄰近節點放入OPEN 陣列中,從OPEN 陣列中以啟發式評估函數公式 計算出各個鄰近節點之F(n),選擇最小F(n)節點為下一迭代起點,重覆迭代 至搜尋終點。啟發式評估函數其公式如下。

F(n) = G(n) + H(n) (2-1) 其中 F(n)代表從起點 no至終點 ng的整體花費,G(n)是 n0到任一節點 n 之間 的最小花費,H(n)是節點 n 到 ng之間所估算的最小花費,通常以 n 到 ng線距離為代表[29,30,31];當不具備預估花費時,即 F(n)=G(n),則此演算法 會轉變為全域廣度搜尋的 Dijkstra 演算法;若 H(n)小於從節點 n 至終點的實 際花費時,則必定可以得到最短路徑;若 H(n)非常接近乃至於相等於實際花 費時,則此演算法會具備最佳的效率;但若 H(n)大於實際花費時,則不能保 證獲得最佳解,因此在實務操作上,多以該節點至終點的直線距離定為該節 點的 H(n),以確保能獲得最佳解。

A*演算法的演算過程包含兩大階段:搜尋與重構階段。在搜尋階段時,

演算法會從起點開始依照既定流程蒐集、計算與更新通過之節點資訊;重複 此過程直到抵達終點後,開始進入重構階段,將流程獲得之資訊還原成路徑。

為說明演算流程,本論文定義節點 n 為任何環境中可行的位置,起點與終點 則分別為 n0與 ng,因此演算法即為尋找一條從 n0開始至 ng結束且花費最低 的路徑;一般而言,每個節點至少需要包含以下資訊:節點座標 n、來源節 點 c(n)、實際當前最低花費 G(n)與預估花費 H(n),其中來源節點是用來記錄 通過此節點的上一個節點,於重構階段時所需之資訊。A*演算法的流程如 下[9,29,32,33]:

步驟一:建立 OPEN 陣列與 CLOSE 陣列。OPEN 陣列是即將進行估算 之節點集合,CLOSE 陣列則為已計算完成之節點集合。初始時 OPEN 陣列

16

為起始點 n0;CLOSE 陣列則為空集合。G(n)為起始點 n0至任意節點 n 的實 際最低花費,故可得 G(n0)必為 0。在此步驟同時估算 H(n0),且因 G(n0)=0 得到 F(n0)=H(n0)。

步驟二:建構一個包含步驟三至步驟十的迴圈,當 OPEN 陣列非空集合 時進入迴圈,表示尚未抵達終點,或是若判斷無法產生至終點之路徑,則回 傳規劃失敗的訊息。

步驟三:從 OPEN 陣列找出可產生最小的 F(n)值的節點,並將它視為下 一步當前節點 x,判斷當前節點是否為終點 ng,若是則表示完成搜尋階段,

將其從目標節點 OPEN 陣列中移除並加入至 CLOSE 陣列,跳出由步驟二建 構的迴圈,直接進入步驟十一。

步驟四:搜尋在當前節點附近且可抵達的節點並定義其為 yi

步驟五:建構一個迴圈包含步驟五至步驟十,在迴圈內針對每個節點 yi 進行判斷,直到所有鄰近的節點都判斷完畢。

步驟六:判斷節點 yi是否已經在 CLOSE 陣列內,若是則進行下一個鄰 近節點的判斷,否則繼續下一個步驟。

步驟七:估算節點 yi的 G(yi),此函數定義為通過當前節點 x 的實際花 費函數,並且可以表示成 G(yi)=G(x)+dis(x, yi),其中 dis()函數表示兩個節點 間的直線距離。

步驟八:設定一個布林參數 k 為 false,用來記錄節點資訊是否需要更新。

步驟九:判斷節點 yi是否存在於 OPEN 陣列內,若不在則將節點 yi加入 OPEN 陣列,並將參數k設為 true,否則再次判斷其餘節點的G(yi)是否小於 當下被選擇節點 yi本身具有的 G(yi),若小於則亦將參數 k 設為 true,以表示 節點的資料需要新增或修改。

步驟十:判斷參數 k,若為 false 則不進行任何動作直接回到步驟五;若 為 true 則進行資料更新,包含:設定節點 yi的來源節點為 x,表示是由當前

17

節點 x 建立而得;G(yi)由

) (yi

G 取代,表示有花費更低的路徑。

步驟十一:此為重構階段,將終點 ng存入暫存路徑 P 的第一個位置,

即 P(1)= ng

步驟十二:建構一個迴圈,依照 P(i+1)=c(P(i))逐步將 N 個節點資訊填 入暫存路徑,直到將起點加入至暫存路徑,即滿足 P(N)= n0

步驟十三:將暫存路徑之順序翻轉,即 P(i)=P(N-i+1), i=1,2,…,N-1,便 得正確順序之路徑 P,即完成整個 A*演算法。

從上述流程可得知,搜尋階段為第一至第十步驟,為目標點搜尋之流程;

重構階段為第十一至第十三步驟,為最短路徑生成,而階段轉換位於第三步 驟的跳脫條件,由於重構階段相對簡單而且無巢狀迴圈,因此演算時間花費 集中於搜尋階段。此外,路徑是否能夠建立仰賴於搜尋階段的 OPEN 陣列之 節點數量,演算法過程一方面持續地消耗 OPEN 陣列之節點,同時將地圖的 節點加入至 OPEN 陣列內,一旦無節點可以加入 OPEN 陣列內,則 OPEN 陣列內之節點數量便會下降,若在被消耗殆盡前仍然無法接觸終點,意味著 路徑建立失敗,因此雖於步驟三建立非可預期長度之迴圈,但在正常操作下 並不會造成演算法無窮循環。為了更詳盡地說明整體的運作流程楚,本論文 提供此演算法之虛擬碼,表示於圖 2-1[9,22]。

由於 A*演算法必須建立於有限節點的平面上,並且需給予節點間的連 結,因此問題本身要能網格化或者建立拓樸圖方得使用;而網格化的細膩程 度直接權衡了路徑細膩度以及運算時間,這往往是開發者所需面臨之問題,

利用 A*演算法進行規劃從相同起始點分別抵達不同目標點之路徑相關結果 顯示於圖 2-2。

18

A*(start, goal)

CLOSE_Array := empty set OPEN_Array := {start}

g[start] = 0

while OPEN_Array is not empty

x = the node with lowest cost of f(n) in OPEN_Array if x = goal

while came_from[x] is not start path.append(x)

x = came_from[x]

end_while

return rev(path) end_if

remove x from OPEN_Array add x to CLOSE_Array

for each y in neighbor_nodes of x if y in CLOSE_Array

continue end_if

g_t = g[y]+dis(x,y) k = false

if y is not in OPEN_Array add y to OPEN_Array k = true

else if g_t < g[y]

k = true end_if

if k = true

came_from[y] = x g[y] = g_t

f[y] = g[y] + h(y, goal) end_if

end_for end_while

return failure

圖 2-1 A*演算法用於路徑規劃之虛擬碼

19

圖 2-2 A*演算法之路徑規劃結果

2.3B-Spline 曲線

路徑規劃往往無法以單一種演算法即可精確規劃出滿足使用者需求之 路徑,由前一節規劃出顯示於圖 2-2 之結果不僅缺少路徑連續特性且不適合 用於具有特定大小真實移動機器人之軌跡,為了克服這樣的問題,具有局部 調整特色的 B-Spline 曲線將顯得相當適用。

B-Spline 曲線為 basis spline 的縮寫,是由 Schoenberg 在 1946 年所提出,

規劃上較 Bezier 曲線[34]更具有彈性及使用上較 Cubic 曲線廣泛[35]。

B-Spline 曲線包含 Bezier 曲線的通用數學表示法,然而,Bezier 曲線具有兩 項主要缺點:1.若改變曲線中的任一控制點,則整條曲線皆會改變;2.曲線

20

次數高時,計算較費時。因此,相較於 Bezier 曲線,具有局部控制的能力、

及曲線階數(Order)與控制點數可各別獨立設計特性的 B-Spline 曲線則顯得 具有較高的實用性,例如由四個控制點定義之 Bezier 曲線只能建立出三次曲 線,而 B-Spline 曲線則可建立一到三次不同的曲線。產生如此不同差別的主 要原因為 B-Spline 所選擇的基底函數與 Bezier 曲線選擇不同。

2.3.1B-Spline 曲線定義

B-Spline 曲線定義如下:

2.3.2 B-Spline曲線模型特性

B-Spline曲線設計中基底函數Ni,k(t)是由節點向量所決定,在具有相同

x ,大致上建立B-Spline曲線的節點向量分佈形式主要有均勻分佈、開 放式均勻分佈與非均勻分佈。均勻分佈形式的節點向量內節點值以等差級數 方式排列,且將第一個元素值設為零,例如(0 1 2 3 4 5 6)或(0 2 4 6 8 10),均

21

勻分佈的節點向量會使得B-spline曲線全部的基底函數曲線形狀相同,且僅 在參數線上平移一個節點的增量值。若為當重複首尾曲線階數數目的節點數 時所生成之B-spline曲線的始末端將落於首末的控制點上,即為下一段落提 到的開放式均勻分佈節點向量。非均勻分佈的節點向量所形成之基底函數則

勻分佈的節點向量會使得B-spline曲線全部的基底函數曲線形狀相同,且僅 在參數線上平移一個節點的增量值。若為當重複首尾曲線階數數目的節點數 時所生成之B-spline曲線的始末端將落於首末的控制點上,即為下一段落提 到的開放式均勻分佈節點向量。非均勻分佈的節點向量所形成之基底函數則

相關文件