PID控制器整理分享

2023-05-16

概述

日常开发中,常常需要对速度、温度等物理量进行稳态控制,而在目前的自动化控制原理中,使用最为广泛的方法就是PID控制算法。本文简要整理分享PID控制器的使用。

正文

PID控制器,即比例-积分-微分控制器。它是一个不依赖系统模型,仅依赖系统输出即可进行控制的负反馈控制器。PID控制器通过直观地观测当前误差(比例作用)过去的误差(积分作用)误差的变化趋势(微分作用) 来进行系统控制。

PID控制器的数学公式可以写成: u = K p ∗ e + K i ∗ ∫ e d t + K d ∗ d e d t u=K_p*e+K_i*\int{e}dt+K_d*\frac{de}{dt} u=Kpe+Kiedt+Kddtde

其中:

e e e是当前误差

K p K_p Kp是比例增益系数

K i K_i Ki是积分增益系数

K d K_d Kd是微分增益系数

所以,从上述公式可以看出,PID控制器对系统的控制作用是比例项、积分项、微分项的加权和。

其次,衡量一个系统的状态,可以从稳定性、准确性、快速性来衡量。其中,

P和I降低系统稳定性,D提高系统稳定性

P和I减小静态误差,D无作用

P和D提高响应速度,I降低响应速度

PID调参方法

(1)整定比例项

方法:先将积分、微分作用去除,设置目标值为系统最大控制量的70%。然后,逐渐加大比例作用,直到系统发生震荡。观察控制量波形,若波形的波峰由大变小,且最终稳定在某个值,且第一个波峰与第二个波峰之间数值比约为4:1。那么可以把当前 K p K_p Kp固定。

(2)整定积分项

方法:逐渐减小积分时间,使得积分项作用增强,观察控制量波形。若控制量静差为0,则可以把当前 T i T_i Ti固定下来。

(3)整定微分项

方法:逐渐增加微分时间,使得微分项作用增强,观察控制量波形。若控制量波形震荡减小至基本无震荡,则可以把当前 T d T_d Td固定下来。

(4)微调参数

方法:若发现粗调后,系统稳定性不足(震荡多),则稍稍加大 T d T_d Td;若准确性不足,则稍稍减小 T i T_i Ti;循环往复观察对比,调整 T i T_i Ti T d T_d Td,直到满足系统要求为止。

对于联级PID的调参方法与单环PID调参方法一样,只是联级PID调参时,需要先整定内环,再整定外环(即先将外环作用去除)

使用matlab simulink简单测试调参方法

参数及效果如下:
在这里插入图片描述
在这里插入图片描述

代码实现

PID控制器分为位置式PID增量式PID

位置式PID公式: u ( k ) = K p ∗ e ( k ) + K p ∗ T T i ∗ ∑ i = 1 k e ( i ) + K p ∗ T d T ∗ [ e ( k ) − e ( k − 1 ) ] u(k)=K_p*e(k)+\frac{K_p*T}{T_i}*{\sum_{i=1}^{k}e(i)}+\frac{K_p*T_d}{T}*\left[e(k)-e(k-1)\right] u(k)=Kpe(k)+TiKpTi=1ke(i)+TKpTd[e(k)e(k1)]

由于基于误差的微分方程存在微分冲击的缺陷,所以微分项可以改进为: − K p ∗ T d T [ P v ( k ) − P v ( k − 1 ) ] -\frac{K_p*T_d}{T}\left[Pv(k)-Pv(k-1)\right] TKpTd[Pv(k)Pv(k1)]

所以C代码如下:

