路径规划——RRT算法
路径规划——RRT算法
算法原理
RRT算法的全称是快速扩展随机树算法(Rapidly Exploring Random Tree),它的思想是选取一个初始点作为根节点,通过随机采样,增加叶子节点的方式,生成一个随机扩展树,当随机树中的叶子节点包含了目标点或进入了目标区域,边可以在随机树中通过回溯的方式,找到这条从初始点到目标点的路径。
此算法的重点随机采样+步⻓限制+碰撞检测
算法流程:
1.初始化:以起点start为根节点,创建一棵树(通常用二叉树表示),树的根节点表示起始位置。
2.随机采样:在搜索空间中随机生成一个点x_rand。这个点可能在自由空间中,也可能在障碍物中。
3.寻找最近的节点:在当前的树中找到距离x_rand最近的节点x_near。
4.扩展树:从x_near沿着指向x_rand的方向移动一小步,生成一个新的节点x_new。如果x_new在自由空间中(即不与障碍物碰撞),则将x_new加入到树中,并将x_near和n_new用一条边连接。
5.检查目标:检查x_new是否在目标区域附近,这里的“附近”可以设置一个搜索距离来量化。如果是,则生成一条路径从起点到x_new,并结束算法。
6.迭代:重复步骤2~步骤5,直到找到目标点goal,或达到预设的迭代次数。
由于RRT采用随机采样的方法,RRT生成的路径通常不一定是最优路径,但可以通过多次运行RRT或结合其他优化算法来获得更优路径。

算法实现
import numpy as np
import random
import math
from itertools import combinations
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib.patches as patchesclass RRT:def __init__(self,start,goal,obstacles,board_size,max_try,max_dist,goal_sample_rate,env) -> None:self.start = self.Node(start,None,0)self.goal = self.Node(goal,None,0)self.obstacles = obstaclesself.board_size = board_sizeself.max_try = max_try # Number of iterationsself.max_dist = max_dist # Maximum sampling distanceself.goal_sample_rate = goal_sample_rateself.env = envself.inflation = 1self.searched = []class Node:def __init__(self,position,parent,cost):self.position = positionself.parent = parentself.cost = costdef run(self):cost,path = self.plan()self.visualize(cost,path)def plan(self):self.searched.append(self.start)closed_list = {self.start.position: self.start}# plan max_try timesfor i in range(self.max_try):node_rand = self.get_random_node()# visitedif node_rand.position in closed_list:continue# Get the nearest neighbor nodenode_near = self.get_nearest_neighbor(list(closed_list.values()),node_rand)# Get the new nodenode_new = self.get_new_node(node_rand,node_near)if node_new:closed_list[node_new.position] = node_newself.searched.append(node_new)dist = self.distance(node_new,self.goal)# Found goal successfullyif dist <= self.max_dist and not self.isCollision(node_new,self.goal):self.searched.append(self.goal)self.goal.parent = node_newself.goal.cost = node_new.cost + self.distance(self.goal,node_new)closed_list[self.goal.position] = self.goalcost, path= self.extractPath(closed_list)print("Exploring {} nodes.".format(i))return cost,pathreturn 0,Nonedef get_random_node(self) :"""Return a random node."""if random.random()>self.goal_sample_rate:node = self.Node((random.uniform(0,self.env.height),random.uniform(0,self.env.width)),None,0)else:node = self.Node(self.goal.position,None,0)return nodedef get_nearest_neighbor(self,node_list,node) -> Node:"""Return node that is nearest to 'node' in node_list"""dist = [self.distance(node, n) for n in node_list]node_near = node_list[int(np.argmin(dist))]return node_neardef get_new_node(self,node_rand,node_near):"""Return node found based on node_near and node_rand."""dx = node_rand.position[0] - node_near.position[0]dy = node_rand.position[1] - node_near.position[1]dist = math.hypot(dx,dy)theta = math.atan2(dy, dx)d = min(self.max_dist,dist)position = ((node_near.position[0]+d*math.cos(theta)),node_near.position[1]+d*math.sin(theta))node_new = self.Node(position,node_near,node_near.cost+d)if self.isCollision(node_new, node_near):return Nonereturn node_newdef isCollision(self,node1,node2):"""Judge collision from node1 to node2 """if self.isInObstacles(node1) or self.isInObstacles(node2):return Truefor rect in self.env.obs_rectangle:if self.isInterRect(node1,node2,rect):return Truefor circle in self.env.obs_circle:if self.isInterCircle(node1,node2,circle):return Truereturn Falsedef distance(self,node1,node2):dx = node2.position[0] - node1.position[0]dy = node2.position[1] - node1.position[1]return math.hypot(dx,dy)def isInObstacles(self,node):"""Determine whether it is in obstacles or not."""x,y = node.position[0],node.position[1]for (ox,oy,w,h) in self.env.boundary:if ox-self.inflation<x<ox+w+self.inflation and oy-self.inflation<y<oy+h+self.inflation:return Truefor (ox,oy,w,h) in self.env.obs_rectangle:if ox-self.inflation<x<ox+w+self.inflation and oy-self.inflation<y<oy+h+self.inflation:return Truefor (ox,oy,r) in self.env.obs_circle:if math.hypot(x-ox,y-oy)<=r+self.inflation:return Truereturn Falsedef isInterRect(self,node1,node2,rect):""""Judge whether it will cross the rectangle when moving from node1 to node2"""ox,oy,w,h = rectvertex = [[ox-self.inflation,oy-self.inflation],[ox+w+self.inflation,oy-self.inflation],[ox+w+self.inflation,oy+h+self.inflation],[ox-self.inflation,oy+h+self.inflation]]x1,y1 = node1.positionx2,y2 = node2.positiondef cross(p1,p2,p3):x1 = p2[0]-p1[0]y1 = p2[1]-p1[1]x2 = p3[0]-p1[0]y2 = p3[1]-p1[0]return x1*y2 - x2*y1for v1,v2 in combinations(vertex,2):if max(x1,x2) >= min(v1[0],v2[0]) and min(x1,x2)<=max(v1[0],v2[0]) and \max(y1,y2) >= min(v1[1],v2[1]) and min(y1,y2) <= max(v1[1],v2[1]):if cross(v1,v2,node1.position) * cross(v1,v2,node2.position)<=0 and \cross(node1.position,node2.position,v1) * cross(node1.position,node2.position,v2):return Truereturn Falsedef isInterCircle(self,node1,node2,circle):"""Judge whether it will cross the circle when moving from node1 to node2"""ox,oy,r = circledx = node2.position[0] - node1.position[0]dy = node2.position[1] - node1.position[1]# Projectiont = ((ox - node1.position[0]) * dx + (oy - node1.position[1]) * dy) / (dx * dx + dy * dy)# The projection point is on line segment ABif 0 <= t <= 1:closest_x = node1.position[0] + t * dxclosest_y = node1.position[1] + t * dy# Distance from center of the circle to line segment ABdistance = math.hypot(ox-closest_x,oy-closest_y)return distance <= r+self.inflationreturn Falsedef extractPath(self,closed_list):""""Extract the path based on the closed list."""node = closed_list[self.goal.position]path = [node.position]cost = node.costwhile node != self.start:parent = node.parentnode_parent = closed_list[parent.position]node = node_parentpath.append(node.position)return cost,pathdef visualize(self, cost, path):"""Plot the map."""....
结果图:

