纯跟踪(Pure Pursuit)路径跟踪算法研究(2)

news2024/9/28 17:30:15

纯跟踪(Pure Pursuit)路径跟踪算法研究(2)

下午进行了简单的公式推导,理论推导部分是没有问题的

在这里插入图片描述
在这里插入图片描述

下面的博客提供了在实车上用 GPS 实现纯跟踪控制的一些思路和注意点

Pure Pursuit(纯追踪算法)ROS实践

并不急于在实车上实现,第一步实现 CarSim 于 Simulink 的联合仿真

下面几篇博客主要是用Python模拟,读着稍微有点困难

无人驾驶汽车系统入门(十八)——使用pure pursuit实现无人车轨迹追踪

无人驾驶运动控制----pure pursuit算法实践和理解

自主跟随学习笔记(一)使用纯跟踪(pure pursuit)算法跟随目标

下面的博客介绍了纯跟踪的原理以及在开源框架 Autoare 中的实现

自动驾驶Motion Planning—Pure Pursuit算法原理及实现

在这里插入图片描述

Pure Pursuit算法的基本思想是:参考人类驾驶的行为,通过计算车辆当前位置到预瞄点(goal point)的曲率,使车辆沿着经过预瞄点的圆弧行驶,从而实现轨迹跟踪(如图1)。因此,该算法的核心在于通过设计合理的预瞄距离,从而计算出轨迹跟踪的控制曲率

在这里插入图片描述

Pure Pursuit本质上是一个基于横向误差控制的比例控制器

预瞄点(goal point)的选择

如何从路径点中选择预瞄点并且保证预瞄点在行驶方向的前方而不是反方向,还不清楚

在这里插入图片描述
在这里插入图片描述

预瞄距离(Ld)的选择

在这里插入图片描述

Pure Pursuit的效果强依赖于预瞄距离的选择,可根据车速动态的调整预瞄距离,从而增强系统的控制鲁棒性

下面的代码是基于上面的 Python 代码,用 MATLAB 实现了下,但代码并不完整

自动驾驶—基于运动学模型约束的纯跟踪控制算法 Pure Pursiut

纯跟踪算法是一种基于运动学约束的算法,对该算法的学习可以更好地理解车辆运动学模型。根据上一文档的讲解,我们可以建立后轮速度、前轮偏角和车辆大地坐标系下的位置、航向角的关系,那么我们在忽略轮胎力学、执行机构特性等情况下,就能根据后轮速度和前轮偏角任意控制车辆的速度、位置。本文只讨论横向控制,假设后轮速度恒定,也就是只控制前轮偏角

首先也应当实现当车辆后轮速度恒定,即车辆纵向速度恒定下的纯跟踪控制

纯跟踪算法提出“预瞄距离”的概念,根据预瞄距离寻找目标轨迹中符合条件的目标路径点,判断逻辑就是寻找目标轨迹上哪个点和当前车辆位置(图中的当前后轮位置)的相对距离等于预瞄距离(可以以当前位置为圆心,预瞄距离为半径,画圆,寻找与目标轨迹的交点),则该点就是当前时刻的目标点(图中的目标后轮位置)。控制目标则是计算多大的前轮偏角,可以使当前后轮位置运动到目标后轮位置

在这里插入图片描述

恒定后轮速度,恒定前轮偏角,那么后轮的运动轨迹将是一个圆,即车辆绕着转动中心做圆周运动,如下图所示:

在这里插入图片描述

基于这个现象,可以认为在每个运行周期内(速度恒定,前轮偏角恒定),车辆绕转动中心做圆周运动。那么控制目标就可以简化为两点:①是怎样的圆周运动轨迹可以将后轮从当前位置运动至目标位置?②如何控制前轮偏角实现这个圆周运动?

在这里插入图片描述

下面的博客并没有给出具体的 Simulink 实现,但对预瞄控制的解释还是很生动的

Pure Pursuit(纯跟踪算法)与Simulink实现

在这里插入图片描述

如上图所示,A点是车辆后轴中心(也是图中坐标系的原点,图中这种坐标系我们一般称之为:车辆坐标系),B点是车辆要达到的目标点(预瞄点),L是AB之间的距离(预瞄距离),O点是假设存在的圆心使得车辆从位置A以转弯半径r可以达到位置B。圆心位置O的坐标与转弯半径r就是计算目标。此图颇有遗憾,因为AO线段看上去比BO线段长,但二者应该是相等的,都是转弯半径

