PID控制算法学习笔记分享

news2024/11/24 18:58:11

目录

一、参数设定

二、PID计算公式

三、位置式PID代码实现

四、增量式PID代码实现

五、两种控制算法的优缺点

六、PID算法的改进


一、参数设定

  1. 比例系数(kp):P项的作用是根据当前误差的大小来产生一个控制量。它直接与误差成正比,误差越大,控制量的变化越大。P项可以提高系统的响应速度,但可能会导致系统的超调和稳态误差

  2. 积分时间(Ti):I项的作用是累积误差并产生一个控制量。它可以消除系统的稳态误差,因为它会积累误差并持续地调整控制量,直到误差为零。然而,I项可能会导致系统的超调和振荡。

  3. 微分常数(Td):D项的作用是根据误差变化的速度来产生一个控制量。它可以提高系统的稳定性,因为它可以减小误差的快速变化。D项可以抑制超调和减小振荡,但可能会增加系统的灵敏度

PD算法:适用于惯性较大的设备,比如舵机。

PI算法:适用于不允许有静差的设备。

二、PID计算公式

1)位置式PID

2)增量式PID

三、位置式PID代码实现

#define IntegralMAX 2000

//pid结构体
typedef struct
 {
     float target_val;               //目标值
     float temp_val;                 //当前值
     float actual_val;                       //输出控制值
     float err;                              //定义偏差值
     float err_last;                         //定义上一个偏差值
     float Kp,Ki,Kd;                         //定义比例、积分、微分系数
     float sum;                              //定义历史偏差
 }pid_t; 
//pid算法实现
 void PID_realize(pid_t *pid)
{
     /*目标值只在这里参与计算,计算目标值与实际值的误差*/
    pid->err=pid->target_val - pid->temp_val;
     /*误差累积*/
    pid->sum+=pid.err;
    //此处可以进行误差限幅
    //*if(pid->integral > IntegralMAX) pid->integral = IntegralMAX;
    // else if(pid->integral < -IntegralMAX) pid->integral = -IntegralMAX;
    //*

     /*PID算法实现*/
    pid->actual_val = pid->Kp*pid->err + pid->Ki*pid->sum
                      + pid->Kd*(pid->err - pid->err_last);
     /*误差传递*/
    pid->err_last=pid->err;

}

位置式 PID 适用于执行机构不带积分部件的对象,如舵机和平衡小车的直立和温控系统的控制。

四、增量式PID代码实现

 /*pid*/
 typedef struct
 {
     float target_val;     //目标值
     float actual_val;     //实际输出值
     float temp_val;       //当前值
     float err;            //定义当前偏差值
     float err_next;       //定义下一个偏差值
     float err_last;       //定义最后一个偏差值
     float Kp, Ki, Kd;     //定义比例、积分、微分系数
 }_pid;
//增量式PID算法实现
void PID_realize(pid_t *pid)
 {
     /*目标值只在这里参与计算,计算目标值与实际值的误差*/
     pid->err = pid->target_val - pid->temp_val;
     /*PID算法实现*/
     float increment_val = pid->Kp*(pid->err - pid->err_next) + pid->Ki*pid->err + pid->Kd*(pid->err - 2 * pid->err_next + pid->err_last);
     /*累加*/
     pid->actual_val += increment_val;
     /*传递误差*/
     pid->err_last = pid->err_next;
     pid->err_next = pid->err;
 }

可见,增量式PID不需要进行累加,能对其产生影响的只有最近的三次的采样,容易通过加权处理获得比较好的控制效果,并且在系统发生问题时,增量式不会严重影响系统的工作。

增量式PID控制输出的是控制量增量,并无积分作用,因此该方法适用于执行机构带积分部件的对象,如步进电机等。

五、两种控制算法的优缺点

1)位置式PID的优缺点

优点:

①位置式PID是一种非递推式算法,可直接控制执行机构(如平衡小车),u(k)的值和执行机构的实际位置(如小车当前角度)是一一对应的,因此在执行机构不带积分部件的对象中可以很好应用

