ROS1 DWB 与 ROS2 DWA 比较

news2024/9/25 3:24:04

“DWA算法(dynamic window approach)是移动机器人在运动模型下推算(v,w)对应的轨迹,确定速度采样空间或者说是动态窗口(三种限制);在速度空间(v,w)中采样多组速度,并模拟这些速度在一定时间内的运动轨迹,通过一个评价函数对这些轨迹打分,选取最优的轨迹来驱动机器人运动”。ROS1导航中局部路径规划便可选用该方法,DWB是在DWA的基础上进行了一定的优化和扩展,被ROS2采用。

在该算法中,重要的函数主要是两个:采样轨迹生成和轨迹评分,下面结合相关源码进行简单的解读和比较。

一. DWB代码和原理简单解读
在这里插入图片描述

轨迹采样函数generateTrajectory:根据机器人当前位姿start_pose,速度start_vel和目标速度cmd_vel,在预设的采样时间内进行速度空间采样,并利用离散机器人运动学模型,生成对应的轨迹,用于后续的评分,中的computeNewVelocity会在机器人运动学约束下使得速度尽可能接近目标速度,而最终的目标速度是指机器人在采样时间段内可达最终速度。

dwb_msgs::msg::Trajectory2D StandardTrajectoryGenerator::generateTrajectory(
const geometry_msgs::msg::Pose2D & start_pose,
const nav_2d_msgs::msg::Twist2D & start_vel,
const nav_2d_msgs::msg::Twist2D & cmd_vel)
{
dwb_msgs::msg::Trajectory2D traj;
traj.velocity = cmd_vel;
// simulate the trajectory
geometry_msgs::msg::Pose2D pose = start_pose;
nav_2d_msgs::msg::Twist2D vel = start_vel;
double running_time = 0.0;
std::vector<double> steps = getTimeSteps(cmd_vel);
traj.poses.push_back(start_pose);
for (double dt : steps) {
// calculate velocities
vel = computeNewVelocity(cmd_vel, vel, dt);
// update the position of the robot using the velocities passed in
pose = computeNewPosition(pose, vel, dt);
traj.poses.push_back(pose);
traj.time_offsets.push_back(rclcpp::Duration::from_seconds(running_time));
running_time += dt;
} // end for simulation steps
if (include_last_point_) {
traj.poses.push_back(pose);
traj.time_offsets.push_back(rclcpp::Duration::from_seconds(running_time));
}
return traj;
}

评分函数:使用每一个预设加载的评分函数对轨迹进行评分,然后进行加权求和,评分越低,代表该轨迹越优。

dwb_msgs::msg::TrajectoryScore
DWBLocalPlanner::scoreTrajectory(
const dwb_msgs::msg::Trajectory2D & traj,
double best_score)
{
dwb_msgs::msg::TrajectoryScore score;
score.traj = traj;
for (TrajectoryCritic::Ptr & critic : critics_) {
dwb_msgs::msg::CriticScore cs;
cs.name = critic->getName();
cs.scale = critic->getScale();
if (cs.scale == 0.0) {
score.scores.push_back(cs);
continue;
}
double critic_score = critic->scoreTrajectory(traj);
cs.raw_score = critic_score;
score.scores.push_back(cs);
score.total += critic_score * cs.scale;
if (short_circuit_trajectory_evaluation_ && best_score > 0 && score.total > best_score) {
// since we keep adding positives, once we are worse than the best, we will stay worse
break;
}
}
return score;
}

可选加载的评分函数有:

轨迹评分:评分越低越优
base_obstacle: 将代价地图在轨迹上每个位姿处的cost值进行加和,如果碰到障碍物或者出界,则会抛出异常,轨迹被视为非法;
GoalAlign:使得机器人在导航过程中方向慢慢朝向目标方向,避免到点后再原地旋转,因为这种方式可能不稳定;
RotateToGoal:
如果不够接近目标,返回0
如果足够接近目标,且当前平移速度大于停止速度,但采样速度超过当前速度,该轨迹不行;
如果足够接近目标,且当前平移速度大于停止速度,采样速度小于当前速度,则采样轨迹终点角度越接近目标角度,速度值越小,评分越低;
如果足够接近目标,且当前平移速度小于停止速度,则有平移的速度都不行;
否则,采样轨迹终点角度越接近目标角度,评分越低;
Oscillation:
轨迹中第一个采样速度为停止(线速度和角速度有一个停止,可能需要修改判断逻辑),则路径非法
否则返回0
PathAlign
如果足够接近目标(参数:forward_point_distance),返回0
否则返回轨迹末尾位姿往前延伸forward_point_distance处的cost值