纯跟踪控制算法就是一种**基于几何关系计算车辆转弯半径**的方法

在这里插入图片描述

纯跟踪算法核心计算部分是非常简洁的,不过实际应用时还有两块工作要做:1,从期望轨迹中找预瞄点B,方法是从期望轨迹上找距离A点等于预瞄距离L的点。2,A点与B点坐标可能都是基于某个全局坐标系,所以需要将B点坐标从全局坐标系转换至车辆坐标系上。这两部分计算是使用纯跟踪算法的准备工作

📌 上面所说的两个问题确实是比较关键的问题

全局坐标系到车辆坐标系的变换或许可以参考下面的代码

自动驾驶Motion Planning—Pure Pursuit算法原理及实现

在这里插入图片描述

float32_t PurePursuit::compute_points_distance_squared(
  const TrajectoryPoint & point1,
  const TrajectoryPoint & point2)
{
  using autoware::common::types::float64_t;
  const float64_t diff_x = point1.pose.position.x - point2.pose.position.x;
  const float64_t diff_y = point1.pose.position.y - point2.pose.position.y;
  return static_cast<float32_t>((diff_x * diff_x) + (diff_y * diff_y));
}

std::pair<float32_t, float32_t> PurePursuit::compute_relative_xy_offset(
  const TrajectoryPoint & current,
  const TrajectoryPoint & target) const
{
  const auto diff_x = target.pose.position.x - current.pose.position.x;
  const auto diff_y = target.pose.position.y - current.pose.position.y;
  const auto yaw = ::motion::motion_common::to_angle(current.pose.orientation);
  const auto cos_pose = std::cos(yaw);
  const auto sin_pose = std::sin(yaw);
  const auto relative_x = static_cast<float32_t>((cos_pose * diff_x) + (sin_pose * diff_y));
  const auto relative_y = static_cast<float32_t>((-sin_pose * diff_x) + (cos_pose * diff_y));
  const std::pair<float32_t, float32_t> relative_xy(relative_x, relative_y);
  return relative_xy;
}

float32_t PurePursuit::compute_steering_rad(const TrajectoryPoint & current_point)
{
  // Compute the steering angle by arctan(curvature * wheel_distance)
  // link: https://www.ri.cmu.edu/pub_files/2009/2/
  //       Automatic_Steering_Methods_for_Autonomous_Automobile_Path_Tracking.pdf
  const float32_t denominator = compute_points_distance_squared(current_point, m_target_point);
  const float32_t numerator = compute_relative_xy_offset(current_point, m_target_point).second;
  constexpr float32_t epsilon = 0.0001F;
  // equivalent to (2 * y) / (distance * distance) = (2 * sin(th)) / distance
  const float32_t curvature = (denominator > epsilon) ? ((2.0F * numerator) / denominator) : 0.0F;
  const float32_t steering_angle_rad = atanf(curvature * m_config.get_distance_front_rear_wheel());
  return steering_angle_rad;
}

车辆当前位置和预瞄点间连线与车辆轴线(前进方向)夹角可以参考下面的公式

《基于纯追踪算法和樽海鞘优化算法的无人驾驶路径跟踪算法研究》

在这里插入图片描述
在这里插入图片描述

纯跟踪算法的轨迹跟随效果,与参数:预瞄距离关系很大。就像人开车时眼睛往前看多远,看的太近了,到了弯道才慌忙打方向盘;看的太远了,又容易导致最近一段的轨迹跟随效果不好

最后谈一下纯跟踪算法的硬伤:纯跟踪算法可以缩小车辆与期望轨迹的位置偏差,但是对角度偏差束手无策,因为数学原理上根本就没有考虑角度偏差

下面的博客用 MATLAB 跟踪了圆形轨迹,并且测试了大预瞄距离和小预瞄距离的情况

路径跟踪之Pure Pursuit控制算法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

减小前视距离,仿真结果如下图所示,可以看出跟踪结果出现了一定程度的震荡,这是因为前视距离减小后,近似P控制器的比例系数增加,从而造成动态响应出现超调和震荡

在这里插入图片描述

同时讨论了朝向角 𝛼 == 90度朝向角 𝛼 > 90度的情况