void pid_calc(pid_t *pid)
{
	float DelPv;
	float ti,ki;
	float td;
	float kd;
	float out;
 
    pid->Ek = pid->Sv - pid->Pv;   		//得到当前偏差值
    pid->Pout = pid->Kp * pid->Ek; 		//比例输出

	//抗积分饱和
 	if(pid->OUT >= pid->pwmcycle)
 	{
 		if(pid->Ek < 0)
 			pid->SEk += pid->Ek;
 	}
 	else if(pid-OUT <= pid->OUT0)
 	{
 		if(pid->Ek > 0)
 			pid->SEk += pid->Ek;
 	}
	else
		pid->SEk += pid->Ek;
// 	pid->SEk += pid->Ek;        		//历史偏差总和
    ti = pid->T / pid->Ti;
    ki = ti * pid->Kp;
    pid->Iout = ki * pid->SEk;  	//积分输出

	DelPv = pid->Pv - pid->Pv_1;
    td = pid->Td / pid->T;
    kd = pid->Kp * td;
    pid->Dout = kd * DelPv;    			//微分输出
 
    out = pid->Pout + pid->Iout - pid->Dout;
 
	//输出限幅
    if(out > pid->pwmcycle)
    {
        pid->OUT = pid->pwmcycle;
    }
    else if(out < 0)
    {
        pid->OUT = pid->OUT0; 
    }
    else 
    {
        pid->OUT = out;
    }

	pid->Pv_1 = pid->Pv;
}

增量式PID公式: Δ u = K p ∗ [ e ( k ) − e ( k − 1 ) ] + K p ∗ T T i ∗ e ( k ) + K p ∗ T d T ∗ [ e ( k ) − 2 ∗ e ( k − 1 ) + e ( k − 2 ) ] \Delta{u}=K_p*\left[e(k)-e(k-1)\right]+\frac{K_p*T}{T_i}*e(k)+\frac{K_p*T_d}{T}*\left[e(k)-2*e(k-1)+e(k-2)\right] Δu=Kp[e(k)e(k1)]+TiKpTe(k)+TKpTd[e(k)2e(k1)+e(k2)]

同样的,可以改进式子以消除微分冲击:

− K p ∗ T d T [ P v ( k ) − 2 ∗ P v ( k − 1 ) + P v ( k − 2 ) ] -\frac{K_p*T_d}{T}\left[Pv(k)-2*Pv(k-1)+Pv(k-2)\right] TKpTd[Pv(k)2Pv(k1)+Pv(k2)]

所以C代码如下:

void incremental_pid_calc(pid_t *pid)
{
	float DelPv;
	float ti,ki;
	float td,kd;
	float beta;
	float out;

	pid->Ek = pid->Sv - pid->Pv;	//当前误差

	//积分分离
	if(fabs(pid->Ek) <= 100) 	//偏差较大时,不加入积分作用
		beta = 1;
	else
		beta = 0;

	//比例项输出
	pid->Pout = pid->Kp * (pid->Ek - pid->Ek_1);
	//积分项输出
	ti = pid->T / pid->Ti;
    ki = ti * pid->Kp;
	pid->Iout = beta * ki * pid->Ek;
	//微分项输出
	DelPv = pid->Pv - (2 * pid->Pv_1 ) + pid->Pv_2;//抗微分冲击
	td = pid->Td / pid->T;
	kd = td * pid->Kp;
	pid->Dout = kd * DelPv;

	out = pid->Pout + pid->Iout - pid->Dout;

	//输出限幅
	if(out > pid->pwmcycle)
        pid->OUT = pid->pwmcycle;
    else if(out < 0)
        pid->OUT = pid->OUT0; 
    else 
        pid->OUT = out;

    //死区限定
	if(fabs(pid->Ek) <= 10)
		pid->OUT = pid->OUT0; 

   	pid->Ek_1 = pid->Ek;
   	pid->Pv_2 = pid->Pv_1;
   	pid->Pv_1 = pid->Pv;
}

总结