PathDist:轨迹离规划路径越接近,得分越低,它偏好更接近给定参考轨迹的轨迹;
GoalDist:找到轨迹在局部代价地图中离当前位姿最远的位姿,使得轨迹最后的位姿更接近该位姿;

ObstacleFootprintCritic:考虑了机器人形状的障碍物规避评估,该形状在局部地图中设置,即footprint

 TwirlingCritic:惩罚旋转,轨迹初始旋转速度越大,得分越高。对于差速机器人,没必要选这个,但对于全向或者接近全向的机器人,有时候机器人在去往目标的过程中,比期望的旋转太多,这个评分提供了一个方式用于惩罚纯旋转速度。

二. DWA代码和原理简单解读

bool DWAPlannerROS::computeVelocityCommands(geometry_msgs::Twist& cmd_vel) {
// dispatches to either dwa sampling control or stop and rotate control, depending on whether we have been close enough to goal
if ( ! costmap_ros_->getRobotPose(current_pose_)) {
ROS_ERROR("Could not get robot pose");
return false;
}
std::vector<geometry_msgs::PoseStamped> transformed_plan;
if ( ! planner_util_.getLocalPlan(current_pose_, transformed_plan)) {
ROS_ERROR("Could not get local plan");
return false;
}

//if the global plan passed in is empty... we won't do anything
if(transformed_plan.empty()) {
ROS_WARN_NAMED("dwa_local_planner", "Received an empty transformed plan.");
return false;
}
ROS_DEBUG_NAMED("dwa_local_planner", "Received a transformed plan with %zu points.", transformed_plan.size());
// update plan in dwa_planner even if we just stop and rotate, to allow checkTrajectory
dp_->updatePlanAndLocalCosts(current_pose_, transformed_plan, costmap_ros_->getRobotFootprint());
if (latchedStopRotateController_.isPositionReached(&planner_util_, current_pose_)) {
//publish an empty plan because we've reached our goal position
std::vector<geometry_msgs::PoseStamped> local_plan;
std::vector<geometry_msgs::PoseStamped> transformed_plan;
publishGlobalPlan(transformed_plan);
publishLocalPlan(local_plan);
base_local_planner::LocalPlannerLimits limits = planner_util_.getCurrentLimits();
return latchedStopRotateController_.computeVelocityCommandsStopRotate(
cmd_vel,
limits.getAccLimits(),
dp_->getSimPeriod(),
&planner_util_,
odom_helper_,
current_pose_,
boost::bind(&DWAPlanner::checkTrajectory, dp_, _1, _2, _3));
} else {
bool isOk = dwaComputeVelocityCommands(current_pose_, cmd_vel);
if (isOk) {
publishGlobalPlan(transformed_plan);
} else {
ROS_WARN_NAMED("dwa_local_planner", "DWA planner failed to produce path.");
std::vector<geometry_msgs::PoseStamped> empty_plan;
publishGlobalPlan(empty_plan);
}
return isOk;
}
}

DWB是DWA算法的扩展和改进,它们的不同之处在于

  1. DWA在轨迹生成器初始化和轨迹生成时,根据参数use_dwa_进行一定的选择,而DWB等同于前者use_dwa_默认为true的情况,但在初始化时并没有对第一个采样速度进行加速度约束,造成速度指令可能超出加速度上限。

  2. DWA在位置到达时,进行纯旋转调整方向,而DWB是使用RotateToGoal评分在位置到达时优先选择纯旋转轨迹;

  3. DWA的评分项中没有考虑机器人底盘(footprint)可能会落入障碍物。

