SLAM从入门到精通(a*搜路算法)

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

        目前机器人常用的搜路算法主要有这么几种,迪杰斯特拉算法、a*算法、贪心算法。每一种算法都有自己的场景和优势,可以灵活选择。但一般来说,客户的场景不算很复杂的话,搜路算法越简单越好,只要能达到最终的目标即可。对于特别复杂的场景,建议也不要通过底层算法的变更来解决业务的问题,这反而是得不偿失的。所以说,这三种算法,如果没有特别原因的话,最好都实现一下,这样方便fae的同学现场部署和实施。搜路算法本身只是一个拓扑算法,它帮助我们分析了目的地本身是否可达,但是机器人能不能过去,这就两说了。

        下面,我们就看下a*算法是怎么实现的。

1、a*算法的核心

        a*算法的核心其实就是F=G+H。其中F是总代价,G是起始点到当前点的代价,H是当前点到目标点的代价。两者加在一起,就是每次选择新插入点的标准。

2、a*算法的流程

a*算法的伪代码流程一般是这样的,

1)将开始点设置为p;

2)p点插入到封闭集当中;

3)搜寻p的所有邻接点,如果邻接点没有在开放集或者封闭集之中,则计算该点的F值,设置该邻接点的parent为p,将临界点插入到开放集当中;

4)判断开放集是否为空,如果为空,则搜路失败,否则继续;

5)从开放集挑出F数值最小的点,作为寻路的下一步起始点;

6)判断该点是否是终点,如果是,结束查找,否则继续;

7)跳转到3继续执行。

3、a*算法的注意事项

        整个a*算法还是不算太复杂的。需要注意的地方只有一处,那就是3)中如果发现邻接点已经在开放集中,那需要重新计算它的G值。一旦发现当前G值更小,则需要同步更新parent、G值和F值。

4、测试代码

        算法的整个过程参考了一本ROS参考书上的python代码。大家可以实际下载下来查看一下效果。代码是用python编写,需要安装matplotlib库。

import matplotlib.pyplot as plt
import mathclass Node:def __init__(self, x, y, parent, cost, index):self.x =xself.y = yself.parent = parentself.cost = costself.index = indexdef calc_path(goaln, closeset):rx,ry = [goaln.x], [goaln.y]print(closeset[-1])parentn = closeset[-1]while parentn != None:rx.append(parentn.x)ry.append(parentn.y)parentn = parentn.parentreturn rx, rydef astar_plan(sx, sy, gx, gy):ox,oy,xwidth,ywidth = map_generation()plt.figure('Astar algorithm')plt.plot(ox, oy, 'ks')plt.plot(sx, sy, 'bs')plt.plot(gx, gy, 'ro')motion = motion_model()openset, closeset = dict(), dict()sidx = sy*xwidth + sxgidx = gy*xwidth + gxstarn = Node(sx, sy, None, 0, sidx)goaln = Node(gx, gy, None, 0, gidx)openset[sidx] = starnwhile 1:c_id = min(openset,key=lambda o:openset[o].cost + h_cost(openset[o], goaln))curnode = openset[c_id]if curnode.x == goaln.x and curnode.y == goaln.y:print('find goal')closeset[-1] = curnodebreakelse:closeset[c_id] = curnodeplt.plot(curnode.x, curnode.y, 'gx')if len(openset.keys())%10 == 0:plt.pause(0.01)del openset[c_id]for j in range(len(motion)):newnode = Node(curnode.x + motion[j][0],curnode.y + motion[j][1],curnode,curnode.cost + motion[j][2],c_id)n_id = index_calc(newnode, xwidth)          if n_id in closeset:continueif node_verify(newnode, ox, oy):continueif n_id not in openset:openset[n_id] = newnodeelse:if openset[n_id].cost >= newnode.cost:openset[n_id] = newnodepx,py = calc_path(goaln, closeset)return px,pydef map_generation():ox,oy=[],[]for i in range(60):ox.append(i)oy.append(0)for i in range(60):ox.append(i)oy.append(60)for i in range(60):ox.append(0)oy.append(i)for i in range(60):ox.append(60)oy.append(i)for i in range(25):ox.append(i)oy.append(20)for i in range(40):ox.append(35)oy.append(i)for i in range(40):ox.append(50)oy.append(60-i)minx = min(ox)miny = min(oy)maxx = max(ox)maxy = max(oy)    xwidth = maxx-minxywidth = maxy-minyreturn ox,oy,xwidth,ywidth def motion_model():motion= [[1,0,1],[1,1,math.sqrt(2)],[1,-1,math.sqrt(2)],[0,1,1],[0,-1,1],[-1,1,math.sqrt(2)],[-1,0,1],[-1,-1,math.sqrt(2)]]return motiondef h_cost(node, goal):w = 1.0h = w * (abs(goal.x-node.x) + abs(goal.y-node.y))return hdef index_calc(node, xwid):n_id = node.y * xwid + node.xreturn n_iddef node_verify(node, ox, oy):if(node.x, node.y) in zip(ox, oy):return Trueelse:return Falsedef main():sx,sy=15,15gx,gy=55,50rx,ry=astar_plan(sx,sy,gx,gy)print(rx,ry)plt.plot(rx,ry,'r-',linewidth=3)plt.show()if __name__ == '__main__':main()

        代码中motion_model表示了当前点周围8个点的行驶代价;node_verify则是判断当前点是否在障碍物上;astar_plan是所有算法真正的入口;而map_generation则构建了一个基本的搜寻场景。