这样就可以移植和使用PID控制了。实际开发中,经典PID控制器基本不适用,所以常常需要对PID控制器进行一下改进,如加入积分分离、微分先行、死区控制等方式优化。所以,虽然PID控制原理很简单,但是调参及优化才是比较花时间的地方。熟能生巧,用多了,自然就会了。关于PID的整理分享就到这儿,说得不好的地方请大佬们指教。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PID控制器整理分享 的相关文章

  • 关于ARM_math数学库的使用

    关于ARM math数学库的使用 ARM math好强大的好吧 话不多说 请看截图 各种数学库看到没有 好强大的说 其实使用这些写函数 最快上手的方法就是看官方手册 话不多说 上官方链接arm math库的官网 举个栗子 一般步骤 1 首先
  • PID控制器开发笔记之九:基于前馈补偿的PID控制器的实现

    对于一般的时滞系统来说 设定值的变动会产生较大的滞后才能反映在被控变量上 从而产生合理的调节 而前馈控制系统是根据扰动或给定值的变化按补偿原理来工作的控制系统 其特点是当扰动产生后 被控变量还未变化以前 根据扰动作用的大小进行控制 以补偿扰
  • 电机控制进阶——PID速度控制

    之前的几篇文章 电机控制基础篇 介绍的电机编码器原理 定时器输出PWM 定时器编码器模式测速等 本篇在前几篇的基础上 继续来学习电机控制 通过PID算法 来进行电机的速度控制 并进行实验测试 PID基础 PID即 Proportional
  • PID自控理论(频域bode图理论分析)

    PID 迟后超前矫正 临界比例度法整定PID 在低频区 主要是PI控制器起作用 用以提高系统型别消除或减小稳态误差 在中 高频区 主要是PD控制器起作用 用以增大幅值穿越频率和相位裕度 提高系统的响应速度 因此 PID控制器可以全面地提高系
  • PID算法应用于室内温度控制的C语言实现

    我最近在学习PID算法 对此很感兴趣 所以与大伙分享下 有不足的地方欢迎指出 非常谢谢 PID算法的基本内容本篇博客就不做阐述了 网上有很多资料 文章的主题是用C语言实现PID算法 为了更好的理解 我采用软件模拟室内温度控制的方式与大伙分享
  • 深入浅出PID控制算法(三)————增量式与位置式PID算法的C语言实现与电机控制经验总结

    前文对PID算法离散化和增量式PID算法原理进行来探索 之后又使用Matlab进行了仿真实验 对PID三个参数又有了更深入的认识 接下来我们来使用C语言进行PID算法实现 并且结合控制电机的项目来深入学习 1 PID 算法C 语言原代码 先
  • # Arduino小车PID调速——整定参数初试水

    Arduino小车PID调速 整定参数初试水 在实现了小车较为可靠的测速基础上 便可以正式开展PID调速实验了 本文是基于使用Arduino平台上由Brett Beauregard大神写的PID库进行参数整定的 侧重于在对PID算法有基本了
  • PID控制算法01

    PID控制算法 PID控制算法公式 原理 参数作用 PID算法及改进 两个基本类型 位置型PID控制 增量型PID控制 积分环节改进的PID控制 积分分离的PID控制 变速积分的PID控制 抗积分饱和的PID控制 微分环节改进的PID控制
  • 如何在Python中检查是否存在给定pid的进程?

    有没有办法检查 pid 是否对应于有效进程 我从其他来源获取 pid 而不是os getpid 我需要检查机器上是否不存在具有该 pid 的进程 我需要它在 Unix 和 Windows 中可用 我还在检查 PID 是否未被使用 如果 pi
  • copy_from_user() 的任何示例吗?内核和用户空间

    我正在寻找将 PID 值从用户空间复制到内核空间 这是我的代码快照 内核模块 include
  • 在 Unix 环境中检测过时的 pid 文件

    在 Unix 环境中检测陈旧 pid 文件的标准 跨平台方法是什么 假设我想终止应用程序的旧实例 但如果该应用程序已经退出 我当然不想破坏具有相同 PID 的不相关进程 现在我找到了一种在我的 Ubuntu 也可能是其他基于 GNU Lin
  • 有没有办法确定 Linux PID 是否暂停?

    我有一个 python 脚本 它使用 SIGSTOP 和 SIGCONT 命令与 os kill 来暂停或恢复进程 有没有办法判断相关PID是处于暂停状态还是恢复状态 您可以从进程的 proc 目录 proc
  • Ubuntu Java:查找特定程序的 pid 并终止该程序

    我正在尝试创建一个应用程序来检查此特定应用程序是否正在运行 然后在指定的时间后终止该应用程序 我打算获取应用程序的 pid 如何获取应用程序的 pid Thanks 你可以尝试ps aux grep foobar获取 pid 然后发出kil
  • os.kill 没有引发 OSError,但是我没有看到给定的 pid 正在运行

    在我的 ubuntu 服务器上运行以下命令 python c import os os kill 5555 0 这样做是为了查看 pid 5555 是否正在运行 根据我的理解 如果 pid 没有运行 这应该会引发 OSError 这不会对我
  • 检查给定 pid 的进程是否存在

    给定 Linux 进程的 pid 我想从 C 程序检查该进程是否仍在运行 Issue a kill 2 http linux die net man 2 kill系统调用0作为信号 如果调用成功 则说明存在该pid的进程 如果呼叫失败并且e
  • 如何查看linux中特定进程每5秒的内存消耗情况

    我只是想知道如何找到特定进程在特定时间 比如5秒 的内存消耗 我是linux新手 因此 详细的步骤将不胜感激 Use top p PID其中 PID 是进程 ID 应显示有关进程的信息 包括使用的系统内存百分比 类型d以及一个以秒为单位的整
  • mysql.server 启动时出现 PID 错误?

    我刚刚尝试使用自制程序 在 Mac OS X 10 6 上 安装 MySQL 但我在第一个障碍时遇到了问题 当尝试手动启动服务器 mysql server start 时 出现以下错误 ERROR Manager of pid file q
  • 在 python 中,是否有跨平台的方法来确定哪个进程正在侦听给定端口?

    在linux下 我可以使用lsof i如以下函数所示 def FindProcessUsingPort portnum import os fp os popen lsof i s portnum lines fp readlines fp
  • 如何通过VBA获取当前Excel实例的进程ID,而不使用标题?

    如何获取运行 VBA 代码的当前 Excel 实例的进程 ID 我不想通过标题中的名称来请求它 当我有两个或多个具有相同标题的 Excel 实例时 这会导致问题 您可以使用此方法来获取当前进程ID Declare Function GetC
  • 查找PID所属的tmux会话

    我正在使用 htop 所以看看哪些进程占用了大量内存 以便我可以杀死它们 我有很多 tmux 会话和很多类似的流程 如何检查 PID 位于哪个 tmux 窗格中 以便确定我正在杀死我想杀死的东西 鉴于PID下面一行是目标 pid 号 tmu

