当前位置: 首页 > news >正文

自动驾驶控制与规划——Project 2: 车辆横向控制

目录

  • 零、任务介绍
  • 一、环境配置
  • 二、算法
  • 三、代码实现
  • 四、效果展示

零、任务介绍

  1. 补全src/ros-bridge/carla_shenlan_projects/carla_shenlan_stanley_pid_controller/src/stanley_controller.cpp中的TODO部分。

一、环境配置

上一次作业中没有配置docker使用gpu,后续可能有GPU计算的需求,因此重新运行一个带有GPU的容器。docker使用GPU的配置教程可以参考:在docker容器中使用nvidia显卡渲染rviz2界面。运行容器的命令如下:

docker run -d --net=host -it --name foxy_gpu --gpus all -e NVIDIA_DRIVER_CAPABILITIES=all\-v /home/star:/home/star \-v /tmp/.X11-unix:/tmp/.X11-unix \-v /dev:/dev \-v /dev/dri:/dev/dri \--env DISPLAY=unix:1 \--env ROS_DISTRO=foxy \fishros2/ros:foxy-desktop

二、算法

Stanley控制使用前轮中心作为参考点,根据轨迹上距离参考点最近的点计算偏航误差和横向误差。
在这里插入图片描述
首先根据参考点的heading和车的heading计算偏航误差 θ e \theta_e θe。然后考虑横向误差,由几何关系可得
tan ⁡ δ e = e d , d = v / k \begin{aligned} \tan \delta_e = \frac{e}{d}, d = v/k \end{aligned} tanδe=de,d=v/k
可得
δ e = tan ⁡ − 1 k e v \delta_e = \tan^{-1} \frac{ke}{v} δe=tan1vke
此处的增益 k k k根据实验调整。结合上述两个误差项可以得到Stanley控制律
δ ( t ) = θ e ( t ) + tan ⁡ − 1 k e ( t ) v ( t ) \delta(t) = \theta_e(t) + \tan^{-1}\frac{ke(t)}{v(t)} δ(t)=θe(t)+tan1v(t)ke(t)
观察上述控制律可以发现,当车速 v v v较低时,即便是比较小的横向误差 e e e也会引起反正切函数的剧烈变化,因此在分母上增加一项常数,控制律变为
δ ( t ) = θ e ( t ) + tan ⁡ − 1 ( k e ( t ) k s + v ( t ) ) \delta(t) = \theta_e(t) + \tan^{-1}\left(\frac{ke(t)}{k_s + v(t)} \right) δ(t)=θe(t)+tan1(ks+v(t)ke(t))
当车速较快时,如果轨迹的偏航角变化较大,直接跟踪会导致车辆横向振荡,因此可以在 θ e \theta_e θe中加入阻尼,即增加PD控制器。综上所述,最终的Stanley控制器如下
δ = P D ( θ ) + tan ⁡ − 1 ( k e ( t ) k s + v ( t ) ) \delta = PD(\theta) + \tan^{-1}\left(\frac{ke(t)}{k_s + v(t)} \right) δ=PD(θ)+tan1(ks+v(t)ke(t))

三、代码实现

此处使用的PD控制器可以参考上一个project中的实现方法自动驾驶控制与规划——Project 1: 车辆纵向控制。为了避免低速行驶时的横向振荡,加入参数 k s k_s ks

class StanleyController {
public:StanleyController(){};~StanleyController(){};void LoadControlConf();void ComputeControlCmd(const VehicleState &vehicle_state,const TrajectoryData &planning_published_trajectory,ControlCmd &cmd);void ComputeLateralErrors(const double x, const double y, const double theta,double &e_y, double &e_theta);TrajectoryPoint QueryNearestPointByPosition(const double x, const double y);protected:std::vector<TrajectoryPoint> trajectory_points_;double k_y_ = 0.0;double k_s_ = 0.0;	// 低速行驶时v小,较小的e也会导致atan振荡double u_min_ = 0.0;double u_max_ = 100.0;double theta_ref_;double theta_0_;
};
} // namespace control
} // namespace shenlan

这里的参数可以根据实验效果进行调整

void StanleyController::LoadControlConf() {k_y_ = 0.5;k_s_ = 0.5;
}

控制器整体的流程是:1.计算heading error;2.计算cross tracking error;3.利用Stanley控制器计算控制指令。需要注意对输出进行限幅。

