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

news2025/1/10 21:22:08

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱: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 math

class Node:
    def __init__(self, x, y, parent, cost, index):
        self.x =x
        self.y = y
        self.parent = parent
        self.cost = cost
        self.index = index

def 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.parent
    return rx, ry

def 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 + sx
    gidx = gy*xwidth + gx
    
    starn = Node(sx, sy, None, 0, sidx)
    goaln = Node(gx, gy, None, 0, gidx)
    openset[sidx] = starn
    while 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] = curnode
            break
        else:
            closeset[c_id] = curnode
            plt.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:
                continue
                
            if node_verify(newnode, ox, oy):
                continue
                
            if n_id not in openset:
                openset[n_id] = newnode
            else:
                if openset[n_id].cost >= newnode.cost:
                    openset[n_id] = newnode
            
    px,py = calc_path(goaln, closeset)
    return px,py


def 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-minx
    ywidth = maxy-miny
    return 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 motion

def h_cost(node, goal):
    w = 1.0
    h = w * (abs(goal.x-node.x) + abs(goal.y-node.y))
    return h

def index_calc(node, xwid):
    n_id = node.y * xwid + node.x
    return n_id
    
def node_verify(node, ox, oy):
    if(node.x, node.y) in zip(ox, oy):
        return True
    else:
        return False
        
def main():
    sx,sy=15,15
    gx,gy=55,50
    rx,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.coloradmin.cn/o/1100233.html

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

相关文章

如何在Linux环境中远程访问企业级夜莺监控分析工具?

文章目录 前言1. Linux 部署Nightingale2. 本地访问测试3. Linux 安装cpolar4. 配置Nightingale公网访问地址5. 公网远程访问Nightingale管理界面6. 固定Nightingale公网地址 前言 夜莺监控是一款开源云原生观测分析工具,采用 All-in-One 的设计理念,集…

微信小程序2

一,视图层 1.什么视图层 框架的视图层由 WXML 与 WXSS 编写,由组件来进行展示。 将逻辑层的数据反映成视图,同时将视图层的事件发送给逻辑层。 WXML(WeiXin Markup language) 用于描述页面的结构。 WXS(WeiXin Script) 是小程序的一套脚本语…

深入理解强化学习——强化学习智能体的四要素:策略(Policy)

分类目录:《深入理解强化学习》总目录 相关文章: 强化学习智能体的四要素:策略(Policy) 强化学习智能体的四要素:收益信号(Revenue Signal) 强化学习智能体的四要素:价…

备忘录模式-撤销功能的实现

在idea写代码的过程中,会经常用到一个快捷键——“crtl z”,即撤销功能。“备忘录模式”则为撤销功能提供了一个设计方案。 1 备忘录模式 备忘录模式提供一种状态恢复机制。在不破坏封装的前提下,捕获对象内部状态并在该对象之外保存这个状态。可以在…

关于职业规划的学习经验总结

目录 前言 结构化思考 思考快与慢 积极主动 以终为始 要事第一 前言 每一年的年中或者年终都有一场很重要的活动就是述职,需要花费一定精力投入,那么述职是一种形式吗?当然不是。述职是一种组织的管理手段和机制,通过这种机制除了对战略方向和项目进度进行把控,还对…

chatgpt 4V 识图功能

1.获取图片的sig和file_id 2e0edc6e489ed13a3f32f0dd87527d77.jpg是本地图片的名字 头部认证信息自己F12 抓取 1.获取图片的sighttps://chat.openai.com/backend-api/filesAuthorization:Bearer eyJhbGc****************5V-lztYwLb9hr6LP7g Cookie: **********************…

set_data_check做等长线

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 常常会遇见2out的多个信号需要做等长,下面分享一个脚本。 set port1_coll [get_ports out[*]] set port2_coll [get_ports out[*]] foreach_in_collection temp1 $…

ChatGPT教你5分钟解锁国际象棋技能

