写在前面:
🌟 欢迎光临 清流君 的博客小天地,这里是我分享技术与心得的温馨角落。📝
🎭 人生如戏,我们并非能选择舞台和剧本,但我们可以选择如何演绎 🌟感谢您的支持与关注,让我们一起在知识的海洋中砥砺前行~~~
文章目录
- 引言
- 一、控制算法编程基础
- 二、Carsim配置
- 1、整车参数获取与侧偏刚度计算
- 2、车辆状态与规划轨迹信息
- 三、路径规划与轨迹生成
- 1、路径规划代码概述
- 2、直线与圆弧子函数详解
- (1)直线函数使用方法
- (2)圆弧函数使用方法
- 3、路径拼接实例
- 4、Carsim路面设置
- 四、模型搭建与仿真运行
- 1、变量准备
- 2、预测模块实现
- 3、误差和曲率计算模块实现
- 4、AB模块 + LQR模块
- 5、前馈模块实现
- 6、避免代数环的延迟模块
- 7、仿真测试
- 五、总结
- 参考资料
引言
本篇博客是 自动驾驶控制算法 系列的第八节第Ⅲ部分。内容整理自 B站知名up主 忠厚老实的老王 的视频,作为博主的学习笔记,分享给大家共同学习。
本篇博客是最长的一节,主要讲解如何搭建模型。
大家有需要可以自己下载相关的代码模型,主页链接如下:
一、控制算法编程基础
在开始本节之前,首先要把第八节的第二部分 Carsim 设置给设置完毕。具体操作见第八节第Ⅱ部分:
【自动驾驶】控制算法(八)横向控制Ⅱ | Carsim 与 Matlab 联合仿真基本操作
在开始本节之前,首先要有算法准备,就是第八讲第一节的编程基础内容:
【自动驾驶】控制算法(八)横向控制Ⅰ | 算法与流程
编程就是照着算法流程图编写程序:
这是整个编程的核心,横向控制算法主要需要三类参数:
- 整车参数
- 车辆当前状态
- 规划轨迹信息
二、Carsim配置
1、整车参数获取与侧偏刚度计算
注意:质量只是弹簧上质量,不包括悬架质量,所以
计算侧偏刚度,先大概估计四轮垂向力的大小,在表上查垂向力对应的曲线,求斜率。
注意:侧偏刚度的单位是
注意:把风阻、空气动力学关掉。
暂时不考虑风阻,先简单再复杂,把空气动力学关掉。
其实风阻在控制中是很要命的因素,特别是在高速时,空气阻力会极大影响车轮的垂向力,垂向力变化,侧偏刚度就变了,导致 LQR 相关东西全都变了,所以风阻是很重要的因素,但如果讲风阻就太复杂了,先暂时先不考虑风阻,等以后学到时再去考虑风阻。
2、车辆状态与规划轨迹信息
所以做控制时不仅仅写控制算法,还要写规划算法,先把模型的框架搭建立起来,点Send to Simulink
。
三、路径规划与轨迹生成
1、路径规划代码概述
规划代码不是这一节的重点,所以规划代码已经事先写好了,看起来挺复杂,实际上就写了两个子函数,在设计路径时,调用这两个子函数把拼起来就可以了。规划代码如下:
routing_planning.m
2、直线与圆弧子函数详解
具体讲一下这两个子函数该怎么用,这两个子函数的名字是直线、圆弧。代码上半部分的内容是拼起来的路径,也就是要用的路径,暂时先注释掉。
(1)直线函数使用方法
(2)圆弧函数使用方法
3、路径拼接实例
本篇博客所演示的路径比较复杂,各种直线和圆弧拼在一起,具体路径如下图所示:
要设计比较好的路径,需要在直线和圆弧中间用回旋线做过渡,让曲率连续变化。但是因为规划并不是本篇博客的重点,所以就凑合用一用, count
是控制点的数量,选择点多一点的,这样控制效果相对会好一点。
4、Carsim路面设置
为了看起来更直观,把 Carsim 的路面也设置一下。
点Procedure
,在 3D Road
里面选
在车道这里选 two lines
,再点 stretch east
,在这里根据规划设计道路走向。
Rows
输入
straight
代表直线,
radius
代表圆弧。
圆弧转过的角度,即左转右转和规划的符号不一样,左转默认半径为正,右转默认半径为负。在规划代码里,若终点角度如果大于起点角度,就是左转;反之就是右转。在这里是根据半径来的,半径为负,就是右转;半径是正,就是左转。一定要把 Treat as loop
勾上,变成闭合曲线处理。
有很多连续弯道,路况算比较严苛。
四、模型搭建与仿真运行
1、变量准备
先跑一遍路径规划,就是Matlab变量工作区里要有路径才可以:
打开 Simulink 看一下控制模型,先做单位换算,把千米每小时换成米每秒,以及把角度换成弧度。建立 Matlab Function
模块,在里面编程。
这六个模块从逻辑顺序来上来说,从左往右写比较好,因为左边的输出是右边的输入,所以先写左边,再写右边。因此先写预测模块,在写代码之前先写上名字,因为模型比较复杂,先标上记号,要不然可能不知道哪根线对应哪个变量。
2、预测模块实现
predict_module
3、误差和曲率计算模块实现
计算模块需要车辆状态,还需要规划轨迹信息。所以规划要先把它写好,而且写好之后也必须跑一遍,规划代码和控制代码是独立的。所以在规划时,需要先把代码跑一下,在工作区里要有这些规划的变量。
在工作区里有这些变量后,才能传到 Simlink 模型里,
注意:
err_kappa_calculate_module
From Workspace
模块,从工作区里把变量导入到 Simlink 里必须要工作区里有
注意: From workspace
只能导行向量,能导列向量、不能导矩阵,也不能导结构体。实际上通过技巧操作可以导矩阵以及列向量,但省事点尽量变成行向量就可以了。
4、AB模块 + LQR模块
本来 LQR 模块应该最难写,也最复杂,但是很幸运 Matlab 自己有 LQR 模块包。用离线LQR,所以 LQR 变成了最好写的模块,而且 LQR 模块和 AB 计算模块是紧密联系的,所以把 AB 计算模块和 LQR 模块合在一起写。
先建立脚本文件,作为LQR离线查表的数据,代码如下:
lqr_offline.m
如何查表找和
这样的小数,对应哪个,用速度除,除出来是小数而不是整数,那怎么办呢?
离线 LQR 算法程序代码如下:
Workspace
里有
LQR中的权重矩阵
和
只要记住两句话即可:
-
控制量 -
过程比较平缓比较重要,因为要保证平缓、舒适性、安全性。
模块写好之后,用 Simlink 拼起来即可。
5、前馈模块实现
forward_control
最后把所有结果整合起来即可。
last_angle
这样所有代码就都写完了,把它打个包封装成子系统,看起来整洁一点。
最后算出来前轮转角,再反馈给 Carsim 的前轮转角即可。
注意:单位换算弧度,要化成角度才能输入到 Carsim, Carsim 根据角度控制,不是根据弧度控制的。
6、避免代数环的延迟模块
在算出角度的线上再加延迟模块,作用是如果输入是这一时刻的值,输出是上时刻的值,它就等于延迟单元。这是为了避免代数环,即输入直接决定输出,输出又直接决定输入,会导致套娃式循环。所以为了打破循环就要加延迟模块来避免代数环。
7、仿真测试
可能觉得是个椭圆而不是圆,这是因为横坐标和纵坐标间隔不完全一样,横坐标要宽一点,纵坐标窄一点,所以看起来不太像是圆,而像是椭圆,实际上应该是个圆。
看一下算出来的前端转角,其实是不太好的,有的地方在不停鬼畜,不停地抖来抖去,其实不是一件好事情。
在有的地方突变太厉害,突然猛的打一下方向盘,在转弯时打得非常快。算法写出来有利有弊,方向盘打的太快了,而且方向盘在转弯时,不停的鬼畜抖来抖去,这是无法接受的。
但是也有好的地方,至少控制的跟踪效果做出来了,确实是按照所规划的轨迹在跑,而且规划的轨迹是比较严苛的。
转弯半径很小,而且有很多很急的弯,结果也算勉强能跟上,在没有做纵向控制且在不停加速的情况下,仍然勉强能跟上规划的轨迹,所以有一定的控制效果,但舒适性并不是特别好,方向盘在不停抖来抖去。
为什么会导致方向盘在鬼畜?而且在转弯时,方向盘会猛的突变?
这是有原因的,在下一节会讲算法性能不好的原因以及怎么改进。
五、总结
本节博客详细介绍了自动驾驶控制算法的建模过程,涵盖了从Carsim设置到模型搭建的各个方面。通过配置Carsim软件,获取整车参数并计算侧偏刚度,为后续的控制算法提供基础数据。
通过编写路径规划代码,生成所需的轨迹信息。在Matlab中,搭建了控制模型的各个模块,包括预测模块、误差和曲率计算模块、AB模块和LQR模块、前馈控制模块等。
最后,将模型整合并进行了仿真测试,展示了控制算法对规划轨迹的跟踪效果。
大家不妨在这一节照着思路把模型搭好,在下一节就会告诉各位怎么调模型,使其更平顺。欢迎关注后续内容!
参考资料
后记:
🌟 感谢您耐心阅读这篇关于 自动驾驶横向控制算法代码与模型 的技术博客。 📚
🎯 如果您觉得这篇博客对您有所帮助,请不要吝啬您的点赞和评论 📢
🌟您的支持是我继续创作的动力。同时,别忘了收藏本篇博客,以便日后随时查阅。🚀
🚗 让我们一起期待更多的技术分享,共同探索移动机器人的无限可能!💡
🎭感谢您的支持与关注,让我们一起在知识的海洋中砥砺前行 🚀