如果预瞄点如下图所示,那么𝛼大于90度,车辆后轮的运行轨迹应该是大圆,绕了一个大圈,是在向后跟踪,此时的前轮转角计算公式仍然不变

在这里插入图片描述

𝛼等于90度的情况,车辆后轮的运行轨迹应该是右上那个半圆

在这里插入图片描述

通过以上分析,不难发现,三种情况下的前轮转角计算公式均适用,同样“近似P控制器”这个结论在上述三种情况下也都成立

下面的方法简要分析了 Pure Pursuit、Stanley、MPC 这几种轨迹跟踪控制方法,可以作为后面继续研究的开展

横向自动控制方法:Purepursuit, Stanley, MPC对比

下面的博客给出了 Pure Pursuit 的仿真实现,可以参考学习下,实测可以跑

PurePursuit纯追踪算法MATLAB程序个人总结

Pure Pursuit纯跟踪算法Python/Matlab算法实现

%% 纯跟踪算法跟随效果与预瞄距离关系很大。就像人开车时眼睛往前看多远,看的太近了,到了弯道才慌忙打方向盘;看的太远了,又容易导致最近一段的轨迹跟随效果不好。

%% initialization
k = 0.1;                                  % look forward gain  前向预测距离所用增益
Kp = 1.0 ;                                % speed propotional gain
Lfc = 1;                                  % 基础预瞄距离
dt = 0.1;                                 % [s]
L = 2.9  ;                                % [m] wheel base of vehicle
cx = 0:0.1:50;                            %0.1长度取一次预瞄点的x值

for i = 1:length(cx)                      %全局路径c(y)生成 路径初始化
     cy(i) = cos(cx(i)/5)*cx(i)/4;
end

i = 1;
target_speed = 10/3.6;                    %设定速度  如果实际自动驾驶,这个就是设定要到达的速度,
                                          %附加:目前这里没有规划,如果有规划,就在过弯的时候给出横向加速度,所以车身方向速度就会减小。
T = 500;
lastIndex = length(cx);                   %返回cx的向量长度   有501个预瞄点x值   有501个序号
x = 0; y = 4; yaw = 0; v = 0;             %车辆初始位置  
time = 0;
Ld = k * v + Lfc;                         %初始速度为0时的预瞄距离Ld=Lfc
 
 figure(1);
while T > time 
  target_index = calc_target_index(x,y,cx,cy);                 %输出距离车辆当前最近的点的位置
  ai = PIDcontrol(target_speed,v,Kp); %
  Ld = k * v + Lfc ;
  delta = pure_pursuit_control(x,y,yaw,v,cx,cy,target_index,k,Lfc,L,Ld); %前轮要转的角度
   
  [x,y,yaw,v] = update(x,y,yaw,v, ai, delta,dt,L); %更新车辆状态
  time = time + dt;                          %时间过完一周期
% pause(0.1)
  plot(cx,cy,'b',x,y,'r-*')                 %将预瞄点位置用蓝色表示,当前位置用红色表示
  drawnow
  hold on
  
end

function [x, y, yaw, v] = update(x, y, yaw, v, ai, delta,dt,L)   %更新车辆状态的函数
    x = x + v * cos(yaw) * dt;
    y = y + v * sin(yaw) * dt;
    yaw = yaw + v / L * tan(delta) * dt;
    v = v + ai * dt;
end

function [a] = PIDcontrol(target_v, current_v, Kp)              %计算加速度的函数
a = Kp * (target_v - current_v);
end

function [delta] = pure_pursuit_control(x,y,yaw,v,cx,cy,ind,k,Lfc,L,Ld)  %纯追踪控制器前轮转角方程的函数
    tx = cx(ind);                          %距离车辆当前最近的点的位置对应的cx值     ind是距离车辆当前最近的点的位置
    ty = cy(ind);                          %距离车辆当前最近的点的位置对应的cy值
    
    alpha = atan((ty-y)/(tx-x))-yaw;       %该处定义向左转为alpha=beta-Fai,所以向右转就输出-alpha
    
 Ld = k * v + Lfc ;                        % 预瞄距离Ld与车速成线性关系 
 delta = atan(2*L * sin(alpha)/Ld)  ;                %前轮转角
end

function [ind] = calc_target_index(x,y, cx,cy)      %计算找到距车辆当前位置最近点的序号  输出最近点的函数
N =  length(cx);                                     %N = 501
Distance = zeros(N,1);                               % 5011列的矩阵

