Pure Pursuit控制器路径跟随

参考博客:
Pure Pursuit 纯追踪法
Autoware(Pure pursuit代码学习)

1 Pure Pursuit纯追踪法

适用场景:低速场景(速度过高会产生转弯内切以及超调)
简化前轮转向角和后轴将遵循的曲率之间的关系
自行车模型在这里插入图片描述(Gx,Gy)是下一个需要追踪的路点,位于已经规划好的全局路径上,现在需要控制车辆的后轴经过该路点。

  • L d L_{d} Ld: 车辆后轴中心(Cx,Cy)到目标路点(Gx,Gy)的距离,即预瞄距离
  • α \alpha α: 目前车身姿态和目标路点的夹角
  • R R R: 跟踪的曲率半径
  • δ δ δ: 前轮转角

L d s i n 2 α = R s i n ( π 2 − α ) \Large\frac{L_{d}}{sin2\alpha } =\frac{R}{sin(\frac{\pi }{2} -\alpha ){\large }} sin2αLd=sin(2πα)R
=> k a p p a = 1 R = 2 s i n α L d \large kappa =\frac{1}{R} =\frac{2sin\alpha}{Ld } kappa=R1=Ld2sinα
=> δ ( t ) = a r c t a n ( 2 L s i n α ( t ) L d ) {\Large {\delta (t)=arctan(\frac{2Lsin\alpha (t)}{Ld} )} } δ(t)=arctan(Ld2Lsinα(t))

调节预瞄距离成为纯追踪算法的关键

2 代码分析

pure_pursuit.h

#pragma once
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>

using namespace std;
class PurePursuit {
public:
    double calTargetIndex(vector<double>robot_state, vector<vector<double>> ref_path, double l_d);

    double Pure_Pursuit_Control(vector<double> robot_state, vector<double> current_ref_point, double l_d, double psi, double L);
};

pure_pursuit.cpp

#include "Pure_pursuit.h"

// 计算邻近路点 (G_x, G_y)
// robot_state:当前机器人位置 ref_path:参考轨迹 l_d:前向距离
double PurePursuit::calTargetIndex(vector<double> robot_state, vector<vector<double>> ref_path, double l_d)
{
    vector<double> dists;
    for (vector<double> xy : ref_path)
    {
        double dist = sqrt(pow(xy[0] - robot_state[0], 2) + pow(xy[1] - robot_state[1], 2));
        dists.push_back(dist);
    }
    double min_index = min_element(dists.begin(), dists.end()) - dists.begin();
    double delta_l = sqrt(pow(ref_path[min_index][0] - robot_state[0], 2) + pow(ref_path[min_index][1] - robot_state[1], 2));

    while (l_d > delta_l && min_index < ref_path.size() - 1)
    {
        delta_l = sqrt(pow(ref_path[min_index + 1][0] - robot_state[0], 2) + pow(ref_path[min_index + 1][1] - robot_state[1], 2));
        min_index += 1;
    }
    return min_index;
}

// Pure Pursuit Control
// robot_state 当前机器人位置; current_ref_point 参考轨迹点 ; l_d 前向距离 ; psi 机器人航向角 ; L 轴距 ; return 转角控制量
double PurePursuit::Pure_Pursuit_Control(vector<double> robot_state, vector<double> current_ref_point, double l_d, double psi, double L)
{
    double alpha = atan2(current_ref_point[1] - robot_state[1], current_ref_point[0] - robot_state[0]) - psi;
    double delta = atan2(2 * L * sin(alpha), l_d);
    return delta;
}

main.cpp

#include "KinematicModel.h"
#include "matplotlibcpp.h"
#include "Pure_pursuit.h"
namespace plt = matplotlibcpp;

#define PI 3.1415926

int main()
{
    double x0 = 0.0, y0 = 2.3, psi = 0.5, v=2, L=2, dt=0.1;
    double lam = 0.01; // 前视距离
    double c = 2;
    vector<vector<double>> ref_path(1000, vector<double>(2));
    vector<double> ref_x, ref_y; // 保存参考数据用于画图
    // 生成参考轨迹
    for (int i = 0; i < 1000; i++) {
        ref_path[i][0] = 0.1 * i;
        ref_path[i][1] = 2 * sin(ref_path[i][0] / 3.0) + 2.5 * cos(ref_path[i][0] / 2.0);
        ref_x.push_back(ref_path[i][0]);
        ref_y.push_back(ref_path[i][1]);
    }
    KinematicModel model(x0, y0, psi, v, L, dt);

    vector<double> x_, y_;
    vector<double> robot_state(2);
    PurePursuit pp;
    for (int i = 0; i < 600; i++) {
        plt::clf();
        robot_state[0] = model.x;
        robot_state[1] = model.y;
        double l_d = lam * model.v + c;
        double min_ind = pp.calTargetIndex(robot_state, ref_path, l_d);
        double delta = pp.Pure_Pursuit_Control(robot_state, ref_path[min_ind], l_d, model.psi, L);
        model.updateState(0, delta);
        x_.push_back(model.x);
        y_.push_back(model.y);

        plt::plot(ref_x, ref_y, "b--");
        plt::plot(x_, y_, "r--");
        plt::grid(true);
        plt::ylim(-5, 5);
        plt::pause(0.01);
    }
    const char* filename = "./pure_pursuit.png";
    plt::save(filename);
    plt::show();
    return 0;
}

