Dynamic Window Approach_機器人區域性避障的動態視窗法
阿新 • • 發佈:2018-11-06
- 最近正在學習DWA,按照DynamicWindowApproachSample.m 提供的matlab模擬程式碼簡單梳理下,但是這並不是ros裡用的,只是一個簡單的模擬。
- DWA的原理:假設一個機器人要從當前點通過一定的速度和方向到達目標點,在速度(v, w)空間中取樣多組軌跡,為這些軌跡使用評價函式進行評價,選取最優的軌跡對應的速度(v_best, w_best)來驅動機器人,最終到達目標點。
程式碼分析:
首先定義一些初始狀態
% 機器人的初始狀態,包括初始位置,朝向(這裡可以理解為yaw角)速度,角速度 % [x(m),y(m),yaw(Rad),v(m/s),w(rad/s)]
進入模擬主迴圈
迴圈主要函式為DynamicWindowApproach,輸入機器人當前的狀態x,運動模型引數,評價函式引數,障礙物,障礙-物半徑,輸出最優的控制量u(v, w)以及模擬軌跡,控制量傳遞給運動模型後機器人開始運動,最終到達目標點,後面繪圖部分不重要,不予解釋了。for i=1:5000 % DWA引數輸入 [u,traj]=DynamicWindowApproach(x,Kinematic,goal,evalParam,obstacle,obstacleR); % 機器人運動模型 x=f(x,u); % 模擬結果的儲存 result.x=[result.x; x']; % 是否到達目的地 if norm(x(1:2)-goal')<0.5 disp('Arrive Goal!!');break; end %% ====繪圖部分=== hold off; ArrowLength=0.5;% % 機器人 quiver(x(1),x(2),ArrowLength*cos(x(3)),ArrowLength*sin(x(3)),'ok');hold on; plot(result.x(:,1),result.x(:,2),'-b');hold on; plot(goal(1),goal(2),'*r');hold on; plot(obstacle(:,1),obstacle(:,2),'*k');hold on; % 探索軌跡 if ~isempty(traj) for it=1:length(traj(:,1))/5 ind=1+(it-1)*5; plot(traj(ind,:),traj(ind+1,:),'-g');hold on; end end axis(area); grid on; drawnow; end
運動模型 x=f(x,u)指的是在世界座標系下,機器人從a點運動到b點遵循的運動規則,w指的是世界座標系
用矩陣的形式表示這個模型如下:
function x = f(x, u)
% u = [vt; wt];當前時刻的速度、角速度
global dt;
F = [1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 0 0
0 0 0 0 0];
B = [dt*cos(x(3)) 0
dt*sin(x(3)) 0
0 dt
1 0
0 1];
x= F*x+B*u;
DynamicWindowApproach函式,這個是DWA函式的模型,輸出最優的線速度和角速度
首先會根據機器人模型引數中的最高速度,最高旋轉速度,加速度,旋轉加速度等引數計算出機器人在dt時間內速度和角速度可以到達的最大最小範圍,這個範圍可以根據情況調整;
之後將這個視窗範圍內的速度(包含角速度)進行取樣,輸入到評價函式Evaluation中,計算出每個取樣速度對應的評價值evalDB,在對這些評價值進行歸一化操作,分別乘以評價值對應的評價引數(cost = a*heading+b*dist+c*velocity),得到最優的評價值後找到其對應的u(v, w),輸出這個最佳的速度和角速度function [u,trajDB]=DynamicWindowApproach(x,model,goal,evalParam,ob,R) % 動態視窗 [vmin,vmax,wmin,wmax] Vr=CalcDynamicWindow(x,model); % 評價函式的計算 [evalDB,trajDB]=Evaluation(x,Vr,goal,ob,R,model,evalParam); if isempty(evalDB) disp('no path to goal!!'); u=[0;0];return; end % 各評價函式正則化 evalDB=NormalizeEval(evalDB); % 最終評價函式的計算 feval=[]; for id=1:length(evalDB(:,1)) feval=[feval;evalParam(1:3)*evalDB(id,3:5)']; end evalDB=[evalDB feval]; % 最優評價函式 [maxv,ind]=max(feval); % 最優的速度和角速度 u=evalDB(ind,1:2)';
CalcDynamicWindow
function Vr=CalcDynamicWindow(x,model) % global dt; % 車子速度的最大最小範圍 Vs=[0 model(1) -model(2) model(2)]; % 根據當前速度以及加速度限制計算的動態視窗 Vd=[x(4)-model(3)*dt x(4)+model(3)*dt x(5)-model(4)*dt x(5)+model(4)*dt]; % 最終的Dynamic Window Vtmp=[Vs;Vd]; Vr=[max(Vtmp(:,1)) min(Vtmp(:,2)) max(Vtmp(:,3)) min(Vtmp(:,4))];
Evaluation函式,評價函式的計算,輸入初始x的狀態,動態視窗,障礙物,衝突判定用的障礙物半徑,機器人運動模型引數以及評價函式引數,通過兩個for迴圈計算出需要評價的引數heading dist vel
function [evalDB,trajDB]=Evaluation(x,Vr,goal,ob,R,model,evalParam) % 評價函式值 evalDB=[]; % 預測軌跡 trajDB=[]; for vt=Vr(1):model(5):Vr(2) for ot=Vr(3):model(6):Vr(4) % GenerateTrajectory軌跡推測 % 得到 xt: 機器人向前運動後的預測位姿; traj: 當前時刻到預測時刻之間的軌跡 % evalParam(4),前向模擬時間; [xt,traj]=GenerateTrajectory(x,vt,ot,evalParam(4),model); %% 各評價函式的計算 % 當前機器人和目標點的朝向 heading=CalcHeadingEval(xt,goal); % 當前機器人和障礙物的距離 dist=CalcDistEval(xt,ob,R); vel=abs(vt); % 制動距離的計算 stopDist=CalcBreakingDist(vel,model); if dist>stopDist % evalDB=[evalDB;[vt ot heading dist vel]]; trajDB=[trajDB;traj]; end end end
GenerateTrajectory函式
function [x,traj]=GenerateTrajectory(x,vt,ot,evaldt,model) % 軌跡生成函式 % evaldt:前向模擬時間; vt、ot當前速度和角速度; global dt; time=0; % 輸入值 u=[vt;ot]; % 機器人軌跡 traj=x; while time<=evaldt % 時間更新 time=time+dt; % 運動更新 x=f(x,u); traj=[traj x]; end
CalcHeadingEval函式,heading的評價函式計算
function heading=CalcHeadingEval(x,goal) % 機器人朝向 theta = toDegree(x(3)); % 目標點的方位 goalTheta = toDegree(atan2(goal(2)-x(2),goal(1)-x(1))); if goalTheta > theta targetTheta = goalTheta - theta;% [deg] else targetTheta = theta - goalTheta;% [deg] end % theta越小,評價越高 heading = 180 - targetTheta;
CalcDistEval函式,障礙物距離評價函式
function dist=CalcDistEval(x,ob,R) dist=100; for io=1:length(ob(:,1)) disttmp=norm(ob(io,:)-x(1:2)')-R; % 離障礙物最小的距離 if dist>disttmp dist=disttmp; end end % 障礙物距離評價限定一個最大值,如果不設定,一旦一條軌跡沒有障礙物,將太佔比重 if dist>=2*R dist=2*R; end