SLAM从入门到精通(dwa算法)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        要说搜路算法,这个大家都比较好理解。毕竟从一个地点走到另外一个地点,这个都是直觉上可以感受到的事情。但是这条道路上机器人应该怎么走,以什么样的速度、什么样的角速度走,这里面有很大的学问。一方面,机器人本身的机械特性决定了它的速度、角速度这些参数都有一定范围约束的;另外一方面,不同的速度、角速度走出来的轨迹可能是不一样的,特别是拐弯的时候。这个时候,什么样的轨迹最适合我们机器人,就需要设计出一套标准来甄别了。比如,是越快越好,还是越安全越好,还是说离目标越近越好。

        对于客户来说,速度、角速度肯定是越快越好。但是机械的特性决定了很多时候它快不了,比如转弯的时候,甚至是连续转弯的时候,速度快了反而不安全。正因为有了这些需求,所以才会有了dwa算法设计出来帮助我们来解决这些问题。

1、了解机器人的参数

        每一款机器人都有自己独特的参数,比如最小速度、最大速度;最小角速度、最大加速度;最小线加速度、最大线加速度等等。这些数据都需要做很好的了解。不仅如此,我们还需要知道机器人的最小转弯半径。如果可以原地旋转,这固然很好。但是大多数机器人不一定可以做到这一点。而且根据v=w*r,一旦转弯半径定了,v和w只要一个确定了,另外一个也就确定了。

2、知晓机器人的运动学模型

        之前我们说过差速轮的运动学模型,假设速度分别为v和w,那么后面小车的轨迹应该是这样的,

x += v * cos(theta) * dt
y += v * cos(theta) * dt
theta += w * dt

        当然这里描述的只是差速轮的运动学模型,其他机器人的运动学模型也可以通过类似的方法进行计算。

3、速度采样、加速度采样

        以速度为例,机器人本身有一个最小速度,还有一个最大速度。此外,它还有一个最小加速度、最大加速度。所以某个时刻速度v,依据加速度的范围可以得到一个数值[v_min, v_max],但是这个范围不能超过[vmin,v_max]机器人本身要求的范围。所以最终机器人的速度应该是在[max(v_min, vmin), min(v_max, vmax)]这个范围之内。加速度也是一个道理。

4、轨迹评价标准

        本身dwa提供了三个评价标准,分别是目标、速度以及和障碍物的最小距离。当然,这三个标准是不一定的,我们完全可以自己来设计。

5、测试代码

        dwa算测的测试代码是用python实现的,参考一本ros书上的内容,在此表示感谢。此python代码用python3执行,依赖于库matplotlib。代码内容如下,