随机推荐

  • python watchdog:监控文件系统事件的Python库

    python watchdog xff1a 监控文件系统事件的Python库和shell工具 watchdog用来监控指定目录 文件的变化 xff0c 如添加删除文件或目录 修改文件内容 重命名文件或目录等 xff0c 每种变化都会产生一个
  • 关于c语言的udp通讯详细讲解

    目录 1 UDP简介 2 UDP通信流程 3 UDP的函数接口说明 4 UDP通讯测试代码 1 UDP简介 UDP全称 User Datagram Protocol xff0c 即 xff1a 用户数据报协议 是面向无连接的协议 通常 xf
  • python中关于Opencv中关于矩形的函数总结

    最近处理图像 xff0c 以前用的都是matlab xff0c 现在入手python比较慢 xff0c 这几天看到了很多命名和功能相似的函数 xff0c 作个记录总结一下 只是为了能够看下函数知道它是做什么的 xff0c 因此不会对其用法说
  • 在虚拟机中安装Ubuntu-Docker

    在虚拟机中安装Ubuntu Docker 第一步 安装虚拟机 1 安装虚拟机 xff0c 测试网络联网 图 1 安装ubuntu 图 2 设置系统时间 2 建立快照 建立快照 xff1a 快照001 安装成功 第二步 内核更新 可以通过do
  • Java中的toString()方法

    一 toString 方法介绍 toString 方法是 Object 类中的方法 xff0c toString 方法源代码如下 xff1a 1 getClass getName 返回类的全类名 包名 43 类名 2 Integer toH
  • 二十八. Semaphore的使用详解

    前言 Semaphore的官方注释如下 计数信号量 从概念上讲 xff0c 信号量维护一组许可证 xff08 permits xff09 通常 xff0c 每次调用Semaphore acquire方法时如果已经没有许可证 xff0c 则会
  • FreeRTOS vTaskDelay 卡死

    在Task中使用动态方法创建任务后 xff0c 在任务中调用vTaskDelay卡死 xff0c 然后排查问题 xff0c 定时器工作正常 xff0c 如果不使用vTaskDelay也可以一直运行 解决办法 xff0c 改成在main方法中
  • 图像为什么能相减

    前面提到 xff0c 我们可以把图像看作一个函数 xff0c 函数和函数之间是可以相加的 f x y 61 I 1 x y 43 I 2 x y 那么 xff0c 既然函数可以相加 xff0c 函数也是可以相减的 所以 xff0c 图像之间
  • 分析评估和定位声音质量

    64 author wangdaopo 64 email 3168270295 64 qq com 影响音频质量和稳定性的因素 音质好坏的评价 xff0c 响度 音高 音色 xff0c 测试 xff0c 你的语音引擎是基本可用的 xff0c
  • Linux下Clang-format代码格式化

    64 author wangdaopo 64 email 3168270295 64 qq com 1 Clang format 代码格式化介绍 平时团队进行合作的时候需要注意代码的格式 xff0c 虽然很难统一每个人的编码风格 xff0c
  • OOM问题预防和排查内存泄漏及解决方法

    64 author wangdaopo 64 email 3168270295 64 qq com 理解了这个算法我们就理解了为啥 MySQL 躺着也能中枪了 xff0c 因为它的体积总是最大 xff08 一般来说它在系统上占用内存最多 x
  • API调用次数限制实现

    API调用次数限制实现 在开发接口服务器的过程中 xff0c 为了防止客户端对于接口的滥用 xff0c 保护服务器的资源 xff0c 通常来说我们会对于服务器上的各种接口进行调用次数的限制 比如对于某个 用户 xff0c 他在一个时间段 x
  • 虚拟声卡

    一 虚拟声卡是什么 xff1f 虚拟声卡是一种软件产品 xff0c 它只对声音数字信号进行处理 虽然它不能产生声音 xff0c 但可以用来实现声音的传输 存储或混音等功能 1 xff09 虚拟声卡工作原理 xff1a 虚拟声卡通过软件技术实
  • 常用排查调试工具

    64 author wangdaopo 64 email 3168270295 64 qq com 工具 描述 strace Linux分析程序运行速度瓶颈 strace是个功能强大的Linux调试分析诊断工具 尤其是针对源码不可读或源码无
  • meson是用Python语言开发的构建工具,编译需要Ninja(用C++实现)命令。Meson 旨在开发最具可用性和快速的构建系统。

    目录 一 meson和ninja简介 二 meson构建和ninja编译环境搭建 三 meson构建和ninja编译程序使用步骤 四 项目构建工具Meson PyAnnolib pyBit Open Build Service介绍 五 参考
  • 一套实时音视频传输机制和QOS策略选择及语音视频SDK的选型标准

    64 author wangdaopo 64 email 3168270295 64 qq com 语音视频SDK的选型标准 设备的问题 网络部分 物理场景 一套实时的传输机制 sip是通讯协议 xff0c sip只是信令 xff0c 就是
  • sample.html

    目录 一 Html使用注意 1 二 界面设计 xff08 css xff09 9 三 表单使用 15 Jquery判断表单是否修改 15 表单序列化为json对象 16 json对象转为json字符串 16 json对象赋值到表单 xff0
  • Cgi使用

    目录 一 CGI xff08 通用网关接口 xff09 是外部扩展应用程序与 Web 服务器交互的一个标准接口 1 二 web服务器配置 3 三 Cgi编程 xff08 根据CGI标准 xff0c 编写Web服务器运行时的外部扩展应用程序
  • mmap内存映射在应用和内核/驱动交互,进程间交互,大规模数据传输/大文件读写中的使用

    目录 一 Mmap用途 步骤实例 细节 及相关函数 2 1 mmap函数主要用途有三个 xff08 应用和内核 驱动交互 xff0c 进程间交互 xff0c 大规模数据传输 大文件读写 xff09 2 2 使用步骤 xff1a 所有对mma
  • PID控制器整理分享

    概述 日常开发中 xff0c 常常需要对速度 温度等物理量进行稳态控制 xff0c 而在目前的自动化控制原理中 xff0c 使用最为广泛的方法就是PID控制算法 本文简要整理分享PID控制器的使用 正文 PID控制器 xff0c 即比例 积