CMakeList.txt

cmake_minimum_required(VERSION 3.0.2)
project(Pure_pursuit)
find_package(catkin REQUIRED COMPONENTS
  roscpp
  std_msgs
)

set(CMAKE_CXX_STANDARD 11)

file(GLOB_RECURSE PYTHON2.7_LIB "/usr/lib/python2.7/config-x86_64-linux-gnu/*.so")
set(PYTHON2.7_INLCUDE_DIRS "/usr/include/python2.7")

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES huatu
#  CATKIN_DEPENDS roscpp std_msgs
#  DEPENDS system_lib
)

include_directories(include
        ${PYTHON2.7_INLCUDE_DIRS}
)

add_executable(pp_controller src/Pure_pursuit.cpp
                              src/KinematicModel.cpp
                              src/main.cpp)
target_link_libraries(pp_controller ${PYTHON2.7_LIB})

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【实战】一、Jest 前端自动化测试框架基础入门(二) —— 前端要学的测试课 从Jest入门到TDD BDD双实战(二)

文章目录 一、Jest 前端自动化测试框架基础入门5.Jest 中的匹配器toBe 匹配器toEqual匹配器toBeNull匹配器toBeUndefined匹配器和toBeDefined匹配器toBeTruthy匹配器toBeFalsy匹配器数字相关的匹配器字符串相关的匹配器数组相关的匹配器异常情况的匹配器 6.Jest 命令行工具的使…

C++【AVL树】

目录 1.AVL树&#xff08;高度平衡搜索二叉树&#xff09;定义 1.1平衡因子&#xff08;Balance Factor简写成bf&#xff09; 1.2avl树的定义 2.AVL树插入的基本操作 2.1逻辑抽象图 2.2插入流程 2.3左单旋 2.4右单旋 2.5右左双旋 2.6左右双旋 3.AVL树的检验技巧 3.1…

AI:127-基于卷积神经网络的交通拥堵预测

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带有在本地跑过的关键代码,详细讲解供…

2024-02-13 Unity 编辑器开发之编辑器拓展4 —— EditorGUIUtility

文章目录 1 EditorGUIUtility 介绍2 加载资源2.1 Eidtor Default Resources2.2 不存在返回 null2.3 不存在则报错2.4 代码示例 3 搜索框查询、对象选中提示3.1 ShowObjectPicker3.2 PingObject3.3 代码示例 4 窗口事件传递、坐标转换4.1 CommandEvent4.2 GUIPoint 和 ScreenPoi…

Excel模板2:进度条甘特图

Excel模板2&#xff1a;进度条甘特图 ‍ 今天复刻B站up【名字叫麦兜的狗狗】的甘特图&#xff1a;还在买Excel模板吗&#xff1f;自己做漂亮简洁的甘特图吧&#xff01;_哔哩哔哩_bilibili 阿里网盘永久分享&#xff1a;https://www.alipan.com/s/cXhq1PNJfdm 当前效果&…

片上网络NoC(5)——非直连拓扑

目录 一、前言 二、概念阐述 三、交叉开关 四、蝶形网络 五、clos网络 六、fat tree网络 6.1 clos网络的折叠过程 七、总结 一、前言 本文继续介绍片上网络的拓扑&#xff0c;在之前的文章中&#xff0c;我们已经介绍了片上网络的拓扑指标和直连拓扑的相关内容&#xf…

【新年第一辑 | TortoiseGit常见用法】

TortoiseGit常见用法 概述常用操作建立仓库提交代码更新代码回滚版本添加忽略文件设置比较工具&#x1fa78; 解决冲突 主页传送门 &#xff1a; &#x1f4c0; 传送 概述 TortoiseGit是一个Windows平台上的Git客户端工具&#xff0c;它提供了一个直观和易于使用的图形用户界面…

面向对象2:继承