void StanleyController::ComputeControlCmd(const VehicleState &vehicle_state, const TrajectoryData &planning_published_trajectory, ControlCmd &cmd) {trajectory_points_ = planning_published_trajectory.trajectory_points;// find the closest point on the reference trajectoryTrajectoryPoint nearest_pt = QueryNearestPointByPosition(vehicle_state.x, vehicle_state.y);// theta_ref_在QueryNearestPointByPosition中已经更新了// get lateral error and heading errordouble e_y = 0.0;double e_theta = 0.0;ComputeLateralErrors(vehicle_state.x - nearest_pt.x, vehicle_state.y - nearest_pt.y, vehicle_state.heading, e_y, e_theta);double e_theta_pd = e_theta_pid_controller.Control(e_theta, 0.01);cmd.steer_target = e_theta_pd + atan2(k_y_ * e_y, vehicle_state.velocity + k_s_);// 输出限幅if (cmd.steer_target > 1.0) {cmd.steer_target = 1.0;} else if (cmd.steer_target < -1.0) {cmd.steer_target = -1.0;}
}

在计算误差时需要注意,横向误差是带有方向的,以车辆朝向为参考,左正右负。偏航误差在计算时超过 [ − π , π ) [-\pi, \pi) [π,π)的需要重新标准化到 [ − π , π ) [-\pi, \pi) [π,π)中。

void StanleyController::ComputeLateralErrors(const double x, const double y, const double theta, double &e_y, double &e_theta) {// 车头方向的单位矢量 (cos(theta), sin(theta))// 横向误差以车辆朝向为参考,左正右负e_y = cos(theta) * y - sin(theta) * x;e_theta = theta - theta_ref_;if (e_theta <= -M_PI) {e_theta += 2 * M_PI;} else if (e_theta >= M_PI) {e_theta -= 2 * M_PI;}std::cout << "theta: " << theta << " theta_ref_: " << theta_ref_ << std::endl;std::cout << "e_theta: " << e_theta << std::endl;
}

四、效果展示

在宿主机启动carla仿真器

./CarlaUE4.sh -carla-rpc-port=2000 -prefernvidia

在docker容器中启动carla-ros-bridge

ros2 launch carla_shenlan_bridge_ego_vis carla_bridge_ego_vehicle.launch.py

启动控制节点

ros2 run carla_shenlan_stanley_pid_controller carla_shenlan_stanley_pid_controller_node

运行效果如下:

自动驾驶控制与规划——Project 2: 车辆横向控制

相关文章:

自动驾驶控制与规划——Project 2: 车辆横向控制

目录 零、任务介绍一、环境配置二、算法三、代码实现四、效果展示 零、任务介绍 补全src/ros-bridge/carla_shenlan_projects/carla_shenlan_stanley_pid_controller/src/stanley_controller.cpp中的TODO部分。 一、环境配置 上一次作业中没有配置docker使用gpu&#xff0c;…...

Bootstrap-HTML(五)图像基础样式

Bootstrap-HTML&#xff08;五&#xff09;图像基础样式 前言一、圆角图片二、圆形图片三、缩略图四、对齐图像五、图片居中六、响应式图片 前言 在之前的博客中&#xff0c;我们已经详细了解了 Bootstrap5 中诸多实用的组件和样式类&#xff0c;比如徽章与表格等&#xff0c;…...

bain.js(十二):RNN神经网络实战教程 - 音乐乐谱生成 -人人都是作曲家~

系列文章&#xff1a; &#xff08;一&#xff09;&#xff1a;可以在浏览器运行的、默认GPU加速的神经网络库概要介绍&#xff08;二&#xff09;&#xff1a;项目集成方式详解&#xff08;三&#xff09;&#xff1a;手把手教你配置和训练神经网络&#xff08;四&#xff09…...

Endnote | 查看文献所在分组

软件版本&#xff1a;Endnote X8 第一种方式&#xff1a; 在文献上右键——记录摘要&#xff0c;即可在弹出页面上看到自定义和智能组的分组情况。 第二种方式&#xff1a; 在菜单栏点击文献——记录摘要&#xff0c;也可以查看分组情况。 注&#xff1a; 新版本的endnote软件…...

DateRangePickerDialog组件的用法

文章目录 概念介绍使用方法示例代码我们在上一章回中介绍了DatePickerDialog Widget相关的内容,本章回中将介绍DateRangePickerDialog Widget.闲话休提,让我们一起Talk Flutter吧。 概念介绍 我们在这里说的DateRangePickerDialog是一种弹出窗口,只不过窗口的内容固定显示为…...

数据库合并操作:深入理解 MERGE INTO 语句

在数据管理和操作中&#xff0c;我们常常面临着将源数据合并到目标表中的需求。无论是对现有记录进行更新&#xff0c;还是对缺失的记录进行插入&#xff0c;甚至有时候需要删除不再符合条件的记录&#xff0c;这些操作通常都需要多条 SQL 语句来完成。然而&#xff0c;SQL 中有…...

联发科MTK8788_MT8788安卓核心板安兔兔跑分_安卓主板方案商

MT8788安卓核心板具有集成的蓝牙、fm、WLAN和gps模块&#xff0c;是一个高度集成的基带平台&#xff0c;包括调制解调器和应用处理子系统&#xff0c;启用LTE/LTE-A和C2K智能设备应用程序。该芯片集成了工作在2.0GHz的ARM Cortex-A73、最高可达2.0GHz的ARM Cortex-A53和功能强大…...

