0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

MATLAB学习笔记之PID算法2

jf_78858299 来源:滑小稽笔记 作者:电子技术园地 2023-02-24 14:57 次阅读

2.4.3 C算法

#include
#include
struct _pid
{
    float SetSpeed ;                                                //设置速度
    float ActualSpeed ;                                             //实际速度
    float err ;                                                     //误差
    float err_last ;                                                  //最终误差
    float Kp , Kd , Ki ;                                              //比例系数
    float voltage ;                                                 //输出电压
    float integral ;                                                  //积分值
    float umax ;                                                  //积分上限
    float umin ;                                                  //积分下限
}pid;
void PID_Init()
{
    pid.SetSpeed = 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.Kd = 0.2 ;
    pid.Ki = 0.1 ;
    pid.umax = 400 ;
    pid.umin = -200 ;
}
float PID_Realize( float Speed )
{
    char index ;
    pid.SetSpeed = Speed ;
    pid.err = pid.SetSpeed-pid.ActualSpeed ;
    if( abs(pid.err)<= pid.umax )
    {
        index = 1 ;
        pid.integral += pid.err ;
    }
    else
        index = 0 ;
    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 ;
}
void main()
{
    int count ;
    count = 0 ;
    PID_Init() ;
    while( count<1000 )
    {
        float Speed = PID_Realize( 200.0 ) ;
        count ++ ;
        printf( "%.2f\\n" , Speed ) ;
    }
}

2.5 抗积分饱和型PID算法

2.5.1 实现原理

所谓积分饱和现象是指如果系统存在一个方向的偏差,PID控制器的输出会因为存在积分环节而不断累积增大,从而导致执行机构达到极限位置,若控制器输出响应继续增大,执行器开度不可能再增大,此时计算机输出控制量超出了正常运行范围而进入饱和区,一旦系统出现反向偏差,输出响应逐渐从饱和区退出,进入饱和区时间越长则退出饱和区的时间也就随之增加,这段时间里,执行机构仍然停留在极限位置而不能随着偏差方向立即作出相应的改变,造成控制性能恶化,这种现象称为积分饱和现象或积分失控现象。实现抗积分饱和算法的基本思路是计算系统的响应时,首先判断上一时刻的控制量是否超出了极限范围,如果超过上限,则只累计反向偏差,若低于下限,则只累计正向偏差,从而避免控制量长时间停留在饱和区。

2.5.2 MATLAB算法

clc
clear
%PID初始化
len = 180 ;                                                                 %运算次数
y = zeros(1,len);                                                          %期望值
y_d = zeros(1,len);                                                       %过程值
err = zeros(1,len);                                                       %误差值
err_0 = 0 ;                                                                 %k时刻误差
err_1 = 0 ;                                                                 %k-1时刻误差
y_d_last = 0 ;                                                             %k-1时刻输出
integral = 0;                                                              %积分值
Kp = 0.2;                                                                   %比例系数
Kd = 0.2;                                                                   %微分值
Ki = 0.1 ;                                                                  %积分值
max = 400 ;                                                                 %积分上限
min = -200 ;                                                                %积分下限
index = 0 ;                                                                 %积分有效性
%运算过程
for k=1:1:len
y(k) = 200 ;                                                            %期望输出
err_0 = y(k)-y_d_last;                                                 %计算偏差
    if y_d_last>max
        if abs(err_0) <= y(k)
            index = 1 ;
            if err_0 < 0
                integral = integral+err_0;                                %误差累计
            end
        else
            index = 0 ;
        end
    elseif y_d_last<min
        if abs(err_0) <= y(k)
            index = 1 ;
            if err_0 > 0
                integral = integral+err_0;                                  %误差累计
            end
        else
            index = 0 ;
        end
    else
        if abs(err_0) <= y(k)
            index = 1 ;
            integral = integral+err_0;                                      %误差累计
        else
            index = 0 ;
        end
    end
    y_d_last = Kp*err_0 + Ki*index*integral + Kd*(err_1-err_0);   %位置型PID运算公式
err_1 = err_0 ;
    %更新参数
    y_d(k) = y_d_last ;
    err(k) = err_1 ;
end
%输出图像绘制
t = 1:1:len;
subplot( 2, 1, 1 ) ;
plot( t, y, 'r', t, y_d, 'b' );
axis([0 len, 0 1.5*y(1)])
title('输出曲线');
xlabel('t')
ylabel('y(t)')
%误差图像绘制
subplot( 2, 1, 2 ) ;
plot( t, err );
axis([0 len, 0 1.5*y(1)])
title('误差曲线');
xlabel('t')
ylabel('e(t)')

