单片机学习小组
登录
直播中
香脆面
11年用户
575经验值
私信
关注
什么是PID控制算法呢?PID控制算法有何作用
开启该帖子的消息推送
PID
控制算法
PID控制
什么是PID控制算法呢?PID控制算法有何作用?
PID控制算法有哪几种类型呢?如何对其进行测试?
回帖
(1)
李丽波
2022-2-25 09:42:02
1、PID算法简介
PID(proportion integration differentiation)其实就是指比例,积分,微分控制。目前来说,PID控制算法是一种使用非常广泛的算法。比在平衡车、无人机等方面的应用。PID算法是简单,又能体现反馈思想的控制算法,可谓经典中的经典。
PID控制流程简单,通过误差信号控制被测量,并且控制器本身就是比例、积分、微分3个环节的加和。通过这三个的组合可有效地纠正被控制对象的偏差,从而使其达到一个稳定的状态。
PID控制规律:
kp——比例增益,kp与比例度成倒数关系;
T——积分时间常数;
TD——微分时间常数;
u(x)——PID控制器的输出信号;
e(t)——给定值r(t)与测量值之差。
1.1、各个环节的作用
1、PID控制其实是对偏差的控制。
2、如果偏差为0,则比例环节不起作用,只有存在偏差时,比例环节才起作用。
3、积分环节主要是来消除静差,所谓静差,就是系统稳定后输出值和和设定值之间的差值,积分环节实际上就是偏差累计的过程,把累计的误差加到原来的所有系统上以抵消系统的静差。
4、微分信号则反应了偏差信号的变换规律,或者说变化趋势,根据偏差信号变化趋势来经行超前调节,增加系统的快速性。
2、位置型PID算法
2.1、离散表达形式:
2.2、位置型代码
核心算法部分。
main函数,按下开发板的KEY0,程序开始测试。
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "pid.h"
#include "usart.h"
#include "key.h"
//PID算法测试
int main(void)
{
int count;
u8 key;
delay_init(); //延时函数初始化
LED_Init(); //初始化与LED连接的硬件接口
KEY_Init();
PID_init();
uart_init(9600);
printf("System begin rn");
while(1)
{
key = KEY_Scan(0);
while(count<1000)
{
float speed = PID_realize(200.0);
printf("%f rr",speed);
count++;
}
delay_ms(10);
if(key == KEY0_PRES)
{
count =0;
}
}
}
pid.c 文件
统一初始化变量,尤其是Kp、Ki、Kd3个参数,对于要求的控制效果调试过程中,通过调试这个3个变量直接进行调参。
#include "pid.h"
#include "usart.h"
struct _pid
{
float SetSpeed; //定义设定值
float ActualSpeed; //定义实际值
float err ; // 定义偏差值
float err_last; //定义上一个偏差值
float Kp,Ki,Kd; //定义比例、积分、微分系数
float voltage; //定义电压值 控制器执行的变量
float integral; //定义积分值
}pid;
void PID_init()
{
printf("Pid_init beginrn");
pid.SetSpeed = 0.0;
pid.ActualSpeed = 0.0;
pid.err = 0.0;
pid.err_last = 0.0;
pid.voltage = 0.0;
pid.integral = 0.0;
pid.Kp = 0.2;
pid.Ki = 0.015;
pid.Kd =0.2;
printf("PID_init end rn");
}
float PID_realize(float speed)
{
pid.SetSpeed = speed;
pid.err = pid.SetSpeed - pid.ActualSpeed ;
pid.integral += pid.err ;
// 算法基本公式 没有考虑死区问题和上下限
pid.voltage = pid.Kp*pid.err+pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last);
pid.err_last = pid.err;
pid.ActualSpeed = pid.voltage*1.0;
return pid.ActualSpeed;
}
pid.h 文件
#ifndef __PID_H
#define __PID_H
void PID_init(void);
float PID_realize(float speed);
#endif
2.3、测试效果
emsp; 一部分数据,可以看到,逐渐的趋近了200,设定值200,但是这个过程相对比较长。
3、增量型PID算法
3.1 、离散表达式:
3.2 增量型代码
核心算法部分。
main函数代码如下:
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "pid.h"
#include "usart.h"
#include "key.h"
//PID算法测试
int main(void)
{
int count;
u8 key;
delay_init(); //延时函数初始化
LED_Init(); //初始化与LED连接的硬件接口
KEY_Init();
PID_init();
uart_init(9600);
printf("System begin rn");
while(1)
{
key = KEY_Scan(0);
while(count<1000)
{
float speed = PID_realize(200.0);
printf("%f rr",speed);
count++;
}
delay_ms(10);
if(key == KEY0_PRES)
{
count =0;
}
}
}
pid.c 代码如下:
统一初始化变量,尤其是Kp、Ki、Kd3个参数,对于要求的控制效果调试过程中,通过调试这个3个变量直接进行调参。
#include "pid.h"
#include "usart.h"
#include
#include
struct _pid
{
float SetSpeed; //定义设定值
float ActualSpeed; //定义实际值
float err ; // 定义偏差值
float err_next; //定义上一个偏差值
float err_last; //定义上上一个偏差值
float Kp,Ki,Kd; //定义比例、积分、微分系数
}pid;
void PID_init()
{
printf("Pid_init beginrn");
pid.SetSpeed = 0.0;
pid.ActualSpeed = 0.0;
pid.err = 0.0;
pid.err_next = 0.0;
pid.err_last = 0.0;
pid.Kp = 0.2;
pid.Ki = 0.015;
pid.Kd =0.2;
printf("PID_init end rn");
}
float PID_realize(float speed)
{
float incrementSpeed;
pid.SetSpeed = speed;
pid.err = pid.SetSpeed - pid.ActualSpeed ;
// 算法基本公式
incrementSpeed = pid.Kp*(pid.err-pid.err_next)+pid.Ki *pid.err+pid.Kd*(pid.err-2*pid.err_next+pid.err_last);
pid.ActualSpeed += incrementSpeed;
pid.err_last = pid.err_next ;
pid.err_next = pid.err ;
return pid.ActualSpeed ;
}
pid.h 文件如下:
#ifndef __PID_H
#define __PID_H
void PID_init(void);
float PID_realize(float speed);
#endif
3.3、效果展示
4、积分分离的PID控制算法
基本思路是,当被控制量与设定的值偏差较大时,取消积分作用,当被控量接近给定值时,引入积分控制,以消除静差,提高精度。
4.1、代码实现
main函数:
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "pid.h"
#include "usart.h"
#include "key.h"
//PID算法测试
int main(void)
{
int count;
u8 key;
delay_init(); //延时函数初始化
LED_Init(); //初始化与LED连接的硬件接口
KEY_Init();
PID_init();
uart_init(9600);
printf("System begin rn");
while(1)
{
key = KEY_Scan(0);
while(count<1000)
{
float speed = PID_realize(200.0);
printf("%f rr",speed);
count++;
}
delay_ms(10);
if(key == KEY0_PRES)
{
count =0;
}
}
}
pid.c 文件
#include “pid.h”
#include “usart.h”
#include
#include
struct _pid
{
float SetSpeed; //定义设定值
float ActualSpeed; //定义实际值
float err ; // 定义偏差值
float err_last; //定义上一个偏差值
float Kp,Ki,Kd; //定义比例、积分、微分系数
float voltage; //定义电压值 控制器执行的变量
float integral; //定义积分值
}pid;
void PID_init()
{
printf(“Pid_init beginrn”);
pid.SetSpeed = 0.0;
pid.ActualSpeed = 0.0;
pid.err = 0.0;
pid.err_last = 0.0;
pid.voltage = 0.0;
pid.integral = 0.0;
pid.Kp = 0.2; //比例
pid.Ki = 0.04; //积分
pid.Kd =0.2; //微分
printf(“PID_init end rn”);
}
float PID_realize(float speed)
{
int index;
pid.SetSpeed = speed;
pid.err = pid.SetSpeed - pid.ActualSpeed ;
pid.integral += pid.err ;
// 算法实现过程
if(abs(pid.err)>200) //设定值 200
{
index = 0;
}
else
{
index = 1;
pid.integral += pid.err ;
}
pid.voltage = pid.Kp*pid.err+index*pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last);
pid.err_last = pid.err;
pid.ActualSpeed = pid.voltage*1.0;
return pid.ActualSpeed;
}
4.2、效果图
通过测试,系统数据达到199所用的时间为原来的1/2,系统的快速性得到提升。
1、PID算法简介
PID(proportion integration differentiation)其实就是指比例,积分,微分控制。目前来说,PID控制算法是一种使用非常广泛的算法。比在平衡车、无人机等方面的应用。PID算法是简单,又能体现反馈思想的控制算法,可谓经典中的经典。
PID控制流程简单,通过误差信号控制被测量,并且控制器本身就是比例、积分、微分3个环节的加和。通过这三个的组合可有效地纠正被控制对象的偏差,从而使其达到一个稳定的状态。
PID控制规律:
kp——比例增益,kp与比例度成倒数关系;
T——积分时间常数;
TD——微分时间常数;
u(x)——PID控制器的输出信号;
e(t)——给定值r(t)与测量值之差。
1.1、各个环节的作用
1、PID控制其实是对偏差的控制。
2、如果偏差为0,则比例环节不起作用,只有存在偏差时,比例环节才起作用。
3、积分环节主要是来消除静差,所谓静差,就是系统稳定后输出值和和设定值之间的差值,积分环节实际上就是偏差累计的过程,把累计的误差加到原来的所有系统上以抵消系统的静差。
4、微分信号则反应了偏差信号的变换规律,或者说变化趋势,根据偏差信号变化趋势来经行超前调节,增加系统的快速性。
2、位置型PID算法
2.1、离散表达形式:
2.2、位置型代码
核心算法部分。
main函数,按下开发板的KEY0,程序开始测试。
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "pid.h"
#include "usart.h"
#include "key.h"
//PID算法测试
int main(void)
{
int count;
u8 key;
delay_init(); //延时函数初始化
LED_Init(); //初始化与LED连接的硬件接口
KEY_Init();
PID_init();
uart_init(9600);
printf("System begin rn");
while(1)
{
key = KEY_Scan(0);
while(count<1000)
{
float speed = PID_realize(200.0);
printf("%f rr",speed);
count++;
}
delay_ms(10);
if(key == KEY0_PRES)
{
count =0;
}
}
}
pid.c 文件
统一初始化变量,尤其是Kp、Ki、Kd3个参数,对于要求的控制效果调试过程中,通过调试这个3个变量直接进行调参。
#include "pid.h"
#include "usart.h"
struct _pid
{
float SetSpeed; //定义设定值
float ActualSpeed; //定义实际值
float err ; // 定义偏差值
float err_last; //定义上一个偏差值
float Kp,Ki,Kd; //定义比例、积分、微分系数
float voltage; //定义电压值 控制器执行的变量
float integral; //定义积分值
}pid;
void PID_init()
{
printf("Pid_init beginrn");
pid.SetSpeed = 0.0;
pid.ActualSpeed = 0.0;
pid.err = 0.0;
pid.err_last = 0.0;
pid.voltage = 0.0;
pid.integral = 0.0;
pid.Kp = 0.2;
pid.Ki = 0.015;
pid.Kd =0.2;
printf("PID_init end rn");
}
float PID_realize(float speed)
{
pid.SetSpeed = speed;
pid.err = pid.SetSpeed - pid.ActualSpeed ;
pid.integral += pid.err ;
// 算法基本公式 没有考虑死区问题和上下限
pid.voltage = pid.Kp*pid.err+pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last);
pid.err_last = pid.err;
pid.ActualSpeed = pid.voltage*1.0;
return pid.ActualSpeed;
}
pid.h 文件
#ifndef __PID_H
#define __PID_H
void PID_init(void);
float PID_realize(float speed);
#endif
2.3、测试效果
emsp; 一部分数据,可以看到,逐渐的趋近了200,设定值200,但是这个过程相对比较长。
3、增量型PID算法
3.1 、离散表达式:
3.2 增量型代码
核心算法部分。
main函数代码如下:
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "pid.h"
#include "usart.h"
#include "key.h"
//PID算法测试
int main(void)
{
int count;
u8 key;
delay_init(); //延时函数初始化
LED_Init(); //初始化与LED连接的硬件接口
KEY_Init();
PID_init();
uart_init(9600);
printf("System begin rn");
while(1)
{
key = KEY_Scan(0);
while(count<1000)
{
float speed = PID_realize(200.0);
printf("%f rr",speed);
count++;
}
delay_ms(10);
if(key == KEY0_PRES)
{
count =0;
}
}
}
pid.c 代码如下:
统一初始化变量,尤其是Kp、Ki、Kd3个参数,对于要求的控制效果调试过程中,通过调试这个3个变量直接进行调参。
#include "pid.h"
#include "usart.h"
#include
#include
struct _pid
{
float SetSpeed; //定义设定值
float ActualSpeed; //定义实际值
float err ; // 定义偏差值
float err_next; //定义上一个偏差值
float err_last; //定义上上一个偏差值
float Kp,Ki,Kd; //定义比例、积分、微分系数
}pid;
void PID_init()
{
printf("Pid_init beginrn");
pid.SetSpeed = 0.0;
pid.ActualSpeed = 0.0;
pid.err = 0.0;
pid.err_next = 0.0;
pid.err_last = 0.0;
pid.Kp = 0.2;
pid.Ki = 0.015;
pid.Kd =0.2;
printf("PID_init end rn");
}
float PID_realize(float speed)
{
float incrementSpeed;
pid.SetSpeed = speed;
pid.err = pid.SetSpeed - pid.ActualSpeed ;
// 算法基本公式
incrementSpeed = pid.Kp*(pid.err-pid.err_next)+pid.Ki *pid.err+pid.Kd*(pid.err-2*pid.err_next+pid.err_last);
pid.ActualSpeed += incrementSpeed;
pid.err_last = pid.err_next ;
pid.err_next = pid.err ;
return pid.ActualSpeed ;
}
pid.h 文件如下:
#ifndef __PID_H
#define __PID_H
void PID_init(void);
float PID_realize(float speed);
#endif
3.3、效果展示
4、积分分离的PID控制算法
基本思路是,当被控制量与设定的值偏差较大时,取消积分作用,当被控量接近给定值时,引入积分控制,以消除静差,提高精度。
4.1、代码实现
main函数:
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "pid.h"
#include "usart.h"
#include "key.h"
//PID算法测试
int main(void)
{
int count;
u8 key;
delay_init(); //延时函数初始化
LED_Init(); //初始化与LED连接的硬件接口
KEY_Init();
PID_init();
uart_init(9600);
printf("System begin rn");
while(1)
{
key = KEY_Scan(0);
while(count<1000)
{
float speed = PID_realize(200.0);
printf("%f rr",speed);
count++;
}
delay_ms(10);
if(key == KEY0_PRES)
{
count =0;
}
}
}
pid.c 文件
#include “pid.h”
#include “usart.h”
#include
#include
struct _pid
{
float SetSpeed; //定义设定值
float ActualSpeed; //定义实际值
float err ; // 定义偏差值
float err_last; //定义上一个偏差值
float Kp,Ki,Kd; //定义比例、积分、微分系数
float voltage; //定义电压值 控制器执行的变量
float integral; //定义积分值
}pid;
void PID_init()
{
printf(“Pid_init beginrn”);
pid.SetSpeed = 0.0;
pid.ActualSpeed = 0.0;
pid.err = 0.0;
pid.err_last = 0.0;
pid.voltage = 0.0;
pid.integral = 0.0;
pid.Kp = 0.2; //比例
pid.Ki = 0.04; //积分
pid.Kd =0.2; //微分
printf(“PID_init end rn”);
}
float PID_realize(float speed)
{
int index;
pid.SetSpeed = speed;
pid.err = pid.SetSpeed - pid.ActualSpeed ;
pid.integral += pid.err ;
// 算法实现过程
if(abs(pid.err)>200) //设定值 200
{
index = 0;
}
else
{
index = 1;
pid.integral += pid.err ;
}
pid.voltage = pid.Kp*pid.err+index*pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last);
pid.err_last = pid.err;
pid.ActualSpeed = pid.voltage*1.0;
return pid.ActualSpeed;
}
4.2、效果图
通过测试,系统数据达到199所用的时间为原来的1/2,系统的快速性得到提升。
举报
更多回帖
rotate(-90deg);
回复
相关问答
PID
控制算法
PID控制
PID
控制
算法
是如何形成的
2021-12-21
1823
PID
控制
算法
的基本思想是什么?
PID
控制
算法
是如何形成的?
2021-06-30
2664
PID
控制
算法
的原理是什么
2021-10-11
1160
什么是
PID
控制
算法
?
PID
控制
算法
C语言是如何实现的?
2021-06-29
1895
求
PID
等自动
控制
算法
2013-10-28
2584
PID
控制
算法
的基本思想是什么
2021-12-21
1038
【最新课程推荐】
PID
控制
算法
2016-10-12
8941
基于单片机的
pid
控制
算法
该怎样去使用
呢
2021-12-21
1794
什么
算法
能够代替
PID
控制
?
2023-11-01
385
PID
是什么意思?
PID
有
何
作用
2021-08-31
1640
发帖
登录/注册
20万+
工程师都在用,
免费
PCB检查工具
无需安装、支持浏览器和手机在线查看、实时共享
查看
点击登录
登录更多精彩功能!
英国威廉希尔公司网站
william hill官网 版块
小组
免费开发板试用
ebook
直播
搜索
登录
×
20
完善资料,
赚取积分