计算机网络技术基础:6.数据传输方式

数据传输是指利用信号把数据从发送端传送到接收端的过程&#xff0c;通常可以从多个不同的角度对数据传输方式进行描述。 一、并行传输和串行传输 数据在信道上传输时&#xff0c;按照使用信道的多少可以分为串行传输和并行传输两种方式。 1.串行传输 在计算机中&#xff0c;…...

免费开源了一个图床工具 github-spring-boot-starter

文章目录 第一步&#xff0c;新建一个SpringBoot项目第二步&#xff0c;在pom文件里面引入jar包第三步&#xff0c;配置你的github信息github.authorization1、进入github官网&#xff0c;登录账号&#xff0c;点击头像&#xff0c;选择setting2、选择[Developer Settings](htt…...

Mysql之YUM安装时GPG 密钥报错问题处理

一、背景说明 使用YUM安装mysql5.7的时候报错&#xff0c;报错信息提示未安装公钥。博主查看/etc/yum.repos.d/mysql-community.repo配置文件中关于公钥的配置&#xff0c;确实启用了公钥验证&#xff0c;博主再排查过程中还是走了一些弯路&#xff0c;最终顺利解决了&#xff…...

Hw亮度省电

1. 亮度控制策略 /decompile-hw/decompile/app/HwPowerGenieEngine3/src/main/res/xml/backlight_policy.xml <?xml version"1.0" encoding"utf-8"?> 2 <backlight_policy xmlns:android"http://schemas.android.com/apk/res/android&qu…...

【信息系统项目管理师-论文真题】2015下半年论文详解

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 论题一:大项目或多项目的成本管理解题思路写作要点论题二:项目的采购管理解题思路写作要点论题一:大项目或多项目的成本管理 随着移动互联网、物联网、云计算、大数据等新一代信息技术的广泛应用,我国目前…...

django的model中定义【记录修改次数】的这个字段该用什么类型

django中定义对于某个文章应用的数据库中使用到记录修改次数的这个字段 如models.py中的配置 from django.db import models from django.utils import timezone from django.contrib.postgres.fields import ArrayFieldclass Article(models.Model):# Titlestitle_cn model…...

windows openssl编译x64版libssl.lib,编译x64版本libcurl.lib,支持https,vs2015编译器

不要纠结&#xff0c;直接选择用perl编译&#xff01; 告诫想要用弄成vs编译版的&#xff0c;暂时先别给自己增加麻烦 告诫&#xff0c;以下执行的每一步&#xff0c;都不要纠结 先安装环境 nasm 64位版本 https://www.nasm.us/pub/nasm/releasebuilds/2.16.01/win64/nasm-…...

搭建 Elasticsearch 集群:完整教程

本文将详细介绍如何在 Linux 环境下搭建一个 Elasticsearch 集群&#xff0c;涵盖环境准备、配置优化、服务启动等多个环节。 一、环境准备 创建安装目录 mkdir /es cd /es解压 Elasticsearch 安装包 tar -xzf elasticsearch-7.10.1-linux-x86_64.tar.gz -C /es配置环境变量 编…...

如何实现序列化和反序列化?如何处理对象的生命周期管理?

序列化和反序列化 实现思路&#xff1a; 序列化&#xff1a;将对象的状态信息转换为可以存储或传输的格式&#xff0c;通常是字节流。 确定要序列化的对象的数据成员。将这些数据成员按照一定的规则&#xff08;如二进制、文本、JSON、XML 等&#xff09;编码为字节序列。将生…...

WPF+MVVM案例实战与特效(三十八)- 封装一个自定义的数字滚动显示控件

文章目录 1、运行效果2、案例实现1、功能设计2、页面布局3、控件使用4、运行效果3、拓展:多数字自定义控件1、控件应用4、总结1、运行效果 在Windows Presentation Foundation (WPF)应用程序中,自定义控件允许开发者创建具有特定功能和外观的独特UI元素。本博客将介绍一个名…...

docker安装Redis、docker使用Redis、docker离线安装redis、Redis离线安装

服务器到期了&#xff0c;换了一个新的环境要重搭&#xff0c;就记录一下好了&#xff1a; -----docker在线安装Redis 拉取 Redis 镜像 docker pull redis:6.2 运行 Redis 容器 docker run --name redis -d redis docker run --name redis -d redis:6.2 映射端口 docker run -…...

单目动态新视角合成

目录 单目动态新视角合成 Generative Camera Dolly:Extreme Monocular Dynamic Novel View Synthesis 单目动态新视角合成 Generative Camera Dolly: Extreme Monocular Dynamic Novel View Synthesis Generative Camera Dolly: Extreme Monocular Dynamic Novel View Synth…...

STM32--IO引脚复用

IO引脚复用...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...