说到PID算法,想必大部人并不陌生,PID算法在很多方面都有重要应用,比如电机的速度控制,恒温槽的温度控制,四轴飞行器的平衡控制等等,作为闭环控制系统中的一种重要算法,其优点和可实现性都成为人们的首选。下面简单来讲解一下PID算法:

首先PID算法是有比例,积分,微分三部分组成,先说下比例部分,所谓比例部分,就是呈线性关系,举个例子,一个电热丝加热水,开始的时候温度很低,离50℃很大,这时应该加大功率,离目标温度越大,其功率应该越大,反之越小,这就是比例部分。

乍一看,既然比例部分已经可以控制温度了为啥还需要积分和微分部分呢,难道是多此一举么?其实不然,在实际中会出现这种情况,当加热到50℃时,系统很难停止下来,而是会持续一段时间,这样就会超过预设值,所以仅有比例控制并不完美,这是就需要积分部分和微分部分。积分部分就是把之前的误差全部累加起来,这样起始时由于误差很大加热功率就大,随着接近预设值后功率开始减少,微分部分就是起始时温度增加很快,表示此时需要很大的功率,随着温度接近预设值,其斜率开始减小最后为零,意味着功率也减少,当然很难为零,一般在一定的范围内波动。

现在开始用C语言来实现PID算法:

位置式:

比例部分

    Kp:比例系数  SetValue:预设值  FactValue:当前实际值  Error_1:当前误差

则比例部分为:

    Sp  =   Kp*(SetValue - FactValue)

或者

    Sp  =  Kp*Error_1

注解:Sp大小反应需要控制的量大小,比如Sp越大,功率越大。当Sp为负值时,表示要超过预设值,如果是电机,则需要反转

积分部分

    Ki:积分系数  Error_1:当前误差  Error_2:上一次误差  Error_3:上上一次误差  ........Error_n:开始时的误差

则积分部分为:

    Si  =  Ki*(Error_1+Error_2+Error_3+......+Error_n)

注解:因为整个是一个过程,所以上一次误差其实就是上一次的当前误差

微分部分

    Kd:微分系数  Error_1:当前误差  Error_2:上一次误差 

则微分部分为:

    Sd  =  Kd*(Error_1-Error_2)

综上部分的PID得:

    PID=Sp + Si + Sd = Kp*Error_1 + Ki*(Error_1+Error_2+Error_3+......+Error_n) + Kd*(Error_1-Error_2)

增量式

将上述推导的PID记作时间为k时刻的PID控制量,则

    PID(k) =Sp + Si + Sd = Kp*Error_1(k) + Ki*(Error_1(k)+Error_2(k-1)+Error_3(k-2)+......+Error_n(0)) + Kd*(Error_1(k)-Error_2(k-1))        1

将上式k=k-1代入得:

    PID(k-1) =Sp + Si + Sd = Kp*Error_1(k-1) + Ki*(Error_1(k-1)+Error_2(k-2)+Error_3(k-3)+......+Error_n(0)) + Kd*(Error_1(k-1)-Error_2(k-2))               2

1-2得:

    PID(k) - PID(k-1) =  Kp*(Error_1(k)-Error_1(k-1)) + Ki*(Error_1(k)) + Kd*(Error_1(k)-2*Error_2(k-1)+Error_2(k-2))

PID(k) - PID(k-1)记作detPID

    detPID = Kp*(Error_1(k)-Error_1(k-1)) + Ki*(Error_1(k)) + Kd*(Error_1(k)-2*Error_2(k-1)+Error_2(k-2))

这样就得到了增量式的PID算法,其计算的结果为增加的控制量

增量式的PID有个好处就是只与当前三个误差量有关系,与其他无关,这样就简化的处理过程,而且提高了精度,下面是PID源码:

/*文件名:PID.h*/

#ifndef  _PID_H_
#define _PID_H_ extern float Kp,Ki,Kd; //系数(全局变量)
extern float AclValue; //实际值
extern float SetValue; int PID(void); #endif
/*########################################################################
文件名:PID.c
时间: 2018.9.7
备注:无
#########################################################################*/ #include "PID.h" float Kp=,Ki=0.8,Kd=0.5; //系数 float SetValue=; //设定值 float AclValue=; //实际 float Error1=,Error2=,Error3=; //误差 /* 下面为增量式PID算法 */ /**********************************************************************************
函数名:PID
返回值:输出增量
参数:无
备注:当输出大于0表示小于预设值,当输出小于0表示大于预设值
***********************************************************************************/
int PID(void)
{
float OutValue =;
Error3 = SetValue - AclValue; OutValue = Kp*(Error3-Error2)+Ki*(Error3)+Kd*(Error3-*Error2+Error1); Error1=Error2; //这部分是迭代,因为上次的误差就是上次的当前误差
Error2=Error3; if(OutValue>) //这部分是规定最大输出增量
OutValue=;
if(OutValue<-)
OutValue=-; return OutValue;
}

下面给出计算机模拟代码;

#include "stdio.h"

float Kp=,Ki=,Kd=0.5;  //系数

float SetValue=;  //设定值

float AclValue=; //实际

float Error1=,Error2=,Error3=;     //误差

/*  下面为增量式PID算法  */

