1. 最佳優先搜索(Best-First Search)
最佳優先搜索(BFS),又稱A算法,是一種啟發式搜索算法(Heuristic Algorithm)。[不是廣度優先搜索算法( Breadth First Search , BFS )]BFS算法在廣度優先搜索的基礎上,用啟發估價函數對將要被遍歷到的點進行估價,然后選擇代價小的進行遍歷,直到找到目標節點或者遍歷完所有點,算法結束。要實現最佳優先搜索我們必須使用一個優先隊列(priority queue)來實現,通常采用一個open優先隊列和一個closed集,open優先隊列用來儲存還沒有遍歷將要遍歷的節點,而closed集用來儲存已經被遍歷過的節點。1.1 最佳優先搜索的過程最佳優先搜索的過程可以被描述為:1、將根節點放入優先隊列open中。2、從優先隊列中取出優先級最高的節點X。3、根據節點X生成子節點Y:X的子節點Y不在open隊列或者closed中,由估價函數計算出估價值,放入open隊列中。X的子節點Y在open隊列中,且估價值優于open隊列中的子節點Y,將open隊列中的子節點Y的估價值替換成新的估價值并按優先值排序。X的子節點Y在closed集中,且估價值優于closed集中的子節點Y,將closed集中的子節點Y移除,并將子節點Y加入open優先隊列。4、將節點X放入closed集中。5、重復過程2,3,4直到目標節點找到,或者open為空,程序結束。

2. A-Star算法
1968年發明的A*算法就是把啟發式方法(heuristic approaches)如BFS,和常規方如Dijsktra算法結合在一起的算法。A-Star算法是一種靜態路網中求解最短路徑最有效的直接搜索方法,也是解決許多搜索問題的有效算法。?和Dijkstra一樣,A*能用于搜索最短路徑。?和BFS一樣,A*能用啟發式函數引導它自己。左圖為Astar算法效果圖,右圖為Dijkstra算法效果圖


(x1,y1)——起始節點的坐標;
(x2,y2)——目標節點的坐標;


(xi,yi)——當前節點的坐標;
(xk,yk)——目標節點的坐標;











3. 其他Astar算法
3.1 Astar——三維地圖規劃 3.1.1 3D-Astar原理三維柵格地圖,顧名思義不是簡單的二維平面,它必須得有三維方向,也就是高度方向上的拓展。柵格地圖在XY水平面上的柵格的投影顏色不盡相同,柵格黃色程度越高,表明此處的高度越高。