MATLAB运行结果如下图所示。

2.5.3 C算法

#include
#include
struct _pid
{
    float SetSpeed ;                                                //设置速度
    float ActualSpeed ;                                             //实际速度
    float err ;                                                     //误差
    float err_last ;                                                  //最终误差
    float Kp , Kd , Ki ;                                              //比例系数
    float voltage ;                                                 //输出电压
    float integral ;                                                  //积分值
    float umax ;                                                  //积分上限
    float umin ;                                                  //积分下限
}pid;
void PID_Init()
{
    pid.SetSpeed = 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.Kd = 0.2 ;
    pid.Ki = 0.1 ;
    pid.umax = 400 ;
    pid.umin = -200 ;
}
float PID_Realize( float Speed )
{
    char index ;
    pid.SetSpeed = Speed ;
    pid.err = pid.SetSpeed-pid.ActualSpeed ;
    if( pid.ActualSpeed>pid.umax )
    {
        if( abs(pid.err)<=200 )
        {
            index = 1 ;
            if( pid.err<0 )
                pid.integral += pid.err ;
        }
        else
            index = 0 ;
    }
    else if( pid.ActualSpeed

2.6 梯形积分PID算法

2.6.1 实现原理

根据梯形算法的积分环节公式

作为PID控制的积分项,其作用是消除余差,为了尽量减小余差,应提高积分项运算精度,为此可以将矩形积分改为梯形积分,具体实现的语句为pid.voltage = pid.Kppid.err+indexpid.Ki pid.integral/2+pid.Kd ( pid.err-pid.err_last ) ;

2.6.2 MATLAB算法

clc
clear
%PID初始化
len = 358 ;                                                                 %运算次数
y = zeros(1,len);                                                          %期望值
y_d = zeros(1,len);                                                       %过程值
err = zeros(1,len);                                                       %误差值
err_0 = 0 ;                                                                 %k时刻误差
err_1 = 0 ;                                                                 %k-1时刻误差
y_d_last = 0 ;                                                             %k-1时刻输出
integral = 0;                                                              %积分值
Kp = 0.2;                                                                   %比例系数
Kd = 0.2;                                                                   %微分值
Ki = 0.1 ;                                                                  %积分值
max = 400 ;                                                                 %积分上限
min = -200 ;                                                                %积分下限
index = 0 ;                                                                 %积分有效性
%运算过程
for k=1:1:len
y(k) = 200 ;                                                            %期望输出
err_0 = y(k)-y_d_last;                                                 %计算偏差
    if y_d_last>max
        if abs(err_0) <= y(k)
            index = 1 ;
            if err_0 < 0
                integral = integral+err_0;                                %误差累计
            end
        else
            index = 0 ;
        end
    elseif y_d_last<min
        if abs(err_0) <= y(k)
            index = 1 ;
            if err_0 > 0
                integral = integral+err_0;                                  %误差累计
            end
        else
            index = 0 ;
        end
    else
        if abs(err_0) <= y(k)
            index = 1 ;
            integral = integral+err_0;                                      %误差累计
        else
            index = 0 ;
        end
    end
    y_d_last = Kp*err_0 + Ki*index*integral/2 + Kd*(err_1-err_0);   %PID运算公式
err_1 = err_0 ;
    %更新参数
    y_d(k) = y_d_last ;
    err(k) = err_1 ;
end
%输出图像绘制
t = 1:1:len;
subplot( 2, 1, 1 ) ;
plot( t, y, 'r', t, y_d, 'b' );
axis([0 len, 0 1.5*y(1)])
title('输出曲线');
xlabel('t')
ylabel('y(t)')
%误差图像绘制
subplot( 2, 1, 2 ) ;
plot( t, err );
axis([0 len, 0 1.5*y(1)])
title('误差曲线');
xlabel('t')
ylabel('e(t)')

2.6.3 C算法

#include
#include
struct _pid
{
    float SetSpeed ;                                                //设置速度
    float ActualSpeed ;                                             //实际速度
    float err ;                                                     //误差
    float err_last ;                                                  //最终误差
    float Kp , Kd , Ki ;                                              //比例系数
    float voltage ;                                                 //输出电压
    float integral ;                                                  //积分值
    float umax ;                                                  //积分上限
    float umin ;                                                  //积分下限
}pid;
void PID_Init()
{
    pid.SetSpeed = 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.Kd = 0.2 ;
    pid.Ki = 0.1 ;
    pid.umax = 400 ;
    pid.umin = -200 ;
}
float PID_Realize( float Speed )
{
    char index ;
    pid.SetSpeed = Speed ;
    pid.err = pid.SetSpeed-pid.ActualSpeed ;
    if( pid.ActualSpeed>pid.umax )
    {
        if( abs(pid.err)<=200 )
        {
            index = 1 ;
            if( pid.err<0 )
                pid.integral += pid.err ;
        }
        else
            index = 0 ;
    }
    else if( pid.ActualSpeed
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • matlab
    +关注

    关注

    182

    文章

    2963

    浏览量

    230171
  • 直流电机
    +关注

    关注

    36

    文章

    1708

    浏览量

    70081
  • PID
    PID
    +关注

    关注

    35

    文章

    1471

    浏览量

    85289
收藏 人收藏

    评论

    相关推荐

    旋转倒立摆的PID算法MATLAB仿真原理图

    有木有大侠旋转倒立摆的PID算法MATLAB仿真原理图
    发表于 09-06 11:06

    PID算法模糊PID 精选资料推荐

    这方面的需求而设计的。专家算法和模糊算法都归属于智能算法的范畴,智能算法最大的优点就是在控制模型未知的情况下,可以对模型进行控制。这里需要注意的是,专家
    发表于 07-19 06:29

    连续控制系统的PID算法MATLAB仿真

    连续控制系统的PID算法MATLAB仿真
    发表于 08-11 15:36

    使用C语言进行PID算法实现

    前文对PID算法离散化和增量式PID算法原理进行来探索,之后又使用Matlab进行了仿真实验,对PID
    发表于 09-15 09:20

    使用C语言进行PID算法实现

    前文对PID算法离散化和增量式PID算法原理进行来探索,之后又使用Matlab进行了仿真实验,对PID
    发表于 09-16 09:11

    求大佬分享MatLab学习笔记

    求大佬分享MatLab学习笔记
    发表于 11-19 07:00

    PID算法学习笔记分享

    最近在学习与无人机有关的一些控制算法,在这里做一些笔记,今天学的是有关于PID算法。什么是PID
    发表于 01-14 06:50

    基于遗传算法PID 控制及其MATLAB 仿真

    本 文介绍了遗传算法和基于遗传算法PID 控制设计, 并对设计MATLAB/SIMULINK 下进行了仿真,取得了良好的控制效果。关键词:遗传算法
    发表于 06-11 09:06 101次下载

    模糊PID控制及其MATLAB仿真

    模糊PID控制及其MATLAB仿真,主要是MATLAB仿真,对于研究模糊PID算法有借鉴意义
    发表于 11-12 17:15 0次下载

    PID算法Matlab仿真程序和C程序

    PID算法Matlab仿真程序和C程序 有需要的看一看,不收积分。
    发表于 11-20 17:06 76次下载

    PID学习算法

    PID学习算法,有兴趣的小伙伴们可以看看。
    发表于 06-17 17:40 11次下载

    OpenStackCinder学习笔记

    OpenStackCinder学习笔记(开关电源技术教程ppt)-该文档为OpenStackCinder学习
    发表于 09-23 12:40 5次下载
    OpenStack<b class='flag-5'>之</b>Cinder<b class='flag-5'>学习</b><b class='flag-5'>笔记</b>

    PID算法学习笔记

    最近在学习与无人机有关的一些控制算法,在这里做一些笔记,今天学的是有关于PID算法。什么是PID
    发表于 01-14 11:13 9次下载
    <b class='flag-5'>PID</b><b class='flag-5'>算法学习</b><b class='flag-5'>笔记</b>

    MATLAB学习笔记PID算法3

    为了消除系统的稳态误差,提高控制精度引入了积分环节,但是在启动,结束和大幅度增减设定时,短时间内系统输出有很大的偏差,会造成PID运算的积分积累,导致控制量超过执行机构可能允许的最大动作范囲所对应
    的头像 发表于 02-24 14:57 1991次阅读
    <b class='flag-5'>MATLAB</b><b class='flag-5'>学习</b><b class='flag-5'>笔记</b><b class='flag-5'>之</b><b class='flag-5'>PID</b><b class='flag-5'>算法</b>3

    MATLAB如何实现PID

    实现PID控制:1.打开MATLAB,启动MATLAB软件。2.创建新的MATLAB脚本,在MATLAB
    的头像 发表于 11-04 08:00 2788次阅读
    <b class='flag-5'>MATLAB</b>如何实现<b class='flag-5'>PID</b>?