工业伺服电机位置控制编程:实现精准定位的三环PID参数自整定逻辑
伺服定位不是“位置误差乘个Kp发脉冲”就完事。标准结构是三环串级:位置环(外)→速度环(中)→电流环(内),内环响应必须远快于外环,外环输出只是内环指令。 自整定也不是魔法一键完美,工程做法是“由内向外辨参+临界振荡取初值+位置环保守微调”。
一、三环分工与调度频率
目标位置 ─▶ 位置环(P) ─▶ 速度指令
│
目标速度 ─▶ 速度环(PI) ─▶ 电流指令(Iq)
│
目标电流 ─▶ 电流环(PI) ─▶ PWM占空比 ─▶ FOC ─▶ 电机
电流环:PWM中断内跑,10~20kHz
速度环:1kHz左右
位置环:100~500Hz,常用纯P,避免积分引起定位超调
位置环输出是“目标速度”不是直接驱动力矩;速度环输出Iq给定;电流环才是真正控转矩。
二、三环PID骨架(C)
typedef struct {
float kp,ki,kd;
float err,last_err,integ;
float out_max;
} pid_t;
static inline float pid_calc(pid_t*p,float err,float d_in){
p->integ += err;
if(p->integ> p->out_max) p->integ=p->out_max;
if(p->integ<-p->out_max) p->integ=-p->out_max; // 抗饱和
float out = p->kp*err + p->ki*p->integ - p->kd*d_in;
if(out> p->out_max) out=p->out_max;
if(out<-p->out_max) out=-p->out_max;
return out;
}
/* 电流环:PWM中断 */
void current_loop_isr(float iq_ref, float iq_fb){
iq_cmd = pid_calc(&pid_i, iq_ref-iq_fb, 0);
set_pwm(iq_cmd);
}
/* 速度环:1ms任务 */
void speed_loop_1k(int32_t pos_fb){
static int32_t last_pos;
float spd = (pos_fb-last_pos)*1000/ENC_LINE; // 位置微分
float iq_ref = pid_calc(&pid_s, spd_ref-spd, 0);
last_pos=pos_fb;
}
/* 位置环:4ms任务 */
void pos_loop_4ms(int32_t pos_fb){
float verr = pos_target - pos_fb;
spd_ref = pid_p.kp * verr; // 位置环纯P
if(spd_ref>SPD_MAX)spd_ref=SPD_MAX;
if(spd_ref<-SPD_MAX)spd_ref=-SPD_MAX;
}
位置环别加I,定位收尾会来回过冲;要消静差靠速度环Iq积分和前馈补偿。
三、自整定顺序:先内后外
颠倒顺序必震。电流环没稳,速度环怎么调都抖。
电流环:现代驱动器上电自动辨识R/L,一般不动;自写FOC才需调Kpi/Kii
速度环:位置环切到“速度模式”或禁能,给阶跃速度指令,看转速响应
位置环:速度环稳了再开,给目标位置做点对点定位
四、继电反馈取临界参数(速度环用)
自整定让系统在小幅继电输出下起等幅振荡,测临界增益Ku和周期Tu:
typedef enum{T_INIT,T_OSC,T_DONE}tune_st;
tune_st ts=T_INIT;
float relay_h=0.3f; // 输出幅值(标幺)
float last_pv, t0, tu, ku;
uint8_t edges;
void speed_autotune(float spd_fb){
float e = spd_target - spd_fb;
if(ts==T_INIT){
spd_ref = (e>0)? relay_h : -relay_h; // 继电切换
if((last_pv-spd_fb)<0 && e<0){ // 过零记录
float period = now_us()-t0;
t0=now_us();
if(period>500){ tu=period/1e6f; edges++; }
}
last_pv=spd_fb;
if(edges>=4){ // 稳定振荡
ku = 4*relay_h/(3.14159f*osc_amp);
pid_s.kp = 0.45f*ku; // PI保守初值
pid_s.ki = 0.45f*ku/(0.83f*tu);
ts=T_DONE;
}
}
}
Z-N公式给的是初值不是终值,伺服现场再乘0.6~0.8系数防振。
五、位置环自整定只给初值
位置环不建议继电振荡(机械冲击大),做法:
速度环整定完后,位置环Kp从自整定值60%起步
发一段定位指令,看超调/调节时间
每次Kp加10%~20%,出现换向抖动就回退
加速度前馈spd_ref += Kff * d(pos_target)
spd_ref = kp_pos*verr + kff*(pos_target-pos_last)/dt;
前馈补动态,P补稳态误差,别全靠Kp硬拉。
六、必须加的兜底
输出限幅:电流环限Iq_max,速度环限额定转速
积分抗饱和:外环给内环指令超限时清integ
软件限位:目标位置超出行程直接钳位
自整定失败→回默认参数,别写0
机械谐振:速度环加陷波滤波器,别一味降增益
自整定时空载/轻载,带重负载再手动微调
参数存NVRAM,上电加载,别每次自整定
七、落坑清单
直接调位置环Kp→平台抖动
位置环加I→定位过冲来回摆
速度环没稳就开位置环→失稳
自整定在带载下做→Ku偏小响应钝
Z-N参数直接用→伺服啸叫
无积分抗饱和→限位后冲一下
速度反馈用位置差分不滤波→噪声放大
前馈系数过大→启停冲击
自整定结果不存→掉电重来
谐振靠降Kp压→动态变烂
八、落地顺序
FOC电流环先跑稳(自动辨识或手调PI)
速度环禁位置环,继电自整定取Ku/Tu
Z-N初值×0.7写入,阶跃微调
开位置环纯P,Kp从60%起加
加速度前馈、限幅、抗饱和
出现谐振加陷波不降刚性的
参数存NVRAM,自整定失败回退
带载复测,重负载工况补微调
三环PID自整定的本质不是“自动算出完美参数”,是内环先稳→外环才有基础;自整定只给初值→现场按超调收敛微调。位置环别碰I、速度环别省抗饱和、电流环别在自整定里瞎动;继电反馈适合速度环,位置环靠阶跃+前馈更稳。真正量产伺服里,自整定是“出厂给一组可用参数”,不是“运行期替代调试”——这点想通了,定位抖动和换向啸叫基本都能收住。





