用python实现Pure Pursuit控制算法

2023-10-14 14:38

本文主要是介绍用python实现Pure Pursuit控制算法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

之前对Pure Pursuit控制算法作了介绍,并用Matlab进行了仿真,具体参考:https://blog.csdn.net/Ronnie_Hu/article/details/115817922?spm=1001.2014.3001.5501。

下面改用python对其进行仿真,同样跟踪一个圆形轨迹,具体代码如下:

import numpy as np
import matplotlib.pyplot as plt
import math# set figure size
plt.figure(figsize=(8, 8))# define UGV class
class UGV_model:def __init__(self, x0, y0, theta0, v0, L, T):self.x = x0self.y = y0self.theta = theta0self.v = v0self.l = Lself.dt = Tdef update(self,deltat):dx_vs_dt = self.v*np.cos(self.theta) dy_vs_dt = self.v*np.sin(self.theta)dtheta_vs_dt = self.v*np.tan(deltat)/self.lself.x += dx_vs_dt*self.dtself.y += dy_vs_dt*self.dtself.theta += dtheta_vs_dt*self.dtdef draw(self):plt.scatter(self.x, self.y, color='r')plt.axis([-20, 20, -20, 20])plt.grid(linestyle=":")# set circle reference trajectory
refer_traj = np.ones((200,2))
for k in range(200):refer_traj[k,0] = 15*math.cos(2*np.pi/200*k)refer_traj[k,1] = 15*math.sin(2*np.pi/200*k)# draw reference trajectory
plt.plot(refer_traj[:,0], refer_traj[:,1], color='b')# an UGV instance
ugv = UGV_model(0, 0, np.pi/2, 1.6, 2.6, 0.5)# define lookahead
ld = ugv.v*2# Pure Pursuit algorithm
flag = 0for i in range(200):vehicle_state = np.zeros(2)vehicle_state[0] = ugv.xvehicle_state[1] = ugv.ycnt = 0;min_ds = 100000000; Q = []for m in range(flag,200):deltax,deltay = refer_traj[m] - vehicle_stateds = math.sqrt(deltax*deltax+deltay*deltay)if(ds >= ld):temp = [ds,refer_traj[m,0],refer_traj[m,1],m]Q.append(temp)cnt += 1else:passpass# catch the nearest reference pointfor j in range(cnt):if(Q[j][0]<min_ds):flag = Q[j][3]min_ds = Q[j][0]            else:passpassdx,dy = refer_traj[flag] - vehicle_statealpha = math.atan2(dy,dx) - ugv.thetadelta = math.atan(2*np.sin(alpha)*ugv.l/min_ds)ugv.update(delta)ugv.draw()# pursuit the end reference pointif(flag==199):breakelse:pass

仿真的结果如下图所示,蓝色为参考轨迹、红色为跟踪轨迹。从上面的代码不难看出,仿真中采用了“走捷径”的方法,即每次在剩余跟踪点中挑选距离最近的点来跟踪

下面的代码就没有采取“走捷径”的方法。

import numpy as np
import matplotlib.pyplot as plt
import math# set figure size
plt.figure(figsize=(8, 8))# define UGV class
class UGV_model:def __init__(self, x0, y0, theta0, v0, L, T):self.x = x0self.y = y0self.theta = theta0self.v = v0self.l = Lself.dt = Tdef update(self,deltat):dx_vs_dt = self.v*np.cos(self.theta) dy_vs_dt = self.v*np.sin(self.theta)dtheta_vs_dt = self.v*np.tan(deltat)/self.lself.x += dx_vs_dt*self.dtself.y += dy_vs_dt*self.dtself.theta += dtheta_vs_dt*self.dtdef draw(self):plt.scatter(self.x, self.y, color='r')plt.axis([-20, 20, -20, 20])plt.grid(linestyle=":")# set circle reference trajectory
refer_traj = np.ones((200,2))
for k in range(200):refer_traj[k,0] = 15*math.cos(2*np.pi/200*k)refer_traj[k,1] = 15*math.sin(2*np.pi/200*k)# draw reference trajectory
plt.plot(refer_traj[:,0], refer_traj[:,1], color='b')# an UGV instance
ugv = UGV_model(0, 0, np.pi/2, 1.6, 2.6, 0.5)# define lookahead
ld = ugv.v*2# Pure Pursuit algorithm
flag = 0for i in range(200):vehicle_state = np.zeros(2)vehicle_state[0] = ugv.xvehicle_state[1] = ugv.ycnt = 0;Q = []for m in range(flag,200):ds = np.linalg.norm(vehicle_state-refer_traj[m])if(ds >= ld):flag = mbreakelse:passpassds = np.linalg.norm(vehicle_state-refer_traj[flag])dx,dy = refer_traj[flag] - vehicle_statealpha = math.atan2(dy,dx) - ugv.thetadelta = math.atan(2*np.sin(alpha)*ugv.l/ld)ugv.update(delta)ugv.draw()# pursuit the end reference pointif(flag==199):breakelse:pass

