PID连续控制算法的表达式以及C语言实现


1.      数字(离散)PID控制算法的表达式:

将PID调节器离散化,用差分方程来代替连续系统的微分方程,分为位置式和增量式两类。

重点理解概念如下:

a)  基本偏差e(t):表示当前测量值与设定目标值间的差,设定目标是被减数,结果可为正或负值,正值表示未达到目标,负值表示超过设定值。(代表比例)

b)  偏差和:即每次测量的差值总和,注意正负(代表积分)

c)  基本偏差的相对偏差:即e(t)-e(t-1)用本次的基本偏差减去上一次的基本偏差。(代表微分)


位置式:


增量式:


位置式和增量式三个参数的作用:

1.      Kp参数:能迅速反映误差,从而减小误差,但他不能消除稳态误差,加大Kp还会引起系统的不稳定。

2.      Ki参数:只要有足够的时间,积分作用将能完全消除误差。但其缺点积分控制是偏差累积控制,控制作业缓慢,但是如果积分作用太强会使系统的超调量加大,甚至出现振荡。

3.      Kd参数:预测误差变化趋势,减小超调量,克服振荡,使系统的稳定性提高,还能加快系统的动态响应速度,减小调整时间,从而改善系统的动态性能。


参考代码如下:

/*

	位置型pid

*/
#include <stdio.h>
#include<ioctl.h>

struct _pid{
float SetSpeed; 		//定义设定值
float ActualSpeed; 		//定义实际值
float err; 				//定义偏差值
float err_last; 		//定义上一个偏差值
float Kp,Ki,Kd; 		//定义比例、积分、微分系数
float voltage; 			//定义电压值(控制执行器的变量)
float integral;		    //定义积分值
}pid;

//项目中获取到的参数
void PID_init(){
	printf("PID_init begin \n");
	pid.SetSpeed=0.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.Ki=0.015;			//自己设定
	pid.Kd=0.2;				//自己设定
	printf("PID_init end \n");
}

float PID_realize(float speed){
	pid.SetSpeed=speed;						//设定值
	pid.err=pid.SetSpeed-pid.ActualSpeed;	//设定值-实际值
	pid.integral+=pid.err;					//积分值,偏差累加
	pid.voltage=pid.Kp*pid.err+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;					//返回
}

int main(){
	printf("System begin \n");
	PID_init();
	int count=0;
	while(count<1000)
	{
	float speed=PID_realize(200.0);
	printf("%f\n",speed);
	count++;
	}
	return 0;
}


增量式代码:

/*
	增量型pid
*/
#include<stdio.h>
#include<stdlib.h>
struct _pid{
	float SetSpeed; //定义设定值
	float ActualSpeed; //定义实际值
	float err; //定义偏差值
	float err_next; //定义上一个偏差值
	float err_last; //定义最上前的偏差值
	float Kp,Ki,Kd; //定义比例、积分、微分系数
}pid;
void PID_init(){
	pid.SetSpeed=0.0;
	pid.ActualSpeed=0.0;
	pid.err=0.0;
	pid.err_last=0.0;
	pid.err_next=0.0;
	pid.Kp=0.2;
	pid.Ki=0.015;
	pid.Kd=0.2;
}
float PID_realize(float speed){
	pid.SetSpeed=speed;
	pid.err=pid.SetSpeed-pid.ActualSpeed;
	float
	incrementSpeed=pid.Kp*(pid.err-pid.err_next)+pid.Ki*pid.err+pid.Kd*(pid.err-2*pid.err_next+pid.err_last);
	pid.ActualSpeed+=incrementSpeed;
	pid.err_last=pid.err_next;
	pid.err_next=pid.err;
	return pid.ActualSpeed;
}
int main(){
	PID_init();
	int count=0;
	while(count<1000)
	{
	float speed=PID_realize(200.0);
	printf("%f\n",speed);
	count++;
	}
	return 0;
}



  • 34
    点赞
  • 195
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值