路径规划 | 图解RRT*算法(附ROS C++/Python/Matlab仿真)

news2024/12/24 2:29:23

目录

  • 0 专栏介绍
  • 1 图解RRT*算法原理
  • 2 ROS C++算法实现
  • 3 Python算法实现
  • 4 Matlab算法实现

0 专栏介绍

🔥附C++/Python/Matlab全套代码🔥课程设计、毕业设计、创新竞赛必备!详细介绍全局规划(图搜索、采样法、智能算法等);局部规划(DWA、APF等);曲线优化(贝塞尔曲线、B样条曲线等)。

🚀详情:图解自动驾驶中的运动规划(Motion Planning),附几十种规划算法


1 图解RRT*算法原理

RRT*算法针对传统RRT算法进行了渐进最优改进,在添加 x n e w x_{\mathrm{new}} xnew到搜索树的过程中进行重连选择(Rewire):构造以 x n e w x_{\mathrm{new}} xnew为圆心 r r r为优化半径的邻域圆,找到与 x n e w x_{\mathrm{new}} xnew连接后路径代价最小的点 x m i n x_{\mathrm{min}} xmin作为 x n e w x_{\mathrm{new}} xnew的父节点,而非直接将 x n e a r x_{\mathrm{near}} xnear x n e w x_{\mathrm{new}} xnew相连;与此同时也会优化圆内其他节点 x n x_n xn的代价——若路径

< x i n i t , ⋯   , x n > > < x i n i t , ⋯   , x n e w , x n > \left< x_{\mathrm{init}},\cdots ,x_{\mathrm{n}} \right> >\left< x_{\mathrm{init}},\cdots ,x_{\mathrm{new}},x_{\mathrm{n}} \right> xinit,,xn>xinit,,xnew,xn

则将 x n e w x_{\mathrm{new}} xnew重连为 x n x_n xn的父节点,如图所示。

在这里插入图片描述

RRT*算法流程如下所示,与RRT算法相比只是增加了一个重连优化函数,更新节点连接情况

在这里插入图片描述