4. MATLAB實現Astar算法
4.1 defColorMap.m 用于初始化地圖參數
function [field,cmap] = defColorMap(rows, cols)
cmap = [1 1 1; ... % 1-白色-空地
0 0 0; ... % 2-黑色-靜態障礙
1 0 0; ... % 3-紅色-動態障礙
1 1 0;... % 4-黃色-起始點
1 0 1;... % 5-品紅-目標點
0 1 0; ... % 6-綠色-到目標點的規劃路徑
0 1 1]; % 7-青色-動態規劃的路徑
% 構建顏色MAP圖
colormap(cmap);
% 定義柵格地圖全域,并初始化空白區域
field = ones(rows, cols);
% 障礙物區域
obsRate = 0.3;
obsNum = floor(rows*cols*obsRate);
obsIndex = randi([1,rows*cols],obsNum,1);
field(obsIndex) = 2;
4.2 getChildNode.m
用于獲取子節點信息
function childNodes = getChildNode(field,closeList, parentNode)
% 選取父節點周邊8個節點作為備選子節點,線性化坐標
% 排除超過邊界之外的、位于障礙區的、位于closeList中的
[rows, cols] = size(field);
[row_parentNode, col_parentNode] = ind2sub([rows, cols], parentNode);
childNodes = [];
closeList = closeList(:,1);
% 第1個子節點(右節點)
childNode = [row_parentNode, col_parentNode+1];
if ~(childNode(1) < 1 || childNode(1) > rows ||...
childNode(2) < 1 || childNode(2) > cols)
if field(childNode(1), childNode(2)) ~= 2
childNode_LineIdx = sub2ind([rows, cols], childNode(1), childNode(2));
if ~ismember(childNode_LineIdx, closeList)
childNodes(end+1) = childNode_LineIdx;
end
end
end
% 第2個子節點(右上節點)
childNode = [row_parentNode-1, col_parentNode+1];
child_brother_node_sub1 = [row_parentNode-1, col_parentNode];
child_brother_node_sub2 = [row_parentNode, col_parentNode+1];
if ~(childNode(1) < 1 || childNode(1) > rows ||...
childNode(2) < 1 || childNode(2) > cols)
if field(childNode(1), childNode(2)) ~= 2
if ~(field(child_brother_node_sub1(1), child_brother_node_sub1(2)) == 2 & field(child_brother_node_sub2(1), child_brother_node_sub2(2)) == 2)
childNode_LineIdx = sub2ind([rows, cols], childNode(1), childNode(2));
if ~ismember(childNode_LineIdx, closeList)
childNodes(end+1) = childNode_LineIdx;
end
end
end
end
% 第3個子節點(上節點)
childNode = [row_parentNode-1, col_parentNode];
if ~(childNode(1) < 1 || childNode(1) > rows ||...
childNode(2) < 1 || childNode(2) > cols)
if field(childNode(1), childNode(2)) ~= 2
childNode_LineIdx = sub2ind([rows, cols], childNode(1), childNode(2));
if ~ismember(childNode_LineIdx, closeList)
childNodes(end+1) = childNode_LineIdx;
end
end
end
% 第4個子節點(左上)
childNode = [row_parentNode-1, col_parentNode-1];
child_brother_node_sub1 = [row_parentNode-1, col_parentNode];
child_brother_node_sub2 = [row_parentNode, col_parentNode-1];
if ~(childNode(1) < 1 || childNode(1) > rows ||...
childNode(2) < 1 || childNode(2) > cols)
if field(childNode(1), childNode(2)) ~= 2
if ~(field(child_brother_node_sub1(1), child_brother_node_sub1(2)) == 2 & field(child_brother_node_sub2(1), child_brother_node_sub2(2)) == 2)
childNode_LineIdx = sub2ind([rows, cols], childNode(1), childNode(2));
if ~ismember(childNode_LineIdx, closeList)
childNodes(end+1) = childNode_LineIdx;
end
end
end
end
% 第5個子節點(左節點)
childNode = [row_parentNode, col_parentNode-1];
if ~(childNode(1) < 1 || childNode(1) > rows ||...
childNode(2) < 1 || childNode(2) > cols)
if field(childNode(1), childNode(2)) ~= 2
childNode_LineIdx = sub2ind([rows, cols], childNode(1), childNode(2));
if ~ismember(childNode_LineIdx, closeList)
childNodes(end+1) = childNode_LineIdx;
end
end
end
% 第6個子節點(左下)
childNode = [row_parentNode+1, col_parentNode-1];
child_brother_node_sub1 = [row_parentNode, col_parentNode-1];
child_brother_node_sub2 = [row_parentNode+1, col_parentNode];
if ~(childNode(1) < 1 || childNode(1) > rows ||...
childNode(2) < 1 || childNode(2) > cols)
if field(childNode(1), childNode(2)) ~= 2
if ~(field(child_brother_node_sub1(1), child_brother_node_sub1(2)) == 2 & field(child_brother_node_sub2(1), child_brother_node_sub2(2)) == 2)
childNode_LineIdx = sub2ind([rows, cols], childNode(1), childNode(2));
if ~ismember(childNode_LineIdx, closeList)
childNodes(end+1) = childNode_LineIdx;
end
end
end
end
% 第7個子節點(下)
childNode = [row_parentNode+1, col_parentNode];
if ~(childNode(1) < 1 || childNode(1) > rows ||...
childNode(2) < 1 || childNode(2) > cols)
if field(childNode(1), childNode(2)) ~= 2
childNode_LineIdx = sub2ind([rows, cols], childNode(1), childNode(2));
if ~ismember(childNode_LineIdx, closeList)
childNodes(end+1) = childNode_LineIdx;
end
end
end
% 第8個子節點(右下)
childNode = [row_parentNode+1, col_parentNode+1];
child_brother_node_sub1 = [row_parentNode, col_parentNode+1];
child_brother_node_sub2 = [row_parentNode+1, col_parentNode];
if ~(childNode(1) < 1 || childNode(1) > rows ||...
childNode(2) < 1 || childNode(2) > cols)
if field(childNode(1), childNode(2)) ~= 2
if ~(field(child_brother_node_sub1(1), child_brother_node_sub1(2)) == 2 & field(child_brother_node_sub2(1), child_brother_node_sub2(2)) == 2)
childNode_LineIdx = sub2ind([rows, cols], childNode(1), childNode(2));
if ~ismember(childNode_LineIdx, closeList)
childNodes(end+1) = childNode_LineIdx;
end
end
end
end
4.3 Astar.m
主程序
% 基于柵格地圖的機器人路徑規劃算法
% A*算法
clc
clear
close all
%% 柵格界面、場景定義
% 行數和列數
rows = 20;
cols = 20;
[field,cmap] = defColorMap(rows, cols);
% 起點、終點、障礙物區域
startPos = 2;
goalPos = rows*cols-2;
field(startPos) = 4;
field(goalPos) = 5;
%% 預處理
% 初始化closeList
parentNode = startPos;
closeList = [startPos,0];
% 初始化openList
openList = struct;
childNodes = getChildNode(field,closeList,parentNode);
for i = 1:length(childNodes)
[row_startPos,col_startPos] = ind2sub([rows, cols],startPos);
[row_goalPos,col_goalPos] = ind2sub([rows, cols],goalPos);
[row,col] = ind2sub([rows, cols],childNodes(i));
% 存入openList結構體
openList(i).node = childNodes(i);
openList(i).g = norm([row_startPos,col_startPos] - [row,col]); % 實際代價采用歐式距離
openList(i).h = abs(row_goalPos - row) + abs(col_goalPos - col); % 估計代價采用曼哈頓距離
openList(i).f = openList(i).g + openList(i).h;
end
% 初始化path
for i = 1:rows*cols
path{i,1} = i; % 線性索引值
end
for i = 1:length(openList)
node = openList(i).node;
path{node,2} = [startPos,node];
end
%% 開始搜索
% 從openList開始搜索移動代價最小的節點
[~, idx_min] = min([openList.f]);
parentNode = openList(idx_min).node;
% 進入循環
while true
% 找出父節點的8個子節點,障礙物節點用inf,
childNodes = getChildNode(field, closeList,parentNode);
% 判斷這些子節點是否在openList中,若在,則比較更新;沒在則追加到openList中
for i = 1:length(childNodes)
% 需要判斷的子節點
childNode = childNodes(i);
[in_flag,idx] = ismember(childNode, [openList.node]);
% 計算代價函數
[row_parentNode,col_parentNode] = ind2sub([rows, cols], parentNode);
[row_childNode,col_childNode] = ind2sub([rows, cols], childNode);
[row_goalPos,col_goalPos] = ind2sub([rows, cols],goalPos);
g = openList(idx_min).g + norm( [row_parentNode,col_parentNode] -...
[row_childNode,col_childNode]);
h = abs(row_goalPos - row_childNode) + abs(col_goalPos - col_childNode); % 采用曼哈頓距離進行代價估計
f = g + h;
if in_flag % 若在,比較更新g和f
if f < openList(idx).f
openList(idx).g = g;
openList(idx).h = h;
openList(idx).f = f;
path{childNode,2} = [path{parentNode,2}, childNode];
end
else % 若不在,追加到openList
openList(end+1).node = childNode;
openList(end).g = g;
openList(end).h = h;
openList(end).f = f;
path{childNode,2} = [path{parentNode,2}, childNode];
end
end
% 從openList移出移動代價最小的節點到closeList
closeList(end+1,: ) = [openList(idx_min).node, openList(idx_min).f];
openList(idx_min)= [];
% 重新搜索:從openList搜索移動代價最小的節點
[~, idx_min] = min([openList.f]);
parentNode = openList(idx_min).node;
% 判斷是否搜索到終點
if parentNode == goalPos
closeList(end+1,: ) = [openList(idx_min).node, openList(idx_min).f];
break
end
end
%% 畫路徑
% 找出目標最優路徑
path_target = path{goalPos,2};
for i = 1:rows*cols
if ~isempty(path{i,2})
field((path{i,1})) = 7;
end
end
field(startPos) = 4;
field(goalPos) = 5;
field(path_target(2:end-1)) = 6;
% 畫柵格圖
image(1.5,1.5,field);
grid on;
set(gca,'gridline','-','gridcolor','k','linewidth',2,'GridAlpha',0.5);
set(gca,'xtick',1:cols+1,'ytick',1:rows+1);
axis image;
hold on;
[y0,x0] = ind2sub([rows,cols], path_target);
y = y0 + 0.5;
x = x0 + 0.5;
plot(x,y,'-','Color','r','LineWidth',2.5);
hold on;
points = [x',y'];
M = 10;
[x1,y1] = bezir_n(points, M);
plot(x1,y1,'-','Color','y','LineWidth',2.5);
hold on;
values = spcrv([[x(1) x x(end)];[y(1) y y(end)]],3);
plot(values(1,:),values(2,:),'b','LineWidth',2.5);
4.4 算法效果