import numpy as np
import matplotlib.pyplot as plt
import mathclass Info():def __init__(self):self.v_min = -0.5self.v_max = 3.0self.w_max = 50.0 * math.pi / 180.0self.w_min = -50.0 * math.pi / 180.0self.vacc_max = 0.5self.wacc_max = 30.0 * math.pi / 180.0self.v_reso = 0.01self.w_reso = 0.1 * math.pi / 180.0self.radius = 1.0self.dt = 0.1self.predict_time = 4.0self.goal_factor = 1.0self.vel_factor = 1.0self.traj_factor = 1.0def motion_model(x,u,dt):x[0] += u[0] * dt * math.cos(x[2])x[1] += u[0] * dt * math.sin(x[2])x[2] += u[1] * dtx[3] = u[0]x[4] = u[1]return xdef vw_generate(x,info):Vinfo = [info.v_min, info.v_max,info.w_min, info.w_max]Vmove = [x[3] - info.vacc_max * info.dt,x[3] + info.vacc_max * info.dt,x[4] - info.wacc_max * info.dt,x[4] + info.wacc_max * info.dt]vw = [max(Vinfo[0], Vmove[0]), min(Vinfo[1], Vmove[1]),max(Vinfo[2], Vmove[2]), min(Vinfo[3], Vmove[3])]return vwdef traj_calculate(x,u,info):ctraj = np.array(x)xnew = np.array(x)time = 0while time <= info.predict_time:x_new = motion_model(xnew,u,info.dt)ctraj = np.vstack((ctraj, xnew))time += info.dtreturn ctrajdef dwa_core(x,u,goal,info, obstacles):vw = vw_generate(x,info)best_ctraj = np.array(x)min_score = 10000.0for v in np.arange(vw[0], vw[1], info.v_reso):for w in np.arange(vw[2], vw[3], info.w_reso):ctraj = traj_calculate(x, [v,w], info)goal_score = info.goal_factor * goal_evaluate(ctraj, goal)vel_score = info.vel_factor * velocity_evaluate(ctraj, info)traj_score = info.traj_factor * traj_evaluate(ctraj, obstacles,info)ctraj_score = goal_score + vel_score + traj_scoreif min_score >= ctraj_score:min_score = ctraj_scoreu = np.array([v,w])best_ctraj = ctrajreturn u,best_ctrajdef goal_evaluate(traj, goal):goal_score = math.sqrt((traj[-1,0]-goal[0])**2 + (traj[-1,1]-goal[1])**2)return goal_scoredef velocity_evaluate(traj, info):vel_score = info.v_max - traj[-1,3]return vel_scoredef traj_evaluate(traj, obstacles, info):min_dis = float("Inf")for i in range(len(traj)):for ii in range(len(obstacles)):current_dist = math.sqrt((traj[i,0] - obstacles[ii,0])**2 + (traj[i,1] - obstacles[ii,1])**2)if current_dist <= info.radius:return float("Inf")if min_dis >= current_dist:min_dis = current_distreturn 1/min_disdef obstacles_generate():obstacles = np.array([[0,10],[2,10],[4,10],[6,10],[3,5],[4,5],[5,5],[6,5],[7,5],[8,5],[10,7],[10,9],[10,11],[10,13]])return obstaclesdef local_traj_display(x,goal,current_traj, obstacles):plt.cla()plt.plot(goal[0], goal[1], 'or', markersize=10)plt.plot([0,14],[0,0],'-k',linewidth=7)plt.plot([0,14],[14,14],'-k',linewidth=7)plt.plot([0,0],[0,14],'-k',linewidth=7)plt.plot([14,14],[0,14],'-k',linewidth=7)plt.plot([0,6],[10,10],'-y',linewidth=10)plt.plot([3,8],[5,5],'-y',linewidth=10)plt.plot([10,10],[7,13],'-y',linewidth=10)plt.plot(obstacles[:,0], obstacles[:,1],'*b',linewidth=8)plt.plot(x[0], x[1], 'ob', markersize=10)plt.arrow(x[0], x[1], math.cos(x[2]), math.sin(x[2]), width=0.02, fc='red')plt.plot(current_traj[:,0], current_traj[:,1], '-g', linewidth=2)plt.grid(True)plt.pause(0.001)def main():x = np.array([2,2,45*math.pi/180,0,0])u = np.array([0,0])goal = np.array([8,8])info = Info()obstacles = obstacles_generate()global_traj = np.array(x)plt.figure('DWA Algorithm')for i in range(2000):u,current_traj = dwa_core(x,u,goal,info,obstacles)x = motion_model(x,u,info.dt)global_traj = np.vstack((global_traj, x))local_traj_display(x, goal, current_traj,obstacles)if math.sqrt((x[0]-goal[0])**2 + (x[1]-goal[1])**2 <= info.radius):print("Goal Arrived")breakplt.plot(global_traj[:,0], global_traj[:,1], '-r')plt.show()    if __name__ == "__main__":main()

6、执行效果

        代码本身是一个仿真过程,大家可以下载下来在ubuntu环境下测试验证一下。最终实现的效果如下所示,

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于SSM的视频播放系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

NSS [GWCTF 2019]枯燥的抽奖

NSS [GWCTF 2019]枯燥的抽奖 开题让我猜字符串&#xff0c;这种题目肯定不是猜&#xff0c;应该是类似于php伪随机数。 dirsearch扫他一下。 访问/check.php得到源码。 分析一下代码。 通过PHP伪随机数从字符库$str_long1中选取20个字符组成字符串&#xff0c;返回给我们前十…

UE5 运行时生成距离场数据

1.背景 最近有在运行时加载模型的需求&#xff0c;使用DatasmithRuntimeActor可以实现&#xff0c;但是跟在编辑器里加载的模型对比起来&#xff0c;室内没有Lumen的光照效果。 图1 编辑器下加载模型的效果 图2 运行时下加载模型的效果 然后查看了距离场的数据&#xff0c;发现…

【扩散模型从原理到实战】Chapter2 Hugging Face简介

文章目录 Hugging Face的核心功能介绍Hugging Face开源库Hugging Face开源库Gradio工具介绍参考资料 Hugging Face是机器学习从业者协作和交流的平台&#xff0c;成立于2016年&#xff0c;在纽约和巴黎设有办事处&#xff0c;团队成员来自世界各地&#xff0c;远程办公。 致力于…

封装一个Element-ui生成一个可行内编辑的表格(vue2项目)

