机器人局部避障的动态窗口法(dynamic window approach)

转自:http://blog.csdn.net/heyijia0327/article/details/44983551

机器人局部避障的动态窗口法(dynamic window approach)

机器人局部避障的动态窗口法(dynamic window approach)机器人局部避障的动态窗口法(dynamic window approach)

机器人局部避障的动态窗口法(dynamic window approach)

机器人局部避障的动态窗口法(dynamic window approach)

机器人局部避障的动态窗口法(dynamic window approach)机器人局部避障的动态窗口法(dynamic window approach)

[cpp] view plain copy
  1. 首先在V_m∩V_d的范围内采样速度:  
  2. allowable_v = generateWindow(robotV, robotModel)  
  3. allowable_w  = generateWindow(robotW, robotModel)  
  4. 然后根据能否及时刹车剔除不安全的速度:  
  5.     for each v in allowable_v  
  6.        for each w in allowable_w  
  7.        dist = find_dist(v,w,laserscan,robotModel)  
  8.        breakDist = calculateBreakingDistance(v)//刹车距离  
  9.        if (dist > breakDist)  //如果能够及时刹车,该对速度可接收  
  10.     如果这组速度可接受,接下来利用评价函数对其评价,找到最优的速度组  
机器人局部避障的动态窗口法(dynamic window approach)

机器人局部避障的动态窗口法(dynamic window approach)机器人局部避障的动态窗口法(dynamic window approach)机器人局部避障的动态窗口法(dynamic window approach)

[cpp] view plain copy
  1. 来源:http://adrianboeing.blogspot.com/2012/05/dynamic-window-algorithm-motion.html  
  2. BEGIN DWA(robotPose,robotGoal,robotModel)  
  3.    laserscan = readScanner()  
  4.    allowable_v = generateWindow(robotV, robotModel)  
  5.    allowable_w  = generateWindow(robotW, robotModel)  
  6.    for each v in allowable_v  
  7.       for each w in allowable_w  
  8.       dist = find_dist(v,w,laserscan,robotModel)  
  9.       breakDist = calculateBreakingDistance(v)  
  10.       if (dist > breakDist)  //can stop in time  
  11.          heading = hDiff(robotPose,goalPose, v,w)   
  12.           //clearance与原论文稍不一样  
  13.          clearance = (dist-breakDist)/(dmax - breakDist)   
  14.          cost = costFunction(heading,clearance, abs(desired_v - v))  
  15.          if (cost > optimal)  
  16.             best_v = v  
  17.             best_w = w  
  18.             optimal = cost  
  19.     set robot trajectory to best_v, best_w  
  20. END  
机器人局部避障的动态窗口法(dynamic window approach)