缺点:

①每次输出均与过去的状态有关,计算时要对e(k)进行累加,运算工作量大。

2)增量式PID优缺点:

优点:

①误动作时影响小,必要时可用逻辑判断的方法去掉出错数据。

②手动/自动切换时冲击小,便于实现无扰动切换。当计算机故障时,仍能保持原值。

③算式中不需要累加。控制增量Δu(k)的确定仅与最近3次的采样值有关。

缺点:

①积分截断效应大,有稳态误差;

②溢出的影响大。有的被控对象用增量式则不太好;

六、PID算法的改进

1)积分饱和

位置式PID在积分项达到饱和时,误差仍然会在积分作用下继续累积,一旦误差开始反向变化,系统需要一定时间从饱和区退出。

解决方法:

1、积分限幅:在积分积累达到最大值时,停止积分的积累。

//积分限幅
if(pid->integral > IntegralMAX) pid->integral = IntegralMAX;
else if(pid->integral < -IntegralMAX) pid->integral = -IntegralMAX;

2、变速积分:

在系统误差较大时对积分进行积累会导致积分过饱和,此后需要很长的一段时间进行消除。所以我们希望在系统偏差大时积分作用应减弱甚至全无,而在偏差小时则应加强。变速积分可以根据系统偏差大小改变积分的速度。

使用变速积分后I项的表达式:

其中系数f 为:

当积分误差小于B时,对误差进行全积累;当误差大于A+B时,不积累;当误差处于两者之间时,积累量和误差值是线性关系

若A=0,f取值为0或1,此时为积分分离

3、抗积分饱和

是在计算输出的时候,先判断上一时刻的控制量U(k-1)是否已经超出了限制范围。若U(k-1)>Umax,则只累加负偏差;若U(k-1)<Umin,则只累加正偏差。从而避免控制量长时间停留在饱和区。

2)梯形积分

在积分项中,默认是按矩形方式来计算积分,将矩形积分改为梯形积分可以提高运算精度。即在每次计算积分时,积累的误差总是修改为当前误差与上一次误差的平均值。

3)不完全微分

从PID控制的基本原理我们知道,微分信号的引入可改善系统的动态特性,但也存在一个问题,那就是容易引进高频干扰,在偏差扰动突变时尤其显出微分项的不足。为了解决这个问题人们引入低通滤波方式来解决这一问题。

位置式PID的微分部分计算公式:

增量式PID的微分部分计算公式:

其中\alpha为不完全微分系数。

4)死区PID控制

在实际控制中可能总是存在微小的静差难以消除,导致系统频繁地不稳定,这时就可以引入带死区的PID算法,即在偏差达到一定程度时才进行调节,否则认为已经到达目标值。

5)步进式PID

所谓步进式PID算法,实际就是在设定值发生阶跃变化时,不直接对阶跃信号进行响应,而是在一定的时间内逐步改变设定值,直至使设定值达到目标值。这种逐步改变设定值的办法使得对象运行平稳。适用于高精度伺服系统的位置跟踪。

其基本思想是设定一个适当的步长,每次控制移动一个步长的值,直到达到目标值。

float StepInProcessing(pid_t *vPID)
{
  float stepIn=(vPID->maximum-vPID->minimum))*0.1;
  float kFactor=0.0;

  if(fabs(vPID->actual_val - vPID->target_val)<=stepIn)
  {
    vPID->actual_val = vPID->target_val;
  }
  else
  {
    if(vPID->actual_val - vPID->target_val > 0)
    {
      kFactor=-1.0;
    }
    else if(vPID->actual_val - vPID->target_val < 0)
    {
      kFactor=1.0;
    }
    else
    {
      kFactor=0.0;
    }
    vPID->actual_val = vPID->actual_val + kFactor*stepIn;
  }

  return vPID->actual_val;
}

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

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

相关文章

Tensorflow入门实战 T05-运动鞋识别

