4、位置环原理:定位精度、速度环耦合与PID整定

位置环,说白了就是三环控制里最外面那层。它管的是“最终位置准不准”。我刚开始做伺服驱动时,总觉得位置环就是速度环外面加个比例系数,后来被现场打脸好几次,才明白这里面的门道有多深。

4.1 定位精度要求——你到底要停多准?

定位精度不是越高越好。你想想看,一个包装机的位置精度要求,跟一个数控机床的精度要求,能一样吗?

我个人习惯,先看三个指标:

  • 稳态误差:系统稳定后,实际位置跟目标位置的偏差。单位通常是脉冲数或微米。
  • 重复定位精度:同一指令跑十次,每次停的位置偏差范围。这个比绝对精度更重要。
  • 跟随误差:运动过程中,实际位置滞后于指令位置的程度。高速时尤其明显。

经验数据参考:一般工业应用,位置环稳态误差控制在±1个编码器脉冲以内就算合格。高精度场合,比如半导体设备,要求亚脉冲级定位——这时候就得靠前馈和插补了。

我在项目中遇到过一台贴片机,定位精度要求±0.01mm。一开始怎么调都超差,后来发现是编码器分辨率不够。换了17位编码器后,问题迎刃而解。嗯,这里要注意:精度要求先看传感器,再看控制器。

4.2 位置环与速度环的耦合——剪不断理还乱

位置环的输出,就是速度环的输入。这个关系看起来简单,实际调起来很容易互相打架。

为什么会这样?因为位置环的响应速度,受限于速度环的带宽。速度环带宽越高,位置环才能跑得越快越准。反过来,如果速度环调得软绵绵的,位置环再怎么使劲也没用。

我建议的耦合处理原则:

  1. 先调好速度环。速度环没调稳,别碰位置环。这是铁律。
  2. 位置环增益不要超过速度环带宽的1/5。超过这个比例,系统容易振荡。
  3. 注意积分饱和。位置环的积分项如果饱和,速度环会收到一个持续增大的指令,后果就是超调甚至飞车。

我曾经踩过的坑:有一台龙门双驱设备,左右两个位置环独立整定都没问题,一联动就抖。查了两天才发现,是左右速度环的带宽不一致,导致位置环输出打架。解决办法是把两个速度环参数统一,再重新整定位置环。

下面这张图,是我常用的位置环与速度环耦合关系示意:

位置环与速度环耦合关系图 位置环PID 速度环PID 电机+负载 位置传感器 速度估算/测速 速度指令 电流指令 实际位置 位置反馈 速度前馈(可选) 关键说明: 1. 位置环输出限幅 = 速度环最大允许指令,防止积分饱和导致飞车。 2. 速度环带宽决定位置环上限,一般位置环增益 ≤ 速度环带宽 × 0.2。 3. 速度前馈可提升跟随性能,但会降低抗扰能力,需权衡使用。

4.3 位置环的PID参数整定——实战手法

位置环PID跟速度环不太一样。比例项P是主力,积分项I要慎用,微分项D基本不用——除非你搞的是高动态响应。

我总结了一套“三步走”整定法:

步骤 操作 现象判断 我的经验值
第一步 I=0,D=0,只加P 从0开始慢慢加P,直到位置响应出现轻微振荡 P值通常取速度环P的0.1~0.3倍
第二步 P取临界值的60%~80% 阶跃响应无超调或微超调,稳态误差在允许范围 如果稳态误差偏大,考虑加I
第三步 加I项消除静差 I从0.001开始加,观察定位时间 I值一般不超过P的1/10

小技巧:位置环整定时,我习惯用阶跃指令测试。给一个固定位置跳变,看响应曲线。如果出现“爬行”现象——就是快到目标位置时慢吞吞地蹭过去——说明P偏小或I偏大。

这里给一段我常用的位置环PID代码框架,用的是C语言风格:

// 位置环PID计算(增量式)
float pos_pid_calc(float target_pos, float actual_pos, float vel_feedforward)
{
    float error = target_pos - actual_pos;
    float p_out = pos_kp * error;
    
    // 积分项带限幅和抗饱和
    pos_integral += pos_ki * error * dt;
    if(pos_integral > pos_i_limit)  pos_integral = pos_i_limit;
    if(pos_integral < -pos_i_limit) pos_integral = -pos_i_limit;
    
    // 微分项(通常不用,这里保留接口)
    float d_out = 0.0f;
    // if(pos_kd > 0.0f) d_out = pos_kd * (error - last_error) / dt;
    
    // 速度前馈(可选)
    float ff_out = pos_kff * vel_feedforward;
    
    // 输出 = P + I + D + 前馈
    float output = p_out + pos_integral + d_out + ff_out;
    
    // 输出限幅(对应速度环最大指令)
    if(output > pos_out_limit)  output = pos_out_limit;
    if(output < -pos_out_limit) output = -pos_out_limit;
    
    last_error = error;
    return output;
}

注意:上面的积分限幅 pos_i_limit 一定要设。我曾经在一个项目中忘了加这个限幅,结果位置环积分项一路累加,速度环收到一个巨大的指令,电机直接冲过限位开关——还好有硬限位保护,不然就撞机了。

4.4 几个实战避坑点

  • 位置环增益不是越高越好。增益太高,系统会“嗡嗡”响,那是机械谐振的前兆。我一般用扫频法找谐振点,然后避开它。
  • 注意编码器噪声。位置反馈有毛刺的话,位置环输出也会跟着抖。可以在反馈路径上加个低通滤波,但要注意相位延迟。
  • 加减速曲线要匹配。位置环的S曲线或梯形曲线,加速度不能超过电机和机械的承受能力。否则位置环调得再好,机械也会“咔咔”响。

嗯,位置环的内容差不多就这些。核心就三句话:精度看传感器和稳态误差,耦合靠速度环带宽支撑,整定用P为主I为辅。你把这些吃透了,位置环基本不会出大问题。