/**********************************************************************************
函数名:PID
返回值:输出增量
参数:无
备注:当输出大于0表示小于预设值,当输出小于0表示大于预设值
***********************************************************************************/
int PID(void)
{
float OutValue =;
Error3 = SetValue - AclValue; OutValue = Kp*(Error3-Error2)+Ki*(Error3)+Kd*(Error3-*Error2+Error1); Error1=Error2;
Error2=Error3; return OutValue;
} int main(void)
{
unsigned int i=;
while(i)
{ PID(); //特别注意这里:必须要运行,因为需要执行这一步:Error1=Error2; Error2=Error3; printf("当前实际值为:%f \n",AclValue); AclValue += PID(); i--);
    } 

    return ;
}

运行结果:

    

单片机之PID算法的更多相关文章

  1. PID算法笔记2

    总所周知,PID算法是个很经典的东西.而做自平衡小车,飞行器PID是一个必须翻过的坎.因此本节我们来好好讲解一下PID,根据我在学习中的体会,力求通俗易懂.并举出PID的形象例子来帮助理解PID.一. ...

  2. PID算法通俗理解,平衡车,倒立摆,适合不理解PID算法的人来看!

    先插句广告,本人QQ522414928,不熟悉PID算法的可以一起交流学习,随时在线(PID资料再我的另一篇博客里) 倒立摆资料连接↓ https://www.cnblogs.com/LiuXinyu ...

  3. PID算法原理 一图看懂PID的三个参数

    找了好久这一篇算是很容易看懂的了  推荐给大家   写的十分清楚   原文作者DF创客社区virtualwiz LZ以前有个小小的理想,就是让手边的MCU自己"思考"起来,写出真正 ...

  4. 线性控制原理——PID算法应用

    使用控制系统(PID)控制被控对象 PID控制的三要素:控制器,被控对象,反馈器.控制器就是一个数学模型,就PID来说,等同于PID算法.是对反馈量的一个处理与输出.通俗的说就是对于每个被控的量,我的 ...

  5. PID算法学习记录

    最近做项目需要用到PID算法,这个本来是我的专业(控制理论与控制工程),可是我好像是把这个东西全部还给老师了. 没办法,只好抽时间来学习了. 先占个座,后续将持续更新!

  6. 位置式PID与增量式PID算法

    位置式PID与增量式PID算法  PID控制是一个二阶线性控制器     定义:通过调整比例.积分和微分三项参数,使得大多数的工业控制系统获得良好的闭环控制性能.     优点             ...

  7. PID算法

    所谓PID就是比例-积分-微分的英文缩写,但并不是必须同时具备这三种算法,也可以是 PD, PI,甚至只有 P算法控制,下面分别介绍每个参数的含义:首先需要明确一个事实就是,要实现PID算法,必须在硬 ...

  8. PID算法(c 语言)(转)

    PID算法(c 语言)(来自老外) #include <stdio.h> #include<math.h> //定义PID 的结构体 struct _pid { int pv; ...

  9. PID控制器开发笔记之一:PID算法原理及基本实现

    在自动控制中,PID及其衍生出来的算法是应用最广的算法之一.各个做自动控制的厂家基本都有会实现这一经典算法.我们在做项目的过程中,也时常会遇到类似的需求,所以就想实现这一算法以适用于更多的应用场景. ...

随机推荐

  1. Flask与WSGI

    刚开始接触到python及Flask框架时,总是会听到 wsgi等等相关的名词,以及 项目部署时会用到nginx+gunicorn等等,但是对于一个请求从 nignx到gunicorn再到falsk框 ...

  2. 3-hive、sqoop

    1.HIVE 1.交互命令 use db_name; create database db_name //创建数据库 create database if not exists db_name //创 ...

  3. github 添加wiki

    亲们支持我的新博客哦==>地址(以后更新会尽量在新博客更新,欢迎大家访问加入我的后宫w) ) 平时都是写readMe和docs的,一直眼瞎没有注意到有wiki这个功能 随便找一个写了wiki的看 ...

  4. 开启safe_mode之后对php系统函数的影响

    safe_mode即为PHP的安全模式,在php.ini中设置safe_mode = On重启PHP便可开启安全模式. 当安全模式开启后,PHP相应的一些系统函数,文件操作函数等将会受限.例如: ck ...

  5. matlab中变量问题——readonly 索引超出矩阵维度 workspacefunc 215

    matlab程序运行过程中会出现如上提示,在网上检索未果,键入dbstop if error语句也无法定错误之处,就想这个错误不是一般的错误. 通过间隔打断点的方式最后定位错误为一句exist = f ...

  6. Thinkphp语句拼接

    例如查询Stu表中年龄大于18,或者身高低于180cm的男性(1为男性),(例子不太好标题有可能不符,望见谅) $where['age'] = array("gt",18); $w ...

  7. ELK6.0部署:Elasticsearch+Logstash+Kibana搭建分布式日志平台

    一.前言 1.ELK简介 ELK是Elasticsearch+Logstash+Kibana的简称 ElasticSearch是一个基于Lucene的分布式全文搜索引擎,提供 RESTful API进 ...

  8. AR涂涂乐

    <1> 涂涂乐着色 https://blog.csdn.net/begonia__z/article/details/51282932 http://www.manew.com/blog- ...

  9. gridView 删除一行后自动定位到指定行

    /// <summary> /// 删除后定位到某一行 /// </summary> /// <param name="aCode"></ ...

  10. Pandas重塑和轴向旋转

    重塑和轴向旋转 Se import pandas as pd import numpy as np from pandas import Series data=pd.DataFrame(np.ara ...