OpenEdv-开源电子网

 找回密码
 立即注册

扫一扫,访问微社区

正点原子全套STM32开发资料,上千讲STM32视频教程,RT1052教程免费下载啦...

查看: 2057|回复: 7

PID算法的愚见与程序

[复制链接]

  离线 

2

主题

3

帖子

0

精华

初级会员

Rank: 2

积分
50
金钱
50
注册时间
2017-3-4
在线时间
7 小时
发表于 2017-5-5 18:13:19 | 显示全部楼层 |阅读模式
正点原子公众号
本帖最后由 keysking 于 2017-5-5 18:16 编辑

                              对PID算法的愚见
PID算法名字中的三个字母其实是此算法的三个核心系数:
​    P:    比例系数
​    I :    积分系数
​    D:    微分系数
比例系数
在只有比例系数的控制下,如果我们要让四旋翼悬浮在100cm高度,那么由于误差,它可能在90或者110等位置停下
积分系数
加入积分系数控制后,四旋翼飞到110cm的时候,发现不对,便向下飞,又飞过了,就又向上飞,上上下下,最终可能稳定.但是每次上下的速度是相同的.
微分系数
因为上上下下每次速度相同,所以极有可能飞过,所以加入微分系数,当距离目标位置越近时,速度就放的越缓,达到稍微调整就能准确的悬浮到目标位置的目的.

                  程序
刚刚写了一个通用的(耦合度极低)PID函数,使用的是增量式PID算法.自我感觉这个算法并不是准确的PID计算公式,只是简化计算后的计算方法,适合计算能力较弱的单片机等使用.

[C] 纯文本查看 复制代码
//PID.h
typedef struct {
        int         shuzhi[3];        //保存本次和之前两次的设定值与实际测量值的差值
        char        KP;        //比例系数
        char        KI; //积分常数
        char        KD;        //微分常数
        int                PID;//PID输出值
        int                SET;//设定值
        int                CUR;//实际值
        int                THR;//阀值
        int                MAX;//全力输出
} PID_Value;
void PID_Operation(PID_Value *PID);



[C] 纯文本查看 复制代码
//PID.c
//增量法PID算法:
//                PID=U(k)+KP*[E(k)-E(k-1)]+KI*E(k)+KD*[E(k)-2E(k-1)+E(k-2)]
#include "PID.h"
void PID_Operation(PID_Value *PID){
        int temp[3]={0};        //用于辅助计算的临时变量
        if(PID.SET-PID.CUR>PID.THR){                                //当设定值与实际值的差值大于阀值时,直接全力输出
                        PID.PID=MAX;
                        return ;
        }
        if(PID.CUR-PID.SET>PID.THR){                                //当设定值与实际值的差值大于阀值时,直接全力输出
                        PID.PID=0-MAX;
                        return ;
        }
        PID.shuzhi[2]=PID.shuzhi[1];
        PID.shuzhi[1]=PID.shuzhi[0];
        PID.shuzhi[0]=PID.SET-PID.CUR;        //差值.E(k)
//=====PID=U(k)+KP*[E(k)-E(k-1)]+KI*E(k)+KD*[E(k)-2E(k-1)+E(k-2)]==================
        temp[0]=PID.shuzhi[0]-PID.shuzhi[1];                        //E(k)-E(k-1)
        temp[2]=PID.shuzhi[1]*2;                                
        temp[2]=PID.shizhu[0]+PID.shuzhi[2]-temp[2];        //E(k)-2E(k-1)+E(k-2)
        
        temp[0]=PID.KP*temp[0];
        temp[1]=PID.KI*PID.shuzhi[0];
        temp[2]=PID.KD*PID.temp[2];
        PID.PID=PID.PID+temp[0]+temp[1]+temp[2];
        
}


回复

使用道具 举报

  离线 

10

主题

241

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1491
金钱
1491
注册时间
2013-7-29
在线时间
188 小时
发表于 2017-5-16 09:12:21 | 显示全部楼层
很好!顶下!
回复 支持 反对

使用道具 举报

  离线 

11

主题

67

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
379
金钱
379
注册时间
2017-4-3
在线时间
72 小时
发表于 2017-6-13 18:52:24 来自手机 | 显示全部楼层
谢谢分享!
回复 支持 反对

使用道具 举报

  离线 

0

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
79
金钱
79
注册时间
2017-4-10
在线时间
13 小时
发表于 2017-11-6 17:41:56 | 显示全部楼层
老哥,稳。。。。
回复 支持 反对

使用道具 举报

  离线 

3

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2017-11-11
在线时间
10 小时
发表于 2017-11-14 14:18:12 | 显示全部楼层
正点原子公众号
个人而言,对于四旋翼这种系统,PID调节中的I可以不用。
回复 支持 反对

使用道具 举报

  离线 

12

主题

47

帖子

0

精华

初级会员

Rank: 2

积分
131
金钱
131
注册时间
2017-7-1
在线时间
38 小时
发表于 2017-11-15 09:02:37 | 显示全部楼层
学习了,顶一下
回复 支持 反对

使用道具 举报

  离线 

4

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
69
金钱
69
注册时间
2018-6-1
在线时间
10 小时
发表于 2018-6-7 11:17:16 | 显示全部楼层
学习学习
回复 支持 反对

使用道具 举报

  离线 

0

主题

1

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2017-7-18
在线时间
5 小时
发表于 前天 10:04 | 显示全部楼层
可以,顶一下
回复 支持 反对

使用道具 举报

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

本版积分规则




关闭

"原子哥”推荐上一条 /1 下一条

QQ|联系我们|手机版|官方淘宝店|新浪微博|微信公众平台|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2018-7-22 14:48

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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