相关文章:
路径规划——RRT算法
路径规划——RRT算法 算法原理 RRT算法的全称是快速扩展随机树算法(Rapidly Exploring Random Tree),它的思想是选取一个初始点作为根节点,通过随机采样,增加叶子节点的方式,生成一个随机扩展树,当随机树中的叶子节点…...
OPCUA-PLC
下载opcua服务器(有PLC可以直连),UaAnsiCServer下载路径 双击运行如下,Endpoint显示opcua服务路径 opc.tcp://DESKTOP-9SD7K4B:48020 下载opcua客户端(类似编写代码连接操作),UaExpert下载路径 如果连接失败,有一个授权认证,点击同意就行 java代码实现连接opcUA操作 pom.…...
在Windows系统上部署PPTist并实现远程访问
在Windows系统上部署PPTist并实现远程访问 前言PPTist简介本地部署PPTist步骤1:获取PPTist步骤2:安装依赖步骤3:运行PPTist 使用PPTist远程访问PPTist步骤1:安装Cpolar步骤2:配置公网地址步骤3:配置固定公网…...
【Grafana】Prometheus结合Grafana打造智能监控可视化平台
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…...
隐私计算实训营:SplitRec:当拆分学习遇上推荐系统
拆分学习的概念 拆分学习的核心思想是拆分网络结构。每一个参与方拥有模型结构的一部分,所有参与方的模型合在一起形成一个完整的模型。训练过程中,不同参与方只对本地模型进行正向或者反向传播计算,并将计算结果传递给下一个参与方。多个参…...
存在nginx版本信息泄露(请求头中存在nginx中间件版本信息)
在Nginx的配置文件中,server_tokens指令用于控制Nginx在HTTP响应头中包含的服务器版本信息,默认为true,开启状态。当设置为off时,Nginx将不会在响应头中包含任何服务器版本信息,仅显示“Server: nginx”这一行…...
在js中观察者模式讲解
在JavaScript中,观察者模式(Observer Pattern)是一种设计模式,允许一个对象(被观察者,Subject)维护一个依赖它的对象列表(观察者,Observer),并在它自身状态发生变化时自动通知这些观察者。观察者模式的典型使用场景包括事件系统、数据绑定和实时更新等情况。 一 、…...
java常用面试题-基础知识分享
什么是Java? Java是一种高级编程语言,旨在提供跨平台的解决方案。它是一种面向对象的语言,具有简单、结构化、可移植、可靠、安全等特点。 Java的主要特点是什么? Java的主要特点包括: 简单性:Java的语法…...
iOS——runLoop
什么是runloop RunLoop实际上就是一个对象,这个对象管理了其需要处理的事件和消息,并提供了一个入口函数来执行相应的处理逻辑。线程执行了这个函数后,就会处于这个函数内部的循环中,直到循环结束,函数返回。 RunLoo…...
python: 多模块(.py)中全局变量的导入
文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块&…...
0基础学习爬虫系列:Python环境搭建
1.背景 当前网络资源更新非常快,然后对应自己感兴趣的内容,每天盯着刷网站又太费时间。我在尝试借助Ai,搭建一套自己知识抓取更新提醒的系统,这样可以用极少的时间,关注到自己感兴趣的信息。 其实,这套逻辑…...
Unity Shader实现简单的各向异性渲染(采用各向异性形式的GGX分布)
目录 准备工作 BRDF部分 Unity部分 代码 实现的效果 参考 最近刚结束GAMES202的学习,准备慢慢过渡到GAMES103。GAMES103的作业框架为Unity,并没有接触过,因此准备先学一点Unity的使用。刚好101和202都是渲染相关的,因此先学习…...
React开源框架之Refine
React Refine 是一个基于 React 的开源框架,它旨在帮助开发者快速构建企业级后台管理系统(Admin Panel)。Refine 是由 Retax 演变而来,它提供了一套完整的解决方案,用于构建 CRUD(创建、读取、更新、删除&a…...
【iOS】——渲染原理与离屏渲染
图像渲染流水线(图像渲染流程) 图像渲染流程大致分为四个部分: Application 应用处理阶段:得到图元Geometry 几何处理阶段:处理图元Rasterization 光栅化阶段:图元转换为像素Pixel 像素处理阶段࿱…...
详解CSS
目录 CSS 语法 引入方式 选择器 标签选择器 类选择器 ID选择器 通配符选择器 复合选择器 常用CSS color font-size border width和height padding 外边距 CSS CSS(Cascading Style Sheet),层叠样式表, ⽤于控制⻚⾯的样式. CSS 能够对⽹⻚中元素位置…...
Python执行cmd命令
在Python中执行cmd命令,可以使用内置的subprocess模块。以下是一个简单的例子,展示如何执行一个cmd命令并获取输出。 import subprocess# 要执行的cmd命令 cmd "dir"# 使用subprocess.run来执行命令 result subprocess.run(cmd, shellTrue,…...
基于激光雷达的无人机相互避障
本框架是基于激光雷达的无人机群自主避障代码: 其主体框架利用ORCA算法,他是经典的多智能体相互避障算法,此版本只能规避动态障碍物,不能规避环境形成的静态障碍物我们对ORVA算法稍作修改,使其可以分布式部署ÿ…...
Zookeeper基本原理
1.什么是Zookeeper? Zookeeper是一个开源的分布式协调服务器框架,由Apache软件基金会开发,专为分布式系统设计。它主要用于在分布式环境中管理和协调多个节点之间的配置信息、状态数据和元数据。 Zookeeper采用了观察者模式的设计理念,其核心…...
【生日视频制作】西游记孙悟空师徒提笔毛笔书法横幅AE模板修改文字软件生成器教程特效素材【AE模板】
生日视频制作教程西游记孙悟空师徒提笔毛笔书法横幅AE模板修改文字特效广告生成神器素材祝福玩法AE模板工程 怎么如何做的【生日视频制作】西游记孙悟空师徒提笔毛笔书法横幅AE模板修改文字软件生成器教程特效素材【AE模板】 生日视频制作步骤: 下载AE模板 安装AE…...
春日美食汇:基于SpringBoot的订餐平台
2 系统关键技术 2.1JSP技术 JSP(Java脚本页面)是Sun和许多参与建立的公司所提倡的动态web技术。将Java程序添加到传统的web页面HTML文件()。htm,。Html) [1]。 JSP这种能够独立使用的编程语言可以嵌入在html语言里面运行,正因为JSP参照了许多编程语言的特性…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
计算机基础知识解析:从应用到架构的全面拆解
目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...
HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...