三. 局限性
DWA/DWB采样时,采样速度会倾向于目标速度,这使得速度只会单调变化(如单调减少,或者单调增加),对于线速度而言没什么明显不合适,但对于旋转而言,则造成每条采样轨迹只能朝一个方向延伸,如下图所示(黑色表示不合理采样轨迹,绿色无箭头附着的表示合理轨迹,绿色有箭头附着的为想跟随的参考轨迹),不适用于Z字形连续弯道和需要频繁转向的动态避障,这也是一个值得优化的点。有点则在于算法简单高效,低动态场景下适用。
在这里插入图片描述

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

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

相关文章

如何利用桌面工作计划软件制定自己的to do清单?

在我们的日常生活和工作中&#xff0c;经常会遇到各种各样的任务需要完成。如果没有一个明确的计划和安排&#xff0c;我们可能会感到混乱和压力&#xff0c;而桌面工作计划软件可以帮助我们更好地管理和规划我们的时间和任务。今天&#xff0c;我们就来聊聊如何利用这些工具&a…

职升网:二级建造师考试科目分析!

二级建造师考试包含三个主要科目&#xff0c;它们分别是《建设工程施工管理》、《建设工程法规及相关知识》以及《专业工程管理与实务》。以下是这三个科目的详细考试内容&#xff1a; 建设工程施工管理&#xff1a; 此科目作为建造师考试的基础科目&#xff0c;其核心内容是…

走进linux

1、为什么要使用linux 稳定性和可靠性&#xff1a; Linux内核以其稳定性而闻名&#xff0c;能够持续运行数月甚至数年而不需要重新启动。这对于服务器来说至关重要&#xff0c;因为它们需要保持长时间的稳定运行&#xff0c;以提供持续的服务 安全性&#xff1a; Linux系统…

酷克数据亮相第13届PostgreSQL中国技术大会,获数据库杰出贡献奖

7 月 12 日&#xff0c;第 13 届 PostgreSQL 中国技术大会在杭州盛大开幕。本次大会以“聚焦云端创新&#xff0c;汇聚智慧共享”为主题&#xff0c;邀请了国内外 PG 领域众多行业大咖、学术精英及技术专家&#xff0c;共同探讨数据库领域的发展趋势、技术创新和实践经验。酷克…

本地部署,使用ColorizeArtistic_gen.pth大模型进行图像上色

目录 引言 技术背景 模型架构 本地部署 运行结果 实验结果与分析 应用实例 结论 参考文献 引言 图像上色&#xff08;Image Colorization&#xff09;是指将黑白图像转换为彩色图像的技术。在数字化时代&#xff0c;这种技术可以用于修复旧照片、增强艺术作品以及在各…

FDL与Kettle功能对比分析之定时任务DDL

开发者在进行数据处理任务时&#xff0c; 一旦源数据库的表结构发生变化&#xff0c;而目标数据库没有及时进行同步&#xff0c;就会导致任务执行失败。DDL同步就是用来解决这一问题&#xff0c;它会自动识别源表结构变化&#xff0c;并及时更新到目标数据库中&#xff0c;保障…

1. 变量、运算符、表达式、输入与输出习题

第一节题单 1. A B import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);int a,b;a sc.nextInt();b sc.nextInt();System.out.println(ab);} }608.差 604. 圆的面积 注意不能用float,float的精度不够…

智能硬件——0-1开发流程

文章目录 流程图1. 市场分析具体分析 2. 团队组建2. 团队组建早期团队配置建议配置一&#xff1a;基础型团队 (4人)配置二&#xff1a;扩展型团队 (6人)配置三&#xff1a;全面型团队 (7人) 3. 产品需求分析4. ID设计&#xff08;Industrial Design, 工业设计&#xff09;5. 结…

展望未来:在【PyCharm】中结合【机器学习】实现高效的图形化处理

欢迎来到 破晓的历程的 博客 ⛺️不负时光&#xff0c;不负己✈️ 文章目录 引言一、PyCharm简介与配置1.1 PyCharm基础1.2 图形化库配置 二、机器学习项目中的数据可视化2.1 数据加载与预处理2.2 数据探索性可视化2.3 模型训练与结果可视化 三、PyCharm中的图形化调试四、高级…

如何追踪ping连接中的所有路由器的数量和IP

