【自动驾驶】控制算法(十一)深度解析车辆纵向控制 | 纵向双 PID 控制算法

写在前面:
🌟 欢迎光临 清流君 的博客小天地,这里是我分享技术与心得的温馨角落。📝
个人主页:清流君_CSDN博客,期待与您一同探索 移动机器人 领域的无限可能。

🔍 本文系 清流君 原创之作,荣幸在CSDN首发🐒
若您觉得内容有价值,还请评论告知一声,以便更多人受益。
转载请注明出处,尊重原创,从我做起。

👍 点赞、评论、收藏,三连走一波,让我们一起养成好习惯😜
在这里,您将收获的不只是技术干货,还有思维的火花

📚 系列专栏:【运动控制】系列,带您深入浅出,领略控制之美。🖊
愿我的分享能为您带来启迪,如有不足,敬请指正,让我们共同学习,交流进步!

🎭 人生如戏,我们并非能选择舞台和剧本,但我们可以选择如何演绎 🌟
感谢您的支持与关注,让我们一起在知识的海洋中砥砺前行~~~


文章目录

  • 引言
  • 一、Carsim 软件设置
    • 1.1 初速度
    • 1.2 制动与转向
    • 1.3 变速器
    • 1.4 输入输出
    • 1.5 仿真时间
  • 二、整合油门刹车标定表
    • 2.1 整合必要性
    • 2.2 油门采集程序
    • 2.3 刹车采集程序
    • 2.4 数据处理
  • 三、油门刹车表定标的应用
    • 3.1 使用标定表进行纵向控制
    • 3.2 加速度策略与速度匹配
    • 3.3 模型运行与初步结果分析
    • 3.4 加入 PID 控制器以优化控制效果
      • (1) 比例控制器
      • (2) 积分控制器
      • (3) 微分控制器
  • 四、PID 算法各项的作用
    • 4.1 比例项
    • 4.2 积分项
    • 4.3 微分项
    • 4.4 微分项与积分项的对比
      • (1) 微分项的预测作用
      • (2) 积分项的滞后作用
  • 五、PID参数整定
    • 5.1 整定顺序
    • 5.2 比例参数的调整
    • 5.3 积分参数的调整
    • 5.4 微分参数的调整
  • 六、横纵向控制
    • 6.1 参考轨迹生成
    • 6.2 参数调整
    • 6.3 模型打包
  • 七、进阶学习
  • 八、总结
  • 参考资料


引言

  各位小伙伴们大家好,本篇博客是自动驾驶控制算法第 11 节,在第 9 节和第 10 节讲了如何制作电机模型、怎么做油门刹车标定表,本篇博客讲解如何用标定表做纵向控制。内容整理自 B站知名up主 忠厚老实的老王 的视频,作为博主的学习笔记,分享给大家共同学习。


一、Carsim 软件设置

1.1 初速度

  首先看一下软件的设置,用 GitHub 上的代码跑出问题的很大原因就是初速度,初速度是不是为 0 0 0?如果初速度如果不是 0 0 0 ,就会出错。

1.2 制动与转向

  除了初速度之外,还有制动以及转向,不要做任何在 Carsim 软件里预设的制动和转向,而要在 Simulink 上去做。

在这里插入图片描述

1.3 变速器

  Carsim 默认的变速器是五档的,要改成一档变速器,把换挡的时间改短一点,也就是认为没有换挡,像电动车一样。

在这里插入图片描述

1.4 输入输出

  选择 Choose run to get export information,在里面选择最上面 Quick Start 里的 Baseline

  • 输入:发动机的扭距以及制动压力
  • 输出: v x v_x vx a x a_x ax 以及发动机转速 AV_Eng

可以根据单位用 Select by units 选择:

在这里插入图片描述

1.5 仿真时间

  最后把仿真的时间改长一点,因为做纵向标定时,特别是快速减速的话,需要很长时间才能停下来,所以要把时间弄改长一点:

在这里插入图片描述

  一切准备就绪后,点击 Send to simulink


二、整合油门刹车标定表

2.1 整合必要性

  现在希望把油门和刹车做到一张表上,这样就不需要两个表了,所以先做一张总表,不需要两个分开的刹车油门表,这主要是要考虑控制的连续性,做到一张表上,油门和刹车可以在一些没采到的点做插值处理。

  如果把它做到一张表,会变得更加平顺,如果是两个表的话,从零开始到加速还好,但是一旦从比较高的速度减速,如果是两个表就很难过渡,比如规划速度是 10 m / s 10m/s 10m/s,但现在速度是 50 m / s 50m/s 50m/s,要减速的话,一开始肯定会会猛踩刹车,但是一旦刹车已经踩到让车速已接近 10 10 10 时,如果调教不好,可能会出现一下子刹车过头的现象,速度右就小于 10 10 10 了,此时,系统又可能过度补偿,导致速度超过 10 m / s 10 m/s 10m/s,从而产生振荡现象,即速度忽高忽低,无法稳定在目标值附近。

  这种振荡现象主要由于两个表之间缺乏有效的协调机制。在减速过程中,系统需要同时调整油门和刹车,才能实现平稳过渡。而两个表的结构难以实现这种复杂的控制逻辑,导致系统出现过度反应和补偿。

  相比之下,使用一张油门刹车总表可以实现更平滑的控制,可以自动进行插值,因此可以根据当前速度和目标速度,计算出合适的加速度值,从而实现平稳过渡。

  定义统一的油门刹车信号 x x x,如果是正数,就代表油门;负数代表刹车,但此信号还不能直接用,因为要接在油门和刹车上,所以还要写函数来切换。函数的输入是 x x x,输出就是油门和刹车。

