0.前提
前一章我讲解了拉氏变换和PID,这一章我来讲解一下小车巡墙驾驶的理论和部分代码。
![](https://file.jishuzhan.net/article/1790658334777413633/a7c8341824a36797d69edd84a0c16284.webp)
1.前情回顾
1.拉氏变换
![](https://file.jishuzhan.net/article/1790658334777413633/4684cde52cb08fc65352a6d72988234a.webp)
拉普拉斯变换是要将时域问题转换成频域问题来处理。
2.PID控制器
转向角:
误差牺牲:
![](https://file.jishuzhan.net/article/1790658334777413633/a2329496925580c6e52edd2c368760ef.webp)
3.具体参看上一篇文章
2.巡墙驾驶理论
在PID当中我们提到牺牲误差,那实际运用当中我们要如何得到牺牲误差呢?在何时去获取误差(这是一个时域问题)?
回答:我们可以在当前时间利用雷达获取到右墙的距离,而现在这个时刻的距离认为是
,参看下图将小车当前速度设定为
,与速度垂直的角度测得到墙距离
,距离
与
轴的角度为
,在该角度的基础上叠加一个角度
(
),测出一个距离
。
![](https://file.jishuzhan.net/article/1790658334777413633/8b009b5cd76035a10ce431fbf3cf1a9b.webp)
按下图我们可以计算出角度,这时我们也就知道了当前时刻我们所在的位置
![](https://file.jishuzhan.net/article/1790658334777413633/32997201aa9a17021a134eb817d11cd6.webp)
既然我们得到了车和墙现在的距离,那我们设置一个我们的期望值(车和墙的距离),计算牺牲误差
,在低速档的时候按照这个方式计算转向是完全ok的,但当我们小车行驶在超高速度时(雷拉洛的AK-787极速能达到260km/h!),按照这样的测距方式是来不及的,换而言之,在工业上这时不安全的,我们更希望超前预测计算距离。
按下图,我们假设小车按当前速度会向前行驶一段距离,那我们计算的牺牲误差将会是
![](https://file.jishuzhan.net/article/1790658334777413633/17b3996192786915ed5b9b56806fb954.webp)
3. ROS实现巡墙驾驶关键解析
在PID计算中我们需要用到积分与微分,但在实际代码工程中如何实现积分和微分的计算呢?
1.微分(D控制器)
1.导数的定义
![](https://file.jishuzhan.net/article/1790658334777413633/7ac999f25fb70a4ade5a0f376da336db.webp)
导数其实本质上就是关于的函数
和
间的除法关系求极限。
2.D控制器公式
![](https://file.jishuzhan.net/article/1790658334777413633/4aaeef1d4225fc36a514b6f304817f4f.webp)
换个方式表达:
![](https://file.jishuzhan.net/article/1790658334777413633/27acde205cb0e4ba74c113019fc5e073.webp)
其中表示当前时间,
表示之前时间。涉及到时间的函数在ROS中如何获取?
这里我只给出c++的ROS获取当前时间:
roscpp/Overview/Time - ROS Wiki
2.积分(I控制器)
1.积分的定义
![](https://file.jishuzhan.net/article/1790658334777413633/bd5a689fe61bf1ee0575bcb5c9bc2275.webp)
积分其实本质上就是关于的函数
和
间的乘法法关系和求极限。
2.积分控制器公式
![](https://file.jishuzhan.net/article/1790658334777413633/e41d507fd9202d42967a4961d593cf39.webp)
换个方式
![](https://file.jishuzhan.net/article/1790658334777413633/c39e8bc6926114748b9a7656434088b6.webp)
其中表示当前时间,
表示之前时间。
3.PID
最后的PID公式
转向角:
其中表示当前时间,
表示之前时间。
误差牺牲:
4.总结
好了PID的理论和一些代码思路我就讲到这里了,接下来就是大家自己去实践了。