for i = 1:N
Distance(i) =  sqrt((cx(i)-x)^2 + (cy(i)-y)^2);      %每一个预瞄点到初始位置的距离
end

[~, location]= min(Distance);                        %找出最近的距离对应的位置
ind = location;
ind = ind + 5
end

在这里插入图片描述

实际上 MATLAB 本身也提供了 Pure Pursuit 工具箱

MATLAB Pure Pursuit Controller

在这里插入图片描述
GitHub 上也有相关的基于 Gazebo 的仿真

https://github.com/NeXTzhao/planning

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

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

相关文章

勘探开发人工智能技术:机器学习(1)

0 提纲 2.1 什么是机器学习 2.2 不确定性 2.3 数据类型 2.4 分类、回归、聚类 2.5 分类问题的训练与测试 2.6 性能评价指标 1 什么是机器学习 对于西瓜这个抽象类来说&#xff0c;它具有“色泽”&#xff0c;“根蒂”&#xff0c;“敲声”三个属性&#xff1a; 通过观察这个…

值得尝试的进销存软件,新手使用也轻松!

作为一名小老板&#xff0c;我曾经非常担心在操作进销存软件时出现故障&#xff0c;因为这会直接影响到我们的业务开展。然而&#xff0c;在操作管家婆云辉煌的过程中&#xff0c;我发现这种担忧是没有必要的。 管家婆云辉煌的稳定性非常高&#xff0c;几乎不会出现软件故障。 …

软件测试目的和原则

一、软件测试的目的 1&#xff09;软件测试是为了发现错误而执行程序的过程。 2&#xff09;测试是为了证明程序有错&#xff0c;而不是证明程序无错。&#xff08;发现错误不是唯一目的&#xff09; 3&#xff09;一个好的测试用例在于它发现至今未发现的错误。 4&#xf…

uni-app微信小程序开发自定义select下拉多选内容篇

分享-2023年高级前端进阶&#xff1a;前端登顶之巅-最全面的前端知识点总结站点 *分享一个使用比较久的&#x1fa9c; 技术框架公司的选型&#xff1a;uni-app uni-ui vue3 vite4 ts 需求分析&#xff1a;微信小程序-uni-ui内容 1、创建一个自定义的下拉&#xff0c;支持多…

浏览器多管闲事之跨域

年少时的梦想就是买一台小霸王游戏机 当时的宣传语就是小霸王其乐无穷~。 大些了&#xff0c;攒够了零花钱&#xff0c;在家长的带领下终于买到了 那一刻我感觉就是最幸福的人 风都是甜的&#xff01; 哪成想... 刚到家就被家长扣下了 “”禁止未成年人玩游戏机 (问过卖家了&a…

AWS中Lambda集成SNS

1.创建Lambda 在Lambda中&#xff0c;创建名为AWSSNSDemo的函数 use strict console.log(loading function); var aws require(aws-sdk); var docClient new aws.DynamoDB.DocumentClient(); aws.config.regionap-southeast-1;exports.handler function(event,context,cal…

C语言实现选择排序

什么是选择排序&#xff1f; 选择排序是一种简单直观的排序算法&#xff0c;它的核心思想是每次从未排序的元素中选择最小&#xff08;或最大&#xff09;的元素&#xff0c;然后将其放到已排序序列的末尾。通过重复这个过程&#xff0c;直到所有元素都排好序为止。 选择排序…

IntelliJ IDEA如何重新弹出git身份验证窗口

1、点击File菜单—>点击Settings—>点击Appearance & Behavior—>点击System Settings—>点击Passwords—>选中Do not save, forget passwords after restart—>点击Apply—>点击OK&#xff0c;如下所示&#xff1a; 2、重启IntelliJ IDEA—>通过g…

idea集成svn

一、注意 安装svn客户端的时候一定要勾选&#xff0c;否则在idea上集成svn的时候会找不到 svn.exe 而报错。 如果当初安装时忘记勾选&#xff0c;重新运行安装包&#xff0c;选择modify&#xff0c;勾选command line client tools项中的内容。 二、配置idea集成svn 三、检出(c…

生产车间SOP+电子作业指导书系统解决方案

为了提高生产效率&#xff0c;许多企业开始使用SOP电子作业指导书系统来统一管理和快速发布工作指导书。这种系统不仅能够实现无纸化办公&#xff0c;节省企业资源&#xff0c;还能集成生产管理看板系统和安灯呼叫系统&#xff0c;实现生产现场数据的目视化管理。 一、SOP系统拓…