国际象棋是一种很好玩的棋类游戏,走法和规则与中国象棋有所区别。如果想要快速入门,可以把ChatGPT当做私人教练,提出这些问题: ●作为零基础的初学者,学习国际象棋的最佳方法是什么?如何快速入门&#xff…

计算机保研推免面试复习大纲(数学+408)

目录 线性代数概率论高等数学信号与系统离散数学操作系统计算机网络计算机组成数据结构算法编译原理C杂项 线性代数 怎么求逆矩阵 逆矩阵: A A − 1 E AA^{-1}E AA−1E,伴随矩阵: A A ∗ A ∗ A ∣ A ∣ E AA^{*}A^{*}A|A|E AA∗A∗A∣A∣…

算法通关村第一关-链表白银经典问题笔记

大家好今天来写第一关的白银挑战-链表经典问题. 两个链表的第一个公共结点 这是一道经典的链表问题 : 输入两个无环的单向链表,找出它们的第一个公共结点,如果没有公共节点则返回空。 牛客NC66 : 剑指offer56 : 分析 : 屡试不爽的方法: 将常用数据…

第15章 SpringBoot

所有的流程逻辑原理都是针对2.3.2.RELEASE版本 15.1 谈谈你对微服务架构演进的理解 难度:★ 重点:★ 白话解析 还是串主线,在串主线的过程中发现问题,解决问题。主线的入口:随着业务的逻辑越来越复杂,架构再不断升级演进,先理解架构的演进。 这道题参考了:企业IT架构转…

引领虚拟化技术新潮流:VMware Fusion Pro for Mac/win中文版

当谈论虚拟机时,很多人可能会对其有所了解,但并不一定清楚它的具体作用和优势。在这篇文章中,我们将带您走进虚拟机的世界,并深入了解VMware Fusion Pro这一专业虚拟化解决方案的独特魅力。 虚拟机是一种模拟真实计算机环境的软件…

黑马mysql教程笔记(mysql8教程)基础篇——函数(字符串函数、数值函数、日期函数、流程函数)

参考文章1:https://www.bilibili.com/video/BV1Kr4y1i7ru/ 参考文章2:https://dhc.pythonanywhere.com/article/public/1/ 文章目录 基础篇函数字符串函数常用函数使用示例实例:更新已有的所有员工号,使其满足5位数长度&#xff…

抓包工具charles修改请求和返回数据

数据篡改的主要使用场景: (1)mock场景,mock入参和返回值参数,实现mock测试 (2)安全测试,对于支付金额等比较重要的字段,可以修改请求参数来进行安全测试 1.首先选择要…

Flink的算子列表状态的使用

背景 算子的列表状态是平时比较常见的一种状态,本文通过官方的例子来看一下怎么使用算子列表状态 算子列表状态 算子列表状态支持应用的并行度扩缩容,如下所示: 使用方法参见官方示例,我加了几个注解: public class Bufferin…

IP网络广播景区广播广播系统

IP网络广播景区广播广播系统 IP网络广播系统草坪音箱景区系统防水石头,草坪音箱的应用 SV-7045V是深圳锐科达电子有限公司的一款防水网络草坪音箱,具有10/100M以太网接口,可将网络音源通过自带的功放和喇叭输出播放,可达到功率20W。常用场景…

秋日有感之秋诉-于光

诗:于光 秋风扫叶枝不舍, 叶落随风根欢唱。 秋日穿云不入眼, 云亦婆娑诉余年。

卡片翻转效果的实现思路

卡片翻转效果的实现思路 HTML 基础布局 <div class"card"><img class"face" src"images/chrome_eSCSt8hUpR.png" /><p class"back"><span>背面背景</span></p> </div>布局完成后如下所示…

点云处理【二】(点云滤波)

点云滤波 第一章 点云数据采集 第二章 点云滤波 1. 为什么要滤波&#xff1f; 通常我们获取的点云数据中包含噪声&#xff0c;噪声会影响点云的特征提取、配准和语义处理。 点云需要处理的主要情况包括: 数据量过大&#xff0c;不易于处理&#xff0c;需要进行下采样 通常由…