轨迹规划 | 图解动态窗口算法DWA(附ROS C++/Python/Matlab仿真)

news2024/11/25 15:21:39

目录

  • 0 专栏介绍
  • 1 动态障碍建模
  • 2 DWA基本原理
    • 2.1 采样窗口
    • 2.2 评价函数
  • 3 DWA算法流程
  • 4 仿真实现
    • 4.1 ROS C++实现
    • 4.2 Python实现
    • 4.3 Matlab实现

0 专栏介绍

🔥附C++/Python/Matlab全套代码🔥课程设计、毕业设计、创新竞赛必备!详细介绍全局规划(图搜索、采样法、智能算法等);局部规划(DWA、APF等);曲线优化(贝塞尔曲线、B样条曲线等)。

🚀详情:图解自动驾驶中的运动规划(Motion Planning),附几十种规划算法


1 动态障碍建模

室内移动机器人研究的最终目标之一是构建能够在危险和人口密集的环境中安全执行任务的机器人。例如,协助人类在室内办公环境中的服务机器人应能够对意外变化做出快速反应,并在各种外部情况下完成其任务。然而,大多数运动规划器依赖于对环境的准确、静态建模,因此如果人类或其他不可预测的障碍物阻挡了它们的路径,它们往往会停止工作。为了构建自主移动机器人,我们需要构建能够感知环境、对不可预见的情况做出反应并进行动态规划以完成任务的系统

在这里插入图片描述

动态窗口算法(Dynamic Window Approach)应运而生,它是一种在机器人路径规划和导航领域中广泛应用的算法,应用背景可以追溯到无人驾驶车辆、自主移动机器人和其他智能系统需要在复杂环境中高效运动的情况。DWA通过将机器人的运动状态和环境信息建模为一个动态窗口,来实现快速的路径规划和避碰决策。该算法通过评估当前机器人状态下可能的速度和方向组合,利用启发式方法选择最佳动作,以避免与障碍物发生碰撞并尽快到达目标点。

2 DWA基本原理

2.1 采样窗口

DWA关注一个问题

如何对静态/动态障碍物进行反应性避碰?

DWA特别设计用于处理由有限速度和加速度所施加的约束,这些约束直接从移动机器人的运动学模型导出。简言之,DWA仅在计算下一个控制指令时周期性地考虑一个短时间间隔,以避免处理一般运动规划问题所带来的巨大复杂性。在这样的时间间隔内,通过将轨迹近似为圆曲率,得到了一个二维搜索空间,包括平移和旋转速度。此搜索空间被缩小到允许机器人安全停止的合法速度。由于有限加速度,速度受到进一步的限制:机器人只考虑在下一个时间间隔内可以到达的速度。这些速度形成了动态窗口,其在速度空间中围绕机器人当前速度中心。

在这里插入图片描述

在DWA中,构造如下的采样窗口