目录 一、完整代码 二、训练过程 &#xff08;1&#xff09;打印2行10列的数据。 &#xff08;2&#xff09;查看数据集中的一张图片 &#xff08;3&#xff09;训练过程&#xff08;训练50个epoch&#xff09; &#xff08;4&#xff09;训练结果的精确度 三、遇到的问…

0618,0619 ,指针,指针与数组,字符串

目录 第八章&#xff08;指针&#xff09;&#xff0c;第九章&#xff08;指针和数组&#xff09;&#xff0c;第十章&#xff08;字符串&#xff09;思维导图 作业1 逆序打印 解答&#xff1a; 答案&#xff1a; 作业2 判断回文 解答&#xff1a; 答案&#xff1a; …

PCB设计隐藏的陷进

1、BGA芯片的开窗和过油设计。 加工工艺中&#xff0c;范式过孔都需要盖油设计&#xff0c;实心焊盘需要开窗设计&#xff0c;坚决不能盖油。 2、通孔设计的互联连通性 比如H3芯片的wifi设计&#xff0c;实际上是没有联通的&#xff0c;虽然四层板的中间层有焊盘&#xff0c;但…

【C++ | 移动构造函数】C++11的 移动构造函数 详解及例子代码

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; ⏰发布时间⏰&#xff1a;2024-06-12 2…

Mamaba3--RNN、状态方程、勒让德多项式

Mamaba3–RNN、状态方程、勒让德多项式 一、简单回顾 在Mamba1和Mamba2中分别介绍了RNN和状态方程。 下面从两个图和两个公式出发&#xff0c;对RNN和状态方程做简单的回顾&#xff1a; R N N : s t W s t − 1 U x t &#xff1b; O t V s t RNN: s_t Ws_{t-1}Ux_t&…

前字节员工自爆:我原腾讯一哥们,跳槽去小公司做小领导,就签了竞业,又从小公司离职去了对手公司,结果被发现了,小公司要他赔80万

“世界那么大&#xff0c;我想去看看”&#xff0c;这句曾经火遍网络的辞职宣言&#xff0c;说出了多少职场人心中的渴望。然而&#xff0c;当我们真的迈出跳槽那一步时&#xff0c;才发现&#xff0c;现实远比想象中残酷得多。 最近&#xff0c;一起前字节跳动员工爆料的事件…

22种常用设计模式示例代码

文章目录 创建型模式结构型模式行为模式 仓库地址https://github.com/Xiamu-ssr/DesignPatternsPractice 参考教程 refactoringguru设计模式-目录 创建型模式 软件包复杂度流行度工厂方法factorymethod❄️⭐️⭐️⭐️抽象工厂abstractfactory❄️❄️⭐️⭐️⭐️生成器bui…

自学网络安全 or Web安全,一般人我还是劝你算了吧

由于我之前写了不少网络安全技术相关的文章&#xff0c;不少读者朋友知道我是从事网络安全相关的工作&#xff0c;于是经常有人私信问我&#xff1a; 我刚入门网络安全&#xff0c;该怎么学&#xff1f; 要学哪些东西&#xff1f; 有哪些方向&#xff1f; 怎么选&#xff1f;…

福昕PDF编辑器快速去除PDF水印方法

在福昕PDF编辑器软件中打开一个带有水印的PDF文件&#xff0c;点击如图下所示的页面管理->水印&#xff0c;点击全部移除 点击 是 水印消除&#xff08;注&#xff1a;部分类型的水印可以消除&#xff0c;但是有些类型的水印无法通过此方法消除&#xff09;

Day28:回溯法 491.递增子序列 46.全排列 47.全排列 II 332.重新安排行程 51. N皇后 37. 解数独 蓝桥杯 与或异或

491. 非递减子序列 给你一个整数数组 nums &#xff0c;找出并返回所有该数组中不同的递增子序列&#xff0c;递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 数组中可能含有重复元素&#xff0c;如出现两个整数相等&#xff0c;也可以视作递增序列的一种特殊情…

Flask新手入门(一)

