PID算法(没办法完全理解的东西)

快速(P)、准确(I)、稳定(D)
P:Proportion(比例),就是输入偏差乘以一个常数。
I :Integral(积分),就是对输入偏差进行积分运算。
D:Derivative(微分),对输入偏差进行微分运算。
    (输入偏差=读出的被控制对象的值-设定值。比如说我要把温度控制在26度,但是现在我从温度传感器上读出温度为28度。则这个26度就是”设定值“,28度就是“读出的被控制对象的值”。)
 

PID作用

       比例控制:能迅速反映误差,从而减小误差,但比例控制不能消除稳态误
差,KP的加大会引起系统的不稳定;

       积分控制的作用是:只要系统存在误差,积分控制作用就不断地积累,
输出控制量以消除误差。因此只要有足够的时间,积分控制将能完全消
除误差,但是积分作用太强会使系统超调加大,甚至使系统出现振荡;

       微分控制:可以减小超调量,克服振荡,使系统的稳定性提高,同时加快
系统的动态响应速度,减小调整时间,从而改善系统的动态性能。

这里写图片描述

 其中KP为比例增益;
TI为积分时间常数;
TD为微分时间常数;
u(t)为控制量(控制器输出);
err(t)为被控量与给定值的偏差。

   由于计算机控制是一种采样控制,它只能根据采样时刻的偏差值计
算控制量

        在计算机控制系统中,PID控制规律的实现必须用数值逼近的方法
当采样周期相当短时,用求和代替积分、用后向差分代替微分,使模拟
PID离散化变为差分方程
        (1) 数字PID位置型控制算法
        (2) 数字PID增量型控制算法

位置型控制算法

       位置闭环控制就是根据编码器的脉冲累加测量电机的位置信息,并与目标值进行比较,得到控制偏差,然后通过对偏差的比例、积分、微分进行控制,使偏差趋向于零的过程。

在这里插入图片描述

 

增量型控制算法

速度闭环控制就是根据单位时间获取的脉冲数(这里使用了M法测速)测量电机的速度信息,并与目标值进行比较,得到控制偏差,然后通过对偏差的比例、积分、微分进行控制,使偏差趋向于零的过程。

在这里插入图片描述

 e(k):本次偏差
e(k-1):上一次的偏差
e(k-2):上上次的偏差

在这里插入图片描述

如何调节PID参数


PID的调节更像是一门艺术而非科学。观察系统,运用你的直觉和逻辑,这里有给PID调节的7条黄金规则:
1. 将所有参数清零增加P的值,直到能让输出在最短时间内达到期望值
2. 当你的系统开始振荡,意味着你的P值大了,减小P值直到振荡消失。调节完P后,你的系统的实际值也许会稍大小于或小于你的期望值(可看作稳态误差),不用担心,下面的步骤会修复这点。
3. 缓慢的增加I值直到你的误差消失为止。注意:通常I值都比较小(一般为千分之一),也取决于你更新PID的频率。当你在室外,I项对室外误差(如有风时)非常有效。
4. 如果你的输出让系统开始振荡了,可试着缓慢减小I值
5. 如果你的系统是低动态系统,那你的调节可到此为止了。但对于多轴飞行器这种高动态系统来说,必须调节D项。如果你感到你的系统对误差的反应滞后了,你应该缓慢增加D值。
6. 如果你的系统开始出现高频振荡了,这意味你有一个过大的D值放大了噪声导致的,这时你该适当的减小D值。如果你的系统有较大的噪声,最好保持D值为0值。
7. 最后注意你的Limits值
 

概念须知:
最大超调量:是响应曲线的最大峰值与稳态值的差,是评估系统稳定性的一个重要指标;

上升时间:是指响应曲线从原始工作状态出发,第一次到达输出稳态值所需的时间,是评估系统快速性的一个重要指标;

静差:是被控量的稳定值与给定值之差,一般用于衡量系统的准确性,

1.因为响应速度无要求,一般比例控制应该给小一点
2.加大系统的阻尼防止超调,也就是微分参数尽量大。
3.另外因为比例参数较小,应该加入积分控制减小静差

这里写图片描述

 

这里写图片描述

 

这里写图片描述

 

这里写图片描述

 

位置型PID 代码段

#include<stdio.h>
#include<stdlib.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 begin \n");
    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 \n");
}

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;
}

int main(){
    printf("System begin \n");
    PID_init();
    int count=0;
    while(count<1000)
    {
        float speed=PID_realize(200.0);
        printf("%f\n",speed);
        count++;
    }
return 0;
}

增量型PID 代码段

#include<stdio.h>
#include<stdlib.h>

struct _pid{
    float SetSpeed;            //定义设定值
    float ActualSpeed;        //定义实际值
    float err;                //定义偏差值
    float err_next;            //定义上一个偏差值
    float err_last;            //定义最上前的偏差值
    float Kp,Ki,Kd;            //定义比例、积分、微分系数
}pid;

void PID_init(){
    pid.SetSpeed=0.0;
    pid.ActualSpeed=0.0;
    pid.err=0.0;
    pid.err_last=0.0;
    pid.err_next=0.0;
    pid.Kp=0.2;
    pid.Ki=0.015;
    pid.Kd=0.2;
}

float PID_realize(float speed){
    pid.SetSpeed=speed;
    pid.err=pid.SetSpeed-pid.ActualSpeed;
    float 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;
}

int main(){
    PID_init();
    int count=0;
    while(count<1000)
    {
        float speed=PID_realize(200.0);
        printf("%f\n",speed);
        count++;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DDsoup

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值