PID算法代码

//算法调用方式
PID_InitTypeDef pid1;
pid1.enable=1;
pid1.enable_lim_ouput=1;
pid1.enable_lim_sum_error=1;
pid1.lim_sum_error=2000.0;
pid1.lim_up_output=180.0;
pid1.lim_down_output=0.0;
pid1.kp=1.5;
pid1.ki=0.01;
pid1.kd=0.01;

out=pidProcess(&pid1,90, deg);
motor_driver(out);


//结构体定义
typedef struct 
{
	uint8_t enable;						//输出使能
	uint8_t enable_lim_sum_error;	    //积分限幅使能
	uint8_t enable_lim_ouput;			//输出限幅使能
	
	double kp;  			//比例参数
	double ki;  			//积分参数
	double kd;  			//微分参数

	double lim_sum_error;	//误差积分限幅	
	double lim_up_output;		//输出限幅 防止输出过大
	double lim_down_output;
	
	double sum_error;		//误差积分
	double last_error;		//上一次的误差
	double last_last_error;	//上上一次的误差
	
	double kd_output;
	double ki_output;
	double kp_output;
	double error_dec;

	double pid_output;
	double error;
}PID_InitTypeDef;




//代码运算部分                   //定义结构体 设定值 实际值
double PidProcess(PID_InitTypeDef* pid,double input, double measure)
{
	double output = 0;
	double error = input - measure;         //计算误差

	pid->sum_error += error;

	//误差积分限幅
	if(pid->enable_lim_sum_error == 1 && fabs(pid->sum_error) > pid->lim_sum_error)
	{
			if(pid->sum_error > 0)
					pid->sum_error = pid->lim_sum_error;
			else
					pid->sum_error = -pid->lim_sum_error;
	}

	output =        pid->kp * error
							+   pid->ki * pid->sum_error
							+   pid->kd * (error - pid->last_error) ;
/**************************************************************/
    //用于观察参数,可不加
	pid->kp_output = pid->kp * error;
	pid->ki_output = pid->ki * pid->sum_error;
	pid->kd_output = pid->kd * (error - pid->last_error);	
	pid->error_dec = error - pid->last_error;
/*************************************************************/	
	//输出限幅
	if(pid->enable_lim_ouput == 1)
	{
			if(output > pid->lim_up_output)
					output = pid->lim_up_output;
			if(output < pid->lim_down_output)
					output = pid->lim_down_output;
	}
	//更新误差值
	pid->last_error = error;
	//是否使能输出
	if(pid->enable == 1)
	{
		pid->pid_output = output;
		return output;
	}
	else
	{
		pid->pid_output = 0;
		return 0;
	}
}

一、算法的调用

1.声明结构体

2.初始化算法参数

3.函数调用

PID_InitTypeDef pid1;
pid1.enable=1;                    //输出使能
pid1.enable_lim_ouput=1;          //输出限幅使能
pid1.enable_lim_sum_error=1;      //积分限幅使能
pid1.lim_sum_error=2000.0;        //积分上限
pid1.lim_up_output=180.0;         //输出上限
pid1.lim_down_output=0.0;         //输出下限
pid1.kp=1.5;                      //比例系数
pid1.ki=0.01;                     //积分系数
pid1.kd=0.01;                     //微分系数

out=pidProcess(&pid1,90, deg);    //调用算法
motor_driver(out);                //算法返回值传递到执行函数

二、结构体定义

typedef struct 
{
	uint8_t enable;						//输出使能
	uint8_t enable_lim_sum_error;	    //积分限幅使能
	uint8_t enable_lim_ouput;			//输出限幅使能
	
	double kp;  			//比例参数
	double ki;  			//积分参数
	double kd;  			//微分参数

	double lim_sum_error;	    //误差积分限幅	
	double lim_up_output;		//输出限幅 防止输出过大
	double lim_down_output;
	
	double sum_error;		//误差积分
	double last_error;		//上一次的误差
	double last_last_error;	//上上一次的误差
	
	double kd_output;
	double ki_output;
	double kp_output;
	double error_dec;

	double pid_output;
	double error;
}PID_InitTypeDef;

三、算法代码

入口参数为:

1.自己声明含有算法参数的结构体

2.设定值即期望值

3.测量值即真实值

double PidProcess(PID_InitTypeDef* pid,double input, double measure)
{
	double output = 0;
	double error = input - measure;         //计算误差

	pid->sum_error += error;

	//误差积分限幅
	if(pid->enable_lim_sum_error == 1 && fabs(pid->sum_error) > pid->lim_sum_error)
	{
			if(pid->sum_error > 0)
					pid->sum_error = pid->lim_sum_error;
			else
					pid->sum_error = -pid->lim_sum_error;
	}

	output =        pid->kp * error
							+   pid->ki * pid->sum_error
							+   pid->kd * (error - pid->last_error) ;
/**************************************************************/
    //用于观察参数,可不加
	pid->kp_output = pid->kp * error;
	pid->ki_output = pid->ki * pid->sum_error;
	pid->kd_output = pid->kd * (error - pid->last_error);	
	pid->error_dec = error - pid->last_error;
/*************************************************************/	
	//输出限幅
	if(pid->enable_lim_ouput == 1)
	{
			if(output > pid->lim_up_output)
					output = pid->lim_up_output;
			if(output < pid->lim_down_output)
					output = pid->lim_down_output;
	}
	//更新误差值
	pid->last_error = error;
	//是否使能输出
	if(pid->enable == 1)
	{
		pid->pid_output = output;
		return output;
	}
	else
	{
		pid->pid_output = 0;
		return 0;
	}
}

四、调参口诀

参数整定找最佳,从小到大顺序查;
先是比例后积分,最后再把微分加;
曲线振荡很频繁,比例度盘要放大;
曲线漂浮绕大湾,比例度盘往小扳;
曲线偏离回复慢,积分时间往下降;
曲线波动周期长,积分时间再加长;
曲线振荡频率快,先把微分降下来;
动差大来波动慢,微分时间应加长;
理想曲线两个波,前高后低四比一;
一看二调多分析,调节质量不会低。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Xiaoen_Lee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值