智能车制作

 找回密码
 注册

扫一扫,访问微社区

查看: 1211|回复: 0
打印 上一主题 下一主题

[编程类] 这个PID的算法

[复制链接]

2

主题

3

帖子

0

精华

注册会员

Rank: 2

积分
26
威望
18
贡献
6
兑换币
5
注册时间
2015-7-26
在线时间
1 小时
毕业学校
西安电子科技大学
跳转到指定楼层
1#
发表于 2015-7-27 22:52:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
一般形式:
       Up=P*E;
       Ui=i*(E+E_1+E_2+...)     E_n为之前的第n次误差.
       Ud=i*(E-E_1)
       U=Up+Ui+Ud;                 U为PID控制输出量.

       上式中Ui的计算不太方便,长时间单方向的累加将可能出现溢出,于是将上式改为如下所示的增量形式:


??
       Up=p*(E-E_1)                     比例项增量
       Ui=i*(E-2*E_1+E_2)            微分项增量
       Ud=i*E                                积分项增量
       U=Uout_1+Up+Ui+Ud         U为PID控制输出量,Uout_1为前次PID输出值
       Uout=U                               保存本次值

       对于上面的公式或理论,便可得到相应的C语言程序:

       //======================定义PID结构=========================
      static float MinValue;          //最大值限制
      static float MaxValue;         //最小值限制
      static float CurrentValue;   //当前采样值

      static struct PID{
             float Ki;                  //定义积分常数
             float Kp;                //定义比例常数
             float Kd;                //定义微分常数
             float E_2;              //存储前前次误差
             float E_1;              //存诸前次误差
             float E;                  //存储本次误差
             float OutPut;         //本次输出量
             float ValueSet;      //设定值或期望值
           }Control;

      //===========================PID计算函数=====================
      void PidWork() {
            float Up,Ud,Ui;  
           Control.E=CurrentValue-Control.ValueSet;                         //得到本次误差
           Up =Control.Kp*(Control.E-Control.E_1);                            //得到比例项
           Ud=Control.Kd*(Control.E-2*Control.E_1+Control.E_2);     //得到微分项
           Ui=Control.Ki*Control.E;                                                      //得到积分项
           Control.E_2=Control.E_1;                                                   //历史存储
           Control.E_1=Control.E;
           Control.OutPut+=Up+Ud+Ui;                                               //计算增量和
           if(Control.OutPut<MinValue)Control.OutPut=MinValue;      //值域限制
           else if(Control.OutPut>MaxValue)Control.OutPut=MaxValue;  
      }


??
   //==========================初始化速度=========================
     void PidInit() {
         MinValue=0;
         MaxValue=1000;
         CurrentValue=0;
         Control.Kp=-6;
         Control.Ki=-1.5;
         Control.Kd=-0.5;
         Control.E=0;
         Control.E_2=0;
         Control.E_1=0;
         Control.ValueSet=100;
         Control.OutPut=0;
      }






----------------------------------------------------------------------------------
不知道到这个模板能不能用到控制小车的速度上,那么如果用来控速的话,那么程序中ValueSet为所期望的PWM的值还是期望的小车速度值,然后CurrentValue当前采样值是利用测速模块所测得的速度么,那如果CurrentValue采样的是PWM的话,是如何用硬件实现采集实际PWM的值的呢。或者ValueSet与CurrentValue都为速度值,那么如何利用所得求出的增量Control.OutPut来实现对PWM的控制的呢。新手没用过PID,所以问题比较多,见谅

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关于我们|联系我们|小黑屋|亿加合和智能车制作 ( 黑ICP备2022002344号

GMT+8, 2024-5-19 19:13 , Processed in 0.037164 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表