pid控制以及调试经验

01-基本原理

其实pid就是一个反馈的过程,所以如果当前值大于目标值,就应该设置小一点,如果小于,就该设置的大一点。

所以目前设置的测速的增加方向,与设置pwm为正值的方向一致。则误差值应该为目标值减去当前值,这样才能达到反馈的目的。

02-代码编撰

0-pwm速度设置

/**
  * @brief  电机输出控制
  * @param  motor_pwm: 占空比 0-7200
  * @retval None  
  */
void Set_Pwm(int motor_pwm)
{
  if(motor_pwm>0)
  {
	  BIN1=1;
      BIN2=0; //前进 
  }
	 
 else if(motor_pwm<0)
	{
		BIN1=0;
		BIN2=1; //后退
	}		
	else  //停止
	{
		BIN1=0;
		BIN2=0; 
	}
	PWMB=myabs(motor_pwm);//pwm绝对值
	TIM_SetCompare4(TIM1, PWMB);
}

1-定义pid参数结构体

typedef struct
{
	float target_val;   //目标值
	float Error;          /*第 k 次偏差 */
	float LastError;     /* Error[-1],第 k-1 次偏差 */
	float PrevError;    /* Error[-2],第 k-2 次偏差 */
	float Kp,Ki,Kd;     //比例、积分、微分系数
	float integral;     //积分值
	float output_val;   //输出值
}PID;

2-pid初始化

/**
  * @brief  PID参数初始化
  *	@note 	无
  * @retval 无
  */
void PID_param_init()
{
	PosionPID.target_val=3600;				
	PosionPID.output_val=0.0;
	PosionPID.Error=0.0;
	PosionPID.LastError=0.0;
	PosionPID.integral=0.0;
	PosionPID.Kp = 10;
	PosionPID.Ki = 0.5;
	PosionPID.Kd = 0.8;


}

3-位置式pid控制器

/**
  * @brief  位置PID算法实现
  * @param  actual_val:实际测量值
  *	@note 	无
  * @retval 通过PID计算后的输出
  */
float PosionPID_realize(PID *pid, float actual_val)
{
	/*计算目标值与实际值的误差*/
	pid->Error = pid->target_val - actual_val;
	/*积分项*/
	pid->integral += pid->Error;
	/*PID算法实现*/
	pid->output_val = pid->Kp * pid->Error +
	                  pid->Ki * pid->integral +
	                  pid->Kd *(pid->Error -pid->LastError);
	/*误差传递*/
	pid-> LastError = pid->Error;
	/*返回当前实际值*/
	return pid->output_val;
}

4-增量式pid控制器

/**
  * @brief  速度PID算法实现
  * @param  actual_val:实际值
  *	@note 	无
  * @retval 通过PID计算后的输出
  */
float addPID_realize(PID *pid, float actual_val)
{
	/*计算目标值与实际值的误差*/
	pid->Error = pid->target_val - actual_val;
	/*PID算法实现,照搬公式*/
	pid->output_val += pid->Kp * (pid->Error - pid-> LastError) +
	                  pid->Ki * pid->Error +
	                  pid->Kd *(pid->Error -2*pid->LastError+pid->PrevError);
	/*误差传递*/
	pid-> PrevError = pid->LastError;
	pid-> LastError = pid->Error;
	/*返回当前实际值*/
	return pid->output_val;
}

03调试

1-测试极性

观察在pwm为正时,编码器是否为正

此时极性为反,修改一下setpwm的方向就行

2-测试pwm极性

发现当pwm值为0-10时转动极快,到了980-999时几近不转,此时应该修正,修改一下映射关系,将1000映射为0。

3-发现问题

1-正转的时候能够稳定的运行,反转的时候就会走一下卡顿一下(头痛)

最后发现,正转,反转时候需要的pwm占空比不同。正转时占空比越大跑的越快,反转时占空比越大跑的越慢。

2-能稳定在速度为0,但是可以很轻易的摆动。(正拧有一定力气,反拧没有力气)

发现原因,根据上文的关系,正转反转不是需要相反的占空比嘛。但是在一个为90,一个为10的情况下(即相互相反),一个可以转,一个不能转

最终的问题:接线接错了……

如果各位遇见这样的问题的话,记得一定要先排查接线是否有误,别像我似的排查一下午弄出来这么些鬼东西。

4-上位机调试

现在问题已经基本全部解决,能够较为稳定的运行在目标速度,可以进行上位机调参进行优化了。

我认为其实位置式中仅p值,调节的时候就代表一直在加速,只不过误差大的时候加速快,误差小的时候加速慢,直到达到一个值,使pwm值与误差正好对应,此时会形成静差(应该是这样的)。所以调节p值达到的目的应该是能够稳定在一个位置并发生小幅度震荡。之后调节的i值反而是影响响应速度与减少震荡的关键。

之后用vofa上位机捏一个差不多的曲线就行。

调试经验:暂无,以后补充。

04-疑问解释

(纯瞎掰,不用在意)

1-位置式pid

如果调节速度环,那么,只调节p值的话,

①原有速度3m/s,误差7m/s,pwm值占空比为50,此时通过pid控制器将占空比设置为70

②速度升高为6m/s,误差4m/s,pwm值占空比经过pid控制器设置为40,占空比减小了,速度进而下降了

这应该不是所谓稳态误差一类吧(我理解的稳态误差是由于阻力导致的,而不是程序问题导致的)

所以这是为什么?

个人理解:

我认为其实位置式中仅p值,调节的时候就代表一直在加速,只不过误差大的时候加速快,误差小的时候加速慢,直到达到一个值,使pwm值与误差正好对应,此时会形成静差(应该是这样的)。所以调节p值达到的目的应该是能够稳定在一个位置并发生小幅度震荡。之后调节的i值反而是影响响应速度与减少震荡的关键。

2-增量式pid

完全不理解

  • 29
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值