如何快速判断ping连接经过的路由器个数和IP&#xff1f; 方法一&#xff1a; ping命令会返回一个TTL&#xff0c;TTL&#xff08;Time To Live&#xff09;存活时间&#xff0c;一般初始值为64&#xff0c;每经过一个路由器就减一&#xff0c;当TTL为0时丢弃网络包&#xff0…

设置sudo权限

1.使用root账号登录 2.使用visudo打开sudo的配置文件 3.CtrlF翻页到#All root to run any commands anywhere 4.敲击键盘i键切到插入模式 5.在root配置信息一行下方加入一行&#xff0c;以用户test为例&#xff1a; test ALL(ALL) NOPASSWD: ALL

Linux DRM 那些事 - HDMI 接口 DTS 配置

本文基于RockPI 4A单板Debian系统 Linux 4.4 内核介绍DRM框架HDMI接口DTS配置。 在DTS中主要实现&#xff1a;HDMI的使能、VOP绑定、IOMUX引脚配置和HDMI控制器配置。 一、HDMI 配置 文件&#xff1a;arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi #include "rk3…

hutool处理excel时候空指针小记

如图所示&#xff0c;右侧的会识别不到 参考解决方案&#xff1a; /***Description: 填补空缺位置为null/空串*Param: hutool读取的list*return: 无*Author: y*date: 2024/7/13*/public static void formatHutoolExcelArr(List<List<Object>> list) {if (CollUtil…

graphviz subgraph添加边界框

subgraph name 属性必须要以cluster开头。 A Quick Introduction to GraphvizAn awesome tool for software documentation and visualizing graphshttps://www.worthe-it.co.za/blog/2017-09-19-quick-introduction-to-graphviz.html digraph {rankdir"LR"// the n…

教材目录管理功能概述

在智慧校园的教材管理体系中&#xff0c;教材目录管理板块扮演着连接知识与学习者的桥梁角色&#xff0c;对教育资源的有序部署与高效运转起着至关重要的作用。该板块聚焦于基础功能的精炼与优化&#xff0c;力图构建一个界面友好、操作简便的教材信息管理环境。 该板块设计之初…

【Unity学习笔记】第十九 · 物理引擎约束求解解惑(LCP,最优,拉格朗日乘数法,SI,PGS,基于冲量法)

转载请注明出处: https://blog.csdn.net/weixin_44013533/article/details/140309494 作者&#xff1a;CSDN|Ringleader| 在学习物理引擎过程中&#xff0c;有几大问题一直困扰着我&#xff1a; 约束求解到底是LCP还是带约束最优问题&#xff1f;约束求解过程中拉格朗日乘数法…

.NET MAUI开源架构_1.学习资源分享

最近需要开发Android的App&#xff0c;想预研下使用.NET开源架构.NET MAUI来开发App程序。因此网上搜索了下相关资料&#xff0c;现在把我查询的结果记录下&#xff0c;方便后面学习。 1.官方文档 1.1MAUI官方学习网站 .NET Multi-Platform App UI 文档 - .NET MAUI | Micro…

paddlepaddle2.6,paddleorc2.8,cuda12,cudnn,nccl,python10环境

1.安装英伟达显卡驱动 首先需要到NAVIDIA官网去查自己的电脑是不是支持GPU运算。 网址是&#xff1a;CUDA GPUs | NVIDIA Developer。打开后的界面大致如下&#xff0c;只要里边有对应的型号就可以用GPU运算&#xff0c;并且每一款设备都列出来相关的计算能力&#xff08;Compu…

《Python零基础入门》——关于PyCharm使用技巧及python基本概念

从本次文章开始&#xff0c;我们将学习一门新的编程语言——Python。作为最热门的编程语言&#xff0c;Python相对比较清晰、简单。 python主要的编译工具就是pycharm&#xff0c;关于pycharm的安装及python配置环境&#xff0c;大家可自行参考网络上的教程&#xff0c;本文不…

深入Linux:权限管理与常用命令详解

文章目录 ❤️Linux常用指令&#x1fa77;zip/unzip指令&#x1fa77;tar指令&#x1fa77;bc指令&#x1fa77;uname指令&#x1fa77;shutdown指令 ❤️shell命令以及原理❤️什么是 Shell 命令❤️Linux权限管理的概念❤️Linux权限管理&#x1fa77;文件访问者的分类&#…