PID理解

一、背景

pid理解

前几天看了bilibili的视频,链接:更好的理解PID【通过推小车的过程】,那个人使用matlab调整pid,另外使用推小车这个假设来解释pid。我其实当时也只是听懂一些,然后后面自己又琢磨。感觉是理解了。这边记录一下。

首先回顾一下视频的内容,就是有一个小车,一开始是静止的。要让小车以5m/s的速度运动。所以要先给小车推力。让小车从v=0到v=5;一开始使用比例积分,Vtarget = PV,p是比例积分。p越大,达到5m/s目标速度越快;p越小,达到5m/s目标速度越慢。但是加上车的力一定不会正好让车达到5m/s。如果速度小于5m/s还是会继续加大力,最终会超调,然后将往回拉一些,即让v速度减小,可以预见的是也一定会超调小于5m/s。所以如果调整速度足够快,调整时间t足够小,速度一定会越发靠近目标值。但是一定是需要很多次以及不一定很好的收敛。

关于这边为什么比例调节会出现不能收敛的情况,还没想明白。

如果是这样其实。

过了几天我在看这个问题,一开始百度"pid比例积分为什么会达不到目标值",然后看了写帖子,看到这个应该是稳态误差,我之前就觉得是有专业名词的,但是这时候才想起来。

查了个帖子,pid比例积分为什么会有稳态误差:解释如下

简单的说,如果有一个水缸,有一根水管一直往里面加水,当水平面高度距离水缸顶部越来越近,这时距离目标值也越近,P的目的就在于加快水平面到水缸顶部的速度。
如果这个水缸上面有一个洞,在注水的同时,水缸在不断向外面漏水,这时由于进水的速度P是一定的,最后会产生一个这样的情况,在进水速度P不是非常大的情况下,
进水和出水的过程会达到一个动态平衡,这时水平面距离水缸顶部还有一定的距离无法弥补,这时就需要在增加一个水管I来进水,消除这个误差,这个误差就是稳态误差。

但是我还是不能明白,虽然有个洞,但是为什么一开始把水流开的足够大就行了啊。然后写上面文字的时候我突然想到也许会不会是因为p的值设置的不够大。然后负反馈周期是一定的。如果p的值比较小,就达不到目标值。(事实上这边的理解是不对的,但是这是在做个验证之后才知道的)

下面验证上面的疑问。首先编写比例积分代码,实际映射的是推小车使小车目标达到5m/s。

二、 验证比例调节疑惑

2.1 比例调节仿真

比例调节代码如下:

void pid_test()
{float p = 1.5;int t = 1;              // 负反馈周期t = 1s;int target = 5;         // 目标速度5m/sfloat output = 0;std::cout << "output:   " << std::endl;for(int i = 0; i < 30; i++){float error = target - output;output += p * error * t;std::cout << output << std::endl;}
}

output输出情况如下:

0, 7.5, 3.75, 5.625, 4.6875, 5.15625, 4.92188, 5.03906, 4.98047, 5.00977, 4.99512, 5.00244, 4.99878, 5.00061, 4.99969, 5
.00015, 4.99992, 5.00004, 4.99998, 5.00001, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5

仿真显示如下:

在这里插入图片描述

p值设置为1.5,比例调节情况没有出现稳态误差。

现在想模拟出出现稳态误差的情况,按照解释所述,玻璃缸有一个出水口,那么在代码中增加一个差值radis。

2.2 模拟比例调节稳态误差

代码如下

// 稳态误差
void pid_test_wentaiwucha()
{float p = 1.5;p = 1.8;int t = 1;              // t = 1s;int target = 5;         // 5m/sfloat output = 0;float radis = 3;        // 稳态误差std::cout << "output:   " << std::endl;for(int i = 0; i < 30; i++){std::cout << output << ", ";float error = target - output;output += p * error * t - radis;}
}

output输出情况如下:

0, 6, 1.2, 5.04, 1.968, 4.4256, 2.45952, 4.03238, 2.77409, 3.78073, 2.97542, 3.61966, 3.10427, 3.51659, 3.18673, 3.45061
, 3.23951, 3.40839, 3.27329, 3.38137, 3.2949, 3.36408, 3.30874, 3.35301, 3.31759, 3.34593, 3.32326, 3.34139, 3.32689, 3.
33849

仿真显示如下:
在这里插入图片描述

仿真出现了稳态误差。

按照我之前的理解,如果稳态误差是因为比例p的值太小了,导致出现稳态误差,只要增加p的值就行了。下面验证这个想法。