仿真结果如下图所示,蓝色为参考轨迹、红色为跟踪轨迹。

不难看出,在计算前轮转角的时候,反正切运算的分母用的是前视距离,而不是实际距离,如果改用实际距离,跟踪会失败,如下图所示。

这篇关于用python实现Pure Pursuit控制算法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/211159

相关文章

Golang实现基于角色的访问控制(RBAC)的项目实践

《Golang实现基于角色的访问控制(RBAC)的项目实践》基于角色的访问控制(RBAC)是一种安全机制,通过角色来管理用户权限,本文介绍了一种可落地、易扩展的GolangRBAC实现方案,具有一定... 目录一、RBAC 核心模型设计二、RBAC 核心逻辑实现RBAC 管理器定义基础 CRUD:添加用户

Python使用Spire.PDF实现为PDF添加水印

《Python使用Spire.PDF实现为PDF添加水印》在现代数字化办公环境中,PDF已成为一种广泛使用的文件格式,尤其是在需要保持文档格式时,下面我们就来看看如何使用Python为PDF文件添加水... 目录一、准备工作二、实现步骤1. 导入必要的库2. 创建 PdfDocument 对象3. 设置水印

python循环引用和解决过程

《python循环引用和解决过程》文章讨论了在Python中解决循环引用问题的几种方法,包括延迟导入、使用`importlib`、重构代码和类型提示的前向引用,这些方法可以帮助开发者避免导入循环导致的... 目录模拟循环引用解决python循环引用的方法有几种,以下是一些常见的解决android方案常见问题

python在word中插入目录和更新目录实现方式

《python在word中插入目录和更新目录实现方式》文章主要介绍了如何在Word文档中插入和更新目录,并提供了具体的代码示例,插入目录时,需要使用`TablesOfContents`对象,并设置使用... 目录1、插入目录2、更新目录总结1、插入目录需要用到对象:TablesOfContents目录的

PostgreSQ数据库实现在Windows上异地自动备份指南的详细教程

《PostgreSQ数据库实现在Windows上异地自动备份指南的详细教程》这篇文章主要为大家详细介绍了如何在Windows系统上实现PostgreSQL数据库的异地自动备份,文中的示例代码讲解详细,... 目录前期准备实现步骤步骤一:创建备份脚本步骤二:配置免密登录(可选但推荐)步骤三:设置任务计划程序步

基于Python编写一个git自动上传的脚本(打包成exe)

《基于Python编写一个git自动上传的脚本(打包成exe)》这篇文章主要为大家详细介绍了如何基于Python编写一个git自动上传的脚本并打包成exe,文中的示例代码讲解详细,感兴趣的小伙伴可以跟... 目录前言效果如下源码实现利用pyinstaller打包成exe利用ResourceHacker修改e

Python在二进制文件中进行数据搜索的实战指南

《Python在二进制文件中进行数据搜索的实战指南》在二进制文件中搜索特定数据是编程中常见的任务,尤其在日志分析、程序调试和二进制数据处理中尤为重要,下面我们就来看看如何使用Python实现这一功能吧... 目录简介1. 二进制文件搜索概述2. python二进制模式文件读取(rb)2.1 二进制模式与文本

Python中Tkinter GUI编程详细教程

《Python中TkinterGUI编程详细教程》Tkinter作为Python编程语言中构建GUI的一个重要组件,其教程对于任何希望将Python应用到实际编程中的开发者来说都是宝贵的资源,这篇文... 目录前言1. Tkinter 简介2. 第一个 Tkinter 程序3. 窗口和基础组件3.1 创建窗

基于C++的UDP网络通信系统设计与实现详解

《基于C++的UDP网络通信系统设计与实现详解》在网络编程领域,UDP作为一种无连接的传输层协议,以其高效、低延迟的特性在实时性要求高的应用场景中占据重要地位,下面我们就来看看如何从零开始构建一个完整... 目录前言一、UDP服务器UdpServer.hpp1.1 基本框架设计1.2 初始化函数Init详解

Java中Map的五种遍历方式实现与对比

《Java中Map的五种遍历方式实现与对比》其实Map遍历藏着多种玩法,有的优雅简洁,有的性能拉满,今天咱们盘一盘这些进阶偏基础的遍历方式,告别重复又臃肿的代码,感兴趣的小伙伴可以了解下... 目录一、先搞懂:Map遍历的核心目标二、几种遍历方式的对比1. 传统EntrySet遍历(最通用)2. Lambd