目录 2.1继承 2.2 继承的好处 2.3 权限修饰符 2.4 单继承、Object 2.5 方法重写 2.6 子类中访问成员的特点 2.7 子类中访问构造器的特点 面向对象1&#xff1a;静态 2.1继承 向对象编程之所以能够能够被广大开发者认可&#xff0c;有一个非常重要的原因&#xff0c;是…

springboot184基于springboot的校园网上店铺的设计与实现

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

如何把华为手机上的数据转移到荣耀手机上?

方法/步骤 点击并进入华为手机&#xff08;旧手机&#xff09;的【手机克隆】应用&#xff0c;选择【这是旧设备】&#xff1b; 点击并进入荣耀手机&#xff08;新手机&#xff09;的【换机克隆】应用&#xff0c;选择【这是新设备】&#xff1b; 荣耀手机&#xff08;新…

LeetCode-第70题-爬楼梯

1.题目描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 2.样例描述 3.思路描述 画图就可以发现规律&#xff0c;典型的斐波那契额数列 4.代码展示 class Solution {public int climbStair…

webgis后端安卓系统部署攻略,超详细Termux攻略

目录 前言 一、将后端项目编译ARM64 二、安卓手机安装termux 1.更换为国内源 2.安装ssh远程访问 3.安装文件远程访问 三、安装postgis数据库 1.安装数据库 2.数据库配置 3.数据导入 四、后端项目部署 五、自启动设置 总结 前言 因为之前一直做的H5APP开发&#xf…

机器学习、深度学习、强化学习、迁移学习的关联与区别

Hi&#xff0c;大家好&#xff0c;我是半亩花海。本文主要了解并初步探究机器学习、深度学习、强化学习、迁移学习的关系与区别&#xff0c;通过清晰直观的关系图展现出四种“学习”之间的关系。虽然这四种“学习”方法在理论和应用上存在着一定的区别&#xff0c;但它们之间也…

2024幻兽帕鲁服务器创建教程_阿里PK腾讯超简单

幻兽帕鲁官方服务器不稳定&#xff1f;自己搭建幻兽帕鲁服务器&#xff0c;低延迟、稳定不卡&#xff0c;目前阿里云和腾讯云均推出幻兽帕鲁专用服务器&#xff0c;腾讯云直接提供幻兽帕鲁镜像系统&#xff0c;阿里云通过计算巢服务&#xff0c;均可以一键部署&#xff0c;鼠标…

深度学习-吴恩达L1W2作业

作业1&#xff1a;吴恩达《深度学习》L1W2作业1 - Heywhale.com 作业2&#xff1a;吴恩达《深度学习》L1W2作业2 - Heywhale.com 作业1 你需要记住的内容&#xff1a; -np.exp&#xff08;x&#xff09;适用于任何np.array x并将指数函数应用于每个坐标 -sigmoid函数及其梯度…

【编程题】合法括号的判断

合法括号的判断—难度&#xff1a;⭐⭐ 我的答案&#xff1a;错误 class Parenthesis {public:bool chkParenthesis(string A, int n) { // write code hereif (n % 2 ! 0) {return false;}stack<char> st;auto ch A.begin(); // cout<<"hello?"<&l…

react渲染流程是怎样的

整体流程&#xff1a; react的核心可以用uifn(state)来表示&#xff0c;更详细可以用&#xff1a; const state reconcile(update); const UI commit(state);上面的fn可以分为如下一个部分&#xff1a; Scheduler&#xff08;调度器&#xff09;&#xff1a; 调度任务&…

Netty应用(十一) 之 ChannelHandler Channel生命周期 @Sharable 心跳

目录 27.ChannelHandler总结 27.1 一些概念 27.2 到底有几个handler&#xff1f;真的只有你想的那样吗&#xff1f; 27.3 channel.writeAndFlush 和 ctx.writeAndFlush的区别 27.4 ByteBuf的创建和销毁 27.5 Channel的生命周期方法 27.5.1 handlerAdded 27.5.2 channelR…

VS Code主题设置(美化VS Code)

主题的具体效果放在了文章末尾&#xff0c;这篇文章后续也会进行更新 目录 切换整体主题&#xff08;整体主题&#xff09; 1.VS Code内置主题&#xff08;快捷键&#xff1a;CtrlK &#xff0c;CtrlT&#xff09; 1.VS Code左上角点击文件 2.选择首选项-->主题-->颜色…

理解JAVA EE设计模式

理解JAVA EE设计模式 在Web应用程序的设计和开发阶段,开发人员在开发类似的项目时可能会遇到相似的问题。每名开发人员可能会遇到的问题找出不同或相似的解决方案。但是,这导致一些时间和精力浪费在为相似的问题寻找解决方案上。因此,要啊节省时间和精力,需要记录常见问题…