5. python實現Astar算法
可以參考這篇文章https://www.jianshu.com/p/5704e67f40aa這篇文章介紹了Astar以及后續的變種算法python 版本的偽代碼(來源:https://brilliant.org/wiki/a-star-search/)如下:
make an openlist containing only the starting node
make an empty closed list
while (the destination node has not been reached):
consider the node with the lowest f score in the open list
if (this node is our destination node) :
we are finished
if not:
put the current node in the closed list and look at all of its neighbors
for (each neighbor of the current node):
if (neighbor has lower g value than current and is in the closed list) :
replace the neighbor with the new, lower, g value
current node is now the neighbor's parent
else if (current g value is lower and this neighbor is in the open list ) :
replace the neighbor with the new, lower, g value
change the neighbor's parent to our current node
else if this neighbor is not in both lists:
add it to the open list and set its g
6. Java實現Astar算法
可以參考這篇文章:https://www.jianshu.com/p/950233af52df7. 實踐案例—基于ROS實現Astar與DWA算法
本項目以Astar算法作為全局路徑規劃算法,DWA作為局部路徑規劃算法,實現效果如下。(具體原理與算法代碼解釋與說明會在之后的文章附上)
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
算法
+關注
關注
23文章
4646瀏覽量
93719 -
Open
+關注
關注
0文章
20瀏覽量
11124 -
自動駕駛
+關注
關注
788文章
14002瀏覽量
167715
原文標題:自動駕駛路徑規劃:A*(Astar)算法
文章出處:【微信號:3D視覺工坊,微信公眾號:3D視覺工坊】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
FPGA在自動駕駛領域有哪些應用?
是FPGA在自動駕駛領域的主要應用:
一、感知算法加速
圖像處理:自動駕駛中需要通過攝像頭獲取并識別道路信息和行駛環境,這涉及到大量的圖像處理任務。FPGA在處理圖像上的運算速度快,可并行性強,且功耗
發表于 07-29 17:09
自動駕駛的到來
得益于2025規劃,中國整車廠與Tier1目前對于自動駕駛有極大的熱忱及投入,有機會在這個領域實現彎道超車。目前的顧慮在于法規政策的制定,以及中國特色的交通情況帶給自動駕駛的挑戰。安全問題 目前主要
發表于 06-08 15:25
AI/自動駕駛領域的巔峰會議—國際AI自動駕駛高峰論壇
由南德意志出版及活動有限公司舉辦的 國際AI自動駕駛高峰論壇 將于 2017年11月28/29日 在 德國慕尼黑 舉辦,中德聯合股份公司作為中國獨家合作伙伴,誠邀您撥冗蒞臨!【活動背景】AI
發表于 09-13 13:59
即插即用的自動駕駛LiDAR感知算法盒子 RS-Box
RS-LiDAR-Algorithms 感知算法。經過與多個自動駕駛汽車研發團隊的聯合調試打磨,RS-LiDAR-Algorithms 目前已經可以駕馭常見的大部分自動駕駛場景,其以內測為主的階段性使命已經完成。速騰
發表于 12-15 14:20
UWB主動定位系統在自動駕駛中的應用實踐
3萬美元以上,相當于一輛中級車的價格。自動駕駛四大核心技術分別為環境感知、高精度定位、路徑規劃、控制執行。其中環境感知技術是最基礎、最重要的一環。通過環境感知,可實時、可靠且準確地識別出車輛行駛
發表于 12-14 17:30
如何讓自動駕駛更加安全?
等功能。關于自動駕駛的應用,產業界存在兩種不同的轉型路徑。第一種是傳統汽車制造商的“漸進演化”路線,即在傳統的汽車上逐漸新增一些自動駕駛的功能,最終過渡到完全自動駕駛的階段。另外一種是
發表于 05-13 00:26
自動駕駛系統設計及應用的相關資料分享
作者:余貴珍、周彬、王陽、周亦威、白宇目錄第一章 自動駕駛系統概述1.1 自動駕駛系統架構1.1.1 自動駕駛系統的三個層級1.1.2 自動駕駛系統的基本技術架構1.2
發表于 08-30 08:36
自動駕駛技術的實現
的帶寬有了更高的要求。從而使用以太網技術及中央域控制(Domain)和區域控制(Zonal)架構是下一代車載網絡的發展方向。然而對于自動駕駛技術的實現,涉及到感知、規劃、執行三個層面。由于車輛行...
發表于 09-03 08:31
解析自動駕駛汽車路徑規劃算法
車輛自主駕駛系統從本質上講是一個智能控制機器,其研究內容大致可分為信息感知、行為決策及操縱控制三個子系統。路徑規劃是智能車輛導航和控制的基礎,是從軌跡決策的角度考慮的,可分為局部路徑
發表于 07-28 09:04
?4974次閱讀
自動駕駛之路徑規劃
路徑規劃是自動駕駛技術中最重要的部分,之前的文章有一些這方面的介紹,但是并不全面和系統: 初探路徑規劃:主要從? 帶約束的多項式擬合;貝賽爾
發表于 06-01 15:12
?0次下載

評論