{ w i n ( v ) = [ max ⁡ { v min ⁡ , v − a v d t } , min ⁡ { v max ⁡ , v + a v d t } ] w i n ( ω ) = [ max ⁡ { ω min ⁡ , ω − a ω d t } , min ⁡ { ω max ⁡ , ω + a ω d t } ] \begin{cases} win\left( v \right) =\left[ \max \left\{ v_{\min},v-a_v\mathrm{d}t \right\} , \min \left\{ v_{\max}, v+a_v\mathrm{d}t \right\} \right]\\ win\left( \omega \right) =\left[ \max \left\{ \omega _{\min},\omega -a_{\omega}\mathrm{d}t \right\} , \min \left\{ \omega _{\max}, \omega +a_{\omega}\mathrm{d}t \right\} \right]\\\end{cases} {win(v)=[max{vmin,vavdt},min{vmax,v+avdt}]win(ω)=[max{ωmin,ωaωdt},min{ωmax,ω+aωdt}]

2.2 评价函数

接着在窗口内采样二元点对 ( v , ω ) \left( v,\omega \right) (v,ω),设置仿真时间 t t t,模拟出机器人从当前位置开始以 ( v , ω ) \left( v,\omega \right) (v,ω)恒速行进的轨迹,并对轨迹进行评价

G ( v , ω ) = α ⋅ h e a d i n g ( v , ω ) + β ⋅ d i s t ( v , ω ) + γ ⋅ v e l o c i t y ( v , ω ) G\left( v,\omega \right) =\alpha \cdot \mathrm{heading}\left( v,\omega \right) +\beta \cdot \mathrm{dist}\left( v,\omega \right) +\gamma \cdot \mathrm{velocity}\left( v,\omega \right) G(v,ω)=αheading(v,ω)+βdist(v,ω)+γvelocity(v,ω)

其中方向角评价函数

h e a d i n g ( v , ω ) = π − ∣ θ g o a l − θ ∗ ∣ \mathrm{heading}\left( v,\omega \right) =\pi -\left| \theta _{\mathrm{goal}}-\theta ^* \right| heading(v,ω)=πθgoalθ

其中 θ g o a l \theta _{\mathrm{goal}} θgoal是机器人在模拟轨迹末端和终点连线与 x x x轴的夹角, θ ∗ \theta ^* θ是机器人在模拟轨迹末端的姿态角,旨在选出目标角度与指向角度间差值较小的轨迹,使机器人的前进方向对准终点。障碍物评价函数

d i s t ( v , ω ) = { d 0    , d > d 0 d    , d s a f e ⩽ d ⩽ d 0 0 , d < d s a f e \mathrm{dist}\left( v,\omega \right) =\begin{cases} d_0\,\,, d>d_0\\ d\,\, , d_{\mathrm{safe}}\leqslant d\leqslant d_0\\ 0 , d<d_{\mathrm{safe}}\\\end{cases} dist(v,ω)= d0,d>d0d,dsafedd00,d<dsafe

旨在选出与障碍物距离较远的轨迹,避免机器人运行过程中发生碰撞, d d d表示预测轨迹与障碍物的最近距离; d 0 d_0 d0为障碍物评分最大值,若预测轨迹与障碍物间距超过 d 0 d_0 d0则认为该轨迹安全; d s a f e d_{\mathrm{safe}} dsafe是机器人与障碍的安全间距,若预测轨迹与障碍物间距小于 d s a f e d_{\mathrm{safe}} dsafe则认为该轨迹发生碰撞。速度评价函数

v e l o c i t y ( v , ω ) = ∣ v ∣ \mathrm{velocity}\left( v,\omega \right) =\left| v \right| velocity(v,ω)=v

旨在选出线速度较大的轨迹,使机器人的运动速度尽量快。综上所述,评价函数的物理意义是使机器人以较快的速度朝着目标运动并进行自主避障,实际应用中可根据需要改变评价函数及其权重系数

3 DWA算法流程

DWA算法流程如下所示

在这里插入图片描述

4 仿真实现

4.1 ROS C++实现

构造动态窗口

generator_.initialise(pos,
        vel,
        goal,
        &limits,
        vsamples_);

在这个函数内部构造了采样窗口

max_vel[0] = std::min(max_vel_x, vel[0] + acc_lim[0] * sim_period_);
max_vel[1] = std::min(max_vel_y, vel[1] + acc_lim[1] * sim_period_);
max_vel[2] = std::min(max_vel_th, vel[2] + acc_lim[2] * sim_period_);

min_vel[0] = std::max(min_vel_x, vel[0] - acc_lim[0] * sim_period_);
min_vel[1] = std::max(min_vel_y, vel[1] - acc_lim[1] * sim_period_);
min_vel[2] = std::max(min_vel_th, vel[2] - acc_lim[2] * sim_period_);

再通过迭代器

VelocityIterator x_it(min_vel[0], max_vel[0], vsamples[0]);
VelocityIterator y_it(min_vel[1], max_vel[1], vsamples[1]);
VelocityIterator th_it(min_vel[2], max_vel[2], vsamples[2]);

遍历所有可能的速度组合,存入sample_params_中,生成最优轨迹

std::vector<base_local_planner::Trajectory> all_explored;
scored_sampling_planner_.findBestTrajectory(result_traj_, &all_explored);

findBestTrajectory中主要分为两步:

  • 轨迹生成
    gen_->nextTrajectory(loop_traj);
    
    这里的gen_会通过已构造的sample_params_遍历所有可能的速度组合,通过其generateTrajectory()函数生成轨迹返回
  • 轨迹评价
    loop_traj_cost = scoreTrajectory(loop_traj, best_traj_cost);
    
    这里实际上调用代价函数栈对轨迹进行逐一评价
    for (std::vector<TrajectoryCostFunction *>::iterator score_function = critics_.begin(); score_function != critics_.end(); ++score_function)
    {
      TrajectoryCostFunction *score_function_p = *score_function;
      double cost = score_function_p->scoreTrajectory(traj);
      ...
    }
    
    而这些代价函数可以自定义,它们已经在上一步完成了更新。

最后选择代价最小的轨迹返回即可。

4.2 Python实现

核心代码如下所示

def evaluation(self, vr):
     v_start, v_end, w_start, w_end = vr
     v = np.linspace(v_start, v_end, num=int((v_end - v_start) / self.robot.V_RESOLUTION)).tolist()
     w = np.linspace(w_start, w_end, num=int((w_end - w_start) / self.robot.W_RESOLUTION)).tolist()
     
     eval_win, traj_win = [], []
     for v_, w_ in product(v, w):
         # trajectory prediction, consistent of poses
         traj = self.generateTraj(v_, w_)
         end_state = traj[-1].squeeze().tolist()
         
         # heading evaluation
         theta = self.angle((end_state[0], end_state[1]), self.goal)
         heading = np.pi - abs(end_state[2] - theta)

         # obstacle evaluation
         dist_vector = np.array(tuple(self.obstacles)) - np.array([end_state[0], end_state[1]])
         dist_vector = np.sqrt(np.sum(dist_vector**2, axis=1))
         distance = np.min(dist_vector)
         if distance > self.eval_param["R"]:
             distance = self.eval_param["R"]

         # velocity evaluation
         velocity = abs(v_)
         
         # braking evaluation
         dist_stop = v_ * v_ / (2 * self.robot.V_ACC)

         # collision check
         if distance > dist_stop and distance >= 1:
             eval_win.append((v_, w_, heading, distance, velocity))
             traj_win.append(traj)
 
     ...
     
     # evaluation
     factor = np.array([[1, 0,                          0],
                        [0, 1,                          0],
                        [0, 0, self.eval_param["heading"]],
                        [0, 0, self.eval_param["distance"]],
                        [0, 0, self.eval_param["velocity"]]])

     return eval_win @ factor, traj_win

4.3 Matlab实现

核心代码如下所示

function [eval_win, traj_win] = evaluation(robot, vr, goal, obstacle, kinematic, eval_param)
    eval_win = []; traj_win = [];
    for v = vr(1):kinematic.V_RESOLUTION:vr(2)
        for w=vr(3):kinematic.W_RESOLUTION:vr(4)
            % trajectory prediction, consistent of poses
            [robot_star, traj] = generate_traj(robot, v, w, eval_param(4), eval_param(5));
            
            % heading evaluation
            theta = angle([robot_star.x, robot_star.y], goal(1:2));
            heading = pi - abs(robot_star.theta - theta);

            % obstacle evaluation
            dist_vector = dist(obstacle, [robot_star.x; robot_star.y]);
            distance = min(dist_vector);
            if distance > eval_param(6)
                distance = eval_param(6);
            end

            % velocity evaluation
            velocity = abs(v);
            
            % braking evaluation
            dist_stop = v * v / (2 * kinematic.V_ACC);

            % collision check
            if distance > dist_stop && distance >= 1
                eval_win = [eval_win; [v w heading distance velocity]];
                traj_win = [traj_win; traj];
            end
        end
    end
    
    % normalization
    ...
    
    eval_win = [eval_win(:, 1:2), eval_win(:, 3:5) * eval_param(1:3)'];
end

在这里插入图片描述

完整工程代码请联系下方博主名片获取


🔥 更多精彩专栏

  • 《ROS从入门到精通》
  • 《Pytorch深度学习实战》
  • 《机器学习强基计划》
  • 《运动规划实战精讲》

👇源码获取 · 技术交流 · 抱团学习 · 咨询分享 请联系👇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1097613.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文案配音软件哪个好?(适合新手使用)

随着短视频的逐渐普及&#xff0c;视频博主越来越多&#xff0c;所以很多朋友也期待成为视频博主。但是&#xff0c;如果你想成为一个有名的视频博主&#xff0c;你需要在很多层面上比别人做得更好。其中之一就是视频文字的配音。相信大部分人都没有配音的技巧&#xff0c;所以…

mybatis plus MetaObjectHandler 不生效

首先要知道,spring boot 只会加载启动类同级和下级的bean 如果把bean放在启动类不同的上级目录,是加载不了bean的 如果把mybatisplus的配置文件放在与启动类不同包,就会扫描不到 例如放在这里,就扫描不到 放到这里,就可以扫描到

部署云端SIEM解决方案的5个优势

随着组织迅速转向云端以利用云计算的优势&#xff0c;包括SIEM&#xff08;安全信息与事件管理&#xff09;在内的服务也正在向云端迁移。事实上&#xff0c;SIEM即服务正在迅速崭露头角&#xff0c;成为传统的本地SIEM解决方案的替代品。在Gartner的《采用SaaS SIEM前需回答的…

数学知识总结

素数 质数/素数定义 在大于1的整数中&#xff0c;如果只包含1和本身这两个约数&#xff0c;就被称为质数&#xff0c;或者叫素数 判断素数&#xff08;试除法&#xff09; 约数有一个重要的性质&#xff1a; 假设n代表数字&#xff0c;d代表n的一个约数 即d能整除n(d|n) 那么n…

visual studio安装时候修改共享组件、工具和SDK路径方法

安装了VsStudio后,如果自己修改了Shared路径&#xff0c;当卸载旧版本&#xff0c;需要安装新版本时发现&#xff0c;之前的Shared路径无法进行修改&#xff0c;这就很坑爹了&#xff0c;因为我运行flutter程序的时候&#xff0c;报错找不到windows sdk的位置&#xff0c;所以我…

Windows用VM虚拟机安装MacOS Ventura 13.6系统全流程教程(附资源)

安装成果&#xff1a; 所需容量&#xff1a;至少40GB的硬盘空间&#xff0c;推荐80GB以上。 所需资源 VMware虚拟机激活密钥&#xff1a;VMware Workstation Pro 17.0.2MacOS Ventura 13.6的ISO镜像MacOS的解锁工具卡顿优化工具&#xff1a;beamoff 有人反馈说需要能用的ISO镜…

mysql中特殊字符存储,如表情字符

一.问题&#xff1a;出现下面异常说明是不能存储特殊字符 ### Cause: java.sql.SQLException: Incorrect string value: \xF0\x9F\x98\x81 for column column1 at row 1 ; uncategorized SQLException; SQL state [HY000]; error code [1366]; Incorrect string value: \xF0\x…

UPS 原理和故障案例分享

摘要:不间断电源UPS (Uninterruptible Power System)&#xff0c;主要是由整流器、 逆变器、静态旁路和储能装置等组成;具备高可靠性、高可用性和高质量的独立 电源。通过对收集的 UPS 故障案例进行分析&#xff0c;从施工&#xff0c;调试和运行三个方面筛选 出四个故障案例与…

构建高效问题解答平台:使用Cpolar和Tipas在Ubuntu上搭建专属问答网站

文章目录 前言2.Tipask网站搭建2.1 Tipask网站下载和安装2.2 Tipask网页测试2.3 cpolar的安装和注册 3. 本地网页发布3.1 Cpolar临时数据隧道3.2 Cpolar稳定隧道&#xff08;云端设置&#xff09;3.3 Cpolar稳定隧道&#xff08;本地设置&#xff09; 4. 公网访问测试5. 结语 前…

什么是实验室超声消泡机?工作原理是怎样的?

超声波消泡设备也叫超声波脱气机、超声波消泡机、超声波消泡器。超声波在液体中产生空化作用,使得液体中溶解的气体(如:空气)不断凝聚,成为很细小的气泡,最后成为球状气泡脱离液体表面&#xff0c;从而达到液体脱气、液体消泡的目的。 实验室超声消泡机工作原理&#xff1a; …

买了个Oppo Reno6用于测试

这一段时间开发摄像头APP&#xff0c;一直用手头的主力机。摄像头APP要求经常拔插&#xff0c;担心损坏。而手头的几个USB线似乎也有问题&#xff0c;经常连着电脑就断线。于是决定买个手机用于测试。 经过挑选买了个二手的RENO6&#xff0c;个头小&#xff0c;与手头的X70 PR…

Numpy(二) 元素与数组的操作

Numpy(二) 元素与数组的操作 一、元素的索引访问 1.一维数组索引访问 ①Numpy一维数组索引访问与python内置序列类型索引访问一样&#xff0c;都使用中括号下标&#xff08;[index]&#xff09; ②正值索引/负值索引 正值索引&#xff1a;0 1 2 3 4 5 a数组&#xff…

Android Studio Giraffe | 2022.3.1

Android Gradle 插件和 Android Studio 兼容性 Android Studio 构建系统以 Gradle 为基础&#xff0c;并且 Android Gradle 插件 (AGP) 添加了几项专用于构建 Android 应用的功能。下表列出了各个 Android Studio 版本所需的 AGP 版本。 如果您的项目不受某个特定版本的 Andr…

专业课138,总分390+,西工大,西北工业大学827信号与系统考研分享

数学一 考研数学其实严格意义上已经没有难度大小年之分了&#xff0c;说21年难的会说22年简单&#xff0c;说22年简单的做23年又会遭重&#xff0c;所以其实只是看出题人合不合你的口味罢了&#xff0c;建议同学不要因偶数年而畏惧&#xff0c;踏踏实实复习。资料方面跟谁就用…

实用的窗口管理软件:Display Maid for Mac

Display Maid 是一款用于 macOS 平台的窗口管理工具&#xff0c;它可以帮助用户更高效地管理和组织他们的应用程序窗口。Display Maid 提供了一系列功能和快捷键&#xff0c;使用户可以轻松地调整窗口的位置、大小和布局&#xff0c;以适应不同的工作环境和需求。 以下是 Disp…

基于Java的家庭食谱管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

ubuntu服务器启动报错UNEXPECTED INCONSISTENCY解决方法

遇到这种情况,按照出错提示来进行处理一般不会有问题,我这里尝试使用命令fsck修复出错的分区: 我使用的是&#xff1a;umount /dev/sdb3 然后提示卸载错误&#xff08;所以这一步不是到是否有用&#xff09; 修复: fsck -y /dev/sdb3 ,最后挂载分区上去:mount /dev/sdb3 /da…

基于ebpf的性能工具-bpftrace

在前面我已经分享了关于ebpf入门的文章&#xff1a;基于ubuntu22.04-深入浅出 eBPF。这篇文章介绍一个基于ebpf技术的强大工具–bpftrace。 在现代计算机系统中&#xff0c;了解系统的内部运行情况对于诊断问题、优化性能以及进行安全监控至关重要。bpftrace作为一款强大的跟踪…

BUUCTF学习(8): 随便注,SQL

1、介绍 2、解题 1;set sql_modePIPES_AS_CONCAT;select 1 结束

FL Studio 21.1.3750中文完整至尊版2023最新破解版免费下载

FL Studio 21.1.3750中文完整至尊版2023最新破解版免费下载是最好的音乐开发和制作软件也称为水果循环。它是最受欢迎的工作室&#xff0c;因为它包含了一个主要的听觉工作场所。最新fl studio 21中文版 版有不同的功能&#xff0c;如它包含图形和音乐音序器&#xff0c;帮助您…