5、运行效果图

        运行效果如下所示,供大家参考。直接用python3 astar.py运行即可,

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

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

相关文章

工业电子中的深力科分享一款PWM控制器 KA3525A

关于PWM控制器: PWM控制器是一种用于控制电机或其他设备的电路,它通过改变脉冲宽度调制(PWM)信号的占空比来控制设备的输出。PWM控制器可以使用单片机或开发板等设备来实现,通过设定占空比,可以轻松地控制…

DOS常用命令

1. echo off bat脚本中,该命令可以认为屏蔽掉cmd窗口的盘符 加命令前 加 echo off 之后 2. pause 程序运行完成之后cmd窗口不关闭, 一般程序都是在 1和2之间

堆排序;大顶堆、小顶堆

堆排序 基本介绍 堆排序基本思想 堆排序步骤图解 在第二个步骤中,将节点6和它的两个左右节点比较大小,发现右节点最大,所以将节点6和节点9进行交换,如图所示,数组相应位置的值也交换 总结 代码实现 """…

短视频矩阵系统源头开发

一、智能剪辑、矩阵分发、无人直播、爆款文案于一体独立应用开发 抖去推----主要针对本地生活的----移动端(小程序软件系统,目前是全国源头独立开发),开发功能大拆解分享,功能大拆解: 7大模型剪辑法(数学阶乘&#x…

并发性Socket通信源码(基于linux环境下多线程)

服务器端&#xff1a;server.c 1 #include <stdio.h>2 #include <stdlib.h>3 #include <unistd.h>4 #include <string.h>5 #include <arpa/inet.h>6 #include <pthread.h>7 void* working(void *arg);8 //信息结构体9 struct sockinfo10 …

h5的扫一扫功能 (非微信浏览器环境下)

必须在 https 域名下才生效 <template><div><van-field label"服务商编码" right-icon"scan" placeholder"扫描二维码获取" click-right-icon"getCameras" /> <div class"scan" :style"{disp…

CyclicBarrier线程同步

关于作者&#xff1a; CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP&#xff0c;带领团队单日营收超千万。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业化变现、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览…

软考系统架构设计师考试冲刺攻略

系统架构冲刺攻略 上篇为综合知识&#xff0c;介绍了系统架构设计师应熟练掌握的基本知识&#xff0c;主要包括绪论、计算机系统、信息系统、信息安全技术、软件工程、数据库设计、系统架构设计、系统质量属性与架构评估、软件可靠性、软件架构的演化和维护、未来信息综合技术等…

PHPEXCEL解决行数超过65536不显示问题

起因自然是导出数据到excel文件时&#xff0c;数据缺少现象。 百度讲解是将xls文件另存为xlsx文件。 除了这里的原因&#xff0c;还有一点是phpExcel存在两个写入类PHPExcel_Writer_Excel2007和PHPExcel_Writer_Excel5&#xff0c;而只有PHPExcel_Writer_Excel2007支持超过65…

NLP Bi-Encoder和Re-ranker

Retrieve & Re-Rank https://www.sbert.net/examples/applications/retrieve_rerank/README.html Bi-Encoder vs. Cross-Encoder https://www.sbert.net/examples/applications/cross-encoder/README.html Bi-Encoder会用BERT对输入文本编码&#xff0c;再根据cosine相似度…

Autosar诊断实战系列25-UDS 0x27服务相关问题思考

本文框架 前言0x27服务几个相关问题1. 安全访问种子的随机数能不能是全0?2. 安全级别之间是否有联系?是怎么确定的?3. 安全访问错误计数器具体变化策略?前言 在本系列笔者将结合工作中对诊断实战部分的应用经验进一步介绍常用UDS服务的进一步探讨及开发中注意事项, Dem/D…

华为云HECS服务器下docker可视化(portainer)

一、docker安装 华为云HECS安装docker-CSDN博客 二、portainer安装 portainer地址&#xff1a;Portainer: Docker and Kubernetes Management Platform 当前portainer分CE&#xff08;开源版&#xff09; 和 BE&#xff08;商业版&#xff09;&#xff0c;用CE即可 1 创建…

RK3568驱动指南|第七期-设备树-第58章 实例分析:时钟

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…

类的继承简介

一、声明格式&#xff1a; class 子类名&#xff1a;继承方式(public private protected) 父类名{子类成员表} 二、继承过程&#xff1a; 吸取父类成员——>改造父类成员——>添加新成员 三、作用&#xff1a; 子类会继承父类中的方法(不包括构造和析构函数)与属性 …

stable diffusion如何解决gradio外链无法开启的问题

问题确认 为了确认gradio开启不了是gradio库的问题还是stable diffusion的问题&#xff0c;可以先执行这样一段demo代码 import gradio as grdef greet(name):return "Hello " name "!"demo gr.Interface(fngreet, inputs"text", outputs&q…

Vue生命周期钩子

vue生命周期表示在组件创建后的一系列变化&#xff0c;其中钩子函数会在生命周期的关键节点中被调用 为什么在beforeCreated()时&#xff0c;data和methods方法还没有创建&#xff0c;但是在beforeCreated()里面打印this可以看到data相关的数据&#xff1f; 跟浏览器有关&…

FL Studio中文最新21破解版本水果软件下载

那么&#xff0c;大家知道编曲是什么吗&#xff1f;编曲和作曲又有什么区别呢&#xff1f; 一首歌的制作过程通常是由作词或作曲开始的&#xff0c;作曲就是运用基本乐理、和声学、复调、配器法、曲式结构的技术理论体系来表达创作者音乐思想的方法。说白了其实就是制作一首歌…

LeetCode13——罗马数字转整数

解题思想&#xff1a; 前后指针 左边比右边小 做减法 左边比右边大 做加法 最后一个数字直接加。 package keepcoding.leetcode.leetcode13;public class Result02 {public static void main(String[] args) {int result romanToInt("XIV");System.out.println(re…

设计模式:模板模式(C#、JAVA、JavaScript、C++、Python、Go、PHP)

简介&#xff1a; 模板模式&#xff0c;它是一种行为型设计模式&#xff0c;它定义了一个操作中的算法的框架&#xff0c;将一些步骤延迟到子类中实现&#xff0c;使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 通俗地说&#xff0c;模板模式就是将某一行…

C++初阶(五)类和对象

文章目录 一、C两大类型二、类的6个默认成员函数三、构造函数1、概念2、特性1、构造函数自动调用特性演示2、无参有参调用两种情况演示3、函数重载演示4、默认构造函数组成及演示5、内置类型成员不初始化的补丁演示 3、析构函数1、概念2、特性1、代码演示2、析构两种情况 4、构…