function [thr,brake] = fcn(x)%正数代表油门,负数代表刹车%不允许同时踩油门和刹车if x>=0thr=x;%把油门赋值给xbrake=0;%把刹车弄设为0。elsethr=0;%把油门设为0brake=-x;%刹车设为-xend

  刹车本质是制动压力,制动压力的数值也是正的,所以要加负号。比如 x = − 1 x=-1 x=1,就代表刹车的压力是 1 M P a 1MPa 1MPa,所以要加负号。

  一切准备就绪后,编写标定程序,分成三个部分:首先油门采集代码、刹车采集代码、数据处理。

2.2 油门采集程序

throttle_calibration.m

thr=0;%初始化油门
for i=1:21%该程序非常耗时,如果需要更多更密集的数据,请先测试sim('calibration');v_temp(:,i)=vx.data;a_temp(:,i)=ax.data;thr_temp(:,i)=ones(length(vx.data),1)*thr;thr=thr+0.1;
end%合并,一定要转成行向量再合并,否则会导致合并失败
v=v_temp(:,1)';
a=a_temp(:,1)';
tr=thr_temp(:,1)';
for i=2:length(a_temp(1,:))v=[v,v_temp(:,i)'];a=[a,a_temp(:,i)'];tr=[tr,thr_temp(:,i)'];
end%拟合
F=scatteredInterpolant(v',a',tr');%转成列向量
vu=0:0.1:50;
au=0:0.1:5;
table=zeros(length(vu),length(au));
for i=1:length(vu)for j=1:length(au)table(i,j)=F(vu(i),au(j));end
end

2.3 刹车采集程序

  在刹车代码有不一样的地方,就是初速度。在标定刹车时,初速度必须要很大, 180 k m / h 180km/h 180km/h 144 k m / h 144km/h 144km/h,不能为 0 0 0,这样车就不动了。因此必须要比较大的初速度,然后再标定刹车,其他的代码差不多。刹车代码和油门有点区别。

brake_calibration.m

%启动前检查车的初速度是否为180
x=0;%初始化刹车
%%刹车的初速度一定要比较高,180km/h、144km/h
for i=1:81%该程序非常耗时,如果需要更多更密集的数据,请先测试sim('calibration');v_temp1(:,i)=vx.data;a_temp1(:,i)=ax.data;brake_temp1(:,i)=ones(length(vx.data),1)*x;%%%%这里是消除奇异性,因为无论brake=1还是2,最后都会导致车的v,a=0;这将导致多值性for j=1:length(v_temp1(:,i))if v_temp1(j,i)<0.01%如果的车速足够小的话brake_temp1(j,i)=0;%那就不要踩了,就让他用摩擦力去制动,这样的话就会消除奇异性end        endx=x-0.1;%每做循环, x 是要减0.1
end
a_temp1(1,:)=a_temp1(2,:);%避免初始化的问题,防止数据出现跳跃%合并,一定要转成行向量再合并,否则会导致合并失败
vbr=v_temp1(:,1)';%要起新的名字,免得油门数据被覆盖
abr=a_temp1(:,1)';
br=brake_temp1(:,1)';
for i=2:length(v_temp1(1,:))vbr=[vbr,v_temp1(:,i)'];abr=[abr,a_temp1(:,i)'];br=[br,brake_temp1(:,i)'];
end

2.4 数据处理

大家可以想想为什么油门刹车它不能写在一份代码里,非要写两份代码。

  因为油门和刹车的初速度是要求不一样,油门的初速度要求从 0 0 0 开始慢慢增大,而刹车要求从 180 180 180 或者 144 144 144 开始逐渐减小到 0 0 0。所以必然要做两个设置,首先要初速度设为 0 0 0 跑一次,然后把初速度改成 180 180 180 或者 144 144 144 才可以再跑一次。所以无论如何油门和刹车的标定都不能写到一份代码里。

  一切准备就绪后,开始跑就行了,跑完之后就检查一下数据,看一下有没有问题。

  把初速度改成 180 180 180,再点 Send to simulink,一定要点,不点就白做了。然后再跑刹车程序,刹车标定要远比油门慢,因为刹车代码的循环多,所以如果有人觉得拿不准的话,建议先少跑几个循环,看一下数据到底对不对,数据对了再多加循环

  看一下第三份数据处理代码:

v2=[v,vbr];
a2=[a,abr];
br2=[tr,br];F=scatteredInterpolant(v2',a2',br2');%转成列向量
vubr=0:0.05:50;
aubr=-8:0.05:5;%合并刹车的-8到0和油门的0到5
tablebr=zeros(length(vubr),length(aubr));
for i=1:length(vubr)for j=1:length(aubr)tablebr(i,j)=F(vubr(i),aubr(j));end
end

  其实就把前两份代码,[v,vbr][a,abr][tr,br] 合并起来,然后进行拟合,再制作总表。

  总表就是油门刹车合并的总表,还是和以前一样用 2-D look up table 把表附到 Simulink 里,这样把系统打包后就可以用总表了。

在这里插入图片描述

  把里面的变量设置一下,需要当前的速度 v v v 以及期望加速度 a a a 作为输入,输出就是油门和刹车。

在这里插入图片描述


三、油门刹车表定标的应用

  下面看一下怎么用这张表。

3.1 使用标定表进行纵向控制

  比如现在希望期望速度是 10 10 10,首先把 Carsim 的初速度改成 0 0 0,然后 Send to Simulink。使用简单的 PID 控制,在上一讲已经简略地演示过怎么控制纵向速度。就是速度和加速度要相匹配。以现在的模型举例子,比如期望速度是 10 10 10,但实际肯定是从初速度 0 0 0 开始,加速度策略要和期望速度匹配。

3.2 加速度策略与速度匹配

  为了让速度和加速度匹配,需要确保加速度能够根据速度与目标速度之间的差距进行动态调整。理想情况下,初始阶段加速度应较大,以快速提升速度;随着速度接近目标值,加速度应逐渐减小,直至达到目标速度时,加速度归零。这种匹配关系可以实现平稳、无振荡的运动。

  PID (比例-积分-微分) 算法 是自动控制领域常用的算法,可以有效实现加速度的匹配。在PID控制中,期望速度与当前速度的差值作为误差信号输入。PID 控制器根据误差信号计算控制量,并通过调整加速度来实现对速度的精确控制。

  具体来说,PID 控制器包含三个参数:比例 ( P P P)、积分 ( I I I) 和微分 ( D D D)。比例项根据当前误差的大小来调整加速度,积分项用于消除误差的累积,微分项用于预测误差的变化趋势,并提前进行调节。通过调整这三个参数,可以使PID控制器输出合适的加速度信号,满足“初始阶段加速度大,接近目标时加速度小,达到目标时加速度为零”的控制要求。

3.3 模型运行与初步结果分析

  下面来跑一下模型,结果果是这样:

在这里插入图片描述

  可以看到确实有控制效果,但观察结果发现,速度并未精确达到 10 m / s 10m/s 10m/s,而是略低于该值。分析原因,可能是由于速度逐渐接近目标值时,期望速度与实际速度之间的差值逐渐减小,导致 PID 控制器的加速度输出也随之减小,最终无法克服惯性,使速度达到目标值。

3.4 加入 PID 控制器以优化控制效果

  为了解决这一问题,可以适当增加PID控制器中的比例项 ( P P P)。比例项的大小决定了控制器对误差的响应程度。增加比例项可以使控制器在速度接近目标值时,仍保持一定的加速度输出,从而确保速度能够准确达到目标值。

在这里插入图片描述

  在PID控制算法中,比例项 ( P P P) 是基于期望速度与实际速度之间的差值进行计算的。该差值信号乘以比例项后,输出为加速度信号。这种控制方式能够实现匹配的加速度

  注意:比例项的取值会影响控制效果。如果比例项过大,可能导致系统超调或振荡。

  因此,需要对比例项的输出进行限制,例如将其限制在 − 8 -8 8 5 5 5 的范围内,以防止输出过大或过小,从而影响系统的控制精度和稳定性。加入限制后看看结果:

在这里插入图片描述

(1) 比例控制器

  比例项 ( P P P) 在PID控制算法中起着放大加速度信号的作用。当实际速度与期望速度的差距逐渐缩小时,比例项的输出会相应减小,导致加速度输出也逐渐减小,从而避免速度超过期望值。但比例项的取值并非越大越好。过大的比例项会导致系统对误差信号过于敏感,即使是很小的误差也会引起较大的加速度输出,从而造成系统波动和超调,影响控制精度和稳定性。

  此处就不用增益模块了,直接加 PID 模块上去:

在这里插入图片描述

  在PID控制算法中,比例项 ( P P P) 代表对误差信号的直接响应。其输出与误差信号成正比,即误差越大,比例项输出越大。通过调整比例项系数,可以放大或缩小加速度信号,从而控制系统的响应速度。例如,将比例项系数设置为 2 2 2,则输出信号将变为原来的两倍,而将微分项和积分项系数设置为 0 0 0,则忽略微分和积分对控制的影响。

(2) 积分控制器

  下面看一下积分项的作用,先把 I I I 设成 0.1 0.1 0.1,然后把 P P P 设成 2 2 2,看一下仿真效果。

在这里插入图片描述

  观察速度曲线可以发现,系统存在明显的超调现象,但最终能够收敛到 10 m / s 10m/s 10m/s。这说明比例项 ( P P P) 能够有效地响应误差信号,并使速度逐渐接近期望值。但系统在达到稳态时仍存在一定的误差,即实际速度与期望速度之间存在微小的差距。

  为了消除稳态误差,PID控制算法引入了积分项 ( I I I)。积分项的作用是对误差信号进行积分,并将积分值作为输出信号。只要实际速度与期望速度之间的差值不为零,积分项就会持续积分,从而逐渐减小误差,直至消除稳态误差。然而,积分项的引入也可能导致系统超调,即实际速度超过期望值后再逐渐回落。

  积分项系数的取值会影响积分项对控制的影响程度。系数越大,积分作用越强,消除稳态误差的效果越明显,但超调现象也可能更加严重。因此,需要根据实际情况调整积分项系数,以实现最佳的稳态误差消除效果和控制稳定性。

  积分控制器 ( I I I) 在PID控制算法中发挥着重要作用。尽管积分控制器会导致系统超调,但它能够有效地消除稳态误差。这是因为积分控制器会持续对误差信号进行积分,并随着时间推移,积分值会逐渐增大,从而持续减小误差,直至稳态误差消失。

  与比例控制器 ( P P P) 不同,比例控制器的输出仅与当前误差信号成正比。即使比例系数设置得很大,当误差信号足够小,比例控制器的输出也会随之减小,最终失去控制作用。而积分控制器则不受此限制,只要误差存在,积分控制器就会持续工作,直至消除稳态误差。

  然而,积分控制器的缺点是容易导致系统超调,即实际速度超过期望值后再逐渐回落。这是因为积分控制器对误差信号的持续积分会导致输出信号过大,从而使系统响应过度。因此,需要合理设置积分控制器系数,并在必要时与其他控制器配合使用,以避免超调现象。

(3) 微分控制器

  微分控制器 ( D D D) 是PID控制算法的最后一个组成部分,其作用是对误差信号进行微分处理。微分控制器能够预测误差信号的变化趋势,并提前进行调节,从而抑制系统的振荡和超调现象。

  由于实际信号是离散的,无法进行数学意义上的解析微分,因此微分控制器需要进行数值微分处理。数值微分容易引入噪声和振荡,因此需要对微分信号进行滤波处理,以去除噪声并平滑信号。

  滤波参数的选择会影响微分控制器的性能。滤波参数越大,滤波效果越明显,但也会导致微分控制器对误差信号变化的响应延迟。因此,需要根据实际情况调整滤波参数,以实现最佳的滤波效果和控制性能。此处滤波参数写 10 10 10

在这里插入图片描述

下面一下微分器的作用,给数值 0.1 0.1 0.1,跑一下看看效果。

在这里插入图片描述

  微分项在PID控制中的作用是抑制超调现象。当比例项导致系统出现超调时,微分项便开始发挥作用。在实际应用中,比例项之所以会引起超调,是因为信号存在延迟。与仿真环境不同,实际系统中的信号响应并非瞬时完成。无论是刹车、油门操作,还是发动机和电机的启动,都存在一定的响应时间。

  这种延迟导致当比例项作用时,系统可能会产生超调,因为在仿真中假设信号是瞬间到达的,而在实际中则不是这样。因此,微分项在仿真中可能不会显现出其作用,但在实际应用中,它是必要的,以补偿信号延迟带来的影响。

  可以通过模拟来理解这一点,假设从发出油门或刹车信号到电机或制动系统开始响应之间存在 100 m s 100ms 100ms 的延迟,并且速度数据从传感器传到控制系统的延迟为 10 m s 10ms 10ms。这些延迟在实际系统中是常见的,尤其是对于发动机来说,延迟可能会更长,而电机则可能相对快一些。

  把 PID 的微分项 ( D ) (D) (D) 设为 0.1 0.1 0.1,看一下结果:

在这里插入图片描述

  观察系统响应可以发现,在包含微分项的情况下,系统几乎不会出现超调现象。但如果移除微分项并重新运行系统,将会观察到系统开始震荡,并且出现了超调。这表明微分项的主要作用是抑制超调。


四、PID 算法各项的作用

  PID控制器中的三个组成部分——比例( P P P)、积分( I I I)和微分( D D D)——通常是联合使用的。积分项的作用是消除稳态误差,但它也可能导致超调。为了减少这种超调,我们使用微分项。

4.1 比例项

  比例项的作用是加速信号达到目标速度的过程。如果比例系数设置得较大,系统响应会更快,从而迅速接近期望速度。相反,如果比例系数很小,例如 0.001 0.001 0.001,即使加速度很大,系统达到期望速度的过程也会非常缓慢。

  因此,比例项用于调节速度,但过大的比例系数可能导致超调。理论上,比例项本身不会引起超调,但由于实际系统中存在延迟,它可能会导致超调,此时就需要微分项来消除超调。

4.2 积分项

  积分项在控制系统中并不经常使用,尽管它能消除稳态误差,但它可能引起较大的超调,并且消除这些超调相对困难。因此,除非系统误差非常大,否则通常不使用积分项。

  在大多数控制场合,使用PD控制器就足够了。在实际车辆控制中,并不追求速度严格等于某个特定值,只要误差在可接受的范围内即可。过于追求精度在实际情况中并没有太大意义,只要精度达到容忍的范围内就足够了。

4.3 微分项

  关于为什么微分项( D D D)能够抑制超调,这背后的原理相对复杂,涉及到自动控制理论。以下是一个简化的解释:微分项具有预测和提前控制的作用。例如,如果当前速度是 6 6 6,目标速度是 10 10 10,而预测三秒后的速度将达到 12 12 12

  在没有微分项的情况下,系统会根据当前速度( 6 6 6)和目标速度( 10 10 10)之间的差异持续加速,直到达到目标速度。然而,微分项能够预测未来的速度变化。如果当前速度是 6 6 6,而微分项预测的速度将达到 12 12 12,那么它会产生一个提前的减速信号。因为目标速度是 10 10 10,而预测的速度是 12 12 12,这会产生一个负的误差信号( − 2 -2 2),即使当前速度低于目标速度,系统也会提前开始减速,从而抑制超调。

4.4 微分项与积分项的对比

(1) 微分项的预测作用

  微分项能够预测并响应速度变化的趋势,抑制超调。

  如果没有微分项,系统会持续加速,直到当前速度超过目标速度,导致超调。微分项通过提前作用,可以防止这种超调的发生,因为它可以预测并响应速度变化的趋势。

(2) 积分项的滞后作用

  积分项考虑过去的误差累积,对稳态误差有消除作用。

  相反,积分项具有滞后作用。积分项能够消除稳态误差的原因在于,当系统接近目标速度时,比例项的作用变得较弱,因为误差变得很小。积分项则考虑了过去的误差累积,即使当前误差很小,过去的较大误差仍然会影响积分项的输出,从而使用较大的控制作用来消除稳态误差。


五、PID参数整定

5.1 整定顺序

  调整PID控制器的三个参数是一个试错过程,通常遵循一定的顺序。一般来说,首先调整比例参数( P P P),然后调整微分参数( D D D),最后调整积分参数( I I I)。控制精度只需达到一定的范围即可,不必过分追求完全精确。过度追求消除稳态误差可能会导致超调,因为为了消除稳态误差,需要增加积分参数,而为了抑制由此产生的超调,又需要增加微分参数。但这并非最佳做法,因为增加微分参数可能会放大系统中的噪声。

  至于为什么微分参数会放大噪声,这涉及到控制理论中的伯德图(Bode Plot),其中微分项会导致对数幅频曲线在高频段上翘,从而放大高频噪声。这一部分的解释较为复杂,不在此详细展开。

5.2 比例参数的调整

  在调整参数时,只需记住比例参数可以加快系统收敛速度,但可能会由于实际系统中的延迟而导致超调。尽管理论上比例参数本身不会引起超调,但由于延迟的存在,比例参数设置过大可能会导致超调现象。微分参数的作用正是抑制这种由比例参数引起的超调。

  因此,在大多数情况下,仅使用比例和微分参数就足够了。

5.3 积分参数的调整

  积分项的作用在于消除稳态误差,它能够使系统精确地收敛到目标值。但积分项的使用也可能会导致超调,而且这种由积分引起的超调通过微分项来降低是相对困难的。

  虽然微分项能够较容易地降低由比例项引起的超调,但对于积分项引起的超调则效果有限。

5.4 微分参数的调整

  微分项的值不宜过大,因为过大的微分项会放大噪声。因此,当积分项导致超调时,通常需要通过减小比例项来降低超调,但这会使得系统响应变慢,例如,如果比例项仅为 0.1 0.1 0.1,那么加速度会过慢,可能导致系统缓慢收敛,这也不利于控制精度的提高。

  因此,如果系统误差不是特别大,通常不使用积分项,仅使用比例和微分项就足够了,这样既能保证较快的响应速度,又能满足精度要求。或者,可以添加一个非常小的积分项,以避免引起超调,这样在长时间的控制过程中,积分项也能发挥一定作用,使稳态误差逐渐收敛到 0 0 0


六、横纵向控制

6.1 参考轨迹生成

  在实际的自动控制应用中,像给定固定速度(如 10 10 10)这样的简单控制并不多见。更常见的是需要给定一个参考轨迹,让车辆按照这个轨迹行驶。因此,需要进行更复杂的控制策略设计,下面编写一个生成参考轨迹的函数。

planning

function [s,v,a] = fcn(t)
if t<10%设计两端轨迹, t 小于 10 以及 t 大于10
%这两段轨迹会保证它们之间位置速度、加速度都连续。s=0.1*t^3/3;v=0.1*t^2;a=0.2*t;
elsea=2-0.1*(t-10);v=2*t-0.05*(t-10)^2-10;s=t^2-0.05*(t-10)^3/3-10*t+100/3;
end

  在设计轨迹时,通常需要确保轨迹的连续性。设计过程通常从加速度开始,然后逐步进行积分以得到速度和位置。假设我们设计了两段轨迹,一段适用于时间 t < 10 t < 10 t<10 的区间,另一段适用于时间 t > 10 t > 10 t>10 的区间,这样的设计可以确保在两段轨迹的连接点处,位置、速度和加速度都是连续的。我们检查设计的轨迹,确认它们是连续的。

6.2 参数调整

  接下来,我们分别查看这两段轨迹,希望模拟一个先加速到最大速度,然后减速到零的过程。通过观察速度曲线,我们发现速度一直在增加,因此仿真时间需要进一步延长。经过反复调试,我们将仿真时间设置为 60 60 60 秒,这看起来是一个比较合适的选择。由于对位置 s s s 也有特定的要求,因此在输出结果中,我们还需要输出车辆的 x x x 坐标,即变量 X o X_o Xo

在这里插入图片描述
  控制算法的实现方式是在速度PID控制的基础上,再加入位置PID控制。下面是具体的实现步骤:

  首先,速度PID控制模块采用“ − + + -++ ++”模式,这意味着它不仅需要处理期望速度与实际速度之间的误差,还需要考虑来自位置控制单元的误差信号。即使实际速度与期望速度相同,如果位置存在差异,系统仍然需要调整。如果期望位置在实际位置之前,系统需要加速;如果期望位置在实际位置之后,系统则需要减速。

  因此,仅仅匹配期望速度和实际速度是不够的,我们还需要将期望位置的误差信号输入到系统中。这意味着我们不仅要连接期望速度和实际速度的误差,还需要创建另一个PID控制器来处理期望位置和实际位置之间的误差,并将其纳入控制环路。

  位置PID的控制输出也应当受到限制,以防止其过大,从而确保位置和速度控制的稳定性。至于加速度,我们可以在速度PID信号中加入积分项 ( I I I),并将加速度信号连接到这个积分项上。这样,一个包含双PID控制器的纵向控制模型就建立完成了,如下图所示。

在这里插入图片描述

运行查看结果,下面分别是位置、速度、加速度曲线:

  总的来说,位置跟踪和速度跟踪还算可以,加速度在前面有点不太好,可以再调一调。这里直接给出比较好参数:

  • 位置PID: P = 1 , I = 0 , D = 0.1 , N = 30 P=1,I=0,D=0.1,N=30 P=1,I=0,D=0.1,N=30
  • 速度PID: P = 1 , I = 0 , D = 0.1 , N = 30 P=1,I=0,D=0.1,N=30 P=1,I=0,D=0.1,N=30

这样调出来的效果比较好。

6.3 模型打包

  这样纵向控制模型就讲完了,最后把模型也打个包:

在这里插入图片描述

  至此,我们已经讨论了纵向控制和横向控制的内容。接下来将探讨横纵向控制。首先移除延迟模块,采取由简入繁的方式,先考虑无延迟的情况,再考虑有延迟的情况。因此,本节是关于纵向控制的第十一节,结合之前的第八节横向控制,在下一节将结合起来讨论横纵向控制。

  在最后一节结束后,这个系列课程将正式完结。虽然还有很多内容没有涉及,比如如何规划、如何估算坡度、如何考虑质量变化对控制的影响等问题,这些内容实际上已经超出了纯粹控制理论的范畴。虽然这些知识也可以讲解,但它们并不完全属于控制领域。

  因此,博主计划将横纵向控制作为基础篇章,后续将更复杂的内容作为专题和进阶篇章进行讲解。对于技术层面来说,横纵向控制的基础知识讲解完成后,基本的学习目标也就达到了。


七、进阶学习

  实际上,如果各位学习到了最后一讲,可能会逐渐意识到对计算速度提升的迫切需求。虽然使用 Matlab 进行仿真是一个不错的选择,但当涉及到实际开发时,Matlab 的计算速度就显得过于缓慢。因此,Matlab 更适合作为学习工具,而不是开发者的软件。对于开发来说,无论愿意与否,最终都不得不转向使用 C++。

  对于没有 C++ 基础的同学来说,可能会感到抵触,因为 C++ 确实是一门难以学习和使用的语言。但无可否认的是,C++ 的执行速度非常快,而这正是我们需要的。特别是当我们想要开发一些真正有意义的项目时,不使用C++ 是不现实的。如果计算速度过慢,那么在无人驾驶等领域,车辆可能已经发生事故,而计算却还未完成,这是完全不可接受的。

  因此,无论从哪个角度来看,学习并使用 C++ 都是必要的。在基础篇章使用 Matlab 完成讲解之后,进阶篇章可能会采用 C++ 和 Matlab 相结合的方式,即在 C++ 中编写代码,同时使用 Matlab 进行仿真,这样的形式更接近实际工程。不过,这些都是未来的计划。


八、总结

  本篇博客详细介绍了自动驾驶控制算法中的纵向控制,从软件设置到标定表的应用,再到PID控制器的整定和实际模型运行,我们共同学习并探讨了如何实现平稳、无振荡的车辆运动。通过调整PID控制器中的比例、积分和微分参数,我们能够精确控制车辆的速度,实现与期望速度相匹配的加速度策略。同时,我们理解到,为了实现更好的控制效果,需要对PID参数进行适当的整定,平衡系统的响应速度和稳定性。最后,我们还探讨了如何将控制算法应用于实际的自动驾驶场景中,以及未来学习计划。

  本篇博客的讲解就到这里,感谢大家阅读。


参考资料

  【基础】自动驾驶控制算法第十一讲 纵向双pid控制


后记:

🌟 感谢您耐心阅读这篇关于 深度解析车辆纵向控制 | 双 PID 控制算法 的技术博客。 📚

🎯 如果您觉得这篇博客对您有所帮助,请不要吝啬您的点赞和评论 📢

🌟您的支持是我继续创作的动力。同时,别忘了收藏本篇博客,以便日后随时查阅。🚀

🚗 让我们一起期待更多的技术分享,共同探索移动机器人的无限可能!💡

🎭感谢您的支持与关注,让我们一起在知识的海洋中砥砺前行 🚀

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

记录|Modbus-TCP产品使用记录【德克威尔】

目录 前言一、德克威尔1.1 实验图1.2 DECOWELL IO Tester 软件1.3 读写设置1.4 C#进行Modbus-TCP读写 更新时间 前言 参考文章&#xff1a; 使用的第二款Modbus-TCP产品。 一、德克威尔 1.1 实验图 1.2 DECOWELL IO Tester 软件 这也是自带模块配置软件的。下图就是德克威尔的…

AltiumDesigner脚本开发-DIP封装制作

1.点击工具栏的运行工具(蓝色向右三角图标)可以执行脚本程序&#xff1b; 2.点击菜单栏Run->Run可以执行脚本程序&#xff1b; 3.在脚本编辑器中&#xff0c;按键盘的F9键可以执行脚本程序&#xff1b; 4.通过菜单栏执行脚本程序&#xff08;需要将程序添加到菜单栏中&am…

profinet转ethercat连接伺服在工业现场的配置案例

在工业通信领域&#xff0c;Profinet 转 EtherCAT 网关的应用为实现不同工业网络之间的通信提供了有效的解决方案。以下是一个关于 Profinet 转 EtherCAT 网关链接伺服配置的案例。 首先&#xff0c;我们需要准备好相关的硬件设备&#xff0c;包括 Profinet 转 EtherCAT 网关、…

VoLTE呼叫流程(VoLTE打VoLTE)

目录 01. VoLTE 呼叫流程中的主要子流程 02. 高层来看一个 VoLTE 的基本呼叫过程 03. 场景 04. 高层来看一个 VoLTE 基本呼叫的会话建立 05. 采用 Precondition 的基本呼叫建立流程 06. T-ADS 流程图 07. SIP 头部的 Route 和 Record-Route 头域 08. 第一个 AAR 和第二…

负载箱:充电桩测试利器

RCD负载箱是用于测试和验证电气设备在故障状态下的性能的设备。它可以模拟真实的负载情况&#xff0c;从而帮助工程师和技术人员对设备进行准确的检测和维护。此外&#xff0c;RCD负载箱也是一种重要的安全保护设备&#xff0c;主要用于防止电路中的漏电现象引发的事故。它通常…

Java项目实战II基于Java+Spring Boot+MySQL的美发门店管理系统(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者 一、前言 在当今快节奏的社会中&#xff0c;美发门店的管理效率和服务质量直接关系到客户的满意度和门店的竞争…

R语言非参数回归预测摩托车事故、收入数据:局部回归、核回归、LOESS可视化...

全文链接&#xff1a;https://tecdat.cn/?p37784 非参数回归为经典&#xff08;参数&#xff09;回归方法提供了一种灵活的替代方法。与假定回归关系具有依赖于有限数量的未知参数的已知形式的传统&#xff08;参数&#xff09;方法不同&#xff0c;非参数回归模型尝试从数据样…

Redis篇(应用案例 - UV统计)(持续更新迭代)

目录 一、HyperLogLog 二、测试百万数据的统计 一、HyperLogLog 首先我们搞懂两个概念&#xff1a; UV&#xff1a;全称Unique Visitor&#xff0c;也叫独立访客量&#xff0c;是指通过互联网访问、浏览这个网页的自然人。 1天内同一个用户多次访问该网站&#xff0c;只记录…

【EI会议征稿通知】第八届电气、机械与计算机工程国际学术会议(ICEMCE 2024)

第八届电气、机械与计算机工程国际学术会议&#xff08;ICEMCE 2024&#xff09; 2024 8th International Conference on Electrical, Mechanical and Computer Engineering 本次会议主要围绕“电气”、"机械”和“计算机”三大工程领域展开研讨&#xff0c;为来自国内外…

谷歌SEO:有心栽花花不开,无心插柳柳成荫!

之前一开始是想搞个谷歌SEO免费的技术教程博客&#xff08;https://www.c-sz.com/&#xff09;主要是很多时候遇到在谷歌独立站推广群里的朋友需要咨询和学习一些谷歌技术基础知识&#xff0c;当然我自己也有点小心思&#xff0c;就是希望在谷歌能吸引部分的谷歌SEO爱好者尤其包…

Hbase要点简记

Hbase要点简记 Hbase1、底层架构2、表逻辑结构 Hbase HBase是一个分布式的、列式的、实时查询的、非关系型数据库&#xff0c;可以处理PB级别的数据&#xff0c;吞吐量可以到的百万查询/每秒。主要应用于接口等实时数据应用需求&#xff0c;针对具体需求&#xff0c;设计高效率…

JavaScript中的函数定义

第8章 函数 在JS中函数即对象&#xff0c;程序可以随意操控他们。可以把函数赋值给变量&#xff0c;或者作为参数传递给其他函数。因为函数就是对象&#xff0c;所以可以给他们设置属性&#xff0c;甚至调用他们的方法。 JavaScript的函数可以嵌套在其他函数中定义&#xff0…

Flux最新ControlNet 高清修复模型测评,效果好速度快!

上一篇介绍了Jasper AI 发布了三个模型中的法线贴图&#xff0c;没看过的可以看一下哈&#xff1a; Flux目前最快ControlNet模型现身&#xff01;法线贴图详细测评 (chinaz.com) 这次再介绍一下另一个模型&#xff1a;升频器&#xff0c;可以有比较好的模糊修复效果&#xff…

【数据结构】散列(哈希)表简单介绍

散列表也叫做哈希表&#xff08;Hash table&#xff09;&#xff0c;散列表通过关键码和存储地址建立唯一确定的映射关系&#xff0c;能够快速查找到对应的元素&#xff0c;排序算法中的计数排序就是一种利用哈希进行排序的算法。 一、散列表的概念 散列表&#xff08;Hash ta…

解决DHCP服务异常导致设备无法获取IP地址的方法

DHCP在网络环境中会自动为网络中的设备分配IP地址和其他关键网络参数&#xff0c;可以简化网络配置过程。但是&#xff0c;如果DHCP服务出现异常时&#xff0c;设备可能无法正常获取IP地址&#xff0c;会影响到网络通信。 本文讲述一些办法可以有效解决DHCP服务异常导致设备无法…

怎样在 Python 中创建一个自定义函数?

Python函数一般用来实现某个功能模块&#xff0c;可以反复使用&#xff0c;能极大的提升编程效率&#xff0c;多用函数也是写代码的好习惯。 Python中创建函数有两种方式&#xff0c;第一种使用def关键字创建自定义函数&#xff08;最常见的&#xff09;&#xff0c;第二种使用…

【前端】35道JavaScript进阶问题(1)

来源&#xff1a; javascript-questions/zh-CN/README-zh_CN.md at master lydiahallie/javascript-questions GitHub 记录一些有趣的题。 1 输出是&#xff1f; const shape {radius: 10,diameter() {return this.radius * 2},perimeter: () > 2 * Math.PI * this.rad…

Windows11系统下Docker环境搭建教程

目录 前言Docker简介安装docker总结 前言 本文为博主在项目环境搭建时记录的Docker安装流程&#xff0c;希望对大家能够有所帮助&#xff0c;不足之处欢迎批评指正&#x1f91d;&#x1f91d;&#x1f91d; Docker简介 Docker 就像一个“容器”平台&#xff0c;可以帮你把应用…

XPath入门

&#x1f4dd; 主旨内容 一、XPath语法 XPath 使用路径表达式来选取 XML 文档中的节点或节点集。节点是通过沿着路径 (path) 或者步 (steps) 来选取的。 (一)XML实例文档 我们将在下面的例子中使用这个 XML 文档。 实例 <?xml version"1.0" encoding"UT…

桥接模式和NET模式的区别

桥接模式和NET模式的区别 NAT模式&#xff1a; NAT&#xff1a;网络地址转换&#xff08;模式&#xff09;&#xff1a;借助宿主机来上网&#xff0c;没桥接那么麻烦&#xff0c;只用配置DNS即可。 缺点&#xff1a;扎根于宿主机&#xff0c;不能和局域网内其它真实的主机进行…