Dynamic Window Approach_机器人局部避障的动态窗口法

2024-02-10 03:58

本文主要是介绍Dynamic Window Approach_机器人局部避障的动态窗口法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • 最近正在学习DWA,按照DynamicWindowApproachSample.m 提供的matlab仿真代码简单梳理下,但是这并不是ros里用的,只是一个简单的仿真。
  • DWA的原理:假设一个机器人要从当前点通过一定的速度和方向到达目标点,在速度(v, w)空间中采样多组轨迹,为这些轨迹使用评价函数进行评价,选取最优的轨迹对应的速度(v_best, w_best)来驱动机器人,最终到达目标点。
代码分析:
  1. 首先定义一些初始状态

    % 机器人的初始状态,包括初始位置,朝向(这里可以理解为yaw角)速度,角速度
    % [x(m),y(m),yaw(Rad),v(m/s),w(rad/s)]
    x=[0 0 pi/2 0 0]';% 目标点位置 [x(m),y(m)]
    goal=[10,10];% 障碍物位置列表 [x(m) y(m)]
    obstacle=[0 2;4 2;4 4;5 4;5 5;5 6; 6 7;7 4;9 8;9 11;9 6];% 冲突判定用的障碍物半径
    obstacleR=0.5;% 时间间隔[s],主要用于运动模型
    global dt; dt=0.1;%% 机器人运动学模型参数
    % 最高速度[m/s],最高旋转速度[rad/s],加速度[m/ss],旋转加速度[rad/ss],
    % 速度分辨率[m/s],转速分辨率[rad/s]]
    Kinematic=[1.0,toRadian(20.0),0.2,toRadian(50.0),0.01,toRadian(1)];% 评价函数参数 [heading,dist,velocity,predictDT]
    evalParam=[0.05,0.2,0.1,3.0];% 模拟区域范围 [xmin xmax ymin ymax]
    area=[-1 11 -1 11];% 模拟实验的结果
    result.x=[];
  2. 进入仿真主循环
    循环主要函数为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.5disp('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))/5ind=1+(it-1)*5;plot(traj(ind,:),traj(ind+1,:),'-g');hold on;endendaxis(area);grid on;drawnow; 
    end

    运动模型 x=f(x,u)指的是在世界坐标系下,机器人从a点运动到b点遵循的运动规则,w指的是世界坐标系
    世界坐标系下
    机器人从a点到b点的运动模型
    用矩阵的形式表示这个模型如下:

function x = f(x, u)
% u = [vt; wt];当前时刻的速度、角速度
global dt;F = [1 0 0 0 00 1 0 0 00 0 1 0 00 0 0 0 00 0 0 0 0];B = [dt*cos(x(3)) 0dt*sin(x(3)) 00 dt1 00 1];x= F*x+B*u;
  1. 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)';
  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))];
  3. 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];endend
    end
  4. 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
  5. CalcHeadingEval函数,heading的评价函数计算

    function heading=CalcHeadingEval(x,goal)% 机器人朝向
    theta = toDegree(x(3));
    % 目标点的方位
    goalTheta = toDegree(atan2(goal(2)-x(2),goal(1)-x(1)));if goalTheta > thetatargetTheta = goalTheta - theta;% [deg]
    elsetargetTheta = theta - goalTheta;% [deg]
    end% theta越小,评价越高
    heading = 180 - targetTheta;
  6. 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>disttmpdist=disttmp;endend% 障碍物距离评价限定一个最大值,如果不设定,一旦一条轨迹没有障碍物,将太占比重if dist>=2*Rdist=2*R;end

这篇关于Dynamic Window Approach_机器人局部避障的动态窗口法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/696059

相关文章

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

动态规划---打家劫舍

题目: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 思路: 动态规划五部曲: 1.确定dp数组及含义 dp数组是一维数组,dp[i]代表

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d

使用JS/Jquery获得父窗口的几个方法(笔记)

<pre name="code" class="javascript">取父窗口的元素方法:$(selector, window.parent.document);那么你取父窗口的父窗口的元素就可以用:$(selector, window.parent.parent.document);如题: $(selector, window.top.document);//获得顶级窗口里面的元素 $(

基于树梅派的视频监控机器人Verybot

最近这段时间做了一个基于树梅派 ( raspberry pi ) 的视频监控机器人平台 Verybot ,现在打算把这个机器人的一些图片、视频、设计思路进行公开,并且希望跟大家一起研究相关的各种问题,下面是两张机器人的照片:         图片1:                   图片2                    这个平台的基本组成是:

LeetCode:64. 最大正方形 动态规划 时间复杂度O(nm)

64. 最大正方形 题目链接 题目描述 给定一个由 0 和 1 组成的二维矩阵,找出只包含 1 的最大正方形,并返回其面积。 示例1: 输入: 1 0 1 0 01 0 1 1 11 1 1 1 11 0 0 1 0输出: 4 示例2: 输入: 0 1 1 0 01 1 1 1 11 1 1 1 11 1 1 1 1输出: 9 解题思路 这道题的思路是使用动态规划

js window.addEventListener 是什么?

window.addEventListener 是 JavaScript 中的一个方法,用于向指定对象(在这个情况下是 window 对象,代表浏览器窗口)添加事件监听器,以便在该对象上发生特定事件时执行相应的函数(称为事件处理函数或事件监听器)。 这个方法接受三个参数: 事件类型(type):一个字符串,表示要监听的事件类型。例如,"click" 表示鼠标点击事件,"load" 表示页面加

专题二_滑动窗口_算法专题详细总结

目录 滑动窗口,引入: 滑动窗口,本质:就是同向双指针; 1.⻓度最⼩的⼦数组(medium) 1.解析:给我们一个数组nums,要我们找出最小子数组的和==target,首先想到的就是暴力解法 1)暴力: 2)优化,滑动窗口: 1.进窗口 2.出窗口 3.更新值 2.⽆重复字符的最⻓⼦串(medium) 1)仍然是暴力解法: 2)优化: 进窗口:hash[s[rig

vue2实践:el-table实现由用户自己控制行数的动态表格

需求 项目中需要提供一个动态表单,如图: 当我点击添加时,便添加一行;点击右边的删除时,便删除这一行。 至少要有一行数据,但是没有上限。 思路 这种每一行的数据固定,但是不定行数的,很容易想到使用el-table来实现,它可以循环读取:data所绑定的数组,来生成行数据,不同的是: 1、table里面的每一个cell,需要放置一个input来支持用户编辑。 2、最后一列放置两个b