串级PID算法

单环PID和串级PID的区别(框图表示)

在这里插入图片描述
在这里插入图片描述
串级PID的优势:增加稳定性,增强抗干扰性(其实不是太理解。。。)

代码实现

定义4个PID的结构体,分别用于x方向内环、外环以及y方向内环、外环(当初做板球系统xy方向用的都是同一个PID结构体变量,最后居然能调出来,惊了。。。PID真是玄学)
(一)结构体变量

//定义PID结构体
typedef struct
{
	float ek;
	float ek1;
	float esum;
	float kp;
	float ki;
	float kd;
} PID_StructureDef;

//需要开x,y两个方向的pid结构体
PID_StructureDef PID_shell_Structure_x={0,0,0,0,0,0};	//x外环pid结构体
PID_StructureDef PID_core_Structure_x={0,0,0,0,0,0};	//x内环pid结构体

PID_StructureDef PID_shell_Structure_y={0,0,0,0,0,0};	//y外环pid结构体
PID_StructureDef PID_core_Structure_y={0,0,0,0,0,0};	//y内环pid结构体

(二)PID结构体变量的参数设置函数

//设置PID结构体的初始化参数
void Set_PID_para(float kp,float ki,float kd,PID_StructureDef *PID_Structure)
{
	PID_Structure->kp=kp;
	PID_Structure->ki=ki;
	PID_Structure->kd=kd;
}

(三)PID输出计算函数,输入的是外环的误差,返回的是内环的输出

//PID计算输出
int PID_Calculate(float error,float gyro,PID_StructureDef *PID_shell_Structure,PID_StructureDef *PID_core_Structure)
{
	float shell_output,core_output;
	
	PID_shell_Structure->ek=error;
	//积分限幅
	if(PID_shell_Structure->esum>300)
		PID_shell_Structure->esum=300;
	else if(PID_shell_Structure->esum<-300)
		PID_shell_Structure->esum=-300;
	else
		PID_shell_Structure->esum+=error;
	shell_output=(PID_shell_Structure->ek)*(PID_shell_Structure->kp)+(PID_shell_Structure->esum)*(PID_shell_Structure->ki);
	
	//外环输出,作为内环输入 用陀螺仪当前的角速度作为实际值
	PID_core_Structure->ek=shell_output-gyro;
	//内环积分限幅
	if(PID_core_Structure->esum>500)
		PID_core_Structure->esum=500;
	else if(PID_core_Structure->esum<-500)
		PID_core_Structure->esum=-500;
	else
		PID_core_Structure->esum+=PID_core_Structure->ek;
	core_output=(PID_core_Structure->ek)*(PID_core_Structure->kp)+(PID_core_Structure->esum)*(PID_core_Structure->ki)+(PID_core_Structure->ek-PID_core_Structure->ek1)*(PID_core_Structure->kd);
	PID_core_Structure->ek1=PID_core_Structure->ek;
	
	return (int)core_output;
}

(四)使用的时候,输入角度误差,以及陀螺仪当前的角速度

//计算当前姿态的坐标x和y,并实现控制
void Calculate_Control(void)
{
	float temp_pitch,temp_roll,pid_x,pid_y;
	//获取陀螺仪的三个角速度
	MPU_Get_Gyroscope(&GRY_x,&GRY_y,&GRY_z);
	
	//计算误差值 以及PID xy坐标换算到角度,利用串级pid控制
	temp_pitch=atan2(Height,Goal_X)-pitch;
	pid_x=PID_Calculate(temp_pitch,GRY_x,&PID_shell_Structure_x,&PID_core_Structure_x);
	if(pid_x)
	{
		motor_1=0;
		motor_3=pid_x;
	}
	else
	{
		motor_3=0;
		motor_1=-pid_x;
	}
	
	temp_roll=atan2(Height,Goal_Y)-roll;
	pid_y=PID_Calculate(temp_roll,GRY_y,&PID_shell_Structure_y,&PID_core_Structure_y);
	if(pid_y)
	{
		motor_4=0;
		motor_2=pid_y;
	}
	else
	{
		motor_2=0;
		motor_4=-pid_y;
	}
}

注:代码虽然过了编译,但由于硬件出了问题,代码能否实现功能还不知道。。。

串级PID调参技巧

Reference:https://blog.csdn.net/nemol1990/article/details/45131603

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值