这个封装的是一个供整个项目使用的表格,可多次复用.放在一个全局使用的公共组件文件下. 大致功能介绍,封装自定义指令,点击获得焦点,显示输入框,失去焦点显示文本内容,类型是字典决定类型,图片可以显示图片名还是上传图片 子组件 <script> export default {props: {//生…

SpringCloud ---day1

认识微服务 单体架构 微服务架构 方便进行打包上线,版本的更新上线,降低项目之间的耦合度,减少代码量巨大导致的编译/打包时间长的问题 SpringCloud简介 项目熟悉 业务流程 项目模块划分 服务拆分原则 什么时候拆: 对于一个初创的项目&#xff0c;首先要做的是验证项目的可…

el-table :span-method合并单元格

<el-table :data"tableData" :span-method"objectSpanMethod" border style"width: 100%" :height"300"><el-table-column type"index" label"序号" width"50"></el-table-column>&l…

ajax同步与异步,json-serve的安装与使用,node.js的下载

20.ajax json 轻量级的数据格式做配置文件网络传输 xml 重量级的数据格式 可扩展标记语言做配置文件网络传输 现在目前主流就是大量采用json做网络传输数据格式 1.ajax的概念: 与服务器进行’通信’的一种技术,能够实现异步的刷新页面 **同步:**按照顺序一步步的执行,容易造…

算法通过村第十四关-堆|黄金笔记|中位数

文章目录 前言数据流中的中位数的问题总结 前言 提示&#xff1a;我独自度过了太多的时光&#xff0c;沉默已成一种习惯。 帕瑞尔马卡姆《夜航西飞》 这个是一个比较难的题目&#xff0c;要不尝试一下看看。 数据流中的中位数的问题 参考题目地址&#xff1a;295. 数据流的中位…

MyBatisPlus-02

一 查询条件的三种 1.按条件查询 //方式一&#xff1a;按条件查询QueryWrapper qw new QueryWrapper();qw.lt("age",18);List<User> userList userDao.selectList(qw);System.out.println(userList); 2.lambda格式按条件查询 //方式二&#xff1a;lambda格…

基于EtherCAT的机器人多轴同步运动控制

随着工业自动化的发展&#xff0c;机器人在生产线上的应用越来越广泛。为了实现高效、精确的运动控制&#xff0c;机器人的多轴运动必须能够实现同步操作&#xff0c;它能够提高机器人的运动精度和稳定性&#xff0c;实现更高效的生产线操作。同时&#xff0c;它也为机器人的协…

WebGPU入门一

1 WebGPU学习开发环境配置 WebGPU的环境配置比较简单&#xff0c;不需要vite或webpack配置一个复杂的开发环境&#xff0c;直接使用.html文件即可。 1.1 支持WebGPU的浏览器 Chrome 113 beta测试版开始默认支持WebGPU。 1.2 index.html文件 创建index.html文件&#xff0c…

C++进阶篇1---继承

一、继承的概念和定义 1.1概念 继承机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保持原有类特性的基础上进行扩展&#xff0c;增加功能&#xff0c;这样产生新的类&#xff0c;称为派生类。继承呈现了面向对象程序设计的层次结构&#xff…

ExoPlayer架构详解与源码分析(5)——MediaSource

系列文章目录 ExoPlayer架构详解与源码分析&#xff08;1&#xff09;——前言 ExoPlayer架构详解与源码分析&#xff08;2&#xff09;——Player ExoPlayer架构详解与源码分析&#xff08;3&#xff09;——Timeline ExoPlayer架构详解与源码分析&#xff08;4&#xff09;—…

掌握Python爬虫实现网站关键词扩展提升曝光率

目录 一、关键词优化的重要性 二、关键词优化的基本方法 1、选择与网站内容相关的关键词 2、控制关键词的密度和分布 3、关键词的层次布局 三、Python爬虫实现网站关键词扩展 1、确定目标网站 2、分析目标网站的HTML结构 3、编写Python爬虫代码 4、分析爬取到的关键词…

【算法练习Day22】 组合总和 III电话号码的字母组合

​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;练题 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录 组合总和 III剪枝 电话号码…

深入理解React中的useEffect钩子函数

引言&#xff1a; React是一种流行的JavaScript库&#xff0c;它通过组件化和声明式编程的方式简化了前端开发。在React中&#xff0c;一个核心概念是组件的生命周期&#xff0c;其中包含了许多钩子函数&#xff0c;用于管理组件的不同阶段。其中之一就是useEffect钩子函数&…

LuaJit交叉编译移植到ARM Linux

简述 Lua与LuaJit的主要区别在于LuaJIT是基于JIT&#xff08;Just-In-Time&#xff09;技术开发的&#xff0c;可以实现动态编译和执行代码&#xff0c;从而提高了程序的运行效率。而Lua是基于解释器技术开发的&#xff0c;不能像LuaJIT那样进行代码的即时编译和执行。因此&…

系统架构与Tomcat的安装和配置

2023.10.16 今天是学习javaweb的第一天&#xff0c;主要学习了系统架构的相关知识和原理&#xff0c;下载了web服务器软件&#xff1a;Tomcat&#xff0c;并对其进行了配置。 系统架构 包括&#xff1a;C/S架构 和 B/S架构。 C/S架构&#xff1a; Client / Server&#xff0…

离散数学 学习 之 递推方程和生成函数

递推方程 注意这里的特征根一定不是相等 特解的话一般要去设出基本的形式 这是0 次多项式 生成函数