PID算法

作者: 恰似一碗咸鱼粥 | 来源:发表于2019-07-15 17:24 被阅读0次

1.比例控制

设定一个标准值S_v,传感器每次返回一个值P_v,这两个值之差构成了一个序列E_1,E_2,...,E_k,每次根据这个偏差输出一个POUT=K_pE_k+OUT_0,OUT0为偏置值,Kp为比例系数。其中偏差包括当前偏差、历史偏差和最近偏差。

2.积分控制

对每一次得到传感器的返回值E_k,返回之前所有偏差值之和S_kIOUT=K_pS_k,但是单纯的积分控制也会出现问题,如果历史的偏差值是好的,便不再管现在的偏差值到底是大是小,会导致历史情况干扰当前情况。所以与比例控制相同,我们也许增加一个偏置值IOUT=K_pS_k+OUT_0

3.微分控制

前一个时刻差值为E_{k-1},当前时刻差E_{k},对这两个时间点,将其偏差相减。D_k=E_k-E_{k-1},它可以说明我们的偏差的变化趋势。同样也会加一个偏置,D_k=E_k-E_{k-1}+OUT_0,out0用于维持。

4.参数设置

PID_{out}=K_p*(E_k+S_k+D_k)+OUT_0

(1)Sk处理

S_k=\frac{1}{T_i}*\sum_{k=0}^{n}E_k*T,T称为采样周期,即间隔一部分时间,保证上一次算出得结果已经输出,在不同的情况下,采样周期要改变。Ti称为积分常数,它是人为确定的,它越大,则PID最终输出结果越强,反之则削弱。若果Ti过小,则非常容易产生过冲,即先超过额定值,再慢慢下降到额定值。积分项在比例项失效时发生作用。

(2)Dk处理

D_k=\frac{E_k-E_{k-1}}{T}*T_d,这里的T也是采样周期,Td为微分常数。

此时新的单片机中PID算法表达式:
OUT=K_pE_k+K_p\frac{T}{T_i}S_k+K_p\frac{T_d}{T}(E_k-E_{k-1})+out_0
这种方法称为位置式PID,但是有大量历史数据累加,计数比较繁琐。

5.增量式PID

对于控制系统本身具有记忆功能,可以采用增量式PID
增量式PID即\Delta out=out_k-out_{k-1}

6.C语言PID伪代码

//pid.h
#ifndef _pid_
#define _pid_
#include "stm32f10x_conf.h"

typedef struct{
    float Sv;//用户设定值
    float Pv;//实际值

    float Kp;
    float T;//计算周期或者采样周期
    float Ti;
    float Td;

    float Ek,Ek_1;//本次偏差与上一次偏差
    float SEk;//历史偏差之和

    float OUT0;

    float C10ms;
    float pwmcycle;//pwm周期

    float OUT;//本次应该输出的值
}PID;

extern PID pid;//存放pid算法所需的数据 
void PID_calc();
#endif

//pid.c
#include "pid.h"

PID pid;//存放PID的数据

void PID_calc(){//pid计算
    float DelEk;
    float ti=pid.T/pid.Ti;
    float ki=ti*pid.Kp;

    float td=pid.Td/pid.T;
    float kd=pid.Kp*td;

    float Iout,Pout,Dout;

    if(pid.C10ms<pid.T/10){
        //计算周期没到
        return;
    }
    pid.Ek=pid.Sv-pid.Pv;//得到当前的偏差值

    pid.SEk+=pid.Ek;//历史偏差总和 

    DelEk=pid.Ek-pid.Ek_1;//最近两次的偏差之差

    Pout=pid.Kp*pid.Ek;//比例
    Iout=pid.SEk*ki;//积分
    Dout=kd*DelEk;//微分

    if(Pout+Iout+Dout+pid.OUT0>pid.pwmcycle){
        pid.OUT=pid.pwmcycle;
    }
    else if(Pout+Iout+Dout+pid.OUT0<0){
        pid.OUT=0;
    }else{
        pid.OUT=Pout+Iout+Dout+pid.OUT0;
    }

    pid.Ek_1=pid.Ek;//更新偏差 

    pid.C10ms=0;
}

对于控制输出部分:

void PID_out{
    static u16 pw;
    pw++;
    if(pw>=pid.pwmcycle){
        pw=0;
    }
    //每次dosomething为1ms
    if(pw<pid.OUT){
        //do something
    }
    else{
        //do something else
    }
}

相关文章

  • 2020-04-10

    平头哥比赛之电机控制算法仿真 神经网络自适应pid算法 自适应模糊算法自适应神经网络算法自适应pid算法是在pid...

  • 当PID算法遇上VEX机器人(一)

    pid算法 pid的英文全称为Proportion Integration Differentiation,它是一...

  • (转载)PID算法简单实现

    原文出处 PID算法 1 什么是PID PID,即比例Proportion、积分Integral和微分Deriva...

  • PID调试口诀,再现江湖,各路豪杰纷纷来观

    一 PID基本概述: 1,PID是一个闭环控制算法。因此要实现PID算法,必须在硬件上具有闭环控制,就是得有反馈。...

  • PID算法

    1.比例控制 设定一个标准值,传感器每次返回一个值,这两个值之差构成了一个序列,每次根据这个偏差输出一个,OUT0...

  • 一起打造自己的自动驾驶小车mycar - 5.PID循线

    1 PID算法 PID算法是一种常用的反馈修正算法,根据误差值来不断调整系统的输入,让测量值不断趋近目标值。详细介...

  • PID算法的C语言实现

    PID控制算法的C语言实现(完整版)

  • 2018-01-23

    51单片机 pid算法 常用稳压芯片 常用传感器

  • HDU2063

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2063 匈牙利算法...

  • Arduino与PID算法应用

    这次萌生出写一篇Arduino和PID算法结合的文章,其实是因为刚忙完实验的事情,而实验进行过程中曾尝试着应用PI...

网友评论

      本文标题:PID算法

      本文链接:https://www.haomeiwen.com/subject/ebbnkctx.html