Chapter1 三环串联控制
多环控制
电流、速度、位置 环路

电流环
电流环的输入是速度环PID调节后的输出,我们称为“电流环的给定”。
电流环给定值 和 电流环的反馈值 进行比较后的误差在电流环内做PID调节输出给电机。
速度环
速度环的输入就是位置环PID调节后的输出以及位置设定的前馈值,我们称为“速度设定”。
速度设定 和 速度环反馈 值进行比较后的误差在速度环做PID调节(主要是比例增益和积分处理)后输出就是上面讲到的“电流环的给定”。
速度环的反馈来自于编码器的反馈后的值经过 编码器-速度换算 得到的。所以速度环控制时就包合了速度环和电流环,换句话说任何形式都必须使用电流环,电流环是控制的根本,在速度和位置控制的同时系统实际也在进行电流(转矩)的控制以达到对速度和位置的相应控制。
位置环
位置环的输入就是外部的脉冲(通常情况下,直接写数据到驱动器地址的伺服例外),外部的脉冲经过平滑滤波处理和电子齿轮计算后作为“位置环的设定”。
位置环的设定 和 来自编码器反馈的脉冲信号 经过偏差计数器的计算后的数值在经过位置环的PID调节(比例增益调节,无积分微分环节)后输出和位置给定的前馈信号的合值就构成了上面讲的速度环的给定。
位置环的反馈也来自于编码器。由于位置控制环内部输出就是速度环的设定,位置控制模式下系统进行了所有三个环路的运算,此时的系统运算量最大,动态响应速度也最慢。
编码器安装于伺服电机尾部,它和电流环没有任何联系,他采样来自于电机的转动而不是电机电流,和电流环的输入、输出、反馈没有任何联系。而电流环是在驱动器内部形成的,即使没有电机,只要在每相上安装模拟负载(例如电灯泡)电流环就能形成反馈工作。
三环控制示例
/*----------------------------------三环控制----------------------------------*/
bdcm_position = encoder_get_position(); //计算位置
bdcm_speed_r_min = encoder_get_speed(); //计算速度
bdcm_current_now = get_current(); //获得电流
//位置有偏差,进入PID计算
if((bdcm_position < bdcm_position_pid.target - POS_DEAD_ZONE)\
||(bdcm_position > bdcm_position_pid.target + POS_DEAD_ZONE)))
{
/*----------------------------------位置环----------------------------------*/
bdcm_pwm_period = positional_pid(&bdcm_position_pid,bdcm_position);//位置pid计算
//限制位置环结果,作为速度设置值
#define BDCM_SPEED_PID_SET_LIMIT 100
if(bdcm_pwm_period < -BDCM_SPEED_PID_SET_LIMIT)
{
bdcm_pwm_period = -BDCM_SPEED_PID_SET_LIMIT;
}
else if(bdcm_pwm_period > BDCM_SPEED_PID_SET_LIMIT)
{
bdcm_pwm_period = BDCM_SPEED_PID_SET_LIMIT;
}
bdcm_speed_pid.target = bdcm_pwm_period;//位置pid结果控制速度设置值
if(bdcm_speed_pid.target != 0)
{
/*----------------------------------速度环----------------------------------*/
bdcm_pwm_period = incremental_pid(&bdcm_speed_pid,bdcm_speed_r_min);//速度pid计算
//限制速度环结果,作为电流环设置值
#define BDCM_CURRENT_PID_SET_LIMIT 30
if(bdcm_pwm_period < -BDCM_CURRENT_PID_SET_POINT)
{
bdcm_pwm_period=-BDCM_CURRENT_PID_SET_POINT;
}
else if(bdcm_pwm_period > BDCM_CURRENT_PID_SET_POINT)
{
bdcm_pwm_period=BDCM_CURRENT_PID_SET_POINT;
}
bdcm_current_pid.target = bdcm_pwm_period;//速度pid结果控制电流设置值
/*----------------------------------电流环----------------------------------*/
bdcm_pwm_period = incremental_pid(&bdcm_current_pid,bdcm_current_now);//电流pid计算
if(bdcm_speed_pid.target > 0)
bdcm_set(FORWARD_DIRCTION,bdcm_pwm_period);//正向输出
else
bdcm_set(BACKWARD_DIRCTION,-bdcm_pwm_period);//反向输出
}
}
//死区内不进行控制
else
{
bdcm_speed_pid.setpoint = 0;
bdcm_current_pid.setpoint = 0;
bdcm_pwm_period = 0;
}