前言 Flask是一个用Python编写的轻量级Web应用框架。它最初由Armin Ronacher作为Werkzeug的一个子项目在2010年开发出来。Werkzeug是一个综合工具包&#xff0c;提供了各种用于Web应用开发的工具和函数。自发布以来&#xff0c;Flask因其简洁和灵活性而迅速受到开发者的欢迎。…

昇思大模型学习·第一天

mindspore快速入门回顾 导入mindspore包 处理数据集 下载mnist数据集进行数据集预处理 MnistDataset()方法train_dataset.get_col_names() 打印列名信息使用create_tuple_iterator 或create_dict_iterator对数据集进行迭代访问 网络构建 mindspore.nn: 构建所有网络的基类用…

Docker(四)-Docker镜像

1.概念 镜像是一种轻量级的、可执行的独立软件包&#xff0c;它包含运行某个软件所需的所有内容&#xff0c;我们把应用程序和配置依赖 打包好形成一个可交付的运行环境(包括代码&#xff0c;运行时需要的库&#xff0c;环境变量和配置文件等)&#xff0c;这个打包好的运行环境…

docker pull xxx拉取超时time out

文章目录 前言总结 前言 换了镜像源&#xff0c;改配置的都不行&#xff0c;弄了一个下午&#xff0c;最后运行一下最高指令就可以了 sudo docker_OPTS"--dns 8.8.8.8"总结 作者&#xff1a;加辣椒了吗&#xff1f; 简介&#xff1a;憨批大学生一枚&#xff0c;喜欢…

STM32自己从零开始实操06:无线电路原理图

一、WIFI 模块电路设计 1.1指路 延续使用 ESP-12S 芯片&#xff0c;封装 SMD 16x24mm。 实物图 原理图与PCB图 2.2电路图 电路较为简单&#xff0c;如下图&#xff1a; 2.2.1引脚说明 序号引脚名称描述1RST复位复位引脚&#xff0c;低电平有效3EN使能芯片使能端&#xff0c…

【深度学习】sdwebui A1111 加速方案对比,xformers vs Flash Attention 2

文章目录 资料支撑资料结论sdwebui A1111 速度对比测试sdxlxformers 用contorlnet sdxlsdpa&#xff08;--opt-sdp-no-mem-attention&#xff09; 用contorlnet sdxlsdpa(--opt-sdp-attention) 用contorlnet sdxl不用xformers或者sdpa ,用contorlnet sdxl不用xformers或者sdpa …

Windows安装配置jdk和maven(仅做记录)

他妈的远程连接不上公司电脑&#xff0c;只能在家重新配置一遍&#xff0c;在此记录一下后端环境全部配置 Windows安装配置JDK 1.8一、下载 JDK 1.8二、配置环境变量三、验证安装 Windows安装配置Maven 3.8.8一、下载安装 Maven并配置环境变量二、设置仓库镜像及本地仓库三、测…

BUU CODE REVIEW 11 代码审计之反序列化知识

打开靶场&#xff0c;得到的是一段代码。 通过分析上面代码可以构造下面代码&#xff0c;获取到序列化之后的obj。 <?php class BUU {public $correct "";public $input "";public function __destruct() {try {$this->correct base64_encode(u…

如何解决input输入时存在浏览器缓存问题?

浏览器有时会在你输入表单过后缓存你的输入&#xff0c;有时候能提供方便。 但是在某些新建或新页面情况下出现历史的输入信息&#xff0c;用户体验很差。 解决方案 设置 autocomplete关闭 &#xff1a;<input type"text" autocomplete"off">增加…

[AIGC] MyBatis-Plus中如何使用XML进行CRUD操作?

在MyBatis-Plus中&#xff0c;我们可以非常方便地使用XML进行CRUD&#xff08;创建、读取、更新、删除&#xff09;操作。以下是一些基本步骤和示例&#xff0c;希望能帮助到还在初学阶段的您。 文章目录 1. 创建Mapper接口2. 创建Mapper XML 文件3. 调用Mapper方法 1. 创建Ma…