简单数据类型

目录 前言 一.变量 1.1 变量命名 2.1 变量定义 二.类型 2.1 字符串 2.1.1 定义 2.1.2 操作 2.1.3 python2中的print语句 2.2 整数 2.2.1 运算 2.2.2 浮点数 2.2.3 str()函数 2.3 列表 2.3.1 访问和使用列表元素 2.3.2 在列表中添加元素 2.3.3 从列表中删除元素 2.3.4 组织列表…

LangChain源码逐行解密之LLMs(二)

LangChain源码逐行解密之LLMs(二) 18.3 base.py源码逐行剖析 现在我们要聚焦于源代码中的大语言模型部分。如图18-3所示,LangChain提供了许多语言模型的选择。 Gavin大咖微信:NLP_Matrix_Space 图18- 3 LangChain的llms目录 如图18-4所示,整个LangChain的模块化设计非常出…

最小花费 c++详解

最小花费 c详解 最小花费题目描述输入格式输出格式样例样例输入样例输出 提示 解法代码 最小花费 题目描述 在 n n n 个人中&#xff0c;某些人的银行账号之间可以互相转账。这些人之间转账的手续费各不相同。给定这些人之间转账时需要从转账金额里扣除百分之几的手续费&…

如何实现电子合同管理系统与其他企业应用的无缝对接?

电子合同管理系统是一种利用信息技术来管理和执行合同的系统。随着企业数字化转型的推进&#xff0c;电子合同管理系统已经成为许多企业必备的工具之一。然而&#xff0c;要实现电子合同管理系统与其他企业应用的无缝对接&#xff0c;并不是一件容易的事情。 实现电子合同管理…

深度解读|一站式ABI平台 Smartbi Insight V11 能力再升级

纵观过去&#xff0c;我们发现汽车和BI的发展有异曲同工之妙。 100来年&#xff0c;汽车的动力从蒸汽到燃油再到新能源&#xff0c;汽车的操控方式从手动到自动再到智能无人驾驶。而在BI领域&#xff0c;自1958年BI的概念提出后&#xff0c;底层数据准备从报表开发、Cube多维模…

图像的缩放之c++实现(qt + 不调包)

1.基本原理 图像的缩放一般使用插值算法&#xff0c;而本章将介绍两种常用插值算法&#xff1a;最临近插值法和双线性插值法 1.最临近插值法 将浮点数的位置坐标&#xff0c;进行四舍五入找到原图像的整型坐标即可&#xff0c;具体操作可见下面的公式&#xff0c;其中原图像坐标…

MES系统在机器人行业生产管理种的运用

机器人的智能水平也伴随技术的迭代不断攀升。 2021年的春晚舞台上&#xff0c;来自全球领先工业机器人企业abb的全球首款双臂协作机器人yumi&#xff0c;轻松自如地表演了一出写“福”字&#xff0c;赢得了全国观众的赞叹。 在汽车装配领域&#xff0c;一台机器人可以自主完成一…

【笔记】线段树

【笔记】线段树 目录 简介定义建树更新例题1: 单点修改&#xff0c;区间查询单点修改区间查询本题完整代码 例题2: 区间修改&#xff0c;单点查询思路本题完整代码 例题3: 区间修改&#xff0c;区间查询懒标记基本思想应用 区间修改本题完整代码 简介 线段树是一棵二叉树。如果…

带团队后的日常思考

一、日常问题 1&#xff09;补充产品文档 最近版本迭代&#xff0c;其中涉及一块举报流程的优化&#xff0c;其实会涉及管理后台发送站内信。 刚开始&#xff0c;大家都没怎么在意这个需求&#xff0c;但是在执行时才发现有许多细节没有考虑到。 管理后台的举报页面是在 2018 …

【C++技能树】一文看懂模板匹配

Halo&#xff0c;这里是Ppeua。平时主要更新C&#xff0c;数据结构算法&#xff0c;Linux与ROS…感兴趣就关注我bua&#xff01; 文章目录 0.泛型编程1.模板2 函数模板:2.1函数模板的特化 3. 类模板3.1 非类型模板参数3.2 类的模板刻画3.2.1 全特化3.2.2 偏特化 0.泛型编程 假…