1. 速度环
以控制电机转速为例,希望电机通过编码器的反馈,达到平稳变速的效果。由于增量式PID输出的是控制量增量,如果计算机出现故障,误动作影响较小,而执行机构本身有记忆功能,可仍保持原位,不会严重影响系统的工作,而位置式的输出直接对应对象的输出,因此对系统影响较大。
2. PID控制器
需值得注意的事:
① PID控制器的运算必须在定时中断中执行
② 采样周期和控制周期会影响系数
控制周期即控制代码的周期,一般是放置运算PID代码的定时器周期;采样周期即获取传感器的周期,电机的采样周期是接收到电机实时数据的周期。
3. 调试中遇到的问题:
①电机响应出现极大的滞后:电机匀速时,下发speed=0,过了几秒才停止,响应滞后严重。
②电机在启动和停止时,容易出现抖动。
4. 解决方案
4.1 积分饱和
积分持续增大会造成PID输出积分比重过大,导致响应的严重滞后,需抑制积分的过度积累。
也即:①误差较大时,抑制甚至消除积分项输出;②误差较小时,放开积分项;
- 变速积分
变速积分的实质是用一个连续的函数进行积分的切换,但0和1之间的过渡未免太突兀了,在误差在[B,A+B]时,生成[0,1]的数值index,积分输出乘以index,代码如下所示:
static void Changing_Integral_Rate(PID_TypeDef *pid)
{
if (pid->Err * pid->Iout > 0) // 判断积分是否为积累趋势
{
if (ABS(pid->Err) <= pid->ScalarB)
return; //完整积分
if (ABS(pid->Err) <= (pid->ScalarA + pid->ScalarB))
//使用线性函数过渡
pid->index *= (pid->ScalarA - ABS(pid->Err) + pid->ScalarB) / pid->ScalarA;
else
pid->index= 0;//取消积分环节
}
}
PID计算
float PID_Calculate(PID_TypeDef *pid, float measure, float target)
{
pid->Err = pid->Target - pid->Measure; //得到偏差值
pError=pid->Err-pid->lasterror;
iError=pid->Err;
pid->Pout = pid->Kp * pid->Err;
Changing_Integral_Rate(pid); // 变速积分调用
pid->iout = pid->Ki * pid->Err *pid->index; //计算积分输出
//计算pid增量
pid->increment = pid->Pout + pid->Iout + pid->Dout;
pid->output += pid->increment;
}
4.2 电机加减速
电机在启停时,出现抖动是由于下发的速度突变,加速度过大
控制电机时,对下发的速度进行梯度增加或减小,由时间量计算,返回一个范围在[0,1]的数值。用于解决下发到速度环的速度突变的问题
float MoveRamp( uint8_t status, int16_t *time, int16_t inc, int16_t dec )
{
float factor = 0;
factor = 0.15 * sqrt( 0.15 * (*time) ); //计算速度斜坡,time累加到296.3斜坡就完成
if (status == 1)//按键被按下
{
if (factor < 1)//防止time太大
{
*time += inc;
}
}
else //按键松开
{
if (factor > 0)
{
*time -= dec;
if (*time < 0)
{
*time = 0;
}
}
}
factor = constrain_float( factor, 0, 1 );//注意一定是float类型限幅
return factor; //注意方向
}
评论(0)
您还未登录,请登录后发表或查看评论