FOC电流环速度环调试记录
电流环:
首先foc控制中都采用PI控制,没有引入微分,因为电流的采样率非常高不需要加入微分项;微分项的加入,会使电流采样中的高频小信号误差起到放大的作用,把小的误差放大,带到系统中来,这个时候Kd的加入容易导致震荡不但不减小反而扩大。
从数学公式上就很容易看出,比如说sin100x,微分一下不就是100cos100x了吗。
这里通过先调试 D轴,将 Q轴的 PI控制器设置为零,这样可以排除 Q轴的影响,在单轴达到比较好的响应效果之后,将 D轴的 PI控制器参数拷贝一份送给Q轴的PI控制器即可。
D轴调试时,先只加入比例环节,可以将 的系数逐渐增大,会发现反馈值逐渐靠近 给定值,再加入积分环节发现系统虽然存在超调,但是最终反馈可以稳定在给定值。加入积分环节时有个问题要注意,就是要对积分项进行限幅,否则,过大的积分会让电流环严重超调,而过小电机发挥不出力量。
参数确定:
1、
计算法
由自控原理关于电机PI控制器的传函可以推出(推导可以看TI的文章),这里看结论就行。
这里在图中可以看出,电机在dq坐标系下的电路模型中纯在dq轴的耦合项,这里可以在pi控制器后加入前馈控制器来消除耦合。
不过这里就不用前馈了,相当于在pi控制器中,直接将这误差代入pi控制器去控制了,等于用pi控制器就消去了耦合误差。
2、
经验法
调电流环目标都为0,P加大到有电流尖叫再减小一半,I=P/2。这里噪声来源于电流的反馈,所以PI参数大了就会把噪声放大通过电机震动表现出来。我手头这里有个电机经验法算出的pi和计算的几乎没差,不同电机不同而议把。
3、还有其他一些方法,可以网上再去查查。
验证:上电后,电机机械角度和电角度对准,之后进入电流闭环,再上位机给定iq目标值,电机立即加速到全速,此时用手堵住电机,观察Iq和Id的大小。
Iq表征电机的转矩,但你电机空载转矩往往小于设定的转矩,因为只有你电机转子的那一点重量和空气阻力来提供负载转矩。所以设定iq目标值后电机会立马跑满速度最大值。 当负载转矩增加也就是用手去捏的时候,电流会收敛到设定值。
速度环
这里不难,首先是获取电机速度,我这用的绝对式编码器TLE5012所以比较简单,直接按照速度环的控制周期的时间去计算电机的角度差,即dtheta/dt。
这里不除以周期了,就用dtheta角度差,其实没差,就是本来的单位是角度/每秒,现在就是速度单位改变了。我觉得本来dtheta就有误差了除这么小一个周期,也就是相乘,那么就还把误差放大了,不知道我这里的理解对不对。不过反正都能用。
下面给出我的速度计算代码:
#define SPEED_KP 0.1f
struct Speed
{
float angle;
float last_angle;
float speed;
float speed_last;
};
float SpeedCalculate(struct Speed* Speed) // 计算速度
{
float value;
//dtheta
Speed->speed = (Speed->angle - Speed->last_angle);
//解决速度正负
if(Speed->speed < -180 ){
Speed->speed = Speed->speed + 360;
}else if(Speed->speed > 180 ) {
Speed->speed = Speed->speed - 360;
}
Speed->last_angle = Speed->angle ;
//Speed->speed = Speed->speed/0.0002f; //Ts = 200us
//LPF
value = SPEED_KP * Speed->speed + (1-SPEED_KP) * Speed->speed_last;
Speed->speed_last = value;
return value;
}
这里,速度环PI参数调试就很简单了,直接看上位机图像调参就行,不再赘述。
速度环的输入是编码器角度经过差分和滤波后的值。速度环的输出是Iq的目标值,也就是速度环pid输出到电流和的pid输入。
现象:当你用手去捏电机的时候,电机会加大电流,尽力维持目标速度,当电流加大到速度环限幅也就是电流环的最大目标值的时候,电流就不会再增大了
这里对速度环的限制,同时决定了你的力矩大小。比如说我想让他转动的时候“硬”一点,也就是扭矩大一点,可以把限幅值给大一点。
速度环套一个电流环可以控制最大转矩,保证你输出的电流不至过大导致堵转烧毁。
位置环:
这里调试也比较简单,输入为角度差,输出赋值给速度环输入。
速度环输出限制代表扭矩大小,位置环输出限制代表速度大小。