2.2.1 将比例的值增大为2。

output输出情况如下:

0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7,

仿真显示如下:

在这里插入图片描述

p的值设置为2,找值失败。没有参考价值。

2.2.2 p的值设置为1.8

output输出情况如下:

0, 6, 1.2, 5.04, 1.968, 4.4256, 2.45952, 4.03238, 2.77409, 3.78073, 2.97542, 3.61966, 3.10427, 3.51659, 3.18673, 3.45061
, 3.23951, 3.40839, 3.27329, 3.38137, 3.2949, 3.36408, 3.30874, 3.35301, 3.31759, 3.34593, 3.32326, 3.34139, 3.32689, 3.
33849

仿真结果如下

在这里插入图片描述

2.3 结论

出现稳态误差是因为有外界环境影响,不是增加p的值就可以解决的。计算的output值感觉是趋近于差值。导致出现稳态误差。

另外我现在对比例调节的理解又多了一些。还是拿水缸加水假设,其实入水口的水量是变化的,都是目标值与当前值的差值和比例值相乘,而随着调节过程目标值与当前值的差值逐渐变小,那么入水口的水量是变化的,或者是逐渐变小的。所以这才是比例调节的真正解释啊!

对于稳态误差,可能的原因就是因为误差值的存在,导致最终的值趋于一个稳定值,而这个值等于是将原来的5m/s的区间整体向下移动了,就出现了稳态误差。

三、pid调节

这篇文章好像有点东西:

仅使用pid中的p控制输出为什么无法达到设定输出值

根据文章的信息拷贝下述代码

// pid.cpp文件

#include "pid.h"#define Kp  1.0         // 比例系数
#define Ki  0.1         // 积分系数
#define Kd  0.01        // 微分系数float g_temp = 0;float setPoint = 50.0;  // 设定
float input = 0;
float output = 0;float error = 0;
float last_error = 0;
float intergral = 0;float readTemperature()
{std::cout << g_temp << std::endl;return g_temp;
}void controlHeater(float data)
{g_temp = data;
}void loop()
{input = readTemperature();error = setPoint - input;intergral += error;float derivative = error - last_error;output += Kp * error + Ki * intergral + Kd * derivative;controlHeater(output);last_error = error;
}

// main文件

#include "pid.h"int main()
{std::cout << "output:   " << std::endl;int count = 100;while (count--){loop();}return 0;
}

得到output输出信息如下

0, 55.5, 53.895, 54.0765, 53.651, 53.292, 52.9621, 52.6656, 52.3987, 52.1586, 51.9424, 51.748, 51.5729, 51.4155, 51.2737
, 51.1462, 51.0314, 50.9282, 50.8352, 50.7516, 50.6764, 50.6086, 50.5477, 50.4929, 50.4435, 50.3991, 50.3591, 50.3232, 5
0.2908, 50.2617, 50.2355, 50.2119, 50.1907, 50.1716, 50.1544, 50.139, 50.1251, 50.1125, 50.1013, 50.0911, 50.082, 50.073
8, 50.0664, 50.0598, 50.0538, 50.0484, 50.0435, 50.0392, 50.0353, 50.0317, 50.0286, 50.0257, 50.0231, 50.0208, 50.0187,
50.0168, 50.0152, 50.0136, 50.0123, 50.011, 50.0099, 50.0089, 50.0081, 50.0072, 50.0065, 50.0059, 50.0053, 50.0047, 50.0
043, 50.0038, 50.0035, 50.0031, 50.0028, 50.0025, 50.0023, 50.002, 50.0018, 50.0017, 50.0015, 50.0013, 50.0012, 50.0011,50.001, 50.0009, 50.0008, 50.0007, 50.0006, 50.0006, 50.0005, 50.0005, 50.0004, 50.0004, 50.0003, 50.0003, 50.0003, 50.
0002, 50.0002, 50.0002, 50.0002, 50.0002,

仿真如图所示

在这里插入图片描述

如果将语句改成这样

output += Kp * error + Ki * intergral + Kd * derivative - 20;		// 增加20的损耗

output信息如下:

0, 35.5, 36.095, 37.8345, 39.0396, 40.141, 41.128, 42.0163, 42.8157, 43.535, 44.1823, 44.7648, 45.289, 45.7606, 46.1851,46.5671, 46.9108, 47.2201, 47.4984, 47.7489, 47.9743, 48.1771, 48.3596, 48.5239, 48.6717, 48.8047, 48.9243, 49.032, 49.
129, 49.2162, 49.2946, 49.3653, 49.4288, 49.486, 49.5375, 49.5838, 49.6255, 49.663, 49.6967, 49.7271, 49.7544, 49.779, 4
9.8011, 49.821, 49.8389, 49.8551, 49.8696, 49.8826, 49.8944, 49.905, 49.9145, 49.923, 49.9307, 49.9377, 49.9439, 49.9495
, 49.9546, 49.9591, 49.9632, 49.9669, 49.9702, 49.9732, 49.9759, 49.9783, 49.9805, 49.9824, 49.9842, 49.9858, 49.9872, 4
9.9885, 49.9896, 49.9907, 49.9916, 49.9924, 49.9932, 49.9939, 49.9945, 49.995, 49.9955, 49.996, 49.9964, 49.9968, 49.997
1, 49.9974, 49.9976, 49.9979, 49.9981, 49.9983, 49.9984, 49.9986, 49.9987, 49.9989, 49.999, 49.9991, 49.9992, 49.9993, 4
9.9993, 49.9994, 49.9995, 49.9995,

也是收敛的,是因为有积分的存在。仿真如下图所示:

在这里插入图片描述

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

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

相关文章

python--fasApi学习(Dash+FastAPI框架)

在学习fastApi 框架时&#xff0c;发现了一个好用的框架&#xff0c;参考&#xff1a; 博客参考&#xff1a; https://blog.csdn.net/gitblog_00002/article/details/137331157下载文档并部署&#xff1a; 下载代码&#xff1a; git clone https://gitee.com/insistence2022/…

星戈瑞Sulfo-CY7 NHS Ester结构与荧光性质

【星戈瑞stargraydye】以下数据均来自文献资料,星戈瑞暂未进行独立验证, 仅供参考&#xff01; Sulfo-Cy7 NHS Ester是一种应用于生物医学领域的荧光染料&#xff0c;其结构特性和荧光性质使其在荧光标记、组织成像和药物追踪等方面发挥着作用。 Sulfo-Cy7 NHS Ester的结构特性…

Dxf库中的DL_Extrusion类

类DL_Extrusion DL_Extrusion 是 DXF 库中的一个类&#xff0c;用于表示三维实体的扩展信息。在 DXF 文件中&#xff0c;DL_Extrusion 类通常用于表示具有高度的三维图形实体&#xff0c;如立方体、圆柱体等&#xff0c;以及其它具有体积的几何对象。 以下是一个简单的示例代…

python接口自动化测试数据和代码分离解析

common中存放的是整个项目中公共使用的封装方法 从工程目录上可以看到区分 datas中专门存放测试数据(yml文件) cases中专门集中存放测试用例 ... 数据分离的第一步先找到工程项目路径 1 2 3 4 5 6 7 8 9 10 11 12 # -*- encoding: utf-8 -*- """ __Software…

6月28日PolarDB开源社区长沙站,NineData联合创始人周振兴将带来《数据库DevOps最佳实践》主题分享

6月28日&#xff08;周五&#xff09;&#xff0c;PolarDB 开源社区将来到湖南长沙&#xff0c;与湖南的开发者朋友们一起进行数据库技术交流&#xff01;NineData 联合创始人周振兴受邀参加&#xff0c;并将带来《数据库 DevOps 最佳实践》的主题分享。 本次活动议程&#xff…

GEE问题——EEException:未注册 Earth Engine 或项目未注册。

问题 EEException:未注册 Earth Engine 或项目未注册。 EEException: Not signed up for Earth Engine or project is not registered. 解决方案 在谷歌社区里面这个问题已经被记录了: [Notice] Removing access for unregistered Cloud projects on 2024-06-17 查看下…

SpringBoot集成IotDB

1、引入依赖 <dependency><groupId>org.apache.iotdb</groupId><artifactId>iotdb-session</artifactId><version>0.14.0-preview1</version></dependency><dependency><groupId>cn.hutool</groupId><a…

JAVA小知识29:IO流(上)

IO流是指在计算机中进行输入和输出操作的一种方式&#xff0c;用于读取和写入数据。IO流主要用于处理数据传输&#xff0c;可以将数据从一个地方传送到另一个地方&#xff0c;例如从内存到硬盘&#xff0c;从网络到内存等。IO流在编程中非常常见&#xff0c;特别是在文件操作和…

如何使用Java中的正则表达式