(转载请注明作者和出处:http://blog.csdn.net/heyijia0327 未经允许请勿用于商业用途)



参考:

dwa:

1.Fox.《The Dynamic Window Approach To CollisionAvoidance》

2.MarijaSeder. 《dynamic window based approach tomobile robot motion control in the presence of moving obstacles》

3.http://adrianboeing.blogspot.com/2012/05/dynamic-window-algorithm-motion.html

 

运动模型:

4. http://adrianboeing.blogspot.com.au/2010/09/circular-motion-in-2d-for-graphics-and.html

5.https://www.cs.princeton.edu/courses/archive/fall11/cos495/COS495-Lecture5-Odometry.pdf

6.http://rossum.sourceforge.net/papers/DiffSteer/


最后贴出matlab仿真代码

[python] view plain copy
  1. % -------------------------------------------------------------------------  
  2. %  
  3. % File : DynamicWindowApproachSample.m  
  4. %  
  5. % Discription : Mobile Robot Motion Planning with Dynamic Window Approach  
  6. %  
  7. % Environment : Matlab  
  8. %  
  9. % Author : Atsushi Sakai  
  10. %  
  11. % Copyright (c): 2014 Atsushi Sakai  
  12. %  
  13. % License : Modified BSD Software License Agreement  
  14. % -------------------------------------------------------------------------  
  15.   
  16. function [] = DynamicWindowApproachSample()  
  17.    
  18. close all;  
  19. clear all;  
  20.    
  21. disp('Dynamic Window Approach sample program start!!')  
  22.   
  23. x=[0 0 pi/2 0 0]';% 机器人的初期状态[x(m),y(m),yaw(Rad),v(m/s),w(rad/s)]  
  24. goal=[10,10];% 目标点位置 [x(m),y(m)]  
  25. % 障碍物位置列表 [x(m) y(m)]  
  26. % obstacle=[0 2;  
  27. %           4 2;  
  28. %           4 4;  
  29. %           5 4;  
  30. %           5 5;  
  31. %           5 6;  
  32. %           5 9  
  33. %           8 8  
  34. %           8 9  
  35. %           7 9];  
  36. obstacle=[0 2;  
  37.           4 2;  
  38.           4 4;  
  39.           5 4;  
  40.           5 5;  
  41.           5 6;  
  42.           5 9  
  43.           8 8  
  44.           8 9  
  45.           7 9  
  46.           6 5  
  47.           6 3  
  48.           6 8  
  49.           6 7  
  50.           7 4  
  51.           9 8  
  52.           9 11  
  53.           9 6];  
  54.         
  55. obstacleR=0.5;% 冲突判定用的障碍物半径  
  56. global dt; dt=0.1;% 时间[s]  
  57.   
  58. % 机器人运动学模型  
  59. % 最高速度m/s],最高旋转速度[rad/s],加速度[m/ss],旋转加速度[rad/ss],  
  60. % 速度分辨率[m/s],转速分辨率[rad/s]]  
  61. Kinematic=[1.0,toRadian(20.0),0.2,toRadian(50.0),0.01,toRadian(1)];  
  62.   
  63. % 评价函数参数 [heading,dist,velocity,predictDT]  
  64. evalParam=[0.05,0.2,0.1,3.0];  
  65. area=[-1 11 -1 11];% 模拟区域范围 [xmin xmax ymin ymax]  
  66.   
  67. % 模拟实验的结果  
  68. result.x=[];  
  69. tic;  
  70. % movcount=0;  
  71. % Main loop  
  72. for i=1:5000  
  73.     % DWA参数输入  
  74.     [u,traj]=DynamicWindowApproach(x,Kinematic,goal,evalParam,obstacle,obstacleR);  
  75.     x=f(x,u);% 机器人移动到下一个时刻  
  76.       
  77.     % 模拟结果的保存  
  78.     result.x=[result.x; x'];  
  79.       
  80.     % 是否到达目的地  
  81.     if norm(x(1:2)-goal')<0.5  
  82.         disp('Arrive Goal!!');break;  
  83.     end  
  84.       
  85.     %====Animation====  
  86.     hold off;  
  87.     ArrowLength=0.5;%   
  88.     % 机器人  
  89.     quiver(x(1),x(2),ArrowLength*cos(x(3)),ArrowLength*sin(x(3)),'ok');hold on;  
  90.     plot(result.x(:,1),result.x(:,2),'-b');hold on;  
  91.     plot(goal(1),goal(2),'*r');hold on;  
  92.     plot(obstacle(:,1),obstacle(:,2),'*k');hold on;  
  93.     % 探索轨迹  
  94.     if ~isempty(traj)  
  95.         for it=1:length(traj(:,1))/5  
  96.             ind=1+(it-1)*5;  
  97.             plot(traj(ind,:),traj(ind+1,:),'-g');hold on;  
  98.         end  
  99.     end  
  100.     axis(area);  
  101.     grid on;  
  102.     drawnow;  
  103.     %movcount=movcount+1;  
  104.     %mov(movcount) = getframe(gcf);%   
  105. end  
  106. toc  
  107. %movie2avi(mov,'movie.avi');  
  108.    
  109.   
  110. function [u,trajDB]=DynamicWindowApproach(x,model,goal,evalParam,ob,R)  
  111.   
  112. % Dynamic Window [vmin,vmax,wmin,wmax]  
  113. Vr=CalcDynamicWindow(x,model);  
  114.   
  115. % 评价函数的计算  
  116. [evalDB,trajDB]=Evaluation(x,Vr,goal,ob,R,model,evalParam);  
  117.   
  118. if isempty(evalDB)  
  119.     disp('no path to goal!!');  
  120.     u=[0;0];return;  
  121. end  
  122.   
  123. % 各评价函数正则化  
  124. evalDB=NormalizeEval(evalDB);  
  125.   
  126. % 最终评价函数的计算  
  127. feval=[];  
  128. for id=1:length(evalDB(:,1))  
  129.     feval=[feval;evalParam(1:3)*evalDB(id,3:5)'];  
  130. end  
  131. evalDB=[evalDB feval];  
  132.   
  133. [maxv,ind]=max(feval);% 最优评价函数  
  134. u=evalDB(ind,1:2)';%   
  135.   
  136. function [evalDB,trajDB]=Evaluation(x,Vr,goal,ob,R,model,evalParam)  
  137. %   
  138. evalDB=[];  
  139. trajDB=[];  
  140. for vt=Vr(1):model(5):Vr(2)  
  141.     for ot=Vr(3):model(6):Vr(4)  
  142.         % 轨迹推测; 得到 xt: 机器人向前运动后的预测位姿; traj: 当前时刻 到 预测时刻之间的轨迹  
  143.         [xt,traj]=GenerateTrajectory(x,vt,ot,evalParam(4),model);  %evalParam(4),前向模拟时间;  
  144.         % 各评价函数的计算  
  145.         heading=CalcHeadingEval(xt,goal);  
  146.         dist=CalcDistEval(xt,ob,R);  
  147.         vel=abs(vt);  
  148.         % 制动距离的计算  
  149.         stopDist=CalcBreakingDist(vel,model);  
  150.         if dist>stopDist %   
  151.             evalDB=[evalDB;[vt ot heading dist vel]];  
  152.             trajDB=[trajDB;traj];  
  153.         end  
  154.     end  
  155. end  
  156.   
  157. function EvalDB=NormalizeEval(EvalDB)  
  158. % 评价函数正则化  
  159. if sum(EvalDB(:,3))~=0  
  160.     EvalDB(:,3)=EvalDB(:,3)/sum(EvalDB(:,3));  
  161. end  
  162. if sum(EvalDB(:,4))~=0  
  163.     EvalDB(:,4)=EvalDB(:,4)/sum(EvalDB(:,4));  
  164. end  
  165. if sum(EvalDB(:,5))~=0  
  166.     EvalDB(:,5)=EvalDB(:,5)/sum(EvalDB(:,5));  
  167. end  
  168.   
  169. function [x,traj]=GenerateTrajectory(x,vt,ot,evaldt,model)  
  170. % 轨迹生成函数  
  171. % evaldt:前向模拟时间; vt、ot当前速度和角速度;   
  172. global dt;  
  173. time=0;  
  174. u=[vt;ot];% 输入值  
  175. traj=x;% 机器人轨迹  
  176. while time<=evaldt  
  177.     time=time+dt;% 时间更新  
  178.     x=f(x,u);% 运动更新  
  179.     traj=[traj x];  
  180. end  
  181.   
  182. function stopDist=CalcBreakingDist(vel,model)  
  183. % 根据运动学模型计算制动距离,这个制动距离并没有考虑旋转速度,不精确吧!!!  
  184. global dt;  
  185. stopDist=0;  
  186. while vel>0  
  187.     stopDist=stopDist+vel*dt;% 制动距离的计算  
  188.     vel=vel-model(3)*dt;%   
  189. end  
  190.   
  191. function dist=CalcDistEval(x,ob,R)  
  192. % 障碍物距离评价函数  
  193.   
  194. dist=100;  
  195. for io=1:length(ob(:,1))  
  196.     disttmp=norm(ob(io,:)-x(1:2)')-R;%僷僗偺埵抲偲忈奞暔偲偺僲儖儉岆嵎傪寁嶼  
  197.     if dist>disttmp% 离障碍物最小的距离  
  198.         dist=disttmp;  
  199.     end  
  200. end  
  201.   
  202. % 障碍物距离评价限定一个最大值,如果不设定,一旦一条轨迹没有障碍物,将太占比重  
  203. if dist>=2*R  
  204.     dist=2*R;  
  205. end  
  206.   
  207. function heading=CalcHeadingEval(x,goal)  
  208. % heading的评价函数计算  
  209.   
  210. theta=toDegree(x(3));% 机器人朝向  
  211. goalTheta=toDegree(atan2(goal(2)-x(2),goal(1)-x(1)));% 目标点的方位  
  212.   
  213. if goalTheta>theta  
  214.     targetTheta=goalTheta-theta;% [deg]  
  215. else  
  216.     targetTheta=theta-goalTheta;% [deg]  
  217. end  
  218.   
  219. heading=180-targetTheta;  
  220.   
  221. function Vr=CalcDynamicWindow(x,model)  
  222. %  
  223. global dt;  
  224. % 车子速度的最大最小范围  
  225. Vs=[0 model(1) -model(2) model(2)];  
  226.   
  227. % 根据当前速度以及加速度限制计算的动态窗口  
  228. Vd=[x(4)-model(3)*dt x(4)+model(3)*dt x(5)-model(4)*dt x(5)+model(4)*dt];  
  229.   
  230. % 最终的Dynamic Window  
  231. Vtmp=[Vs;Vd];  
  232. Vr=[max(Vtmp(:,1)) min(Vtmp(:,2)) max(Vtmp(:,3)) min(Vtmp(:,4))];  
  233.   
  234. function x = f(x, u)  
  235. % Motion Model  
  236. % u = [vt; wt];当前时刻的速度、角速度  
  237. global dt;  
  238.    
  239. F = [1 0 0 0 0  
  240.      0 1 0 0 0  
  241.      0 0 1 0 0  
  242.      0 0 0 0 0  
  243.      0 0 0 0 0];  
  244.    
  245. B = [dt*cos(x(3)) 0  
  246.     dt*sin(x(3)) 0  
  247.     0 dt  
  248.     1 0  
  249.     0 1];  
  250.   
  251. x= F*x+B*u;  
  252.   
  253. function radian = toRadian(degree)  
  254. % degree to radian  
  255. radian = degree/180*pi;  
  256.   
  257. function degree = toDegree(radian)  
  258. % radian to degree  
  259. degree = radian/pi*180;