1.位式控制法
2.PID控制法
3.PID调试
控制小车前行包含了许多不确定性,使用开环回路控制系统(open loop)无法顾及不确定性,会以设定的初值一直执行下去,是不理想的控制,所以采用闭环回路控制系统(closed loop)可以通过反馈来减少小车运动工程中的不确定性。反馈理论的要素包括三个部分:测量,比较和执行。通过比较测量的数值与期望值比较,用期望值与实际值差作为偏差值来纠正系统的响应,执行调节控制。其中广泛引用的是以比列,积分和微分控制于一体的,简称为PID控制,也称为PID调节。
1.位式控制法
1.out只有H(高)和L(低)俩种状态
2.out输出依据sv和pv的比较值,pv<sv则未达到设置值,out输出H,反之out输出L。
在转出out时,需要经过一定的时间才会接受执行,而在此过程中执行部件仍然是之前的设置,既达到设置值时,发出终止信号,但是需要时间,信号到达时pv又会大于或者小于sv。
同样位式控制法有缺点,其工作状态只有俩种,要么是全力工作,要么是停止工作。
2.PID控制
开始时,传感器发出当前状态值,X1,X2,X3,······,X(k-1),X(k),是所有采样点的一个数据序列。
P(比例项):
sv-x(k)=E(k)(偏差值)
Ek有三种取值,Ek>0对应未达到设置值,反达标,Ek=0对应达到设置值,此时比例项不在参与调节。
out=Ek*Kp(Kp>1为放大,Kp<1为缩小)
通过系数Kp可以使得信号out在[停止,全力工作] 的范围内,out的值是PWN周期中的有效期。
若当Ek=0时,会变成失控状态,所以需要一个静态误差来维持。
out=Kp*Ek+out0(一个常数,防止失控)。
I(积分项):
偏差值E1,E2,E3,······,Ek相加得到Sk,
Sk=E1+E2+E3+······+Ek(Sk>0历史中未达标多,Sk<0历史中超标多,Sk=0总体看达标)
out=Kp*Sk+out0(积分控制)
D(微分项)
关注最近俩次的偏差值
Ek-E(k-1)=Dk(Dk>0则有增大趋势,Dk<0则有减少趋势,Dk=0无变化)
Dk表示了变化的趋势
3 -> 9
k-1 -> k (通过(k-1)时刻到k时刻的变化来推测k到(k+1)时刻的变化,具有预测性)
out=Kp*Dk+out0(微分控制) (Kp可以提高灵敏,达到快速反应的效果)
但也存在缺点,只关心偏差的变化趋势
时间 | 实际值(设置值为100) | 偏差值 | 偏差值之差 |
8 | 70 | 30 | 2 |
9 | 72 | 28 | 2 |
10 | 74 | 26 | 2 |
此时微分控制就不参与操作。
单片机中PID的数学模型
PIDout=Pout+Iout+Dput
PID=Kp*(Ek+Sk+Dk)+out0
得到的PIDout为PWN中周期的有效周期
发送信号给执行部件时需要时间来响应的,所以计算周期T就是给部件执行完发送信号的时间。
关于积分控制:
未达到设置值时,积分项会协助比例项达到设置值,达到设置值后,比例项不在参与,只有积分项参与。
但达到设置值时,积分控制会继续增大,因为达标之前都是未达标,所以积分控制要中和到之前未达标的,就需要超标的偏差来中和,就会产生过充的现象,此时就需要把Ti给置成无穷大来分离积分控制,除了第一次后面的积分控制都是优良的。
C语言实现增量型PID控制算法:
#include<stdio.h>
#define setspeed a
#define actualspeed b
#define err c
#define errnext d
#define errlast f
struct PID
{
float setspeed; //定义设置值
float actualspeed; //定义实际值
float err; //定义偏差值
float errnext; //定义上一个偏差值
float errlast; //定义前俩个的偏差值
float Kp, Ki, Kd; //定义比例,积分,微分系数
}pid;
void PIDInit()
{
pid.a = 0;
pid.b = 0;
pid.c = 0;
pid.d = 0;
pid.f = 0;
pid.Kp = 0.2;
pid.Ki = 0.01;
pid.Kd = 0.1;
}
float PIDrealize(float speed)
{
pid.a = speed;
pid.c = pid.a - pid.b;
float incrementspeed = pid.Kp * (pid.c - pid.d) + pid.Ki * pid.c + pid.Kd * (pid.c - 2 * pid.d + pid.f);
pid.b += incrementspeed;
pid.f = pid.d;
pid.d = pid.c;
return pid.b;
}
C语言实现位置型PID控制算法
#include<stdio.h>
#define setspeed a
#define actualspeed b
#define err c
#define voltage d
#define errlast f
#define integral g
struct PID
{
float setspeed; //定义设置值
float actualspeed; //定义实际值
float err; //定义偏差值
float voltage; //定义电压值
float errlast; //定义前一个的偏差值
float integral;//定义积分值
float Kp, Ki, Kd; //定义比例,积分,微分系数
}pid;
void PIDInit()
{
pid.a = 0;
pid.b = 0;
pid.c = 0;
pid.d = 0;
pid.f = 0;
pid.Kp = 0.2;
pid.Ki = 0.01;
pid.Kd = 0.1;
}
float PIDrealize(float speed)
{
pid.a = speed;
pid.c = pid.a - pid.b;
pid.g += pid.c;
pid.d = pid.Kp * pid.c + pid.Ki * pid.g + pid.Kd * (pid.c - pid.f);
float incrementspeed = pid.Kp * (pid.c - pid.d) + pid.Ki * pid.c + pid.Kd * (pid.c - 2 * pid.d + pid.f);
pid.d = pid.c;
pid.b = pid.g * 1.0;
return pid.b;
}
3.PID调试
由于自动控制系统被控对象的千差万别,PID的参数也必须随之变化,以满足系统的性能要求。这就给使用者带来相当的麻烦,特别是对初学者。下面简单介绍一下调试PID参数的一般步骤:
3.1负反馈
自动控制理论也被称为负反馈控制理论。首先检查系统接线,确定系统的反馈为负反馈。例如电机调速系统,输入信号为正,要求电机正转时,反馈信号也为正(PID算法时,误差=输入-反馈),同时电机转速越高,反馈信号越大。其余系统同此方法。
5.2.PID调试一般原则
a.在输出不振荡时,增大比例增益P。
b.在输出不振荡时,减小积分时间常数Ti。
c.在输出不振荡时,增大微分时间常数Td。
3.3.位置式PID调节
a.确定比例增益P
确定比例增益P 时,首先去掉PID的积分项和微分项,一般是令Ti=0、Td=0(具体见PID的参数设定说明),使PID为纯比例调节。输入设定为系统允许的最大值的60%~70%,由0逐渐加大比例增益P,直至系统出现振荡;再反过来,从此时的比例增益P逐渐减小,直至系统振荡消失,记录此时的比例增益P,设定PID的比例增益P为当前值的60%~70%。比例增益P调试完成。
b.确定积分时间常数Ti
比例增益P确定后,设定一个较大的积分时间常数Ti的初值,然后逐渐减小Ti,直至系统出现振荡,之后在反过来,逐渐加大Ti,直至系统振荡消失。记录此时的Ti,设定PID的积分时间常数Ti为当前值的150%~180%。积分时间常数Ti调试完成。
c.确定微分时间常数Td
积分时间常数Td一般不用设定,为0即可。若要设定,与确定 P和Ti的方法相同,取不振荡时的30%。
d.系统空载、带载联调,再对PID参数进行微调,直至满足要求。
3.4 增量式pid调节
增量式pid调节目标速度时候参数整定:
先加大KI,这时候会越来越接近实际速度,当KI过大的时候,在切换目标速度的时候,就会抖动,这时候就是KI大了响应速度高了,但导致超调量增加,这时候就加大增量式的KP,来缓减抖动,减小超调量。
参考来源:原文链接:https://blog.csdn.net/qq_31441951/article/details/88858152