打印
[开发资料]

PID算法C语言实现

[复制链接]
330|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
powermaker2568|  楼主 | 2023-2-27 09:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
PID算法C语言实现PID算法介绍
PID 是 Proportional(比例)、Integral(积分)、Differential(微分)的首字母缩写;是一种结合比例、积分和微分三种环节于一体的闭环控制算法。PID 控制的实质是对目标值和实际值误差进行比例、积分、微分运算后的结果用来作用在输出上。
比例 (P)
比例控制是最简单的一种控制方式,成比例的反应控制系统中输入与输出的偏差信号,只要偏差一旦产生,就立即产生控制的作用来减小产生的误差。比例控制器的输出与输入成正比关系,能够迅速的反应偏差,偏差减小的速度取决于比例系数 Kp,Kp 越大偏差减小的就越快,但是极易引起震荡;Kp 减小发生震荡的可能性减小,但是调节的速度变慢,单纯的比例控制存在不能消除的静态误差,这里就需要积分来控制。
积分(I)
在比例控制环节产生了静态误差,在积分环节中,主要用于就是消除静态误差提高系统的无差度。积分作用的强弱,取决于积分时间常数 Ti,Ti 越大积分作用越弱,反之则越强。积分控制作用的存在与偏差 e(t) 的存在时间有关,只要系统存在着偏差,积分环节就会不断起作用,对输入偏差进行积分,使控制器的输出及执行器的开度不断变化,产生控制作用以减小偏差。在积分时间足够的情况下,可以完全消除静差,这时积分控制作用将维持不变。Ti 越小,积分速度越快,积分作用越强。积分作用太强会使系统超调加大,甚至使系统出现振荡。
微分(D)
微分环节的作用是反应系统偏差的一个变化趋势,也可以说是变化率,可以在误差来临之前提前引入一个有效的修正信号,有利于提高输出响应的快速性, 减小被控量的超调和增加系统的稳定性,虽然积分环节可以消除静态误差但是降低了系统的响应速度,所以引入微分控制器就显得很有必要,尤其是具有较大惯性的被控对象使用 PI 控制器很难得到很好的动态调节品质,系统会产生较大的超调和振荡,这时可以引入微分作用。在偏差刚出现或变化的瞬间,不仅根据偏差量作出及时反应(即比例控制作用),还可以根据偏差量的变化趋势(速度)提前给出较大的控制作用(即微分控制作用),将偏差消灭在萌芽状态,这样可以大大减小系统的动态偏差和调节时问,使系统的动态调节品质得以改善。微分环节有助于系统减小超调,克服振荡,加快系统的响应速度,减小调节时间,从而改善了系统的动态性能,但微分时间常数过大,会使系统出现不稳定。微分控制作用一个很大的缺陷是容易引入高频噪声,所有在干扰信号比较严重的流量控制系统中不宜引入微分控制作用。



使用特权

评论回复
沙发
powermaker2568|  楼主 | 2023-2-27 09:07 | 只看该作者
typedef struct
{
    float target_val;               //目标值
    float actual_val;                        //实际值
    float err;                                     //定义偏差值
    float err_last;                          //定义上一个偏差值
    float Kp,Ki,Kd;                          //定义比例、积分、微分系数
    float integral;                          //定义积分值
}pid;

使用特权

评论回复
板凳
powermaker2568|  楼主 | 2023-2-27 09:08 | 只看该作者
float PID_realize(float temp_val)
{
        /*计算目标值与实际值的误差*/
    pid.err=pid.target_val-temp_val;
        /*误差累积*/
    pid.integral+=pid.err;
        /*PID算法实现*/
    pid.actual_val=pid.Kp*pid.err+pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last);
        /*误差传递*/
    pid.err_last=pid.err;
        /*返回当前实际值*/
    return pid.actual_val;
}

使用特权

评论回复
地板
powermaker2568|  楼主 | 2023-2-27 09:08 | 只看该作者
float PID_realize(float temp_val)
{
        /*传入目标值*/
        pid.target_val = temp_val;
        /*计算目标值与实际值的误差*/
    pid.err=pid.target_val-pid.actual_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;
        /*返回当前实际值*/
        return pid.actual_val;
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

31

主题

523

帖子

3

粉丝