PID算法

一、概述

1.1 P I D含义解释

P:Prorosal(比例)力和error比例关系 P越大越灵敏

Kp静态误差系数

D:Derivative(微分) Kd-->抖动现象

Update——Angle
void update_angle(motor_angle* _angle,uint16_t angle_fb)
{
	_angle->encoder = angle_fb;
	if(_angle->encoder_is_init)
	{
		if(_angle->encoder - _angle->last_encoder > 4096)
			_angle->round_cnt --;
		else if(angle->encoder - _angle->last_encoder < - 4096)
			_angle->round_cnt ++;
	}
	else
	{
		_angle->encoder_offset = _angle->encoder;
		_angle->encoder_is_init = 1;
	}
	_angle->angle_offset = _angle->encoder_offset /8192.0f * 360.0f;
	
	_angle->last_encoder = _angle->encoder;
	_angle->total_encoder = _angle->round_cnt * 8192 + _angle->encoder - _angle->encoder_offset;
	_angle->angle = _angle->total_encoder/8192.0f * 360.f;
}

I:Integral(积分)对误差进行累积-->稳态误差

三个参数都不能太大,否则过冲

适用于二阶以内信息系统

1.2控制系统概述

  • image

               反馈是在输出后的与期望比较,前馈是对干扰进行检测或是预判得到的

  • image

  • image

传感器是测量作用,用于测量实际输出与期望输出之间的差值,并反馈给输入,然后做出调节

这里和运放的负反馈机制一样

  • image

 

  • image

  • image

参数详解

        误差

        控制器输出

        执行器输出

        实际输出

1.3连续离散信号

 

  • image

离散系统通常加保持器所以横线

  • image

1.4P I D公式理解

  • image

  • image

  • image

  • image

无人机事例

  • image

只有P的话 P增大到100 上升到99m就悬停了 所以我们引用I 来累积误差

I

  • image

D

如果没有D,升降不平稳,防止超调

D图示

1.4.1概念补充

1.4.1.1 积分限幅

             情境引入

工人按住无人机,I会累积很多,一旦松开,起飞的时候飞的就很高

设置上限卡住

1.4.1.2积分分离

1.4.1.3微分先行

二、调参

P I D 整定(一般PI就行,系统振荡明显在加上Kd)

Kp 尽量调的接近目标值

Ki 从小到大给,越大消除误差啊效果好一点

Kd 让振荡效果减弱,但是不能太大,要不然相应很慢

三、应用

RM M3508速度单环 

代码讲解

RM电机M3508速度单环

chassis_motor_pid[i].SpeedPID.target = 500;
chassis_motor_pid[i].SpeedPID.current = motor_chassis[i].speed_rpm;
pid_calc(&chassis_motor_pid[i].SpeedPID);
/*位置pid算法*/
void pid_calc(_pid* pid)
{
	pid->e = pid->target - pid->current;         //计算error
	
	pid->p_out = (int32_t)(pid->Kp * pid->e);    //计算p_out
	pid->i_out += (int32_t)(pid->Ki * pid->e);   //计算i_out
	
	//积分限幅
	limit(&(pid->i_out),pid->IntegralLimit);
	
	/* //积分分离   可以不要 只要限幅和上面的i_out
	if (fabs(pid->e) < I_Band)
	{
		pid->i_out += (int32_t)(pid->Ki * pid->e);
	}
	else
	{
			pid->i_out = 0;
	} */
	
	pid->d_out = (int32_t )(pid->Kd * (pid->e - pid->last_e)); //计算d_out
	
	pid->total_out = pid->p_out + pid->i_out + pid->d_out;
	//pid输出限幅
	limit(&(pid->total_out),pid->MaxOutput);
	
	pid->last_e = pid->e;
}

RM6020速度、角度双环(电机只能执行速度,量纲转化)

外环totalout 就是内环的target

以下是伪代码,内外环均需要做pid

update_angle(&manipulator_motor_pid[i].angle,motor_manipulator[i].angle);
manipulator_motor_pid[i].AnglePID.current = manipulator_motor_pid[i].angle.angle;
pid_calc(&manipulator_motor_pid[i].AnglePID);

manipulator_motor_pid[i].SpeedPID.target = manipulator_motor_pid[i].AnglePID.total_out;
manipulator_motor_pid[i].SpeedPID.current = manipulator_motor_pid[i].speed_rpm;
pid_calc(&manipulator_motor_pid[i].SpeedPID);

/*位置pid算法*/
void pid_calc(_pid* pid)
{
	pid->e = pid->target - pid->current;         //计算error
	
	pid->p_out = (int32_t)(pid->Kp * pid->e);    //计算p_out
	pid->i_out += (int32_t)(pid->Ki * pid->e);   //计算i_out
	
	//积分限幅
	limit(&(pid->i_out),pid->IntegralLimit);
	
	/* //积分分离   可以不要 只要限幅和上面的i_out
	if (fabs(pid->e) < I_Band)
	{
		pid->i_out += (int32_t)(pid->Ki * pid->e);
	}
	else
	{
			pid->i_out = 0;
	} */
	
	pid->d_out = (int32_t )(pid->Kd * (pid->e - pid->last_e)); //计算d_out
	
	pid->total_out = pid->p_out + pid->i_out + pid->d_out;
	//pid输出限幅
	limit(&(pid->total_out),pid->MaxOutput);
	
	pid->last_e = pid->e;
}

代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值