【路径规划】基于D星算法实现栅格地图机器人路径规划

news2024/11/29 22:46:09

目录

  • 算法介绍
  • 栅格地图
  • 代码
  • 运行效果

算法介绍

A* 在静态路网中非常有效(very efficient for static worlds),但不适于在动态路网,环境如权重等不断变化的动态环境下。

D是动态A(D-Star,Dynamic A Star) 卡内及梅隆机器人中心的Stentz在1994和1995年两篇文章提出,主要用于机器人探路。是火星探测器采用的寻路算法。

Optimal and Efficient Path Planning for Partially-Known Environments

The Focussed D* Algorithm for Real-Time Replanning

主要方法(这些完全是Drew在读了上述资料和编制程序中的个人理解,不能保证完全正确,仅供参考):

1.先用Dijstra算法从目标节点G向起始节点搜索。储存路网中目标点到各个节点的最短路和该位置到目标点的实际值h,k(k为所有变化h之中最小的值,当前为k=h。每个节点包含上一节点到目标点的最短路信息1(2),2(5),5(4),4(7)。则1到4的最短路为1-2-5-4。 原OPEN和CLOSE中节点信息保存。

2.机器人沿最短路开始移动,在移动的下一节点没有变化时,无需计算,利用上一步Dijstra计算出的最短路信息从出发点向后追述即可,当在Y点探测到下一节点X状态发生改变,如堵塞。机器人首先调整自己在当前位置Y到目标点G的实际值h(Y),h(Y)=X到Y的新权值c(X,Y)+X的原实际值h(X).X为下一节点(到目标点方向Y->X->G),Y是当前点。k值取h值变化前后的最小。

3.用A或其它算法计算,这里假设用A算法,遍历Y的子节点,点放入CLOSE,调整Y的子节点a的h值,h(a)=h(Y)+Y到子节点a的权重C(Y,a),比较a点是否存在于OPEN和CLOSE中,方法如下:

while() { 从OPEN表中取k值最小的节点Y; 遍历Y的子节点a,计算a的h值 h(a)=h(Y)+Y到子节点a的权重C(Y,a) { if(a in OPEN) 比较两个a的h值 if( a的h值小于OPEN表a的h值 ) {      更新OPEN表中a的h值;k值取最小的h值 有未受影响的最短路经存在 break; } if(a in CLOSE) 比较两个a的h值 //注意是同一个节点的两个不同路径的估价值 if( a的h值小于CLOSE表的h值 ) {      更新CLOSE表中a的h值; k值取最小的h值;将a节点放入OPEN表 有未受影响的最短路经存在 break; } if(a not in both) 将a插入OPEN表中; //还没有排序 } 放Y到CLOSE表; OPEN表比较k值大小进行排序; } 机器人利用第一步Dijstra计算出的最短路信息从a点到目标点的最短路经进行。

D*算法在动态环境中寻路非常有效,向目标点移动中,只检查最短路径上下一节点或临近节点的变化情况,如机器人寻路等情况。对于距离远的最短路径上发生的变化,则感觉不太适用。
在这里插入图片描述
上图是Drew在4000个节点的随机路网上做的分析演示,细黑线为第一次计算出的最短路,红点部分为路径上发生变化的堵塞点,当机器人位于982点时,检测到前面发生路段堵塞,在该点重新根据新的信息计算路径,可以看到圆圈点为重新计算遍历过的点,仅仅计算了很少得点就找到了最短路,说明计算非常有效,迅速。绿线为计算出的绕开堵塞部分的新的最短路径。

栅格地图

栅格地图有两种表示方法,直角坐标系法和序号法,序号法比直角坐标法节省内存。
在这里插入图片描述
在这里插入图片描述
室内环境栅格法建模步骤

1.栅格粒大小的选取

栅格的大小是个关键因素,栅格选的小,环境分辨率较大,环境信息存储量大,决策速度慢。

栅格选的大,环境分辨率较小,环境信息存储量小,决策速度快,但在密集障碍物环境中发现路径的能力较弱。

2.障碍物栅格确定

当机器人新进入一个环境时,它是不知道室内障碍物信息的,这就需要机器人能够遍历整个环境,检测障碍物的位置,并根据障碍物位置找到对应栅格地图中的序号值,并对相应的栅格值进行修改。自由栅格为不包含障碍物的栅格赋值为0,障碍物栅格为包含障碍物的栅格赋值为1.

3.未知环境的栅格地图的建立

通常把终点设置为一个不能到达的点,比如(-1,-1),同时机器人在寻路过程中遵循“下右上左”的原则,即机器人先向下行走,当机器人前方遇到障碍物时,机器人转向右走,遵循这样的规则,机器人最终可以搜索出所有的可行路径,并且机器人最终将返回起始点。

备注:在栅格地图上,有这么一条原则,障碍物的大小永远等于n个栅格的大小,不会出现半个栅格这样的情况。

代码

%D* Lite算法
%By Aword 2019/05/20
%*********************************************初始化开始,给出全局参数************************************************
clc;
clear;
global n_r;
global n_c;
global s_start;
global s_goal;
global U;
global km;
global g;
global rhs;
global key;
global neighbour;
global map;
%*******************************可修改参数*************************************
n_r=30;%定义地图大小-行
n_c=30;%定义地图大小-列
s_start=[1 1];%起始点
s_goal=[30 30];%目标点
%********************************初始化***************************************
U=[];%优先级列表,用于存储待扩展的非一致节点(g(s)!=rhs(s))
km=0;%记录最初起点到当前起始点的代价值
g=[];%g和rhs表示节点s到目标点的最小代价的估计值
rhs=[];%rhs是由其前向节点(起始点到当前点)的g值计算得到
key=[];
path=[];%存储规划路径
neighbour=[1,0; %八向搜寻
           0,1;
           0,-1;
           -1,0;
           1,1;
           1,-1;
           -1,1;
           -1,-1]; 
% neighbour=[1,0; %四向搜寻
%            0,1;
%            0,-1;
%            -1,0]; 
s_last=s_start;%当前位置点sl(下一时刻的位置点)视为新的起始点反复计算目标点sg与新的起始点间的最短路径
g(1:n_r,1:n_c)=Inf;%遍历地图节点集S并初始化,这里注意行列对应的坐标是相反的
rhs(1:n_r,1:n_c)=Inf;
rhs(s_goal(1),s_goal(2))=0;%目标点rhs置0
CalculateKey(s_goal);
U=[s_goal,key(s_goal(1),s_goal(2)).key1,key(s_goal(1),s_goal(2)).key2];%讲目标点及其key值插入到优先列表U中
%*******************************生成原始地图************************************
cmap = [1 1 1; ...% 1 -白色-无障碍
        0 0 0; ...% 2 -有障碍
        0 1 0; ...% 3 -起始点
        0 0 1; ...% 4 -目标点
        1 0 0; ...% 5 -最终路径
        0.5 0.5 0.5]; % 6 -扩展节点
%0 0 0 
%1 1 1
%1 0 0 
% 绿   0 1 0
%0 0 1
%1 1 0
%0.5 0.5 0.5 
% 洋红  1 0 1
% 青蓝  0 1 1
% 天蓝  0.67 0 1
% 橘黄  1 0.5 0
% 深红  0.5 0 0
colormap(cmap); 
map = ones(n_r,n_c);
randmap = rand(n_r,n_c);%返回一个n_rxn_c的(01)随机数矩阵,生成随机地图
for i=1:n_r%遍历地图节点并初始化障碍物信息
    for j=1:n_c
        if (randmap(i,j) >= 0.75)%该数大小决定障碍物密度
            map(i,j) = 2;%置为障碍物
        end
    end
end
map(s_start(1), s_start(2)) = 3; % 起点坐标
map(s_goal(1), s_goal(2)) = 4; % 终点坐标
% set(gca,'xtick',[],'ytick',[])%去掉刻度标记
subplot(1, 3, 1)
image(1.5,1.5,map); 
grid on; %网格
axis image; %显示更新前地图
hold on;
%*******************************生成动态地图************************************
map_ob = ones(n_r,n_c);
randmap = rand(n_r,n_c);%返回一个n_rxn_c的(01)随机数矩阵

    end
%*******************************动态绘制地图************************************
    for i=1:size(path,1)
        map(path(i,1),path(i,2))=5;
    end
    map(s_start(1), s_start(2)) = 3; % 起点坐标
    map(s_goal(1), s_goal(2)) = 4; % 终点坐标
    subplot(1, 3, 3)
    image(1.5,1.5,map); 
    if (n_r==10)&&(n_c==10)
        for i=1:n_r%遍历地图节点并标记节点信息
            for j=1:n_c
                text(j,i+0.2,num2str(g(i,j)),'FontSize',10,'color','k')
                text(j,i+0.5,num2str(rhs(i,j)),'FontSize',10,'color','k')
                text(j,i+0.8,num2str(key(i,j).key1),'FontSize',10,'color','k')
                text(j+0.5,i+0.8,num2str(key(i,j).key2),'FontSize',10,'color','k')
            end
        end
    end
    grid on; %网格
    axis image; %显示路径
    pause(0.1);
%*******************************动态绘制地图************************************
end
%*************************************************主体循环结束******************************************************   
for i=1:n_r%查看扩展节点
    for j=1:n_c
        if map(i,j)==1
            if rhs(i,j)~=Inf
                map(i,j)=6;
            elseif key(i,j).key2~=Inf
                map(i,j)=6;
            end    
        end
    end
end    
subplot(1, 3, 3)
image(1.5,1.5,map); 
if (n_r==10)&&(n_c==10)
    for i=1:n_r%遍历地图节点并标记节点信息
        for j=1:n_c
            text(j,i+0.2,num2str(g(i,j)),'FontSize',10,'color','k')
            text(j,i+0.5,num2str(rhs(i,j)),'FontSize',10,'color','k')
            text(j,i+0.8,num2str(key(i,j).key1),'FontSize',10,'color','k')
            text(j+0.5,i+0.8,num2str(key(i,j).key2),'FontSize',10,'color','k')
        end
    end
end
grid on; %网格
axis image; %显示路径
-----------------------------------

运行效果

在这里插入图片描述

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

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

相关文章

nodejs 如何实现自动化部署?

什么是自动化部署 我接触到的自动化部署概念最早是在 Vercel 上提供的,Vercel 可以提供和 github 联动的功能,通过和你自己的 github 上的某个库建立‘链接’,当你 commit 到 github 远程库时就可以自动部署,Vercel 会帮你完成以…

腾龙健康冲刺A股上市:计划募资10亿元,彭学文家族色彩浓厚

近日,广州腾龙健康实业股份有限公司(下称“腾龙健康”)预披露招股书,准备在深圳证券交易所主板上市。 本次冲刺上市,腾龙健康计划募资10.13亿元,其中4.09亿元用于水疗按摩池配件生产基地升级项目&#xff0…

数据可视化做出的个人年终总结报告,高颜值更高更具说服力

年终总结与个人业绩、晋升、加薪、离职或留任密切相关。聪明人利用年终报告来总结自己的成就和获得资源,领导者也可以从年终报告看出员工的成长和变化。例如我用可视化互动平台,智能分析做出的公司年终总结报告,高颜值高说服力,领…

Java异常的分类和注意点

异常体系结构 Error与Exception Error是程序无法处理的错误,它是由JVM产生和抛出的,比如OutOfMemoryError、ThreadDeath等。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。 Exception是程序本身可以处理的异常…

国内外BI数据分析工具做报表有多大区别?

有什么样的土壤就会早就什么样的产品。国内外企业对报表的不同需求导致了国内外BI数据分析工具做表格时的巨大差异,这也是很多时候国外BI数据分析工具在中国水土不服,遭遇口碑体验两极化的一大原因。下面就来简单看看国内外BI数据分析工具做表格时的不同…

【前端】Vue项目:旅游App-(10)city:以indexBar的形式显示数据

文章目录目标过程与代码分析数据并展示封装到一个组件添加indexBar样式修改优化tab栏的切换效果总代码修改或新增的文件common.csscity.vuecurrentGroupCity.vuemain.js目标 上一篇显示了服务器中的数据:【前端】Vue项目:旅游App-(9&#xf…

(九)devops持续集成开发——jenkins流水线发布一个docker版的前端vue项目

前言 本节内容主要介绍如何使用jenkins的流水线发布一个docker版的前端项目。关于本节内容中使用到的jenkins的组件,请参考往期博客内容,自行安装。我们使用NodeJS完成前端项目的编译安装,使用ssh组件完成编译后工程的传输,以及d…

Allegro如何快速复制铜皮到其它层面的两种方法详细操作指导

Allegro如何快速复制铜皮到其它层面的两种方法详细操作指导 在做PCB设计的时候,通常需要复制一个做好的铜皮到其它层面,如下图 需要把L3层的铜皮复制到其它的内层 Allegro支持快速将铜皮拷贝到其它层,下面介绍两种方法,具体操作如下 方法一 选择Edit

快速生成100万条数据并存入mysql数据库(1):游戏人物数据

最近正在一直苦恼如果去获取更多的数据以用来进行后期的查询和进行测试,发现了Navicat这个不错的宝藏,他可以一下子根据你数据库里面创建的各种各样的字段和约束创建出各种各样你自己想要的大量数据,当然这些数据非真实数据而是虚拟数据&…

Swin Transformer原理详解篇

🍊作者简介:秃头小苏,致力于用最通俗的语言描述问题 🍊往期回顾:CV攻城狮入门VIT(vision transformer)之旅——近年超火的Transformer你再不了解就晚了! CV攻城狮入门VIT(vision transformer)之旅——VIT原…

Nacos多级服务存储模型, NacosRule负载均衡规则入门

👳我亲爱的各位大佬们好😘😘😘 ♨️本篇文章记录的为 NacosRule负载均衡规则 相关内容,适合在学Java的小白,帮助新手快速上手,也适合复习中,面试中的大佬🙉🙉🙉。 ♨️如…

【毕设必备】Python制作GUI学生管理系统,这把直接稳赢

前言 最近有个朋友说,能不能让我搞个学术上管理系统出来,想自己用用,好朋友嘛,那就搞个给他用用咯 之前还有个小朋友说,想弄个出来发给老师,让老师表扬一下自己哈哈哈 话说,这个还是可以做毕…

基于微信小程序的高校毕业论文管理系统小程序

文末联系获取源码 开发语言:Java 框架:ssm JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7/8.0 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包:Maven3.3.9 浏览器…

深入剖析B端产品权限设计-功能权限设计篇

权限设计是B端产品永远绕不开的一个课题,良好的产品权限设计架构是支撑企业复杂业务的基础与关键。接下来会分两篇文章剖析产品权限管理,一篇分享功能权限管理,一篇分享数据权限管理。一、什么是权限管理权限管理,一般指根据系统设…

1.9第三周星期一

LAMP环境搭建 1. 下载 yum install gcc gcc-c cmake ncurses ncurses-devel bison wget openssl-devel -y rpm -qa | grep mysql rpm -qa| grep mariadb yum install gcc gcc-c cmake ncurses ncurses-devel bison wget openssl-devel -y 2.建立mysql 组&#xff0c;<--新…

Linux常用命令与常见操作:重启服务器

Linux系统运维经验 Xshell prompt与Linux 【Linux】【CentOS】xshell连接Linux虚拟机 Linux linux常用命令 常见操作 升级补丁后重启服务器 cd /opt/zc/ nohup ./startup-linux.sh &有36、37两台服务器&#xff0c;37直接执行上面2条语句即可重启成功。 36这台服务器…

【计算机网络】网络基础

目录前言一、计算机网络发展二、初识“协议”1. 协议的概念2. 协议分层三、OSI七层模型四、TCP/IP五层(四层)模型五、网络传输基本流程1. 网络传输流程图2.数据包封装和分用六、网络中的地址管理1. IP地址2. MAC地址前言 本文是博主首次学习网络知识后进行的总结&#xff0c;文…

毫米波雷达「战火」升级

车载毫米波雷达市场的「战火」&#xff0c;也在快速蔓延到行业上游。 比如&#xff0c;雷达SoC&#xff08;新一代RF CMOS&#xff09;集成化趋势。这意味着&#xff0c;毫米波雷达芯片方案商一次性集成射频前端、雷达信号处理基带和微处理器以及其他元器件&#xff08;包括电源…

文件IO操作开发笔记(二):使用Cpp的ofstream对磁盘文件存储进行性能测试以及测试工具

文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/128626548 红胖子(红模仿)的博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结…

Docker | 深度学习中的docker看这一篇就够啦

目录 1.了解Docker 1.1.为什么要用docker? 1.2.可以用docker做什么? 1.3.docker 框架 2.Docker 的基本使用 3.实例 :VS code远程连接服务器上的docker环境 3-1:环境框架可视化及ssh连接&#xff0c;搭建pytorch深度学习环境 3-2:搭建一个新的容器pytorch深度学习环境…