如何使用Java中的正则表达式 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;在Java开发中&#xff0c;正则表达式是处理文本和字符串的重要工具。本文将介绍如何…

第4章 客户端-Java客户端Jedis

1.获取Jedis maven配置加入项目中 <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.8.2</version> </dependency>2.Jedis的基本使用 Jedis的使用方法非常简单&#xff0c;只要下面三…

陕西师范大学的教育学、汉语语言文学、外国语言文学(英语)和历史学专业的招聘专业要求

结合西安教师招聘汇公众号的信息以及参考文章中的相关内容&#xff0c;对于陕西师范大学的教育学、汉语语言文学、外国语言文学&#xff08;英语&#xff09;和历史学专业的招聘专业要求&#xff0c;可以做出如下总结和推荐&#xff1a; 教育学专业 专业要求与特点&#xff1…

每天一个数据分析题(三百八十七)- 线性回归分析

下列关于线性回归分析中的残差&#xff08;Residuals&#xff09;的假设说法正确的是&#xff1f; A. 残差均值总是为零 B. 残差均值总是小于零 C. 残差均值总是大于零 D. 以上说法都不对 数据分析认证考试介绍&#xff1a;点击进入 题目来源于CDA模拟题库 点击此处获取…

首次30米空间分辨率生成中国年度耕地栅格数据1986-2021

中国1986-2021年30米分辨率年度耕地数据集 数据介绍 精确、详细且及时的耕地范围信息对于粮食安全保障和环境可持续性至关重要。然而&#xff0c;由于农业景观的复杂性和足够训练样本的缺乏&#xff0c;在大范围下进行高时空分辨率的耕地动态监测仍然具有挑战性&#xff0c;尤其…

如何在next14项目中加入favicon

如何在next14项目中加入favicon 第一次碰见这个问题的时候很头疼&#xff0c;直接搜官方文档也没有详细介绍这个&#xff0c;但其实next14提供了很简单的方法&#xff1a; Convention 将 favicon.ico 放置在 app/ 或 public/ 文件夹中&#xff0c;Next.js 将自动生成必要的元…

基于深度学习的双目重建

基于深度学习的双目重建 双目重建是通过从两个相机视角的图像中提取深度信息&#xff0c;重建场景的三维结构。传统的双目重建方法依赖于特征匹配和几何计算&#xff0c;而基于深度学习的方法通过训练神经网络&#xff0c;可以直接从图像对中学习到深度信息和场景的三维结构。…

通俗易懂的理解zookeeper的作用

举个例子&#xff0c;乌鸡国国王想找唐僧师徒安排点任务&#xff0c;所以乌鸡国国王找了唐僧师徒团队的leader唐僧&#xff0c;因为唐僧可以管理团队的成员&#xff0c;知道团队内的大大小小事情。唐僧协调安排了合适的人帮乌鸡国国王解决需求。 那么leader唐僧&#xff0c;实…

ChatGPT的原理简介

ChatGPT的原理简介 目录 ChatGPT简介自然语言处理基础 词嵌入序列模型注意力机制 生成式预训练模型 Transformer架构GPT模型 ChatGPT的工作原理 预训练微调生成回复 应用和局限 应用场景局限和挑战 未来发展方向总结 ChatGPT简介 ChatGPT是OpenAI开发的一种生成式预训练模型…

sql优化方法

基础优化方法 1.使用索引&#xff0c;在创建索引时&#xff0c;需要考虑查询的频率和数据的更新频率&#xff0c;避免过度索引或不必要的索引。 2.尽量避免使用SELECT *&#xff0c;而是明确指定需要查询的字段。这样可以减少返回的数据量&#xff0c;提高查询效率。 优化查询…

洞察用户需求,Xinstall数据统计App让你的App运营如虎添翼

在互联网时代&#xff0c;App推广和运营面临着前所未有的挑战。流量红利逐渐衰退&#xff0c;用户获取成本不断攀升&#xff0c;如何确保在多变的互联网环境下&#xff0c;迅速搭建起能时刻满足用户需求的运营体系&#xff0c;成为众多企业急待解决的问题。今天&#xff0c;我们…

docker部署FastDFS整合Springboot

文章目录 1、FastDFS是什么&#xff1f;2、搭建docker环境3、部署fastdfs4、整合springboot5、接口测试参考文章 1、FastDFS是什么&#xff1f; FastDFS是一个开源的轻量级分布式文件系统&#xff0c;它对文件进行管理&#xff0c;功能包括&#xff1a;文件存储、文件同步、文…