其中碰撞检测算法 C o l l i s i o n F r e e ( ⋅ ) \mathrm{CollisionFree}\left( \cdot \right) CollisionFree()常用连线采样法,如图所示,计算概率路图中的连线 ( q , q ′ ) \left( q,q' \right) (q,q)是否合法需要考虑两个方面

  • 连线长度小于阈值 d ( q , q ′ ) < d max ⁡ \mathrm{d}\left( q,q' \right) <\mathrm{d}_{\max} d(q,q)<dmax d max ⁡ \mathrm{d}_{\max} dmax对无意义的长距离连线进行剪枝;
  • 连线不穿过障碍:在连线上按一定步长采样,判断是否存在落入障碍中的采样点。

在这里插入图片描述

2 ROS C++算法实现

核心代码如下所示

Node RRTStar::_findNearestPoint(std::unordered_set<Node, NodeIdAsHash, compare_coordinates> list, Node& node)
{
  Node nearest_node, new_node(node);
  double min_dist = std::numeric_limits<double>::max();

  for (const auto node_ : list)
  {
    // calculate distance
    double new_dist = _dist(node_, new_node);

    // update nearest node
    if (new_dist < min_dist)
    {
      nearest_node = node_;
      new_node.pid_ = nearest_node.id_;
      new_node.g_ = new_dist + node_.g_;
      min_dist = new_dist;
    }
  }

  // distance longer than the threshold
  if (min_dist > max_dist_)
  {
    // connect sample node and nearest node, then move the nearest node
    // forward to sample node with `max_distance` as result
    double theta = _angle(nearest_node, new_node);
    new_node.x_ = nearest_node.x_ + (int)(max_dist_ * cos(theta));
    new_node.y_ = nearest_node.y_ + (int)(max_dist_ * sin(theta));
    new_node.id_ = grid2Index(new_node.x_, new_node.y_);
    new_node.g_ = max_dist_ + nearest_node.g_;
  }

  // obstacle check
  if (!_isAnyObstacleInPath(new_node, nearest_node))
  {
    // rewire optimization
    for (auto node_ : sample_list_)
    {
      // inside the optimization circle
      double new_dist = _dist(node_, new_node);
      if (new_dist < r_)
      {
        double cost = node_.g_ + new_dist;
        // update new sample node's cost and parent
        if (new_node.g_ > cost)
        {
          if (!_isAnyObstacleInPath(new_node, node_))
          {
            new_node.pid_ = node_.id_;
            new_node.g_ = cost;
          }
        }
        else
        {
          // update nodes' cost inside the radius
          cost = new_node.g_ + new_dist;
          if (cost < node_.g_)
          {
            if (!_isAnyObstacleInPath(new_node, node_))
            {
              node_.pid_ = new_node.id_;
              node_.g_ = cost;
            }
          }
        }
      }
      else
        continue;
    }
  }
  else
    new_node.id_ = -1;
  return new_node;
}

在这里插入图片描述

3 Python算法实现

核心代码如下

def getNearest(self, node_list: list, node: Node) -> Node:
	'''
	Get the node from `node_list` that is nearest to `node` with optimization.
	
	Parameters
	----------
	node_list: list
	    exploring list
	node: Node
	    currently generated node
	
	Return
	----------
	node: Node
	    nearest node 
	'''
	node_new = super().getNearest(node_list, node)
	if node_new:
	    #  rewire optimization
	    for node_n in node_list:
	        #  inside the optimization circle
	        new_dist = self.dist(node_n, node_new)
	        if new_dist < self.r:
	            cost = node_n.g + new_dist
	            #  update new sample node's cost and parent
	            if node_new.g > cost and not self.isCollision(node_n, node_new):
	                node_new.parent = node_n.current
	                node_new.g = cost
	            else:
	                #  update nodes' cost inside the radius
	                cost = node_new.g + new_dist
	                if node_n.g > cost and not self.isCollision(node_n, node_new):
	                    node_n.parent = node_new.current
	                    node_n.g = cost
	        else:
	            continue
	    return node_new
	else:
	    return None 

在这里插入图片描述

4 Matlab算法实现

核心代码如下所示

function [new_node, flag] = get_nearest(node_list, node, map, param)
%@breif: Get the node from `node_list` that is nearest to `node`.
    flag = false;
    % find nearest neighbor
    dist_vector = dist(node_list(:, 1:2), node');
    [~, index] = min(dist_vector);
    node_near = node_list(index, :);

    % regular and generate new node
    distance = min(dist(node_near(1:2), node'), param.max_dist);
    theta = angle(node_near, node);
    new_node = [node_near(1) + distance * cos(theta), ...
                           node_near(2) + distance * sin(theta), ...
                           node_near(3) + distance, ...
                           node_near(1:2)];

    % obstacle check
    if is_collision(new_node(1:2), node_near(1:2), map, param)
        return
    end
    
    %  rewire optimization
    [node_num, ~] = size(node_list);
    for i=1:node_num
        node_n = node_list(i, :);
        %  inside the optimization circle
        new_dist = dist(node_n(1:2), new_node(1:2)');
        if new_dist < param.r
            cost = node_n(3) + new_dist;
            %  update new sample node's cost and parent
            if new_node(3) > cost && ~is_collision(new_node(1:2), node_n(1:2), map, param)
                new_node(4:5) = node_n(1:2);
                new_node(3) = cost;
            else
                %  update nodes' cost inside the radius
                cost = new_node(3) + new_dist;
                if node_n(3) > cost && ~is_collision(new_node(1:2), node_n(1:2), map, param)
                    node_list(i, 4:5) = new_node(1:2);
                    node_list(i, 3) = cost;
                end
            end
        else
            continue;
        end
    end
    
    flag = true;
end

在这里插入图片描述

完整工程代码请联系下方博主名片获取


🔥 更多精彩专栏

  • 《ROS从入门到精通》
  • 《Pytorch深度学习实战》
  • 《机器学习强基计划》
  • 《运动规划实战精讲》

👇源码获取 · 技术交流 · 抱团学习 · 咨询分享 请联系👇

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

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

相关文章

chatgpt赋能python:使用Numpy在Python中进行科学计算

使用Numpy在Python中进行科学计算 对于需要进行科学计算和数据分析的程序员&#xff0c;Python是一个非常有用的编程语言。而Numpy&#xff08;Numerical Python&#xff09;则是Python生态系统中最受欢迎和广泛使用的科学计算库之一。该库提供了高效的数组操作&#xff0c;线…

跟着我学 AI丨知识图谱,搜索的根

搜索是现在大家都很熟悉的功能&#xff0c;同时也是我们搜集信息离不开的重要手段。而搜索之所以能帮助我们获取到对应的信息&#xff0c;其实离不开知识图谱的重要支撑。知识图谱是什么呢&#xff1f;为什么能够支撑起搜索的提升呢&#xff1f;今天我们就来认识一下知识图谱。…

36从零开始学Java之到底什么是方法的重载?

作者&#xff1a;孙玉昌&#xff0c;昵称【一一哥】&#xff0c;另外【壹壹哥】也是我哦 千锋教育高级教研员、CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者 前言 壹哥在之前给大家讲解构造方法的时候说过&#xff0c;在一个类中&#xff0c;可以定义多个构造方法&a…

老胡的周刊(第092期)

老胡的信息周刊[1]&#xff0c;记录这周我看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。 &#x1f3af; 项目 chathub[2] ChatHub 是款全能聊天机器人客户…

Kubernetes最佳实战案例:优化容器化部署与扩展性

▲ 点击上方"DevOps和k8s全栈技术"关注公众号 Kubernetes&#xff08;简称为K8s&#xff09;作为目前最流行的容器编排平台&#xff0c;为企业提供了强大的容器管理和自动化部署能力。在实践中&#xff0c;许多组织已经成功地应用了Kubernetes来提高应用程序的可靠性…

旗舰手机割不动年轻人了,纷纷降价千元贱卖,苹果也未能幸免

618促销即将开启&#xff0c;而手机企业的促销优惠更早&#xff0c;在5月中旬就已开始&#xff0c;苹果率先降价1200元促销&#xff0c;随即国产手机第一大品牌跟进&#xff0c;苹果再反击&#xff0c;如今国产手机开始全面降价&#xff0c;就连最顽强的某国产手机品牌也开始跟…

自动化测试之JUnit单元测试框架

目录 一、什么是 JUnit 二、JUnit5 相关技术 1.注解 1.1 Test 1.2 Disabled 1.3 BeforeAll、AfterAll 1.4 BeforeEach、AfterEach 2.参数化 2.1 单参数 2.2 CSV 获取参数 2.3 方法获取参数 2.4 多参数 3.测试用例的执行顺序 3.1 顺序执行&#xff1a;TestMethodO…

应收账款天数和应付账款天数和现金比率和速动比率

应收账款和应付账款天数 应收账款天数计算公式为&#xff1a; 应收账款天数 平均应收账款 * 360 除以 销售额 应收账款天数&#xff08;DOS&#xff09;显示公司需要多少天才能从客户那里收回账款&#xff0c;所以应收账款天数增加的时候&#xff0c;表明应收账款管理出现恶化…

Pyside6-第二篇-QPushButton一个普通按钮

今天是Pyside6的第二篇内容。一起来看一个普通的按钮。 QPushButton。 from PySide6.QtWidgets import QWidget, QApplication, QPushButtonapp QApplication([])win QWidget() win.setWindowTitle("QPushButton按钮")btn QPushButton(win) btn.setText("触发…

浅析多模态机器学习

GPT-4的发布给ChatGPT带来了又一次飞跃&#xff0c;ChatGPT不仅支持文字输入&#xff0c;还能看得懂图片、甚至是漫画、梗图&#xff0c;以GPT-4为代表的多模态大模型非常强大。多模态大模型就是指模型可以处理多种结构/类型的数据&#xff0c;例如GPT-4&#xff0c;它既可以处…

Hugging Face 介绍

Hugging Face 是一家在自然语言处理和人工智能领域著名的公司&#xff0c;以开发开源的软件库和工具为主要贡献&#xff0c;其中最受欢迎的是 Transformers 库&#xff0c;广泛应用于诸如语言翻译、情感分析和问答等多种自然语言处理任务。此外&#xff0c;Hugging Face 还开发…

c++ 11标准模板(STL) std::map(七)

定义于头文件<map> template< class Key, class T, class Compare std::less<Key>, class Allocator std::allocator<std::pair<const Key, T> > > class map;(1)namespace pmr { template <class Key, class T, clas…

100种思维模型之顺势而为思维模型-68

“我领悟到&#xff0c;人是不能推着石头往上走的&#xff0c;这样会很累&#xff0c;而且会被山上随时滚落的石头给打下去。要做的是&#xff0c;先爬到山顶&#xff0c;随便踢块石头下去。”——雷军说。 “只要站在风口上&#xff0c;猪也能飞起来“。——雷军。 顺势而为是…

JetBrains的多数据库管理和SQL工具DataGrip 2023版本在Linux系统的下载与安装配置教程

目录 前言一、DataGrip安装二、使用配置总结 前言 DataGrip是一款多数据库管理和SQL工具&#xff0c;适用于不同类型的数据库。它提供了丰富的功能和工具&#xff0c;可以帮助开发人员更高效地管理数据库、编写SQL查询和执行数据操作。注&#xff1a;已在CentOS7.9和Ubuntu20.…

海思sdk快速上手

mpp&#xff1a;视频H.264的编码压缩 1.看linux、uboot的文档 2.移植SDK到ubuntu 2.1、三个脚本 source sdk.unpack解压 2.2、osdrv/Makefile和readme make OSDRV_CROSSarm-hisiv300-linux CHIPhi3518ev200 all报错 参考&#xff1a;ubuntu16.04 编译错误: /bin/sh: 1: pushd…

《写作脑科学:如何用脑科学改善写作能力》

《写作脑科学&#xff1a;如何用脑科学改善写作能力》 前言引言概述评价结论 &#x1f3d8;️&#x1f3d8;️个人简介&#xff1a;以山河作礼。 &#x1f396;️&#x1f396;️:Python领域新星创作者&#xff0c;CSDN实力新星认证&#xff0c;阿里云社区专家博主 前言 &…

【C++】23.C++的IO流(补)

1.C标准IO流 C标准库提供了4个全局流对象cin、cout、cerr、clog&#xff0c;使用cout进行标准输出&#xff0c;即数据 从内存流向控制台(显示器)。使用cin进行标准输入即数据通过键盘输入到程序中&#xff0c;同时C 标准库还提供了cerr用来进行标准错误的输出&#xff0c;以…

chatgpt赋能python:Python中OP怎么用

Python中OP怎么用 Python是一种高级编程语言&#xff0c;可用于快速开发网站、桌面应用程序、网络爬虫和数据科学等各种领域。Python作为一种功能强大的编程语言&#xff0c;其操作符&#xff08;OP&#xff09;是一个必须学习的基本知识点。本文将介绍Python中OP的使用方法。…

DataTables表格库(一)

目录 1、零配置使用 1.2、代码 1.3、步骤 1.4、效果 2、禁用分页&#xff0c;排序等功能的配置 2.1、说明 2.2、代码 2.3、效果 3、默认排序配置 3.1、说明 3.2、代码 3.3、效果 4、多列排序 4.1、说明 4.2、代码示例 4.3、效果 5、多个表格 5.1、说明 5.2、…

【源码解析】SpringBoot使用DeferredResult实现长轮询的原理分析

使用背景 在Nacos配置更新和Apollo的配置更新&#xff0c;我们可以看到长轮询&#xff08;长连接&#xff09;的身影。长连接的实现可以节约系统资源&#xff0c;长连接可以在连接建立后持续通信&#xff0c;避免频繁地建立和断开连接&#xff0c;减少系统开销。使用长连接可以…